From a33fe13cd1c30b24a3d1e44d21ed3d575771efb6 Mon Sep 17 00:00:00 2001 From: "github-merge-queue[bot]" Date: Mon, 27 May 2024 01:16:31 +0000 Subject: [PATCH] =?UTF-8?q?Deploying=20to=20gh-pages=20from=20@=20actix/ac?= =?UTF-8?q?tix-web@26efa64278ccb0ec2a0d49f0364c9d7930bb57f5=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .lock | 0 .nojekyll | 0 actix_files/all.html | 1 + actix_files/directory/struct.Directory.html | 11 + actix_files/files/struct.Files.html | 11 + actix_files/fn.file_extension_to_mime.html | 4 + actix_files/index.html | 11 + actix_files/named/struct.NamedFile.html | 11 + actix_files/range/struct.HttpRange.html | 11 + actix_files/service/struct.FilesService.html | 11 + actix_files/sidebar-items.js | 1 + actix_files/struct.Directory.html | 25 + actix_files/struct.Files.html | 131 + actix_files/struct.FilesService.html | 29 + actix_files/struct.HttpRange.html | 27 + actix_files/struct.NamedFile.html | 306 ++ actix_http/all.html | 1 + .../body/body_stream/struct.BodyStream.html | 11 + actix_http/body/boxed/struct.BoxBody.html | 11 + actix_http/body/either/enum.EitherBody.html | 11 + actix_http/body/enum.BodySize.html | 46 + actix_http/body/enum.EitherBody.html | 57 + actix_http/body/fn.to_bytes.html | 15 + actix_http/body/fn.to_bytes_limited.html | 22 + actix_http/body/index.html | 3 + .../body/message_body/trait.MessageBody.html | 11 + actix_http/body/none/struct.None.html | 11 + actix_http/body/sidebar-items.js | 1 + actix_http/body/size/enum.BodySize.html | 11 + .../body/sized_stream/struct.SizedStream.html | 11 + actix_http/body/struct.BodyLimitExceeded.html | 19 + actix_http/body/struct.BodyStream.html | 37 + actix_http/body/struct.BoxBody.html | 26 + actix_http/body/struct.None.html | 29 + actix_http/body/struct.SizedStream.html | 39 + actix_http/body/trait.MessageBody.html | 139 + actix_http/body/utils/fn.to_bytes.html | 11 + .../body/utils/fn.to_bytes_limited.html | 11 + .../body/utils/struct.BodyLimitExceeded.html | 11 + .../builder/struct.HttpServiceBuilder.html | 11 + actix_http/config/struct.ServiceConfig.html | 11 + .../encoding/decoder/struct.Decoder.html | 11 + .../encoding/encoder/struct.Encoder.html | 11 + actix_http/encoding/index.html | 2 + actix_http/encoding/sidebar-items.js | 1 + actix_http/encoding/struct.Decoder.html | 260 ++ actix_http/encoding/struct.Encoder.html | 30 + actix_http/enum.ConnectionType.html | 32 + actix_http/enum.KeepAlive.html | 35 + actix_http/enum.Payload.html | 268 ++ actix_http/enum.Protocol.html | 31 + actix_http/enum.RequestHeadType.html | 20 + actix_http/error/enum.ContentTypeError.html | 24 + actix_http/error/enum.DispatchError.html | 40 + actix_http/error/enum.ParseError.html | 40 + actix_http/error/enum.PayloadError.html | 32 + actix_http/error/index.html | 2 + actix_http/error/sidebar-items.js | 1 + actix_http/error/struct.Error.html | 18 + actix_http/error/struct.HttpError.html | 26 + actix_http/extensions/struct.Extensions.html | 11 + actix_http/h1/client/struct.ClientCodec.html | 11 + .../h1/client/struct.ClientPayloadCodec.html | 11 + actix_http/h1/codec/struct.Codec.html | 11 + .../h1/dispatcher/struct.Dispatcher.html | 11 + actix_http/h1/enum.Message.html | 36 + actix_http/h1/enum.MessageType.html | 29 + .../h1/expect/struct.ExpectHandler.html | 11 + actix_http/h1/index.html | 2 + actix_http/h1/payload/struct.Payload.html | 11 + actix_http/h1/service/struct.H1Service.html | 11 + .../h1/service/type.H1ServiceHandler.html | 11 + actix_http/h1/sidebar-items.js | 1 + actix_http/h1/struct.ClientCodec.html | 38 + actix_http/h1/struct.ClientPayloadCodec.html | 30 + actix_http/h1/struct.Codec.html | 38 + actix_http/h1/struct.Dispatcher.html | 136 + actix_http/h1/struct.ExpectHandler.html | 40 + actix_http/h1/struct.H1Service.html | 171 + actix_http/h1/struct.Payload.html | 263 ++ actix_http/h1/struct.SendResponse.html | 118 + actix_http/h1/struct.UpgradeHandler.html | 40 + actix_http/h1/type.H1ServiceHandler.html | 2 + .../h1/upgrade/struct.UpgradeHandler.html | 11 + actix_http/h1/utils/struct.SendResponse.html | 11 + .../h2/dispatcher/struct.Dispatcher.html | 11 + actix_http/h2/index.html | 2 + actix_http/h2/service/struct.H2Service.html | 11 + actix_http/h2/sidebar-items.js | 1 + actix_http/h2/struct.Dispatcher.html | 119 + actix_http/h2/struct.H2Service.html | 101 + actix_http/h2/struct.Payload.html | 253 ++ .../header/as_name/trait.AsHeaderName.html | 11 + .../header/common/constant.CACHE_STATUS.html | 11 + .../common/constant.CDN_CACHE_CONTROL.html | 11 + ...constant.CROSS_ORIGIN_EMBEDDER_POLICY.html | 11 + .../constant.CROSS_ORIGIN_OPENER_POLICY.html | 11 + ...constant.CROSS_ORIGIN_RESOURCE_POLICY.html | 11 + .../common/constant.PERMISSIONS_POLICY.html | 11 + .../common/constant.X_FORWARDED_FOR.html | 11 + .../common/constant.X_FORWARDED_HOST.html | 11 + .../common/constant.X_FORWARDED_PROTO.html | 11 + actix_http/header/constant.ACCEPT.html | 10 + .../header/constant.ACCEPT_CHARSET.html | 12 + .../header/constant.ACCEPT_ENCODING.html | 28 + .../header/constant.ACCEPT_LANGUAGE.html | 21 + actix_http/header/constant.ACCEPT_RANGES.html | 7 + ...tant.ACCESS_CONTROL_ALLOW_CREDENTIALS.html | 20 + ...constant.ACCESS_CONTROL_ALLOW_HEADERS.html | 12 + ...constant.ACCESS_CONTROL_ALLOW_METHODS.html | 5 + .../constant.ACCESS_CONTROL_ALLOW_ORIGIN.html | 3 + ...onstant.ACCESS_CONTROL_EXPOSE_HEADERS.html | 3 + .../constant.ACCESS_CONTROL_MAX_AGE.html | 2 + ...nstant.ACCESS_CONTROL_REQUEST_HEADERS.html | 3 + ...onstant.ACCESS_CONTROL_REQUEST_METHOD.html | 3 + actix_http/header/constant.AGE.html | 6 + actix_http/header/constant.ALLOW.html | 7 + actix_http/header/constant.ALT_SVC.html | 2 + actix_http/header/constant.AUTHORIZATION.html | 4 + actix_http/header/constant.CACHE_CONTROL.html | 6 + actix_http/header/constant.CACHE_STATUS.html | 4 + .../header/constant.CDN_CACHE_CONTROL.html | 4 + actix_http/header/constant.CONNECTION.html | 12 + .../header/constant.CONTENT_DISPOSITION.html | 16 + .../header/constant.CONTENT_ENCODING.html | 9 + .../header/constant.CONTENT_LANGUAGE.html | 12 + .../header/constant.CONTENT_LENGTH.html | 4 + .../header/constant.CONTENT_LOCATION.html | 10 + actix_http/header/constant.CONTENT_RANGE.html | 2 + .../constant.CONTENT_SECURITY_POLICY.html | 6 + ...t.CONTENT_SECURITY_POLICY_REPORT_ONLY.html | 6 + actix_http/header/constant.CONTENT_TYPE.html | 9 + actix_http/header/constant.COOKIE.html | 5 + ...constant.CROSS_ORIGIN_EMBEDDER_POLICY.html | 3 + .../constant.CROSS_ORIGIN_OPENER_POLICY.html | 3 + ...constant.CROSS_ORIGIN_RESOURCE_POLICY.html | 3 + actix_http/header/constant.DATE.html | 2 + actix_http/header/constant.DNT.html | 4 + actix_http/header/constant.ETAG.html | 13 + actix_http/header/constant.EXPECT.html | 19 + actix_http/header/constant.EXPIRES.html | 6 + actix_http/header/constant.FORWARDED.html | 9 + actix_http/header/constant.FROM.html | 7 + actix_http/header/constant.HOST.html | 8 + actix_http/header/constant.IF_MATCH.html | 25 + .../header/constant.IF_MODIFIED_SINCE.html | 13 + actix_http/header/constant.IF_NONE_MATCH.html | 31 + actix_http/header/constant.IF_RANGE.html | 12 + .../header/constant.IF_UNMODIFIED_SINCE.html | 22 + actix_http/header/constant.LAST_MODIFIED.html | 2 + actix_http/header/constant.LINK.html | 3 + actix_http/header/constant.LOCATION.html | 29 + actix_http/header/constant.MAX_FORWARDS.html | 3 + actix_http/header/constant.ORIGIN.html | 6 + .../header/constant.PERMISSIONS_POLICY.html | 3 + actix_http/header/constant.PRAGMA.html | 6 + .../header/constant.PROXY_AUTHENTICATE.html | 14 + .../header/constant.PROXY_AUTHORIZATION.html | 5 + .../header/constant.PUBLIC_KEY_PINS.html | 6 + .../constant.PUBLIC_KEY_PINS_REPORT_ONLY.html | 5 + actix_http/header/constant.RANGE.html | 8 + actix_http/header/constant.REFERER.html | 6 + .../header/constant.REFERRER_POLICY.html | 3 + actix_http/header/constant.REFRESH.html | 3 + actix_http/header/constant.RETRY_AFTER.html | 15 + .../header/constant.SEC_WEBSOCKET_ACCEPT.html | 5 + .../constant.SEC_WEBSOCKET_EXTENSIONS.html | 6 + .../header/constant.SEC_WEBSOCKET_KEY.html | 8 + .../constant.SEC_WEBSOCKET_PROTOCOL.html | 6 + .../constant.SEC_WEBSOCKET_VERSION.html | 7 + actix_http/header/constant.SERVER.html | 7 + actix_http/header/constant.SET_COOKIE.html | 2 + .../constant.STRICT_TRANSPORT_SECURITY.html | 2 + actix_http/header/constant.TE.html | 8 + actix_http/header/constant.TRAILER.html | 3 + .../header/constant.TRANSFER_ENCODING.html | 11 + actix_http/header/constant.UPGRADE.html | 2 + .../constant.UPGRADE_INSECURE_REQUESTS.html | 3 + actix_http/header/constant.USER_AGENT.html | 3 + actix_http/header/constant.VARY.html | 9 + actix_http/header/constant.VIA.html | 7 + actix_http/header/constant.WARNING.html | 6 + .../header/constant.WWW_AUTHENTICATE.html | 3 + .../constant.X_CONTENT_TYPE_OPTIONS.html | 11 + .../constant.X_DNS_PREFETCH_CONTROL.html | 10 + .../header/constant.X_FORWARDED_FOR.html | 3 + .../header/constant.X_FORWARDED_HOST.html | 3 + .../header/constant.X_FORWARDED_PROTO.html | 3 + .../header/constant.X_FRAME_OPTIONS.html | 7 + .../header/constant.X_XSS_PROTECTION.html | 9 + actix_http/header/enum.Charset.html | 79 + actix_http/header/enum.ContentEncoding.html | 46 + actix_http/header/fn.fmt_comma_delimited.html | 3 + .../header/fn.from_comma_delimited.html | 4 + actix_http/header/fn.from_one_raw_str.html | 4 + actix_http/header/fn.http_percent_encode.html | 2 + .../header/fn.parse_extended_value.html | 30 + actix_http/header/fn.q.html | 21 + actix_http/header/index.html | 69 + .../into_pair/trait.TryIntoHeaderPair.html | 11 + .../into_value/trait.TryIntoHeaderValue.html | 11 + actix_http/header/map/index.html | 2 + actix_http/header/map/sidebar-items.js | 1 + actix_http/header/map/struct.Drain.html | 203 + actix_http/header/map/struct.HeaderMap.html | 332 ++ actix_http/header/map/struct.IntoIter.html | 206 + actix_http/header/map/struct.Iter.html | 202 + actix_http/header/map/struct.Keys.html | 202 + actix_http/header/map/struct.Removed.html | 220 + .../header/shared/charset/enum.Charset.html | 11 + .../enum.ContentEncoding.html | 11 + .../extended/fn.parse_extended_value.html | 11 + .../shared/extended/struct.ExtendedValue.html | 11 + .../shared/http_date/struct.HttpDate.html | 11 + actix_http/header/shared/quality/fn.q.html | 11 + .../header/shared/quality/struct.Quality.html | 11 + .../quality_item/struct.QualityItem.html | 11 + .../header/shared/struct.LanguageTag.html | 11 + actix_http/header/sidebar-items.js | 1 + actix_http/header/struct.ExtendedValue.html | 39 + actix_http/header/struct.HeaderName.html | 136 + actix_http/header/struct.HeaderValue.html | 204 + actix_http/header/struct.HttpDate.html | 33 + .../header/struct.InvalidHeaderName.html | 19 + .../header/struct.InvalidHeaderValue.html | 20 + actix_http/header/struct.LanguageTag.html | 177 + actix_http/header/struct.Quality.html | 52 + actix_http/header/struct.QualityItem.html | 64 + actix_http/header/struct.ToStrError.html | 21 + actix_http/header/trait.AsHeaderName.html | 2 + actix_http/header/trait.Header.html | 8 + .../header/trait.TryIntoHeaderPair.html | 18 + .../header/trait.TryIntoHeaderValue.html | 9 + .../header/utils/fn.fmt_comma_delimited.html | 11 + .../header/utils/fn.from_comma_delimited.html | 11 + .../header/utils/fn.from_one_raw_str.html | 11 + .../header/utils/fn.http_percent_encode.html | 11 + .../http_message/trait.HttpMessage.html | 11 + actix_http/index.html | 14 + actix_http/keep_alive/enum.KeepAlive.html | 11 + actix_http/message/enum.ConnectionType.html | 11 + actix_http/message/struct.Message.html | 11 + actix_http/payload/enum.Payload.html | 11 + .../payload/type.BoxedPayloadStream.html | 11 + .../requests/head/enum.RequestHeadType.html | 11 + .../requests/head/struct.RequestHead.html | 11 + .../requests/request/struct.Request.html | 11 + .../builder/struct.ResponseBuilder.html | 11 + .../responses/head/struct.ResponseHead.html | 11 + .../responses/response/struct.Response.html | 11 + actix_http/service/struct.HttpService.html | 11 + .../service/struct.TlsAcceptorConfig.html | 11 + actix_http/sidebar-items.js | 1 + actix_http/struct.Extensions.html | 65 + actix_http/struct.HttpService.html | 255 ++ actix_http/struct.HttpServiceBuilder.html | 92 + actix_http/struct.Message.html | 20 + actix_http/struct.Method.html | 71 + actix_http/struct.Request.html | 47 + actix_http/struct.RequestHead.html | 36 + actix_http/struct.Response.html | 51 + actix_http/struct.ResponseBuilder.html | 87 + actix_http/struct.ResponseHead.html | 36 + actix_http/struct.ServiceConfig.html | 37 + actix_http/struct.StatusCode.html | 221 + actix_http/struct.TlsAcceptorConfig.html | 19 + actix_http/struct.Uri.html | 284 ++ actix_http/struct.Version.html | 40 + actix_http/test/index.html | 2 + actix_http/test/sidebar-items.js | 1 + actix_http/test/struct.TestBuffer.html | 172 + actix_http/test/struct.TestRequest.html | 28 + actix_http/test/struct.TestSeqBuffer.html | 169 + actix_http/test/struct.TestSeqInner.html | 17 + actix_http/trait.HttpMessage.html | 31 + actix_http/type.BoxedPayloadStream.html | 2 + actix_http/uri/index.html | 19 + actix_http/uri/sidebar-items.js | 1 + actix_http/uri/struct.Authority.html | 138 + actix_http/uri/struct.Builder.html | 70 + actix_http/uri/struct.InvalidUri.html | 19 + actix_http/uri/struct.InvalidUriParts.html | 19 + actix_http/uri/struct.Parts.html | 28 + actix_http/uri/struct.PathAndQuery.html | 122 + actix_http/uri/struct.Port.html | 48 + actix_http/uri/struct.Scheme.html | 45 + actix_http/uri/struct.Uri.html | 284 ++ actix_http/ws/codec/enum.Frame.html | 11 + actix_http/ws/codec/enum.Item.html | 11 + actix_http/ws/codec/enum.Message.html | 11 + actix_http/ws/codec/struct.Codec.html | 11 + .../ws/dispatcher/struct.Dispatcher.html | 11 + actix_http/ws/enum.CloseCode.html | 72 + actix_http/ws/enum.Frame.html | 37 + actix_http/ws/enum.HandshakeError.html | 39 + actix_http/ws/enum.Item.html | 29 + actix_http/ws/enum.Message.html | 43 + actix_http/ws/enum.OpCode.html | 41 + actix_http/ws/enum.ProtocolError.html | 40 + actix_http/ws/fn.handshake.html | 2 + actix_http/ws/fn.handshake_response.html | 3 + actix_http/ws/fn.hash_key.html | 3 + actix_http/ws/fn.verify_handshake.html | 2 + actix_http/ws/frame/struct.Parser.html | 11 + actix_http/ws/index.html | 4 + actix_http/ws/proto/enum.CloseCode.html | 11 + actix_http/ws/proto/enum.OpCode.html | 11 + actix_http/ws/proto/fn.hash_key.html | 11 + actix_http/ws/proto/struct.CloseReason.html | 11 + actix_http/ws/sidebar-items.js | 1 + actix_http/ws/struct.CloseReason.html | 30 + actix_http/ws/struct.Codec.html | 38 + actix_http/ws/struct.Dispatcher.html | 130 + actix_http/ws/struct.Parser.html | 32 + actix_http_test/all.html | 1 + actix_http_test/fn.test_server.html | 28 + actix_http_test/fn.test_server_with_addr.html | 5 + actix_http_test/fn.unused_addr.html | 2 + actix_http_test/index.html | 2 + actix_http_test/sidebar-items.js | 1 + actix_http_test/struct.TestServer.html | 52 + actix_multipart/all.html | 1 + actix_multipart/enum.MultipartError.html | 52 + .../error/enum.MultipartError.html | 11 + actix_multipart/form/bytes/index.html | 2 + actix_multipart/form/bytes/sidebar-items.js | 1 + actix_multipart/form/bytes/struct.Bytes.html | 29 + .../form/derive.MultipartForm.html | 76 + actix_multipart/form/index.html | 3 + .../form/json/enum.JsonFieldError.html | 23 + actix_multipart/form/json/index.html | 2 + actix_multipart/form/json/sidebar-items.js | 1 + actix_multipart/form/json/struct.Json.html | 33 + .../form/json/struct.JsonConfig.html | 21 + actix_multipart/form/sidebar-items.js | 1 + actix_multipart/form/struct.Limits.html | 33 + .../form/struct.MultipartForm.html | 34 + .../form/struct.MultipartFormConfig.html | 24 + .../form/tempfile/enum.TempFileError.html | 21 + actix_multipart/form/tempfile/index.html | 2 + .../form/tempfile/sidebar-items.js | 1 + .../form/tempfile/struct.TempFile.html | 31 + .../form/tempfile/struct.TempFileConfig.html | 23 + actix_multipart/form/text/enum.TextError.html | 25 + actix_multipart/form/text/index.html | 2 + actix_multipart/form/text/sidebar-items.js | 1 + actix_multipart/form/text/struct.Text.html | 36 + .../form/text/struct.TextConfig.html | 24 + actix_multipart/form/trait.FieldReader.html | 20 + .../form/trait.MultipartCollect.html | 24 + actix_multipart/index.html | 35 + actix_multipart/server/struct.Field.html | 11 + actix_multipart/server/struct.Multipart.html | 11 + actix_multipart/sidebar-items.js | 1 + actix_multipart/struct.Field.html | 269 ++ actix_multipart/struct.Multipart.html | 279 ++ ....create_form_data_payload_and_headers.html | 44 + ...ata_payload_and_headers_with_boundary.html | 9 + actix_multipart/test/index.html | 1 + actix_multipart/test/sidebar-items.js | 1 + actix_multipart_derive/all.html | 1 + .../derive.MultipartForm.html | 76 + actix_multipart_derive/index.html | 4 + actix_multipart_derive/sidebar-items.js | 1 + actix_router/all.html | 1 + actix_router/de/struct.PathDeserializer.html | 11 + actix_router/enum.Patterns.html | 25 + actix_router/index.html | 2 + actix_router/path/struct.Path.html | 11 + actix_router/pattern/enum.Patterns.html | 11 + actix_router/pattern/trait.IntoPatterns.html | 11 + actix_router/quoter/struct.Quoter.html | 11 + actix_router/resource/struct.ResourceDef.html | 11 + .../resource_path/trait.Resource.html | 11 + .../resource_path/trait.ResourcePath.html | 11 + actix_router/router/struct.ResourceId.html | 11 + actix_router/router/struct.Router.html | 11 + actix_router/router/struct.RouterBuilder.html | 11 + actix_router/sidebar-items.js | 1 + actix_router/struct.Path.html | 42 + actix_router/struct.PathDeserializer.html | 103 + actix_router/struct.Quoter.html | 32 + actix_router/struct.ResourceDef.html | 403 ++ actix_router/struct.ResourceId.html | 19 + actix_router/struct.Router.html | 64 + actix_router/struct.RouterBuilder.html | 52 + actix_router/struct.Url.html | 19 + actix_router/trait.IntoPatterns.html | 5 + actix_router/trait.Resource.html | 9 + actix_router/trait.ResourcePath.html | 4 + actix_router/url/struct.Url.html | 11 + actix_test/all.html | 1 + actix_test/enum.PayloadError.html | 35 + actix_test/fn.call_and_read_body.html | 32 + actix_test/fn.call_and_read_body_json.html | 43 + actix_test/fn.call_service.html | 28 + actix_test/fn.config.html | 2 + actix_test/fn.init_service.html | 27 + actix_test/fn.ok_service.html | 3 + actix_test/fn.read_body.html | 28 + actix_test/fn.read_body_json.html | 44 + actix_test/fn.start.html | 29 + actix_test/fn.start_with.html | 30 + actix_test/fn.status_service.html | 4 + actix_test/fn.to_bytes.html | 16 + actix_test/fn.unused_addr.html | 2 + actix_test/index.html | 25 + actix_test/sidebar-items.js | 1 + actix_test/struct.Client.html | 75 + actix_test/struct.ClientRequest.html | 100 + actix_test/struct.ClientResponse.html | 293 ++ actix_test/struct.Connector.html | 90 + actix_test/struct.TestBuffer.html | 179 + actix_test/struct.TestRequest.html | 93 + actix_test/struct.TestServer.html | 46 + actix_test/struct.TestServerConfig.html | 30 + actix_web/all.html | 1 + actix_web/app/struct.App.html | 11 + actix_web/attr.connect.html | 19 + actix_web/attr.delete.html | 19 + actix_web/attr.get.html | 19 + actix_web/attr.head.html | 19 + actix_web/attr.main.html | 10 + actix_web/attr.options.html | 19 + actix_web/attr.patch.html | 19 + actix_web/attr.post.html | 19 + actix_web/attr.put.html | 19 + actix_web/attr.route.html | 21 + actix_web/attr.routes.html | 18 + actix_web/attr.test.html | 7 + actix_web/attr.trace.html | 19 + actix_web/body/enum.BodySize.html | 46 + actix_web/body/enum.EitherBody.html | 61 + actix_web/body/fn.to_bytes.html | 16 + actix_web/body/fn.to_bytes_limited.html | 23 + actix_web/body/index.html | 3 + actix_web/body/sidebar-items.js | 1 + actix_web/body/struct.BodyLimitExceeded.html | 22 + actix_web/body/struct.BodyStream.html | 37 + actix_web/body/struct.BoxBody.html | 26 + actix_web/body/struct.None.html | 29 + actix_web/body/struct.SizedStream.html | 39 + actix_web/body/trait.MessageBody.html | 133 + actix_web/config/struct.AppConfig.html | 11 + actix_web/config/struct.AppService.html | 11 + actix_web/config/struct.ServiceConfig.html | 11 + actix_web/cookie/enum.Expiration.html | 103 + actix_web/cookie/enum.KeyError.html | 23 + actix_web/cookie/enum.ParseError.html | 34 + actix_web/cookie/enum.SameSite.html | 75 + actix_web/cookie/index.html | 58 + actix_web/cookie/sidebar-items.js | 1 + actix_web/cookie/struct.Cookie.html | 534 +++ actix_web/cookie/struct.CookieBuilder.html | 142 + actix_web/cookie/struct.CookieJar.html | 351 ++ actix_web/cookie/struct.Delta.html | 202 + actix_web/cookie/struct.Display.html | 37 + actix_web/cookie/struct.Iter.html | 202 + actix_web/cookie/struct.Key.html | 99 + actix_web/cookie/struct.PrivateJar.html | 113 + actix_web/cookie/struct.SignedJar.html | 112 + actix_web/cookie/time/convert/index.html | 2 + .../cookie/time/convert/sidebar-items.js | 1 + actix_web/cookie/time/convert/struct.Day.html | 30 + .../cookie/time/convert/struct.Hour.html | 31 + .../time/convert/struct.Microsecond.html | 35 + .../time/convert/struct.Millisecond.html | 34 + .../cookie/time/convert/struct.Minute.html | 32 + .../time/convert/struct.Nanosecond.html | 36 + .../cookie/time/convert/struct.Second.html | 33 + .../cookie/time/convert/struct.Week.html | 29 + actix_web/cookie/time/enum.Error.html | 45 + actix_web/cookie/time/enum.Month.html | 63 + actix_web/cookie/time/enum.Weekday.html | 72 + actix_web/cookie/time/error/enum.Error.html | 45 + actix_web/cookie/time/error/enum.Format.html | 27 + .../error/enum.InvalidFormatDescription.html | 76 + actix_web/cookie/time/error/enum.Parse.html | 35 + .../time/error/enum.ParseFromDescription.html | 37 + .../cookie/time/error/enum.TryFromParsed.html | 38 + actix_web/cookie/time/error/index.html | 6 + actix_web/cookie/time/error/sidebar-items.js | 1 + .../time/error/struct.ComponentRange.html | 37 + .../time/error/struct.ConversionRange.html | 29 + .../time/error/struct.DifferentVariant.html | 29 + .../time/error/struct.InvalidVariant.html | 29 + actix_web/cookie/time/ext/index.html | 3 + actix_web/cookie/time/ext/sidebar-items.js | 1 + .../cookie/time/ext/trait.InstantExt.html | 34 + .../time/ext/trait.NumericalDuration.html | 48 + .../time/ext/trait.NumericalStdDuration.html | 68 + .../enum.BorrowedFormatItem.html | 57 + .../format_description/enum.Component.html | 73 + .../format_description/enum.FormatItem.html | 57 + .../enum.OwnedFormatItem.html | 56 + .../time/format_description/fn.parse.html | 9 + .../format_description/fn.parse_borrowed.html | 7 + .../format_description/fn.parse_owned.html | 9 + .../cookie/time/format_description/index.html | 7 + .../modifier/enum.MonthRepr.html | 34 + .../modifier/enum.Padding.html | 34 + .../modifier/enum.SubsecondDigits.html | 49 + .../modifier/enum.UnixTimestampPrecision.html | 36 + .../modifier/enum.WeekNumberRepr.html | 33 + .../modifier/enum.WeekdayRepr.html | 37 + .../modifier/enum.YearRepr.html | 31 + .../format_description/modifier/index.html | 2 + .../modifier/sidebar-items.js | 1 + .../modifier/struct.Day.html | 35 + .../modifier/struct.End.html | 33 + .../modifier/struct.Hour.html | 39 + .../modifier/struct.Ignore.html | 30 + .../modifier/struct.Minute.html | 35 + .../modifier/struct.Month.html | 43 + .../modifier/struct.OffsetHour.html | 39 + .../modifier/struct.OffsetMinute.html | 35 + .../modifier/struct.OffsetSecond.html | 35 + .../modifier/struct.Ordinal.html | 35 + .../modifier/struct.Period.html | 40 + .../modifier/struct.Second.html | 35 + .../modifier/struct.Subsecond.html | 37 + .../modifier/struct.UnixTimestamp.html | 39 + .../modifier/struct.WeekNumber.html | 39 + .../modifier/struct.Weekday.html | 43 + .../modifier/struct.Year.html | 45 + .../time/format_description/sidebar-items.js | 1 + .../format_description/well_known/index.html | 2 + .../well_known/iso8601/enum.DateKind.html | 32 + .../iso8601/enum.FormattedComponents.html | 41 + .../iso8601/enum.OffsetPrecision.html | 30 + .../iso8601/enum.TimePrecision.html | 41 + .../well_known/iso8601/index.html | 2 + .../well_known/iso8601/sidebar-items.js | 1 + .../well_known/iso8601/struct.Config.html | 45 + .../well_known/iso8601/struct.Iso8601.html | 59 + .../iso8601/type.EncodedConfig.html | 4 + .../well_known/sidebar-items.js | 1 + .../well_known/struct.Iso8601.html | 59 + .../well_known/struct.Rfc2822.html | 37 + .../well_known/struct.Rfc3339.html | 36 + actix_web/cookie/time/formatting/index.html | 2 + .../cookie/time/formatting/sidebar-items.js | 1 + .../time/formatting/trait.Formattable.html | 7 + actix_web/cookie/time/index.html | 66 + actix_web/cookie/time/macros/index.html | 2 + actix_web/cookie/time/macros/macro.date!.html | 11 + actix_web/cookie/time/macros/macro.date.html | 1 + .../cookie/time/macros/macro.datetime!.html | 11 + .../cookie/time/macros/macro.datetime.html | 1 + .../macros/macro.format_description!.html | 11 + .../time/macros/macro.format_description.html | 1 + .../cookie/time/macros/macro.offset!.html | 11 + .../cookie/time/macros/macro.offset.html | 1 + actix_web/cookie/time/macros/macro.time!.html | 11 + actix_web/cookie/time/macros/macro.time.html | 1 + actix_web/cookie/time/macros/sidebar-items.js | 1 + actix_web/cookie/time/parsing/index.html | 2 + .../cookie/time/parsing/sidebar-items.js | 1 + .../cookie/time/parsing/struct.Parsed.html | 125 + .../cookie/time/parsing/trait.Parsable.html | 4 + actix_web/cookie/time/sidebar-items.js | 1 + actix_web/cookie/time/struct.Date.html | 479 +++ actix_web/cookie/time/struct.Duration.html | 389 ++ actix_web/cookie/time/struct.Instant.html | 89 + .../cookie/time/struct.OffsetDateTime.html | 632 +++ .../cookie/time/struct.PrimitiveDateTime.html | 467 +++ actix_web/cookie/time/struct.Time.html | 245 ++ actix_web/cookie/time/struct.UtcOffset.html | 131 + actix_web/cookie/time/type.Result.html | 7 + .../cookie/time/util/fn.days_in_year.html | 9 + .../time/util/fn.days_in_year_month.html | 4 + .../cookie/time/util/fn.is_leap_year.html | 9 + .../cookie/time/util/fn.weeks_in_year.html | 6 + actix_web/cookie/time/util/index.html | 3 + actix_web/cookie/time/util/sidebar-items.js | 1 + actix_web/data/struct.Data.html | 11 + actix_web/dev/enum.JsonBody.html | 137 + actix_web/dev/enum.Payload.html | 270 ++ actix_web/dev/fn.fn_factory.html | 38 + actix_web/dev/fn.fn_service.html | 6 + actix_web/dev/index.html | 10 + actix_web/dev/macro.always_ready!.html | 11 + actix_web/dev/macro.always_ready.html | 24 + actix_web/dev/macro.forward_ready!.html | 11 + actix_web/dev/macro.forward_ready.html | 28 + actix_web/dev/sidebar-items.js | 1 + actix_web/dev/struct.AppConfig.html | 34 + actix_web/dev/struct.AppService.html | 32 + actix_web/dev/struct.ConnectionInfo.html | 66 + actix_web/dev/struct.Decompress.html | 260 ++ actix_web/dev/struct.Extensions.html | 70 + actix_web/dev/struct.Path.html | 51 + actix_web/dev/struct.PeerAddr.html | 44 + actix_web/dev/struct.Readlines.html | 260 ++ actix_web/dev/struct.RequestHead.html | 36 + actix_web/dev/struct.ResourceDef.html | 412 ++ actix_web/dev/struct.ResourceMap.html | 41 + actix_web/dev/struct.Response.html | 58 + actix_web/dev/struct.ResponseHead.html | 35 + actix_web/dev/struct.Server.html | 176 + actix_web/dev/struct.ServerHandle.html | 23 + actix_web/dev/struct.ServiceRequest.html | 84 + actix_web/dev/struct.ServiceResponse.html | 40 + actix_web/dev/struct.Url.html | 20 + actix_web/dev/struct.UrlEncoded.html | 121 + actix_web/dev/struct.WebService.html | 37 + actix_web/dev/trait.HttpServiceFactory.html | 8 + actix_web/dev/trait.ResourcePath.html | 4 + actix_web/dev/trait.Service.html | 176 + actix_web/dev/trait.ServiceFactory.html | 135 + actix_web/dev/trait.Transform.html | 89 + actix_web/enum.Either.html | 94 + actix_web/error/enum.ContentTypeError.html | 27 + actix_web/error/enum.DispatchError.html | 43 + actix_web/error/enum.JsonPayloadError.html | 37 + actix_web/error/enum.ParseError.html | 43 + actix_web/error/enum.PathError.html | 23 + actix_web/error/enum.PayloadError.html | 35 + actix_web/error/enum.QueryPayloadError.html | 22 + actix_web/error/enum.ReadlinesError.html | 28 + actix_web/error/enum.UrlGenerationError.html | 32 + actix_web/error/enum.UrlencodedError.html | 39 + actix_web/error/error/struct.Error.html | 11 + actix_web/error/fn.ErrorBadGateway.html | 3 + actix_web/error/fn.ErrorBadRequest.html | 3 + actix_web/error/fn.ErrorConflict.html | 3 + .../error/fn.ErrorExpectationFailed.html | 3 + actix_web/error/fn.ErrorFailedDependency.html | 3 + actix_web/error/fn.ErrorForbidden.html | 3 + actix_web/error/fn.ErrorGatewayTimeout.html | 3 + actix_web/error/fn.ErrorGone.html | 3 + .../fn.ErrorHttpVersionNotSupported.html | 3 + actix_web/error/fn.ErrorImATeapot.html | 3 + .../error/fn.ErrorInsufficientStorage.html | 3 + .../error/fn.ErrorInternalServerError.html | 3 + actix_web/error/fn.ErrorLengthRequired.html | 3 + actix_web/error/fn.ErrorLocked.html | 3 + actix_web/error/fn.ErrorLoopDetected.html | 3 + actix_web/error/fn.ErrorMethodNotAllowed.html | 3 + .../error/fn.ErrorMisdirectedRequest.html | 3 + ...fn.ErrorNetworkAuthenticationRequired.html | 3 + actix_web/error/fn.ErrorNotAcceptable.html | 3 + actix_web/error/fn.ErrorNotExtended.html | 3 + actix_web/error/fn.ErrorNotFound.html | 3 + actix_web/error/fn.ErrorNotImplemented.html | 3 + actix_web/error/fn.ErrorPayloadTooLarge.html | 3 + actix_web/error/fn.ErrorPaymentRequired.html | 3 + .../error/fn.ErrorPreconditionFailed.html | 3 + .../error/fn.ErrorPreconditionRequired.html | 3 + .../fn.ErrorProxyAuthenticationRequired.html | 3 + .../error/fn.ErrorRangeNotSatisfiable.html | 3 + .../fn.ErrorRequestHeaderFieldsTooLarge.html | 3 + actix_web/error/fn.ErrorRequestTimeout.html | 3 + .../error/fn.ErrorServiceUnavailable.html | 3 + actix_web/error/fn.ErrorTooManyRequests.html | 3 + actix_web/error/fn.ErrorUnauthorized.html | 3 + .../fn.ErrorUnavailableForLegalReasons.html | 3 + .../error/fn.ErrorUnprocessableEntity.html | 3 + .../error/fn.ErrorUnsupportedMediaType.html | 3 + actix_web/error/fn.ErrorUpgradeRequired.html | 3 + actix_web/error/fn.ErrorUriTooLong.html | 3 + .../error/fn.ErrorVariantAlsoNegotiates.html | 3 + actix_web/error/index.html | 2 + .../error/internal/fn.ErrorBadGateway.html | 11 + .../error/internal/fn.ErrorBadRequest.html | 11 + .../error/internal/fn.ErrorConflict.html | 11 + .../internal/fn.ErrorExpectationFailed.html | 11 + .../internal/fn.ErrorFailedDependency.html | 11 + .../error/internal/fn.ErrorForbidden.html | 11 + .../internal/fn.ErrorGatewayTimeout.html | 11 + actix_web/error/internal/fn.ErrorGone.html | 11 + .../fn.ErrorHttpVersionNotSupported.html | 11 + .../error/internal/fn.ErrorImATeapot.html | 11 + .../internal/fn.ErrorInsufficientStorage.html | 11 + .../internal/fn.ErrorInternalServerError.html | 11 + .../internal/fn.ErrorLengthRequired.html | 11 + actix_web/error/internal/fn.ErrorLocked.html | 11 + .../error/internal/fn.ErrorLoopDetected.html | 11 + .../internal/fn.ErrorMethodNotAllowed.html | 11 + .../internal/fn.ErrorMisdirectedRequest.html | 11 + ...fn.ErrorNetworkAuthenticationRequired.html | 11 + .../error/internal/fn.ErrorNotAcceptable.html | 11 + .../error/internal/fn.ErrorNotExtended.html | 11 + .../error/internal/fn.ErrorNotFound.html | 11 + .../internal/fn.ErrorNotImplemented.html | 11 + .../internal/fn.ErrorPayloadTooLarge.html | 11 + .../internal/fn.ErrorPaymentRequired.html | 11 + .../internal/fn.ErrorPreconditionFailed.html | 11 + .../fn.ErrorPreconditionRequired.html | 11 + .../fn.ErrorProxyAuthenticationRequired.html | 11 + .../internal/fn.ErrorRangeNotSatisfiable.html | 11 + .../fn.ErrorRequestHeaderFieldsTooLarge.html | 11 + .../internal/fn.ErrorRequestTimeout.html | 11 + .../internal/fn.ErrorServiceUnavailable.html | 11 + .../internal/fn.ErrorTooManyRequests.html | 11 + .../error/internal/fn.ErrorUnauthorized.html | 11 + .../fn.ErrorUnavailableForLegalReasons.html | 11 + .../internal/fn.ErrorUnprocessableEntity.html | 11 + .../fn.ErrorUnsupportedMediaType.html | 11 + .../internal/fn.ErrorUpgradeRequired.html | 11 + .../error/internal/fn.ErrorUriTooLong.html | 11 + .../fn.ErrorVariantAlsoNegotiates.html | 11 + .../error/internal/struct.InternalError.html | 11 + .../response_error/trait.ResponseError.html | 11 + actix_web/error/sidebar-items.js | 1 + actix_web/error/struct.BlockingError.html | 19 + actix_web/error/struct.Error.html | 28 + actix_web/error/struct.HttpError.html | 26 + actix_web/error/struct.InternalError.html | 33 + actix_web/error/trait.ResponseError.html | 16 + actix_web/error/type.Result.html | 8 + actix_web/extract/trait.FromRequest.html | 11 + .../guard/acceptable/struct.Acceptable.html | 11 + actix_web/guard/fn.All.html | 14 + actix_web/guard/fn.Any.html | 12 + actix_web/guard/fn.Connect.html | 10 + actix_web/guard/fn.Delete.html | 10 + actix_web/guard/fn.Get.html | 10 + actix_web/guard/fn.Head.html | 10 + actix_web/guard/fn.Header.html | 11 + actix_web/guard/fn.Host.html | 47 + actix_web/guard/fn.Method.html | 2 + actix_web/guard/fn.Options.html | 10 + actix_web/guard/fn.Patch.html | 10 + actix_web/guard/fn.Post.html | 10 + actix_web/guard/fn.Put.html | 10 + actix_web/guard/fn.Trace.html | 10 + actix_web/guard/fn.fn_guard.html | 11 + actix_web/guard/host/fn.Host.html | 11 + actix_web/guard/index.html | 37 + actix_web/guard/sidebar-items.js | 1 + actix_web/guard/struct.Acceptable.html | 31 + actix_web/guard/struct.AllGuard.html | 21 + actix_web/guard/struct.AnyGuard.html | 21 + actix_web/guard/struct.GuardContext.html | 32 + actix_web/guard/struct.Not.html | 32 + actix_web/guard/trait.Guard.html | 8 + actix_web/handler/trait.Handler.html | 11 + actix_web/http/enum.ConnectionType.html | 32 + actix_web/http/enum.KeepAlive.html | 35 + .../http/header/accept/struct.Accept.html | 11 + .../accept_charset/struct.AcceptCharset.html | 11 + .../struct.AcceptEncoding.html | 11 + .../struct.AcceptLanguage.html | 11 + actix_web/http/header/allow/struct.Allow.html | 11 + .../cache_control/enum.CacheDirective.html | 11 + .../cache_control/struct.CacheControl.html | 11 + actix_web/http/header/constant.ACCEPT.html | 10 + .../http/header/constant.ACCEPT_CHARSET.html | 12 + .../http/header/constant.ACCEPT_ENCODING.html | 28 + .../http/header/constant.ACCEPT_LANGUAGE.html | 21 + .../http/header/constant.ACCEPT_RANGES.html | 7 + ...tant.ACCESS_CONTROL_ALLOW_CREDENTIALS.html | 20 + ...constant.ACCESS_CONTROL_ALLOW_HEADERS.html | 12 + ...constant.ACCESS_CONTROL_ALLOW_METHODS.html | 5 + .../constant.ACCESS_CONTROL_ALLOW_ORIGIN.html | 3 + ...onstant.ACCESS_CONTROL_EXPOSE_HEADERS.html | 3 + .../constant.ACCESS_CONTROL_MAX_AGE.html | 2 + ...nstant.ACCESS_CONTROL_REQUEST_HEADERS.html | 3 + ...onstant.ACCESS_CONTROL_REQUEST_METHOD.html | 3 + actix_web/http/header/constant.AGE.html | 6 + actix_web/http/header/constant.ALLOW.html | 7 + actix_web/http/header/constant.ALT_SVC.html | 2 + .../http/header/constant.AUTHORIZATION.html | 4 + .../http/header/constant.CACHE_CONTROL.html | 6 + .../http/header/constant.CACHE_STATUS.html | 4 + .../header/constant.CDN_CACHE_CONTROL.html | 4 + .../http/header/constant.CONNECTION.html | 12 + .../header/constant.CONTENT_DISPOSITION.html | 16 + .../header/constant.CONTENT_ENCODING.html | 9 + .../header/constant.CONTENT_LANGUAGE.html | 12 + .../http/header/constant.CONTENT_LENGTH.html | 4 + .../header/constant.CONTENT_LOCATION.html | 10 + .../http/header/constant.CONTENT_RANGE.html | 2 + .../constant.CONTENT_SECURITY_POLICY.html | 6 + ...t.CONTENT_SECURITY_POLICY_REPORT_ONLY.html | 6 + .../http/header/constant.CONTENT_TYPE.html | 9 + actix_web/http/header/constant.COOKIE.html | 5 + ...constant.CROSS_ORIGIN_EMBEDDER_POLICY.html | 3 + .../constant.CROSS_ORIGIN_OPENER_POLICY.html | 3 + ...constant.CROSS_ORIGIN_RESOURCE_POLICY.html | 3 + actix_web/http/header/constant.DATE.html | 2 + actix_web/http/header/constant.DNT.html | 4 + actix_web/http/header/constant.ETAG.html | 13 + actix_web/http/header/constant.EXPECT.html | 19 + actix_web/http/header/constant.EXPIRES.html | 6 + actix_web/http/header/constant.FORWARDED.html | 9 + actix_web/http/header/constant.FROM.html | 7 + actix_web/http/header/constant.HOST.html | 8 + actix_web/http/header/constant.IF_MATCH.html | 25 + .../header/constant.IF_MODIFIED_SINCE.html | 13 + .../http/header/constant.IF_NONE_MATCH.html | 31 + actix_web/http/header/constant.IF_RANGE.html | 12 + .../header/constant.IF_UNMODIFIED_SINCE.html | 22 + .../http/header/constant.LAST_MODIFIED.html | 2 + actix_web/http/header/constant.LINK.html | 3 + actix_web/http/header/constant.LOCATION.html | 29 + .../http/header/constant.MAX_FORWARDS.html | 3 + actix_web/http/header/constant.ORIGIN.html | 6 + .../header/constant.PERMISSIONS_POLICY.html | 3 + actix_web/http/header/constant.PRAGMA.html | 6 + .../header/constant.PROXY_AUTHENTICATE.html | 14 + .../header/constant.PROXY_AUTHORIZATION.html | 5 + .../http/header/constant.PUBLIC_KEY_PINS.html | 6 + .../constant.PUBLIC_KEY_PINS_REPORT_ONLY.html | 5 + actix_web/http/header/constant.RANGE.html | 8 + actix_web/http/header/constant.REFERER.html | 6 + .../http/header/constant.REFERRER_POLICY.html | 3 + actix_web/http/header/constant.REFRESH.html | 3 + .../http/header/constant.RETRY_AFTER.html | 15 + .../header/constant.SEC_WEBSOCKET_ACCEPT.html | 5 + .../constant.SEC_WEBSOCKET_EXTENSIONS.html | 6 + .../header/constant.SEC_WEBSOCKET_KEY.html | 8 + .../constant.SEC_WEBSOCKET_PROTOCOL.html | 6 + .../constant.SEC_WEBSOCKET_VERSION.html | 7 + actix_web/http/header/constant.SERVER.html | 7 + .../http/header/constant.SET_COOKIE.html | 2 + .../constant.STRICT_TRANSPORT_SECURITY.html | 2 + actix_web/http/header/constant.TE.html | 8 + actix_web/http/header/constant.TRAILER.html | 3 + .../header/constant.TRANSFER_ENCODING.html | 11 + actix_web/http/header/constant.UPGRADE.html | 2 + .../constant.UPGRADE_INSECURE_REQUESTS.html | 3 + .../http/header/constant.USER_AGENT.html | 3 + actix_web/http/header/constant.VARY.html | 9 + actix_web/http/header/constant.VIA.html | 7 + actix_web/http/header/constant.WARNING.html | 6 + .../header/constant.WWW_AUTHENTICATE.html | 3 + .../constant.X_CONTENT_TYPE_OPTIONS.html | 11 + .../constant.X_DNS_PREFETCH_CONTROL.html | 10 + .../http/header/constant.X_FORWARDED_FOR.html | 3 + .../header/constant.X_FORWARDED_HOST.html | 3 + .../header/constant.X_FORWARDED_PROTO.html | 3 + .../http/header/constant.X_FRAME_OPTIONS.html | 7 + .../header/constant.X_XSS_PROTECTION.html | 9 + .../enum.DispositionParam.html | 11 + .../enum.DispositionType.html | 11 + .../struct.ContentDisposition.html | 11 + .../struct.ContentLanguage.html | 11 + .../content_length/struct.ContentLength.html | 11 + .../content_range/enum.ContentRangeSpec.html | 11 + .../content_range/struct.ContentRange.html | 11 + .../content_type/struct.ContentType.html | 11 + actix_web/http/header/date/struct.Date.html | 11 + .../http/header/encoding/enum.Encoding.html | 11 + .../http/header/entity/struct.EntityTag.html | 11 + actix_web/http/header/enum.ByteRangeSpec.html | 63 + .../http/header/enum.CacheDirective.html | 53 + actix_web/http/header/enum.Charset.html | 79 + .../http/header/enum.ContentEncoding.html | 54 + .../http/header/enum.ContentRangeSpec.html | 57 + .../http/header/enum.DispositionParam.html | 72 + .../http/header/enum.DispositionType.html | 38 + actix_web/http/header/enum.Encoding.html | 33 + actix_web/http/header/enum.IfMatch.html | 69 + actix_web/http/header/enum.IfNoneMatch.html | 71 + actix_web/http/header/enum.IfRange.html | 72 + actix_web/http/header/enum.Preference.html | 50 + actix_web/http/header/enum.Range.html | 76 + actix_web/http/header/etag/struct.ETag.html | 11 + .../http/header/expires/struct.Expires.html | 11 + .../http/header/fn.fmt_comma_delimited.html | 6 + .../http/header/fn.from_comma_delimited.html | 4 + .../http/header/fn.from_one_raw_str.html | 3 + .../http/header/fn.http_percent_encode.html | 5 + .../http/header/fn.parse_extended_value.html | 30 + actix_web/http/header/fn.q.html | 21 + .../http/header/if_match/enum.IfMatch.html | 11 + .../struct.IfModifiedSince.html | 11 + .../if_none_match/enum.IfNoneMatch.html | 11 + .../http/header/if_range/enum.IfRange.html | 11 + .../struct.IfUnmodifiedSince.html | 11 + actix_web/http/header/index.html | 94 + .../last_modified/struct.LastModified.html | 11 + actix_web/http/header/map/index.html | 2 + actix_web/http/header/map/sidebar-items.js | 1 + actix_web/http/header/map/struct.Drain.html | 203 + .../http/header/map/struct.HeaderMap.html | 330 ++ .../http/header/map/struct.IntoIter.html | 206 + actix_web/http/header/map/struct.Iter.html | 202 + actix_web/http/header/map/struct.Keys.html | 202 + actix_web/http/header/map/struct.Removed.html | 220 + .../header/preference/enum.Preference.html | 11 + .../http/header/range/enum.ByteRangeSpec.html | 11 + actix_web/http/header/range/enum.Range.html | 11 + actix_web/http/header/sidebar-items.js | 1 + actix_web/http/header/struct.Accept.html | 3167 +++++++++++++++ .../http/header/struct.AcceptCharset.html | 3141 +++++++++++++++ .../http/header/struct.AcceptEncoding.html | 3155 +++++++++++++++ .../http/header/struct.AcceptLanguage.html | 3149 +++++++++++++++ actix_web/http/header/struct.Allow.html | 3135 +++++++++++++++ .../http/header/struct.CacheControl.html | 3133 +++++++++++++++ .../header/struct.ContentDisposition.html | 138 + .../http/header/struct.ContentLanguage.html | 3135 +++++++++++++++ .../http/header/struct.ContentLength.html | 59 + .../http/header/struct.ContentRange.html | 30 + actix_web/http/header/struct.ContentType.html | 90 + actix_web/http/header/struct.Date.html | 47 + actix_web/http/header/struct.ETag.html | 72 + actix_web/http/header/struct.EntityTag.html | 72 + actix_web/http/header/struct.Expires.html | 50 + .../http/header/struct.ExtendedValue.html | 39 + actix_web/http/header/struct.HeaderMap.html | 330 ++ actix_web/http/header/struct.HeaderName.html | 136 + actix_web/http/header/struct.HeaderValue.html | 208 + actix_web/http/header/struct.HttpDate.html | 35 + .../http/header/struct.IfModifiedSince.html | 50 + .../http/header/struct.IfUnmodifiedSince.html | 50 + .../http/header/struct.InvalidHeaderName.html | 19 + .../header/struct.InvalidHeaderValue.html | 20 + actix_web/http/header/struct.LanguageTag.html | 177 + .../http/header/struct.LastModified.html | 49 + actix_web/http/header/struct.Quality.html | 52 + actix_web/http/header/struct.QualityItem.html | 74 + actix_web/http/header/struct.ToStrError.html | 21 + actix_web/http/header/trait.AsHeaderName.html | 2 + actix_web/http/header/trait.Header.html | 10 + .../http/header/trait.TryIntoHeaderPair.html | 29 + .../http/header/trait.TryIntoHeaderValue.html | 29 + actix_web/http/index.html | 2 + actix_web/http/sidebar-items.js | 1 + actix_web/http/struct.Error.html | 18 + actix_web/http/struct.Method.html | 80 + actix_web/http/struct.StatusCode.html | 221 + actix_web/http/struct.Uri.html | 293 ++ actix_web/http/struct.Version.html | 40 + actix_web/http/uri/index.html | 19 + actix_web/http/uri/sidebar-items.js | 1 + actix_web/http/uri/struct.Authority.html | 138 + actix_web/http/uri/struct.Builder.html | 70 + actix_web/http/uri/struct.InvalidUri.html | 19 + .../http/uri/struct.InvalidUriParts.html | 19 + actix_web/http/uri/struct.Parts.html | 28 + actix_web/http/uri/struct.PathAndQuery.html | 122 + actix_web/http/uri/struct.Port.html | 48 + actix_web/http/uri/struct.Scheme.html | 45 + actix_web/http/uri/struct.Uri.html | 293 ++ actix_web/index.html | 77 + actix_web/info/struct.ConnectionInfo.html | 11 + actix_web/info/struct.PeerAddr.html | 11 + actix_web/macro.services!.html | 11 + actix_web/macro.services.html | 22 + .../middleware/compat/struct.Compat.html | 11 + .../middleware/compress/struct.Compress.html | 11 + .../condition/struct.Condition.html | 11 + .../struct.DefaultHeaders.html | 11 + .../middleware/enum.ErrorHandlerResponse.html | 24 + actix_web/middleware/enum.TrailingSlash.html | 30 + .../enum.ErrorHandlerResponse.html | 11 + .../err_handlers/struct.ErrorHandlers.html | 11 + actix_web/middleware/index.html | 165 + .../middleware/logger/struct.Logger.html | 11 + .../normalize/enum.TrailingSlash.html | 11 + .../normalize/struct.NormalizePath.html | 11 + actix_web/middleware/sidebar-items.js | 1 + actix_web/middleware/struct.Compat.html | 44 + actix_web/middleware/struct.Compress.html | 57 + actix_web/middleware/struct.Condition.html | 36 + .../middleware/struct.DefaultHeaders.html | 38 + .../middleware/struct.ErrorHandlers.html | 139 + actix_web/middleware/struct.Logger.html | 104 + .../middleware/struct.NormalizePath.html | 64 + actix_web/redirect/struct.Redirect.html | 11 + actix_web/request/struct.HttpRequest.html | 11 + actix_web/request_data/struct.ReqData.html | 11 + actix_web/resource/struct.Resource.html | 11 + .../builder/struct.HttpResponseBuilder.html | 11 + .../struct.CustomizeResponder.html | 11 + .../response/responder/trait.Responder.html | 11 + .../response/struct.HttpResponse.html | 11 + actix_web/rmap/struct.ResourceMap.html | 11 + actix_web/route/struct.Route.html | 11 + actix_web/rt/fn.spawn.html | 24 + actix_web/rt/index.html | 50 + actix_web/rt/macro.pin!.html | 11 + actix_web/rt/macro.pin.html | 104 + actix_web/rt/net/index.html | 3 + actix_web/rt/net/sidebar-items.js | 1 + actix_web/rt/net/struct.Ready.html | 91 + actix_web/rt/net/struct.TcpListener.html | 204 + actix_web/rt/net/struct.TcpSocket.html | 400 ++ actix_web/rt/net/struct.TcpStream.html | 891 +++++ actix_web/rt/net/struct.UdpSocket.html | 1188 ++++++ actix_web/rt/net/struct.UnixDatagram.html | 1009 +++++ actix_web/rt/net/struct.UnixListener.html | 96 + actix_web/rt/net/struct.UnixStream.html | 750 ++++ actix_web/rt/sidebar-items.js | 1 + actix_web/rt/signal/fn.ctrl_c.html | 39 + actix_web/rt/signal/index.html | 2 + actix_web/rt/signal/sidebar-items.js | 1 + actix_web/rt/signal/unix/fn.signal.html | 25 + actix_web/rt/signal/unix/index.html | 3 + actix_web/rt/signal/unix/sidebar-items.js | 1 + actix_web/rt/signal/unix/struct.Signal.html | 125 + .../rt/signal/unix/struct.SignalKind.html | 73 + actix_web/rt/struct.Runtime.html | 91 + actix_web/rt/struct.System.html | 34 + actix_web/rt/struct.SystemRunner.html | 22 + actix_web/rt/task/fn.spawn_blocking.html | 89 + actix_web/rt/task/fn.yield_now.html | 24 + actix_web/rt/task/index.html | 2 + actix_web/rt/task/sidebar-items.js | 1 + actix_web/rt/task/struct.JoinError.html | 69 + actix_web/rt/task/struct.JoinHandle.html | 295 ++ actix_web/rt/time/fn.interval.html | 48 + actix_web/rt/time/fn.interval_at.html | 23 + actix_web/rt/time/fn.sleep.html | 36 + actix_web/rt/time/fn.sleep_until.html | 31 + actix_web/rt/time/fn.timeout.html | 44 + actix_web/rt/time/index.html | 9 + actix_web/rt/time/sidebar-items.js | 1 + actix_web/rt/time/struct.Instant.html | 107 + actix_web/rt/time/struct.Interval.html | 150 + actix_web/rt/time/struct.Sleep.html | 158 + actix_web/rt/time/struct.Timeout.html | 123 + actix_web/scope/struct.Scope.html | 11 + actix_web/server/struct.HttpServer.html | 11 + actix_web/service/struct.ServiceRequest.html | 11 + actix_web/service/struct.ServiceResponse.html | 11 + actix_web/service/struct.WebService.html | 11 + .../service/trait.HttpServiceFactory.html | 11 + actix_web/sidebar-items.js | 1 + actix_web/struct.App.html | 216 + actix_web/struct.CustomizeResponder.html | 66 + actix_web/struct.HttpRequest.html | 115 + actix_web/struct.HttpResponse.html | 81 + actix_web/struct.HttpResponseBuilder.html | 191 + actix_web/struct.HttpServer.html | 289 ++ actix_web/struct.Resource.html | 225 ++ actix_web/struct.Route.html | 128 + actix_web/struct.Scope.html | 179 + actix_web/test/fn.call_and_read_body.html | 32 + .../test/fn.call_and_read_body_json.html | 43 + actix_web/test/fn.call_service.html | 25 + actix_web/test/fn.init_service.html | 27 + actix_web/test/fn.ok_service.html | 3 + actix_web/test/fn.read_body.html | 28 + actix_web/test/fn.read_body_json.html | 44 + actix_web/test/fn.status_service.html | 4 + .../test/fn.try_call_and_read_body_json.html | 8 + actix_web/test/fn.try_call_service.html | 7 + actix_web/test/fn.try_read_body.html | 5 + actix_web/test/fn.try_read_body_json.html | 6 + actix_web/test/index.html | 27 + actix_web/test/sidebar-items.js | 1 + actix_web/test/struct.TestBuffer.html | 179 + actix_web/test/struct.TestRequest.html | 89 + .../test/test_request/struct.TestRequest.html | 11 + .../test/test_services/fn.ok_service.html | 11 + .../test/test_services/fn.status_service.html | 11 + .../test_utils/fn.call_and_read_body.html | 11 + .../fn.call_and_read_body_json.html | 11 + .../test/test_utils/fn.call_service.html | 11 + .../test/test_utils/fn.init_service.html | 11 + actix_web/test/test_utils/fn.read_body.html | 11 + .../test/test_utils/fn.read_body_json.html | 11 + .../fn.try_call_and_read_body_json.html | 11 + .../test/test_utils/fn.try_call_service.html | 11 + .../test/test_utils/fn.try_read_body.html | 11 + .../test_utils/fn.try_read_body_json.html | 11 + actix_web/trait.FromRequest.html | 219 + actix_web/trait.Handler.html | 102 + actix_web/trait.HttpMessage.html | 31 + actix_web/trait.Responder.html | 62 + actix_web/type.Result.html | 8 + actix_web/types/either/enum.Either.html | 11 + actix_web/types/form/struct.Form.html | 11 + actix_web/types/form/struct.FormConfig.html | 11 + actix_web/types/form/struct.UrlEncoded.html | 11 + actix_web/types/header/struct.Header.html | 11 + actix_web/types/json/enum.JsonBody.html | 11 + actix_web/types/json/struct.Json.html | 11 + actix_web/types/json/struct.JsonConfig.html | 11 + actix_web/types/path/struct.Path.html | 11 + actix_web/types/path/struct.PathConfig.html | 11 + actix_web/types/payload/struct.Payload.html | 11 + .../types/payload/struct.PayloadConfig.html | 11 + actix_web/types/query/struct.Query.html | 11 + actix_web/types/query/struct.QueryConfig.html | 11 + .../types/readlines/struct.Readlines.html | 11 + actix_web/web/enum.Either.html | 94 + actix_web/web/enum.JsonBody.html | 137 + actix_web/web/fn.block.html | 5 + actix_web/web/fn.delete.html | 12 + actix_web/web/fn.get.html | 12 + actix_web/web/fn.head.html | 12 + actix_web/web/fn.method.html | 11 + actix_web/web/fn.patch.html | 12 + actix_web/web/fn.post.html | 12 + actix_web/web/fn.put.html | 12 + actix_web/web/fn.redirect.html | 12 + actix_web/web/fn.resource.html | 19 + actix_web/web/fn.route.html | 2 + actix_web/web/fn.scope.html | 24 + actix_web/web/fn.service.html | 14 + actix_web/web/fn.to.html | 16 + actix_web/web/fn.trace.html | 12 + actix_web/web/index.html | 22 + actix_web/web/sidebar-items.js | 1 + actix_web/web/struct.Bytes.html | 1398 +++++++ actix_web/web/struct.BytesMut.html | 2826 +++++++++++++ actix_web/web/struct.Data.html | 90 + actix_web/web/struct.Form.html | 99 + actix_web/web/struct.FormConfig.html | 41 + actix_web/web/struct.Header.html | 57 + actix_web/web/struct.Json.html | 75 + actix_web/web/struct.JsonConfig.html | 54 + actix_web/web/struct.Path.html | 78 + actix_web/web/struct.PathConfig.html | 51 + actix_web/web/struct.Payload.html | 312 ++ actix_web/web/struct.PayloadConfig.html | 29 + actix_web/web/struct.Query.html | 96 + actix_web/web/struct.QueryConfig.html | 46 + actix_web/web/struct.Readlines.html | 260 ++ actix_web/web/struct.Redirect.html | 86 + actix_web/web/struct.ReqData.html | 58 + actix_web/web/struct.ServiceConfig.html | 58 + actix_web/web/struct.UrlEncoded.html | 121 + actix_web/web/trait.Buf.html | 632 +++ actix_web/web/trait.BufMut.html | 749 ++++ actix_web_actors/all.html | 1 + .../context/struct.HttpContext.html | 11 + actix_web_actors/index.html | 55 + actix_web_actors/sidebar-items.js | 1 + actix_web_actors/struct.HttpContext.html | 102 + actix_web_actors/ws/enum.CloseCode.html | 72 + actix_web_actors/ws/enum.Frame.html | 37 + actix_web_actors/ws/enum.HandshakeError.html | 42 + actix_web_actors/ws/enum.Message.html | 39 + actix_web_actors/ws/enum.ProtocolError.html | 43 + actix_web_actors/ws/fn.handshake.html | 6 + .../ws/fn.handshake_with_protocols.html | 9 + actix_web_actors/ws/fn.start.html | 9 + actix_web_actors/ws/fn.start_with_addr.html | 14 + .../ws/fn.start_with_protocols.html | 10 + actix_web_actors/ws/index.html | 53 + actix_web_actors/ws/sidebar-items.js | 1 + actix_web_actors/ws/struct.CloseReason.html | 31 + .../ws/struct.WebsocketContext.html | 90 + .../ws/struct.WsResponseBuilder.html | 64 + actix_web_codegen/all.html | 1 + actix_web_codegen/attr.connect.html | 19 + actix_web_codegen/attr.delete.html | 19 + actix_web_codegen/attr.get.html | 19 + actix_web_codegen/attr.head.html | 19 + actix_web_codegen/attr.main.html | 10 + actix_web_codegen/attr.options.html | 19 + actix_web_codegen/attr.patch.html | 19 + actix_web_codegen/attr.post.html | 19 + actix_web_codegen/attr.put.html | 19 + actix_web_codegen/attr.route.html | 21 + actix_web_codegen/attr.routes.html | 18 + actix_web_codegen/attr.test.html | 7 + actix_web_codegen/attr.trace.html | 19 + actix_web_codegen/index.html | 43 + actix_web_codegen/sidebar-items.js | 1 + awc/all.html | 1 + awc/body/enum.BodySize.html | 46 + awc/body/enum.EitherBody.html | 61 + awc/body/fn.to_bytes.html | 16 + awc/body/fn.to_bytes_limited.html | 23 + awc/body/index.html | 3 + awc/body/sidebar-items.js | 1 + awc/body/struct.BodyLimitExceeded.html | 22 + awc/body/struct.BodyStream.html | 37 + awc/body/struct.BoxBody.html | 26 + awc/body/struct.None.html | 29 + awc/body/struct.SizedStream.html | 39 + awc/body/trait.MessageBody.html | 139 + awc/builder/struct.ClientBuilder.html | 11 + awc/client/connector/struct.Connector.html | 11 + awc/client/error/enum.ConnectError.html | 11 + awc/client/error/enum.FreezeRequestError.html | 11 + awc/client/error/enum.InvalidUrl.html | 11 + awc/client/error/enum.SendRequestError.html | 11 + awc/client/struct.Client.html | 11 + awc/client/struct.Connect.html | 11 + awc/connect/enum.ConnectRequest.html | 11 + awc/connect/enum.ConnectResponse.html | 11 + awc/connect/type.BoxConnectorService.html | 11 + awc/connect/type.BoxedSocket.html | 11 + awc/enum.ConnectRequest.html | 26 + awc/enum.ConnectResponse.html | 32 + awc/enum.SendClientRequest.html | 115 + awc/error/enum.ConnectError.html | 38 + awc/error/enum.FreezeRequestError.html | 26 + awc/error/enum.InvalidUrl.html | 23 + awc/error/enum.JsonPayloadError.html | 26 + awc/error/enum.PayloadError.html | 35 + awc/error/enum.SendRequestError.html | 40 + awc/error/enum.WsClientError.html | 36 + awc/error/enum.WsHandshakeError.html | 42 + awc/error/enum.WsProtocolError.html | 43 + awc/error/index.html | 2 + awc/error/sidebar-items.js | 1 + awc/error/struct.HeaderValue.html | 208 + awc/error/struct.HttpError.html | 26 + awc/error/struct.StatusCode.html | 221 + awc/frozen/struct.FrozenClientRequest.html | 11 + awc/frozen/struct.FrozenSendBuilder.html | 11 + awc/http/enum.ConnectionType.html | 32 + awc/http/header/constant.ACCEPT.html | 10 + awc/http/header/constant.ACCEPT_CHARSET.html | 12 + awc/http/header/constant.ACCEPT_ENCODING.html | 28 + awc/http/header/constant.ACCEPT_LANGUAGE.html | 21 + awc/http/header/constant.ACCEPT_RANGES.html | 7 + ...tant.ACCESS_CONTROL_ALLOW_CREDENTIALS.html | 20 + ...constant.ACCESS_CONTROL_ALLOW_HEADERS.html | 12 + ...constant.ACCESS_CONTROL_ALLOW_METHODS.html | 5 + .../constant.ACCESS_CONTROL_ALLOW_ORIGIN.html | 3 + ...onstant.ACCESS_CONTROL_EXPOSE_HEADERS.html | 3 + .../constant.ACCESS_CONTROL_MAX_AGE.html | 2 + ...nstant.ACCESS_CONTROL_REQUEST_HEADERS.html | 3 + ...onstant.ACCESS_CONTROL_REQUEST_METHOD.html | 3 + awc/http/header/constant.AGE.html | 6 + awc/http/header/constant.ALLOW.html | 7 + awc/http/header/constant.ALT_SVC.html | 2 + awc/http/header/constant.AUTHORIZATION.html | 4 + awc/http/header/constant.CACHE_CONTROL.html | 6 + awc/http/header/constant.CACHE_STATUS.html | 4 + .../header/constant.CDN_CACHE_CONTROL.html | 4 + awc/http/header/constant.CONNECTION.html | 12 + .../header/constant.CONTENT_DISPOSITION.html | 16 + .../header/constant.CONTENT_ENCODING.html | 9 + .../header/constant.CONTENT_LANGUAGE.html | 12 + awc/http/header/constant.CONTENT_LENGTH.html | 4 + .../header/constant.CONTENT_LOCATION.html | 10 + awc/http/header/constant.CONTENT_RANGE.html | 2 + .../constant.CONTENT_SECURITY_POLICY.html | 6 + ...t.CONTENT_SECURITY_POLICY_REPORT_ONLY.html | 6 + awc/http/header/constant.CONTENT_TYPE.html | 9 + awc/http/header/constant.COOKIE.html | 5 + ...constant.CROSS_ORIGIN_EMBEDDER_POLICY.html | 3 + .../constant.CROSS_ORIGIN_OPENER_POLICY.html | 3 + ...constant.CROSS_ORIGIN_RESOURCE_POLICY.html | 3 + awc/http/header/constant.DATE.html | 2 + awc/http/header/constant.DNT.html | 4 + awc/http/header/constant.ETAG.html | 13 + awc/http/header/constant.EXPECT.html | 19 + awc/http/header/constant.EXPIRES.html | 6 + awc/http/header/constant.FORWARDED.html | 9 + awc/http/header/constant.FROM.html | 7 + awc/http/header/constant.HOST.html | 8 + awc/http/header/constant.IF_MATCH.html | 25 + .../header/constant.IF_MODIFIED_SINCE.html | 13 + awc/http/header/constant.IF_NONE_MATCH.html | 31 + awc/http/header/constant.IF_RANGE.html | 12 + .../header/constant.IF_UNMODIFIED_SINCE.html | 22 + awc/http/header/constant.LAST_MODIFIED.html | 2 + awc/http/header/constant.LINK.html | 3 + awc/http/header/constant.LOCATION.html | 29 + awc/http/header/constant.MAX_FORWARDS.html | 3 + awc/http/header/constant.ORIGIN.html | 6 + .../header/constant.PERMISSIONS_POLICY.html | 3 + awc/http/header/constant.PRAGMA.html | 6 + .../header/constant.PROXY_AUTHENTICATE.html | 14 + .../header/constant.PROXY_AUTHORIZATION.html | 5 + awc/http/header/constant.PUBLIC_KEY_PINS.html | 6 + .../constant.PUBLIC_KEY_PINS_REPORT_ONLY.html | 5 + awc/http/header/constant.RANGE.html | 8 + awc/http/header/constant.REFERER.html | 6 + awc/http/header/constant.REFERRER_POLICY.html | 3 + awc/http/header/constant.REFRESH.html | 3 + awc/http/header/constant.RETRY_AFTER.html | 15 + .../header/constant.SEC_WEBSOCKET_ACCEPT.html | 5 + .../constant.SEC_WEBSOCKET_EXTENSIONS.html | 6 + .../header/constant.SEC_WEBSOCKET_KEY.html | 8 + .../constant.SEC_WEBSOCKET_PROTOCOL.html | 6 + .../constant.SEC_WEBSOCKET_VERSION.html | 7 + awc/http/header/constant.SERVER.html | 7 + awc/http/header/constant.SET_COOKIE.html | 2 + .../constant.STRICT_TRANSPORT_SECURITY.html | 2 + awc/http/header/constant.TE.html | 8 + awc/http/header/constant.TRAILER.html | 3 + .../header/constant.TRANSFER_ENCODING.html | 11 + awc/http/header/constant.UPGRADE.html | 2 + .../constant.UPGRADE_INSECURE_REQUESTS.html | 3 + awc/http/header/constant.USER_AGENT.html | 3 + awc/http/header/constant.VARY.html | 9 + awc/http/header/constant.VIA.html | 7 + awc/http/header/constant.WARNING.html | 6 + .../header/constant.WWW_AUTHENTICATE.html | 3 + .../constant.X_CONTENT_TYPE_OPTIONS.html | 11 + .../constant.X_DNS_PREFETCH_CONTROL.html | 10 + awc/http/header/constant.X_FORWARDED_FOR.html | 3 + .../header/constant.X_FORWARDED_HOST.html | 3 + .../header/constant.X_FORWARDED_PROTO.html | 3 + awc/http/header/constant.X_FRAME_OPTIONS.html | 7 + .../header/constant.X_XSS_PROTECTION.html | 9 + awc/http/header/enum.Charset.html | 79 + awc/http/header/enum.ContentEncoding.html | 54 + awc/http/header/fn.fmt_comma_delimited.html | 6 + awc/http/header/fn.from_comma_delimited.html | 4 + awc/http/header/fn.from_one_raw_str.html | 3 + awc/http/header/fn.http_percent_encode.html | 5 + awc/http/header/fn.parse_extended_value.html | 30 + awc/http/header/fn.q.html | 21 + awc/http/header/index.html | 69 + awc/http/header/map/index.html | 2 + awc/http/header/map/sidebar-items.js | 1 + awc/http/header/map/struct.Drain.html | 203 + awc/http/header/map/struct.HeaderMap.html | 330 ++ awc/http/header/map/struct.IntoIter.html | 206 + awc/http/header/map/struct.Iter.html | 202 + awc/http/header/map/struct.Keys.html | 202 + awc/http/header/map/struct.Removed.html | 220 + awc/http/header/sidebar-items.js | 1 + awc/http/header/struct.ExtendedValue.html | 39 + awc/http/header/struct.HeaderMap.html | 330 ++ awc/http/header/struct.HeaderName.html | 136 + awc/http/header/struct.HeaderValue.html | 208 + awc/http/header/struct.HttpDate.html | 35 + awc/http/header/struct.InvalidHeaderName.html | 19 + .../header/struct.InvalidHeaderValue.html | 20 + awc/http/header/struct.LanguageTag.html | 177 + awc/http/header/struct.Quality.html | 52 + awc/http/header/struct.QualityItem.html | 74 + awc/http/header/struct.ToStrError.html | 21 + awc/http/header/trait.AsHeaderName.html | 2 + awc/http/header/trait.Header.html | 10 + awc/http/header/trait.TryIntoHeaderPair.html | 29 + awc/http/header/trait.TryIntoHeaderValue.html | 31 + awc/http/index.html | 2 + awc/http/sidebar-items.js | 1 + awc/http/struct.Error.html | 18 + awc/http/struct.Method.html | 71 + awc/http/struct.StatusCode.html | 221 + awc/http/struct.Uri.html | 284 ++ awc/http/struct.Version.html | 40 + awc/http/uri/index.html | 19 + awc/http/uri/sidebar-items.js | 1 + awc/http/uri/struct.Authority.html | 138 + awc/http/uri/struct.Builder.html | 70 + awc/http/uri/struct.InvalidUri.html | 19 + awc/http/uri/struct.InvalidUriParts.html | 19 + awc/http/uri/struct.Parts.html | 28 + awc/http/uri/struct.PathAndQuery.html | 122 + awc/http/uri/struct.Port.html | 48 + awc/http/uri/struct.Scheme.html | 45 + awc/http/uri/struct.Uri.html | 284 ++ awc/index.html | 60 + awc/middleware/index.html | 2 + awc/middleware/redirect/struct.Redirect.html | 11 + awc/middleware/sidebar-items.js | 1 + awc/middleware/struct.Redirect.html | 18 + awc/middleware/trait.Transform.html | 12 + awc/request/struct.ClientRequest.html | 11 + awc/responses/json_body/struct.JsonBody.html | 11 + .../response/struct.ClientResponse.html | 11 + .../response_body/struct.ResponseBody.html | 11 + .../response_body/type.MessageBody.html | 11 + awc/sender/enum.SendClientRequest.html | 11 + awc/sidebar-items.js | 1 + awc/struct.Client.html | 75 + awc/struct.ClientBuilder.html | 80 + awc/struct.ClientRequest.html | 90 + awc/struct.ClientResponse.html | 292 ++ awc/struct.Connect.html | 21 + awc/struct.Connector.html | 90 + awc/struct.FrozenClientRequest.html | 33 + awc/struct.FrozenSendBuilder.html | 26 + awc/struct.JsonBody.html | 125 + awc/struct.ResponseBody.html | 124 + awc/test/index.html | 2 + awc/test/sidebar-items.js | 1 + awc/test/struct.TestResponse.html | 25 + awc/type.BoxConnectorService.html | 1 + awc/type.BoxedSocket.html | 1 + awc/type.MessageBody.html | 1 + awc/ws/enum.CloseCode.html | 72 + awc/ws/enum.Frame.html | 37 + awc/ws/enum.Message.html | 43 + awc/ws/index.html | 23 + awc/ws/sidebar-items.js | 1 + awc/ws/struct.CloseReason.html | 31 + awc/ws/struct.Codec.html | 38 + awc/ws/struct.WebsocketsRequest.html | 52 + crates.js | 1 + help.html | 1 + index.html | 1 + search-index.js | 15 + .../actix_files/actix_files-desc-0-.js | 1 + search.desc/actix_http/actix_http-desc-0-.js | 1 + .../actix_http_test-desc-0-.js | 1 + .../actix_multipart-desc-0-.js | 1 + .../actix_multipart_derive-desc-0-.js | 1 + .../actix_router/actix_router-desc-0-.js | 1 + search.desc/actix_test/actix_test-desc-0-.js | 1 + search.desc/actix_web/actix_web-desc-0-.js | 1 + search.desc/actix_web/actix_web-desc-1-.js | 1 + .../actix_web_actors-desc-0-.js | 1 + .../actix_web_codegen-desc-0-.js | 1 + search.desc/awc/awc-desc-0-.js | 1 + settings.html | 1 + src-files.js | 14 + src/actix_files/chunked.rs.html | 435 ++ src/actix_files/directory.rs.html | 253 ++ src/actix_files/encoding.rs.html | 105 + src/actix_files/error.rs.html | 99 + src/actix_files/files.rs.html | 861 ++++ src/actix_files/lib.rs.html | 2079 ++++++++++ src/actix_files/named.rs.html | 1379 +++++++ src/actix_files/path_buf.rs.html | 377 ++ src/actix_files/range.rs.html | 677 ++++ src/actix_files/service.rs.html | 377 ++ src/actix_http/body/body_stream.rs.html | 429 ++ src/actix_http/body/boxed.rs.html | 243 ++ src/actix_http/body/either.rs.html | 245 ++ src/actix_http/body/message_body.rs.html | 1481 +++++++ src/actix_http/body/mod.rs.html | 55 + src/actix_http/body/none.rs.html | 103 + src/actix_http/body/size.rs.html | 83 + src/actix_http/body/sized_stream.rs.html | 343 ++ src/actix_http/body/utils.rs.html | 397 ++ src/actix_http/builder.rs.html | 517 +++ src/actix_http/config.rs.html | 473 +++ src/actix_http/date.rs.html | 185 + src/actix_http/encoding/decoder.rs.html | 605 +++ src/actix_http/encoding/encoder.rs.html | 879 ++++ src/actix_http/encoding/mod.rs.html | 81 + src/actix_http/error.rs.html | 977 +++++ src/actix_http/extensions.rs.html | 603 +++ src/actix_http/h1/chunked.rs.html | 855 ++++ src/actix_http/h1/client.rs.html | 481 +++ src/actix_http/h1/codec.rs.html | 481 +++ src/actix_http/h1/decoder.rs.html | 2371 +++++++++++ src/actix_http/h1/dispatcher.rs.html | 2501 ++++++++++++ src/actix_http/h1/encoder.rs.html | 1343 +++++++ src/actix_http/h1/expect.rs.html | 67 + src/actix_http/h1/mod.rs.html | 187 + src/actix_http/h1/payload.rs.html | 565 +++ src/actix_http/h1/service.rs.html | 1093 +++++ src/actix_http/h1/timer.rs.html | 163 + src/actix_http/h1/upgrade.rs.html | 65 + src/actix_http/h1/utils.rs.html | 277 ++ src/actix_http/h2/dispatcher.rs.html | 711 ++++ src/actix_http/h2/mod.rs.html | 215 + src/actix_http/h2/service.rs.html | 1037 +++++ src/actix_http/header/as_name.rs.html | 113 + src/actix_http/header/common.rs.html | 107 + src/actix_http/header/into_pair.rs.html | 241 ++ src/actix_http/header/into_value.rs.html | 263 ++ src/actix_http/header/map.rs.html | 2281 +++++++++++ src/actix_http/header/mod.rs.html | 181 + src/actix_http/header/shared/charset.rs.html | 311 ++ .../header/shared/content_encoding.rs.html | 247 ++ src/actix_http/header/shared/extended.rs.html | 389 ++ .../header/shared/http_date.rs.html | 161 + src/actix_http/header/shared/mod.rs.html | 39 + src/actix_http/header/shared/quality.rs.html | 445 +++ .../header/shared/quality_item.rs.html | 611 +++ src/actix_http/header/utils.rs.html | 209 + src/actix_http/helpers.rs.html | 385 ++ src/actix_http/http_message.rs.html | 459 +++ src/actix_http/keep_alive.rs.html | 169 + src/actix_http/lib.rs.html | 233 ++ src/actix_http/message.rs.html | 215 + src/actix_http/payload.rs.html | 213 + src/actix_http/requests/head.rs.html | 355 ++ src/actix_http/requests/mod.rs.html | 19 + src/actix_http/requests/request.rs.html | 509 +++ src/actix_http/responses/builder.rs.html | 859 ++++ src/actix_http/responses/head.rs.html | 539 +++ src/actix_http/responses/mod.rs.html | 19 + src/actix_http/responses/response.rs.html | 877 ++++ src/actix_http/service.rs.html | 2181 ++++++++++ src/actix_http/test.rs.html | 749 ++++ src/actix_http/ws/codec.rs.html | 605 +++ src/actix_http/ws/dispatcher.rs.html | 879 ++++ src/actix_http/ws/frame.rs.html | 811 ++++ src/actix_http/ws/mask.rs.html | 151 + src/actix_http/ws/mod.rs.html | 703 ++++ src/actix_http/ws/proto.rs.html | 709 ++++ src/actix_http_test/lib.rs.html | 639 +++ src/actix_multipart/error.rs.html | 199 + src/actix_multipart/extractor.rs.html | 87 + src/actix_multipart/form/bytes.rs.html | 99 + src/actix_multipart/form/json.rs.html | 423 ++ src/actix_multipart/form/mod.rs.html | 1475 +++++++ src/actix_multipart/form/tempfile.rs.html | 399 ++ src/actix_multipart/form/text.rs.html | 393 ++ src/actix_multipart/lib.rs.html | 123 + src/actix_multipart/server.rs.html | 2723 +++++++++++++ src/actix_multipart/test.rs.html | 435 ++ src/actix_multipart_derive/lib.rs.html | 631 +++ src/actix_router/de.rs.html | 1603 ++++++++ src/actix_router/lib.rs.html | 63 + src/actix_router/path.rs.html | 523 +++ src/actix_router/pattern.rs.html | 185 + src/actix_router/quoter.rs.html | 345 ++ src/actix_router/regex_set.rs.html | 133 + src/actix_router/resource.rs.html | 3557 +++++++++++++++++ src/actix_router/resource_path.rs.html | 79 + src/actix_router/router.rs.html | 565 +++ src/actix_router/url.rs.html | 287 ++ src/actix_test/lib.rs.html | 1499 +++++++ src/actix_web/app.rs.html | 1413 +++++++ src/actix_web/app_service.rs.html | 773 ++++ src/actix_web/config.rs.html | 855 ++++ src/actix_web/data.rs.html | 771 ++++ src/actix_web/dev.rs.html | 95 + src/actix_web/error/error.rs.html | 135 + src/actix_web/error/internal.rs.html | 633 +++ src/actix_web/error/macros.rs.html | 213 + src/actix_web/error/mod.rs.html | 537 +++ src/actix_web/error/response_error.rs.html | 321 ++ src/actix_web/extract.rs.html | 1111 +++++ src/actix_web/guard/acceptable.rs.html | 199 + src/actix_web/guard/host.rs.html | 419 ++ src/actix_web/guard/mod.rs.html | 1031 +++++ src/actix_web/handler.rs.html | 375 ++ src/actix_web/helpers.rs.html | 51 + src/actix_web/http/header/accept.rs.html | 587 +++ .../http/header/accept_charset.rs.html | 125 + .../http/header/accept_encoding.rs.html | 921 +++++ .../http/header/accept_language.rs.html | 447 +++ src/actix_web/http/header/allow.rs.html | 159 + .../http/header/cache_control.rs.html | 385 ++ .../http/header/content_disposition.rs.html | 2015 ++++++++++ .../http/header/content_language.rs.html | 109 + .../http/header/content_length.rs.html | 477 +++ .../http/header/content_range.rs.html | 395 ++ .../http/header/content_type.rs.html | 213 + src/actix_web/http/header/date.rs.html | 89 + src/actix_web/http/header/encoding.rs.html | 111 + src/actix_web/http/header/entity.rs.html | 565 +++ src/actix_web/http/header/etag.rs.html | 197 + src/actix_web/http/header/expires.rs.html | 83 + src/actix_web/http/header/if_match.rs.html | 137 + .../http/header/if_modified_since.rs.html | 81 + .../http/header/if_none_match.rs.html | 183 + src/actix_web/http/header/if_range.rs.html | 235 ++ .../http/header/if_unmodified_since.rs.html | 81 + .../http/header/last_modified.rs.html | 79 + src/actix_web/http/header/macros.rs.html | 641 +++ src/actix_web/http/header/mod.rs.html | 209 + src/actix_web/http/header/preference.rs.html | 141 + src/actix_web/http/header/range.rs.html | 855 ++++ src/actix_web/http/mod.rs.html | 11 + src/actix_web/info.rs.html | 933 +++++ src/actix_web/lib.rs.html | 299 ++ src/actix_web/middleware/compat.rs.html | 473 +++ src/actix_web/middleware/compress.rs.html | 951 +++++ src/actix_web/middleware/condition.rs.html | 415 ++ .../middleware/default_headers.rs.html | 517 +++ src/actix_web/middleware/err_handlers.rs.html | 1241 ++++++ src/actix_web/middleware/logger.rs.html | 2023 ++++++++++ src/actix_web/middleware/mod.rs.html | 567 +++ src/actix_web/middleware/normalize.rs.html | 973 +++++ src/actix_web/redirect.rs.html | 475 +++ src/actix_web/request.rs.html | 1933 +++++++++ src/actix_web/request_data.rs.html | 349 ++ src/actix_web/resource.rs.html | 1733 ++++++++ src/actix_web/response/builder.rs.html | 1065 +++++ .../response/customize_responder.rs.html | 479 +++ src/actix_web/response/http_codes.rs.html | 215 + src/actix_web/response/mod.rs.html | 23 + src/actix_web/response/responder.rs.html | 699 ++++ src/actix_web/response/response.rs.html | 877 ++++ src/actix_web/rmap.rs.html | 1121 ++++++ src/actix_web/route.rs.html | 915 +++++ src/actix_web/rt.rs.html | 157 + src/actix_web/scope.rs.html | 2459 ++++++++++++ src/actix_web/server.rs.html | 2255 +++++++++++ src/actix_web/service.rs.html | 1747 ++++++++ src/actix_web/test/mod.rs.html | 177 + src/actix_web/test/test_request.rs.html | 889 ++++ src/actix_web/test/test_services.rs.html | 79 + src/actix_web/test/test_utils.rs.html | 1187 ++++++ src/actix_web/types/either.rs.html | 721 ++++ src/actix_web/types/form.rs.html | 1119 ++++++ src/actix_web/types/header.rs.html | 209 + src/actix_web/types/json.rs.html | 1539 +++++++ src/actix_web/types/mod.rs.html | 43 + src/actix_web/types/path.rs.html | 579 +++ src/actix_web/types/payload.rs.html | 1295 ++++++ src/actix_web/types/query.rs.html | 549 +++ src/actix_web/types/readlines.rs.html | 423 ++ src/actix_web/web.rs.html | 427 ++ src/actix_web_actors/context.rs.html | 595 +++ src/actix_web_actors/lib.rs.html | 135 + src/actix_web_actors/ws.rs.html | 2119 ++++++++++ src/actix_web_codegen/lib.rs.html | 485 +++ src/actix_web_codegen/route.rs.html | 1113 ++++++ src/awc/any_body.rs.html | 383 ++ src/awc/builder.rs.html | 681 ++++ src/awc/client/config.rs.html | 85 + src/awc/client/connection.rs.html | 909 +++++ src/awc/client/connector.rs.html | 2305 +++++++++++ src/awc/client/error.rs.html | 311 ++ src/awc/client/h1proto.rs.html | 473 +++ src/awc/client/h2proto.rs.html | 395 ++ src/awc/client/mod.rs.html | 411 ++ src/awc/client/pool.rs.html | 1321 ++++++ src/awc/connect.rs.html | 395 ++ src/awc/error.rs.html | 163 + src/awc/frozen.rs.html | 451 +++ src/awc/lib.rs.html | 301 ++ src/awc/middleware/mod.rs.html | 143 + src/awc/middleware/redirect.rs.html | 1361 +++++++ src/awc/request.rs.html | 1307 ++++++ src/awc/responses/json_body.rs.html | 385 ++ src/awc/responses/mod.rs.html | 97 + src/awc/responses/read_body.rs.html | 123 + src/awc/responses/response.rs.html | 527 +++ src/awc/responses/response_body.rs.html | 289 ++ src/awc/sender.rs.html | 631 +++ src/awc/test.rs.html | 239 ++ src/awc/ws.rs.html | 1085 +++++ static.files/COPYRIGHT-23e9bde6c69aea69.txt | 50 + .../FiraSans-LICENSE-db4b642586e02d97.txt | 98 + .../FiraSans-Medium-8f9a781e4970d388.woff2 | Bin 0 -> 132780 bytes .../FiraSans-Regular-018c141bf0843ffd.woff2 | Bin 0 -> 129188 bytes .../LICENSE-APACHE-b91fa81cba47b86a.txt | 201 + static.files/LICENSE-MIT-65090b722b3f6c56.txt | 23 + ...anumBarunGothic-0f09457c7a19b7c6.ttf.woff2 | Bin 0 -> 399468 bytes ...umBarunGothic-LICENSE-18c5adf4b52b4041.txt | 103 + ...ourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 | Bin 0 -> 44896 bytes ...SourceCodePro-LICENSE-d180d465a756484a.txt | 97 + ...CodePro-Regular-562dcc5011b6de7d.ttf.woff2 | Bin 0 -> 52228 bytes ...odePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 | Bin 0 -> 52348 bytes ...urceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 | Bin 0 -> 81540 bytes ...SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 | Bin 0 -> 59716 bytes .../SourceSerif4-LICENSE-3bb119e13b1258b7.md | 98 + ...eSerif4-Regular-46f98efaafac5295.ttf.woff2 | Bin 0 -> 76260 bytes static.files/favicon-2c020d218678b618.svg | 24 + .../favicon-32x32-422f7d1d52889060.png | Bin 0 -> 1125 bytes static.files/main-20a3ad099b048cf2.js | 11 + static.files/normalize-76eba96aa4d2e634.css | 2 + static.files/noscript-df360f571f6edeae.css | 1 + static.files/rust-logo-151179464ae7ed46.svg | 61 + static.files/rustdoc-dd39b87e5fcfba68.css | 46 + .../scrape-examples-ef1e698c1d417c0c.js | 1 + static.files/search-d52510db62a78183.js | 5 + static.files/settings-4313503d2e1961c2.js | 17 + static.files/src-script-e66d777a5a92e9b2.js | 1 + static.files/storage-118b08c4c78b968e.js | 24 + trait.impl/actix/actor/trait.ActorContext.js | 3 + trait.impl/actix/actor/trait.AsyncContext.js | 3 + .../address/envelope/trait.ToEnvelope.js | 3 + .../context_impl/trait.AsyncContextParts.js | 3 + .../body/message_body/trait.MessageBody.js | 5 + .../header/as_name/trait.AsHeaderName.js | 5 + .../into_pair/trait.TryIntoHeaderPair.js | 5 + .../into_value/trait.TryIntoHeaderValue.js | 5 + trait.impl/actix_http/header/trait.Header.js | 5 + .../http_message/trait.HttpMessage.js | 5 + .../actix_multipart/form/trait.FieldReader.js | 3 + .../pattern/trait.IntoPatterns.js | 3 + .../resource_path/trait.Resource.js | 4 + .../resource_path/trait.ResourcePath.js | 4 + trait.impl/actix_service/trait.Service.js | 5 + .../actix_service/trait.ServiceFactory.js | 5 + .../transform/trait.Transform.js | 3 + .../response_error/trait.ResponseError.js | 4 + .../actix_web/extract/trait.FromRequest.js | 4 + trait.impl/actix_web/guard/trait.Guard.js | 3 + trait.impl/actix_web/handler/trait.Handler.js | 3 + .../response/responder/trait.Responder.js | 4 + .../service/trait.HttpServiceFactory.js | 4 + trait.impl/awc/middleware/trait.Transform.js | 3 + trait.impl/bytes/buf/buf_impl/trait.Buf.js | 3 + trait.impl/bytes/buf/buf_mut/trait.BufMut.js | 3 + trait.impl/core/clone/trait.Clone.js | 9 + trait.impl/core/cmp/trait.Eq.js | 5 + trait.impl/core/cmp/trait.Ord.js | 4 + trait.impl/core/cmp/trait.PartialEq.js | 5 + trait.impl/core/cmp/trait.PartialOrd.js | 4 + trait.impl/core/convert/trait.AsRef.js | 4 + trait.impl/core/convert/trait.From.js | 7 + trait.impl/core/convert/trait.TryFrom.js | 3 + trait.impl/core/default/trait.Default.js | 8 + trait.impl/core/error/trait.Error.js | 6 + trait.impl/core/fmt/trait.Debug.js | 8 + trait.impl/core/fmt/trait.Display.js | 6 + trait.impl/core/future/future/trait.Future.js | 5 + trait.impl/core/hash/trait.Hash.js | 5 + .../iter/traits/collect/trait.IntoIterator.js | 3 + .../exact_size/trait.ExactSizeIterator.js | 3 + .../iter/traits/iterator/trait.Iterator.js | 3 + .../iter/traits/marker/trait.FusedIterator.js | 3 + trait.impl/core/marker/trait.Copy.js | 6 + trait.impl/core/marker/trait.Freeze.js | 11 + trait.impl/core/marker/trait.Send.js | 11 + .../core/marker/trait.StructuralPartialEq.js | 5 + trait.impl/core/marker/trait.Sync.js | 11 + trait.impl/core/marker/trait.Unpin.js | 11 + trait.impl/core/ops/deref/trait.Deref.js | 6 + trait.impl/core/ops/deref/trait.DerefMut.js | 6 + trait.impl/core/ops/drop/trait.Drop.js | 6 + trait.impl/core/ops/index/trait.Index.js | 3 + .../panic/unwind_safe/trait.RefUnwindSafe.js | 11 + .../panic/unwind_safe/trait.UnwindSafe.js | 11 + trait.impl/core/str/traits/trait.FromStr.js | 4 + .../futures_core/stream/trait.Stream.js | 6 + trait.impl/serde/de/trait.Deserialize.js | 3 + trait.impl/serde/de/trait.Deserializer.js | 3 + trait.impl/serde/ser/trait.Serialize.js | 3 + trait.impl/std/io/trait.Read.js | 3 + trait.impl/std/io/trait.Write.js | 3 + .../time/ext/instant/trait.InstantExt.js | 3 + .../trait.NumericalDuration.js | 3 + .../trait.NumericalStdDuration.js | 3 + .../formattable/trait.Formattable.js | 3 + .../time/parsing/parsable/trait.Parsable.js | 3 + .../tokio/io/async_read/trait.AsyncRead.js | 3 + .../tokio/io/async_write/trait.AsyncWrite.js | 3 + .../tokio_util/codec/decoder/trait.Decoder.js | 3 + .../tokio_util/codec/encoder/trait.Encoder.js | 3 + type.impl/alloc/boxed/struct.Box.js | 3 + type.impl/alloc/rc/struct.Rc.js | 3 + type.impl/awc/struct.ResponseBody.js | 3 + type.impl/core/pin/struct.Pin.js | 3 + type.impl/core/result/enum.Result.js | 3 + type.impl/std/primitive.u128.js | 3 + 1715 files changed, 215638 insertions(+) create mode 100644 .lock create mode 100644 .nojekyll create mode 100644 actix_files/all.html create mode 100644 actix_files/directory/struct.Directory.html create mode 100644 actix_files/files/struct.Files.html create mode 100644 actix_files/fn.file_extension_to_mime.html create mode 100644 actix_files/index.html create mode 100644 actix_files/named/struct.NamedFile.html create mode 100644 actix_files/range/struct.HttpRange.html create mode 100644 actix_files/service/struct.FilesService.html create mode 100644 actix_files/sidebar-items.js create mode 100644 actix_files/struct.Directory.html create mode 100644 actix_files/struct.Files.html create mode 100644 actix_files/struct.FilesService.html create mode 100644 actix_files/struct.HttpRange.html create mode 100644 actix_files/struct.NamedFile.html create mode 100644 actix_http/all.html create mode 100644 actix_http/body/body_stream/struct.BodyStream.html create mode 100644 actix_http/body/boxed/struct.BoxBody.html create mode 100644 actix_http/body/either/enum.EitherBody.html create mode 100644 actix_http/body/enum.BodySize.html create mode 100644 actix_http/body/enum.EitherBody.html create mode 100644 actix_http/body/fn.to_bytes.html create mode 100644 actix_http/body/fn.to_bytes_limited.html create mode 100644 actix_http/body/index.html create mode 100644 actix_http/body/message_body/trait.MessageBody.html create mode 100644 actix_http/body/none/struct.None.html create mode 100644 actix_http/body/sidebar-items.js create mode 100644 actix_http/body/size/enum.BodySize.html create mode 100644 actix_http/body/sized_stream/struct.SizedStream.html create mode 100644 actix_http/body/struct.BodyLimitExceeded.html create mode 100644 actix_http/body/struct.BodyStream.html create mode 100644 actix_http/body/struct.BoxBody.html create mode 100644 actix_http/body/struct.None.html create mode 100644 actix_http/body/struct.SizedStream.html create mode 100644 actix_http/body/trait.MessageBody.html create mode 100644 actix_http/body/utils/fn.to_bytes.html create mode 100644 actix_http/body/utils/fn.to_bytes_limited.html create mode 100644 actix_http/body/utils/struct.BodyLimitExceeded.html create mode 100644 actix_http/builder/struct.HttpServiceBuilder.html create mode 100644 actix_http/config/struct.ServiceConfig.html create mode 100644 actix_http/encoding/decoder/struct.Decoder.html create mode 100644 actix_http/encoding/encoder/struct.Encoder.html create mode 100644 actix_http/encoding/index.html create mode 100644 actix_http/encoding/sidebar-items.js create mode 100644 actix_http/encoding/struct.Decoder.html create mode 100644 actix_http/encoding/struct.Encoder.html create mode 100644 actix_http/enum.ConnectionType.html create mode 100644 actix_http/enum.KeepAlive.html create mode 100644 actix_http/enum.Payload.html create mode 100644 actix_http/enum.Protocol.html create mode 100644 actix_http/enum.RequestHeadType.html create mode 100644 actix_http/error/enum.ContentTypeError.html create mode 100644 actix_http/error/enum.DispatchError.html create mode 100644 actix_http/error/enum.ParseError.html create mode 100644 actix_http/error/enum.PayloadError.html create mode 100644 actix_http/error/index.html create mode 100644 actix_http/error/sidebar-items.js create mode 100644 actix_http/error/struct.Error.html create mode 100644 actix_http/error/struct.HttpError.html create mode 100644 actix_http/extensions/struct.Extensions.html create mode 100644 actix_http/h1/client/struct.ClientCodec.html create mode 100644 actix_http/h1/client/struct.ClientPayloadCodec.html create mode 100644 actix_http/h1/codec/struct.Codec.html create mode 100644 actix_http/h1/dispatcher/struct.Dispatcher.html create mode 100644 actix_http/h1/enum.Message.html create mode 100644 actix_http/h1/enum.MessageType.html create mode 100644 actix_http/h1/expect/struct.ExpectHandler.html create mode 100644 actix_http/h1/index.html create mode 100644 actix_http/h1/payload/struct.Payload.html create mode 100644 actix_http/h1/service/struct.H1Service.html create mode 100644 actix_http/h1/service/type.H1ServiceHandler.html create mode 100644 actix_http/h1/sidebar-items.js create mode 100644 actix_http/h1/struct.ClientCodec.html create mode 100644 actix_http/h1/struct.ClientPayloadCodec.html create mode 100644 actix_http/h1/struct.Codec.html create mode 100644 actix_http/h1/struct.Dispatcher.html create mode 100644 actix_http/h1/struct.ExpectHandler.html create mode 100644 actix_http/h1/struct.H1Service.html create mode 100644 actix_http/h1/struct.Payload.html create mode 100644 actix_http/h1/struct.SendResponse.html create mode 100644 actix_http/h1/struct.UpgradeHandler.html create mode 100644 actix_http/h1/type.H1ServiceHandler.html create mode 100644 actix_http/h1/upgrade/struct.UpgradeHandler.html create mode 100644 actix_http/h1/utils/struct.SendResponse.html create mode 100644 actix_http/h2/dispatcher/struct.Dispatcher.html create mode 100644 actix_http/h2/index.html create mode 100644 actix_http/h2/service/struct.H2Service.html create mode 100644 actix_http/h2/sidebar-items.js create mode 100644 actix_http/h2/struct.Dispatcher.html create mode 100644 actix_http/h2/struct.H2Service.html create mode 100644 actix_http/h2/struct.Payload.html create mode 100644 actix_http/header/as_name/trait.AsHeaderName.html create mode 100644 actix_http/header/common/constant.CACHE_STATUS.html create mode 100644 actix_http/header/common/constant.CDN_CACHE_CONTROL.html create mode 100644 actix_http/header/common/constant.CROSS_ORIGIN_EMBEDDER_POLICY.html create mode 100644 actix_http/header/common/constant.CROSS_ORIGIN_OPENER_POLICY.html create mode 100644 actix_http/header/common/constant.CROSS_ORIGIN_RESOURCE_POLICY.html create mode 100644 actix_http/header/common/constant.PERMISSIONS_POLICY.html create mode 100644 actix_http/header/common/constant.X_FORWARDED_FOR.html create mode 100644 actix_http/header/common/constant.X_FORWARDED_HOST.html create mode 100644 actix_http/header/common/constant.X_FORWARDED_PROTO.html create mode 100644 actix_http/header/constant.ACCEPT.html create mode 100644 actix_http/header/constant.ACCEPT_CHARSET.html create mode 100644 actix_http/header/constant.ACCEPT_ENCODING.html create mode 100644 actix_http/header/constant.ACCEPT_LANGUAGE.html create mode 100644 actix_http/header/constant.ACCEPT_RANGES.html create mode 100644 actix_http/header/constant.ACCESS_CONTROL_ALLOW_CREDENTIALS.html create mode 100644 actix_http/header/constant.ACCESS_CONTROL_ALLOW_HEADERS.html create mode 100644 actix_http/header/constant.ACCESS_CONTROL_ALLOW_METHODS.html create mode 100644 actix_http/header/constant.ACCESS_CONTROL_ALLOW_ORIGIN.html create mode 100644 actix_http/header/constant.ACCESS_CONTROL_EXPOSE_HEADERS.html create mode 100644 actix_http/header/constant.ACCESS_CONTROL_MAX_AGE.html create mode 100644 actix_http/header/constant.ACCESS_CONTROL_REQUEST_HEADERS.html create mode 100644 actix_http/header/constant.ACCESS_CONTROL_REQUEST_METHOD.html create mode 100644 actix_http/header/constant.AGE.html create mode 100644 actix_http/header/constant.ALLOW.html create mode 100644 actix_http/header/constant.ALT_SVC.html create mode 100644 actix_http/header/constant.AUTHORIZATION.html create mode 100644 actix_http/header/constant.CACHE_CONTROL.html create mode 100644 actix_http/header/constant.CACHE_STATUS.html create mode 100644 actix_http/header/constant.CDN_CACHE_CONTROL.html create mode 100644 actix_http/header/constant.CONNECTION.html create mode 100644 actix_http/header/constant.CONTENT_DISPOSITION.html create mode 100644 actix_http/header/constant.CONTENT_ENCODING.html create mode 100644 actix_http/header/constant.CONTENT_LANGUAGE.html create mode 100644 actix_http/header/constant.CONTENT_LENGTH.html create mode 100644 actix_http/header/constant.CONTENT_LOCATION.html create mode 100644 actix_http/header/constant.CONTENT_RANGE.html create mode 100644 actix_http/header/constant.CONTENT_SECURITY_POLICY.html create mode 100644 actix_http/header/constant.CONTENT_SECURITY_POLICY_REPORT_ONLY.html create mode 100644 actix_http/header/constant.CONTENT_TYPE.html create mode 100644 actix_http/header/constant.COOKIE.html create mode 100644 actix_http/header/constant.CROSS_ORIGIN_EMBEDDER_POLICY.html create mode 100644 actix_http/header/constant.CROSS_ORIGIN_OPENER_POLICY.html create mode 100644 actix_http/header/constant.CROSS_ORIGIN_RESOURCE_POLICY.html create mode 100644 actix_http/header/constant.DATE.html create mode 100644 actix_http/header/constant.DNT.html create mode 100644 actix_http/header/constant.ETAG.html create mode 100644 actix_http/header/constant.EXPECT.html create mode 100644 actix_http/header/constant.EXPIRES.html create mode 100644 actix_http/header/constant.FORWARDED.html create mode 100644 actix_http/header/constant.FROM.html create mode 100644 actix_http/header/constant.HOST.html create mode 100644 actix_http/header/constant.IF_MATCH.html create mode 100644 actix_http/header/constant.IF_MODIFIED_SINCE.html create mode 100644 actix_http/header/constant.IF_NONE_MATCH.html create mode 100644 actix_http/header/constant.IF_RANGE.html create mode 100644 actix_http/header/constant.IF_UNMODIFIED_SINCE.html create mode 100644 actix_http/header/constant.LAST_MODIFIED.html create mode 100644 actix_http/header/constant.LINK.html create mode 100644 actix_http/header/constant.LOCATION.html create mode 100644 actix_http/header/constant.MAX_FORWARDS.html create mode 100644 actix_http/header/constant.ORIGIN.html create mode 100644 actix_http/header/constant.PERMISSIONS_POLICY.html create mode 100644 actix_http/header/constant.PRAGMA.html create mode 100644 actix_http/header/constant.PROXY_AUTHENTICATE.html create mode 100644 actix_http/header/constant.PROXY_AUTHORIZATION.html create mode 100644 actix_http/header/constant.PUBLIC_KEY_PINS.html create mode 100644 actix_http/header/constant.PUBLIC_KEY_PINS_REPORT_ONLY.html create mode 100644 actix_http/header/constant.RANGE.html create mode 100644 actix_http/header/constant.REFERER.html create mode 100644 actix_http/header/constant.REFERRER_POLICY.html create mode 100644 actix_http/header/constant.REFRESH.html create mode 100644 actix_http/header/constant.RETRY_AFTER.html create mode 100644 actix_http/header/constant.SEC_WEBSOCKET_ACCEPT.html create mode 100644 actix_http/header/constant.SEC_WEBSOCKET_EXTENSIONS.html create mode 100644 actix_http/header/constant.SEC_WEBSOCKET_KEY.html create mode 100644 actix_http/header/constant.SEC_WEBSOCKET_PROTOCOL.html create mode 100644 actix_http/header/constant.SEC_WEBSOCKET_VERSION.html create mode 100644 actix_http/header/constant.SERVER.html create mode 100644 actix_http/header/constant.SET_COOKIE.html create mode 100644 actix_http/header/constant.STRICT_TRANSPORT_SECURITY.html create mode 100644 actix_http/header/constant.TE.html create mode 100644 actix_http/header/constant.TRAILER.html create mode 100644 actix_http/header/constant.TRANSFER_ENCODING.html create mode 100644 actix_http/header/constant.UPGRADE.html create mode 100644 actix_http/header/constant.UPGRADE_INSECURE_REQUESTS.html create mode 100644 actix_http/header/constant.USER_AGENT.html create mode 100644 actix_http/header/constant.VARY.html create mode 100644 actix_http/header/constant.VIA.html create mode 100644 actix_http/header/constant.WARNING.html create mode 100644 actix_http/header/constant.WWW_AUTHENTICATE.html create mode 100644 actix_http/header/constant.X_CONTENT_TYPE_OPTIONS.html create mode 100644 actix_http/header/constant.X_DNS_PREFETCH_CONTROL.html create mode 100644 actix_http/header/constant.X_FORWARDED_FOR.html create mode 100644 actix_http/header/constant.X_FORWARDED_HOST.html create mode 100644 actix_http/header/constant.X_FORWARDED_PROTO.html create mode 100644 actix_http/header/constant.X_FRAME_OPTIONS.html create mode 100644 actix_http/header/constant.X_XSS_PROTECTION.html create mode 100644 actix_http/header/enum.Charset.html create mode 100644 actix_http/header/enum.ContentEncoding.html create mode 100644 actix_http/header/fn.fmt_comma_delimited.html create mode 100644 actix_http/header/fn.from_comma_delimited.html create mode 100644 actix_http/header/fn.from_one_raw_str.html create mode 100644 actix_http/header/fn.http_percent_encode.html create mode 100644 actix_http/header/fn.parse_extended_value.html create mode 100644 actix_http/header/fn.q.html create mode 100644 actix_http/header/index.html create mode 100644 actix_http/header/into_pair/trait.TryIntoHeaderPair.html create mode 100644 actix_http/header/into_value/trait.TryIntoHeaderValue.html create mode 100644 actix_http/header/map/index.html create mode 100644 actix_http/header/map/sidebar-items.js create mode 100644 actix_http/header/map/struct.Drain.html create mode 100644 actix_http/header/map/struct.HeaderMap.html create mode 100644 actix_http/header/map/struct.IntoIter.html create mode 100644 actix_http/header/map/struct.Iter.html create mode 100644 actix_http/header/map/struct.Keys.html create mode 100644 actix_http/header/map/struct.Removed.html create mode 100644 actix_http/header/shared/charset/enum.Charset.html create mode 100644 actix_http/header/shared/content_encoding/enum.ContentEncoding.html create mode 100644 actix_http/header/shared/extended/fn.parse_extended_value.html create mode 100644 actix_http/header/shared/extended/struct.ExtendedValue.html create mode 100644 actix_http/header/shared/http_date/struct.HttpDate.html create mode 100644 actix_http/header/shared/quality/fn.q.html create mode 100644 actix_http/header/shared/quality/struct.Quality.html create mode 100644 actix_http/header/shared/quality_item/struct.QualityItem.html create mode 100644 actix_http/header/shared/struct.LanguageTag.html create mode 100644 actix_http/header/sidebar-items.js create mode 100644 actix_http/header/struct.ExtendedValue.html create mode 100644 actix_http/header/struct.HeaderName.html create mode 100644 actix_http/header/struct.HeaderValue.html create mode 100644 actix_http/header/struct.HttpDate.html create mode 100644 actix_http/header/struct.InvalidHeaderName.html create mode 100644 actix_http/header/struct.InvalidHeaderValue.html create mode 100644 actix_http/header/struct.LanguageTag.html create mode 100644 actix_http/header/struct.Quality.html create mode 100644 actix_http/header/struct.QualityItem.html create mode 100644 actix_http/header/struct.ToStrError.html create mode 100644 actix_http/header/trait.AsHeaderName.html create mode 100644 actix_http/header/trait.Header.html create mode 100644 actix_http/header/trait.TryIntoHeaderPair.html create mode 100644 actix_http/header/trait.TryIntoHeaderValue.html create mode 100644 actix_http/header/utils/fn.fmt_comma_delimited.html create mode 100644 actix_http/header/utils/fn.from_comma_delimited.html create mode 100644 actix_http/header/utils/fn.from_one_raw_str.html create mode 100644 actix_http/header/utils/fn.http_percent_encode.html create mode 100644 actix_http/http_message/trait.HttpMessage.html create mode 100644 actix_http/index.html create mode 100644 actix_http/keep_alive/enum.KeepAlive.html create mode 100644 actix_http/message/enum.ConnectionType.html create mode 100644 actix_http/message/struct.Message.html create mode 100644 actix_http/payload/enum.Payload.html create mode 100644 actix_http/payload/type.BoxedPayloadStream.html create mode 100644 actix_http/requests/head/enum.RequestHeadType.html create mode 100644 actix_http/requests/head/struct.RequestHead.html create mode 100644 actix_http/requests/request/struct.Request.html create mode 100644 actix_http/responses/builder/struct.ResponseBuilder.html create mode 100644 actix_http/responses/head/struct.ResponseHead.html create mode 100644 actix_http/responses/response/struct.Response.html create mode 100644 actix_http/service/struct.HttpService.html create mode 100644 actix_http/service/struct.TlsAcceptorConfig.html create mode 100644 actix_http/sidebar-items.js create mode 100644 actix_http/struct.Extensions.html create mode 100644 actix_http/struct.HttpService.html create mode 100644 actix_http/struct.HttpServiceBuilder.html create mode 100644 actix_http/struct.Message.html create mode 100644 actix_http/struct.Method.html create mode 100644 actix_http/struct.Request.html create mode 100644 actix_http/struct.RequestHead.html create mode 100644 actix_http/struct.Response.html create mode 100644 actix_http/struct.ResponseBuilder.html create mode 100644 actix_http/struct.ResponseHead.html create mode 100644 actix_http/struct.ServiceConfig.html create mode 100644 actix_http/struct.StatusCode.html create mode 100644 actix_http/struct.TlsAcceptorConfig.html create mode 100644 actix_http/struct.Uri.html create mode 100644 actix_http/struct.Version.html create mode 100644 actix_http/test/index.html create mode 100644 actix_http/test/sidebar-items.js create mode 100644 actix_http/test/struct.TestBuffer.html create mode 100644 actix_http/test/struct.TestRequest.html create mode 100644 actix_http/test/struct.TestSeqBuffer.html create mode 100644 actix_http/test/struct.TestSeqInner.html create mode 100644 actix_http/trait.HttpMessage.html create mode 100644 actix_http/type.BoxedPayloadStream.html create mode 100644 actix_http/uri/index.html create mode 100644 actix_http/uri/sidebar-items.js create mode 100644 actix_http/uri/struct.Authority.html create mode 100644 actix_http/uri/struct.Builder.html create mode 100644 actix_http/uri/struct.InvalidUri.html create mode 100644 actix_http/uri/struct.InvalidUriParts.html create mode 100644 actix_http/uri/struct.Parts.html create mode 100644 actix_http/uri/struct.PathAndQuery.html create mode 100644 actix_http/uri/struct.Port.html create mode 100644 actix_http/uri/struct.Scheme.html create mode 100644 actix_http/uri/struct.Uri.html create mode 100644 actix_http/ws/codec/enum.Frame.html create mode 100644 actix_http/ws/codec/enum.Item.html create mode 100644 actix_http/ws/codec/enum.Message.html create mode 100644 actix_http/ws/codec/struct.Codec.html create mode 100644 actix_http/ws/dispatcher/struct.Dispatcher.html create mode 100644 actix_http/ws/enum.CloseCode.html create mode 100644 actix_http/ws/enum.Frame.html create mode 100644 actix_http/ws/enum.HandshakeError.html create mode 100644 actix_http/ws/enum.Item.html create mode 100644 actix_http/ws/enum.Message.html create mode 100644 actix_http/ws/enum.OpCode.html create mode 100644 actix_http/ws/enum.ProtocolError.html create mode 100644 actix_http/ws/fn.handshake.html create mode 100644 actix_http/ws/fn.handshake_response.html create mode 100644 actix_http/ws/fn.hash_key.html create mode 100644 actix_http/ws/fn.verify_handshake.html create mode 100644 actix_http/ws/frame/struct.Parser.html create mode 100644 actix_http/ws/index.html create mode 100644 actix_http/ws/proto/enum.CloseCode.html create mode 100644 actix_http/ws/proto/enum.OpCode.html create mode 100644 actix_http/ws/proto/fn.hash_key.html create mode 100644 actix_http/ws/proto/struct.CloseReason.html create mode 100644 actix_http/ws/sidebar-items.js create mode 100644 actix_http/ws/struct.CloseReason.html create mode 100644 actix_http/ws/struct.Codec.html create mode 100644 actix_http/ws/struct.Dispatcher.html create mode 100644 actix_http/ws/struct.Parser.html create mode 100644 actix_http_test/all.html create mode 100644 actix_http_test/fn.test_server.html create mode 100644 actix_http_test/fn.test_server_with_addr.html create mode 100644 actix_http_test/fn.unused_addr.html create mode 100644 actix_http_test/index.html create mode 100644 actix_http_test/sidebar-items.js create mode 100644 actix_http_test/struct.TestServer.html create mode 100644 actix_multipart/all.html create mode 100644 actix_multipart/enum.MultipartError.html create mode 100644 actix_multipart/error/enum.MultipartError.html create mode 100644 actix_multipart/form/bytes/index.html create mode 100644 actix_multipart/form/bytes/sidebar-items.js create mode 100644 actix_multipart/form/bytes/struct.Bytes.html create mode 100644 actix_multipart/form/derive.MultipartForm.html create mode 100644 actix_multipart/form/index.html create mode 100644 actix_multipart/form/json/enum.JsonFieldError.html create mode 100644 actix_multipart/form/json/index.html create mode 100644 actix_multipart/form/json/sidebar-items.js create mode 100644 actix_multipart/form/json/struct.Json.html create mode 100644 actix_multipart/form/json/struct.JsonConfig.html create mode 100644 actix_multipart/form/sidebar-items.js create mode 100644 actix_multipart/form/struct.Limits.html create mode 100644 actix_multipart/form/struct.MultipartForm.html create mode 100644 actix_multipart/form/struct.MultipartFormConfig.html create mode 100644 actix_multipart/form/tempfile/enum.TempFileError.html create mode 100644 actix_multipart/form/tempfile/index.html create mode 100644 actix_multipart/form/tempfile/sidebar-items.js create mode 100644 actix_multipart/form/tempfile/struct.TempFile.html create mode 100644 actix_multipart/form/tempfile/struct.TempFileConfig.html create mode 100644 actix_multipart/form/text/enum.TextError.html create mode 100644 actix_multipart/form/text/index.html create mode 100644 actix_multipart/form/text/sidebar-items.js create mode 100644 actix_multipart/form/text/struct.Text.html create mode 100644 actix_multipart/form/text/struct.TextConfig.html create mode 100644 actix_multipart/form/trait.FieldReader.html create mode 100644 actix_multipart/form/trait.MultipartCollect.html create mode 100644 actix_multipart/index.html create mode 100644 actix_multipart/server/struct.Field.html create mode 100644 actix_multipart/server/struct.Multipart.html create mode 100644 actix_multipart/sidebar-items.js create mode 100644 actix_multipart/struct.Field.html create mode 100644 actix_multipart/struct.Multipart.html create mode 100644 actix_multipart/test/fn.create_form_data_payload_and_headers.html create mode 100644 actix_multipart/test/fn.create_form_data_payload_and_headers_with_boundary.html create mode 100644 actix_multipart/test/index.html create mode 100644 actix_multipart/test/sidebar-items.js create mode 100644 actix_multipart_derive/all.html create mode 100644 actix_multipart_derive/derive.MultipartForm.html create mode 100644 actix_multipart_derive/index.html create mode 100644 actix_multipart_derive/sidebar-items.js create mode 100644 actix_router/all.html create mode 100644 actix_router/de/struct.PathDeserializer.html create mode 100644 actix_router/enum.Patterns.html create mode 100644 actix_router/index.html create mode 100644 actix_router/path/struct.Path.html create mode 100644 actix_router/pattern/enum.Patterns.html create mode 100644 actix_router/pattern/trait.IntoPatterns.html create mode 100644 actix_router/quoter/struct.Quoter.html create mode 100644 actix_router/resource/struct.ResourceDef.html create mode 100644 actix_router/resource_path/trait.Resource.html create mode 100644 actix_router/resource_path/trait.ResourcePath.html create mode 100644 actix_router/router/struct.ResourceId.html create mode 100644 actix_router/router/struct.Router.html create mode 100644 actix_router/router/struct.RouterBuilder.html create mode 100644 actix_router/sidebar-items.js create mode 100644 actix_router/struct.Path.html create mode 100644 actix_router/struct.PathDeserializer.html create mode 100644 actix_router/struct.Quoter.html create mode 100644 actix_router/struct.ResourceDef.html create mode 100644 actix_router/struct.ResourceId.html create mode 100644 actix_router/struct.Router.html create mode 100644 actix_router/struct.RouterBuilder.html create mode 100644 actix_router/struct.Url.html create mode 100644 actix_router/trait.IntoPatterns.html create mode 100644 actix_router/trait.Resource.html create mode 100644 actix_router/trait.ResourcePath.html create mode 100644 actix_router/url/struct.Url.html create mode 100644 actix_test/all.html create mode 100644 actix_test/enum.PayloadError.html create mode 100644 actix_test/fn.call_and_read_body.html create mode 100644 actix_test/fn.call_and_read_body_json.html create mode 100644 actix_test/fn.call_service.html create mode 100644 actix_test/fn.config.html create mode 100644 actix_test/fn.init_service.html create mode 100644 actix_test/fn.ok_service.html create mode 100644 actix_test/fn.read_body.html create mode 100644 actix_test/fn.read_body_json.html create mode 100644 actix_test/fn.start.html create mode 100644 actix_test/fn.start_with.html create mode 100644 actix_test/fn.status_service.html create mode 100644 actix_test/fn.to_bytes.html create mode 100644 actix_test/fn.unused_addr.html create mode 100644 actix_test/index.html create mode 100644 actix_test/sidebar-items.js create mode 100644 actix_test/struct.Client.html create mode 100644 actix_test/struct.ClientRequest.html create mode 100644 actix_test/struct.ClientResponse.html create mode 100644 actix_test/struct.Connector.html create mode 100644 actix_test/struct.TestBuffer.html create mode 100644 actix_test/struct.TestRequest.html create mode 100644 actix_test/struct.TestServer.html create mode 100644 actix_test/struct.TestServerConfig.html create mode 100644 actix_web/all.html create mode 100644 actix_web/app/struct.App.html create mode 100644 actix_web/attr.connect.html create mode 100644 actix_web/attr.delete.html create mode 100644 actix_web/attr.get.html create mode 100644 actix_web/attr.head.html create mode 100644 actix_web/attr.main.html create mode 100644 actix_web/attr.options.html create mode 100644 actix_web/attr.patch.html create mode 100644 actix_web/attr.post.html create mode 100644 actix_web/attr.put.html create mode 100644 actix_web/attr.route.html create mode 100644 actix_web/attr.routes.html create mode 100644 actix_web/attr.test.html create mode 100644 actix_web/attr.trace.html create mode 100644 actix_web/body/enum.BodySize.html create mode 100644 actix_web/body/enum.EitherBody.html create mode 100644 actix_web/body/fn.to_bytes.html create mode 100644 actix_web/body/fn.to_bytes_limited.html create mode 100644 actix_web/body/index.html create mode 100644 actix_web/body/sidebar-items.js create mode 100644 actix_web/body/struct.BodyLimitExceeded.html create mode 100644 actix_web/body/struct.BodyStream.html create mode 100644 actix_web/body/struct.BoxBody.html create mode 100644 actix_web/body/struct.None.html create mode 100644 actix_web/body/struct.SizedStream.html create mode 100644 actix_web/body/trait.MessageBody.html create mode 100644 actix_web/config/struct.AppConfig.html create mode 100644 actix_web/config/struct.AppService.html create mode 100644 actix_web/config/struct.ServiceConfig.html create mode 100644 actix_web/cookie/enum.Expiration.html create mode 100644 actix_web/cookie/enum.KeyError.html create mode 100644 actix_web/cookie/enum.ParseError.html create mode 100644 actix_web/cookie/enum.SameSite.html create mode 100644 actix_web/cookie/index.html create mode 100644 actix_web/cookie/sidebar-items.js create mode 100644 actix_web/cookie/struct.Cookie.html create mode 100644 actix_web/cookie/struct.CookieBuilder.html create mode 100644 actix_web/cookie/struct.CookieJar.html create mode 100644 actix_web/cookie/struct.Delta.html create mode 100644 actix_web/cookie/struct.Display.html create mode 100644 actix_web/cookie/struct.Iter.html create mode 100644 actix_web/cookie/struct.Key.html create mode 100644 actix_web/cookie/struct.PrivateJar.html create mode 100644 actix_web/cookie/struct.SignedJar.html create mode 100644 actix_web/cookie/time/convert/index.html create mode 100644 actix_web/cookie/time/convert/sidebar-items.js create mode 100644 actix_web/cookie/time/convert/struct.Day.html create mode 100644 actix_web/cookie/time/convert/struct.Hour.html create mode 100644 actix_web/cookie/time/convert/struct.Microsecond.html create mode 100644 actix_web/cookie/time/convert/struct.Millisecond.html create mode 100644 actix_web/cookie/time/convert/struct.Minute.html create mode 100644 actix_web/cookie/time/convert/struct.Nanosecond.html create mode 100644 actix_web/cookie/time/convert/struct.Second.html create mode 100644 actix_web/cookie/time/convert/struct.Week.html create mode 100644 actix_web/cookie/time/enum.Error.html create mode 100644 actix_web/cookie/time/enum.Month.html create mode 100644 actix_web/cookie/time/enum.Weekday.html create mode 100644 actix_web/cookie/time/error/enum.Error.html create mode 100644 actix_web/cookie/time/error/enum.Format.html create mode 100644 actix_web/cookie/time/error/enum.InvalidFormatDescription.html create mode 100644 actix_web/cookie/time/error/enum.Parse.html create mode 100644 actix_web/cookie/time/error/enum.ParseFromDescription.html create mode 100644 actix_web/cookie/time/error/enum.TryFromParsed.html create mode 100644 actix_web/cookie/time/error/index.html create mode 100644 actix_web/cookie/time/error/sidebar-items.js create mode 100644 actix_web/cookie/time/error/struct.ComponentRange.html create mode 100644 actix_web/cookie/time/error/struct.ConversionRange.html create mode 100644 actix_web/cookie/time/error/struct.DifferentVariant.html create mode 100644 actix_web/cookie/time/error/struct.InvalidVariant.html create mode 100644 actix_web/cookie/time/ext/index.html create mode 100644 actix_web/cookie/time/ext/sidebar-items.js create mode 100644 actix_web/cookie/time/ext/trait.InstantExt.html create mode 100644 actix_web/cookie/time/ext/trait.NumericalDuration.html create mode 100644 actix_web/cookie/time/ext/trait.NumericalStdDuration.html create mode 100644 actix_web/cookie/time/format_description/enum.BorrowedFormatItem.html create mode 100644 actix_web/cookie/time/format_description/enum.Component.html create mode 100644 actix_web/cookie/time/format_description/enum.FormatItem.html create mode 100644 actix_web/cookie/time/format_description/enum.OwnedFormatItem.html create mode 100644 actix_web/cookie/time/format_description/fn.parse.html create mode 100644 actix_web/cookie/time/format_description/fn.parse_borrowed.html create mode 100644 actix_web/cookie/time/format_description/fn.parse_owned.html create mode 100644 actix_web/cookie/time/format_description/index.html create mode 100644 actix_web/cookie/time/format_description/modifier/enum.MonthRepr.html create mode 100644 actix_web/cookie/time/format_description/modifier/enum.Padding.html create mode 100644 actix_web/cookie/time/format_description/modifier/enum.SubsecondDigits.html create mode 100644 actix_web/cookie/time/format_description/modifier/enum.UnixTimestampPrecision.html create mode 100644 actix_web/cookie/time/format_description/modifier/enum.WeekNumberRepr.html create mode 100644 actix_web/cookie/time/format_description/modifier/enum.WeekdayRepr.html create mode 100644 actix_web/cookie/time/format_description/modifier/enum.YearRepr.html create mode 100644 actix_web/cookie/time/format_description/modifier/index.html create mode 100644 actix_web/cookie/time/format_description/modifier/sidebar-items.js create mode 100644 actix_web/cookie/time/format_description/modifier/struct.Day.html create mode 100644 actix_web/cookie/time/format_description/modifier/struct.End.html create mode 100644 actix_web/cookie/time/format_description/modifier/struct.Hour.html create mode 100644 actix_web/cookie/time/format_description/modifier/struct.Ignore.html create mode 100644 actix_web/cookie/time/format_description/modifier/struct.Minute.html create mode 100644 actix_web/cookie/time/format_description/modifier/struct.Month.html create mode 100644 actix_web/cookie/time/format_description/modifier/struct.OffsetHour.html create mode 100644 actix_web/cookie/time/format_description/modifier/struct.OffsetMinute.html create mode 100644 actix_web/cookie/time/format_description/modifier/struct.OffsetSecond.html create mode 100644 actix_web/cookie/time/format_description/modifier/struct.Ordinal.html create mode 100644 actix_web/cookie/time/format_description/modifier/struct.Period.html create mode 100644 actix_web/cookie/time/format_description/modifier/struct.Second.html create mode 100644 actix_web/cookie/time/format_description/modifier/struct.Subsecond.html create mode 100644 actix_web/cookie/time/format_description/modifier/struct.UnixTimestamp.html create mode 100644 actix_web/cookie/time/format_description/modifier/struct.WeekNumber.html create mode 100644 actix_web/cookie/time/format_description/modifier/struct.Weekday.html create mode 100644 actix_web/cookie/time/format_description/modifier/struct.Year.html create mode 100644 actix_web/cookie/time/format_description/sidebar-items.js create mode 100644 actix_web/cookie/time/format_description/well_known/index.html create mode 100644 actix_web/cookie/time/format_description/well_known/iso8601/enum.DateKind.html create mode 100644 actix_web/cookie/time/format_description/well_known/iso8601/enum.FormattedComponents.html create mode 100644 actix_web/cookie/time/format_description/well_known/iso8601/enum.OffsetPrecision.html create mode 100644 actix_web/cookie/time/format_description/well_known/iso8601/enum.TimePrecision.html create mode 100644 actix_web/cookie/time/format_description/well_known/iso8601/index.html create mode 100644 actix_web/cookie/time/format_description/well_known/iso8601/sidebar-items.js create mode 100644 actix_web/cookie/time/format_description/well_known/iso8601/struct.Config.html create mode 100644 actix_web/cookie/time/format_description/well_known/iso8601/struct.Iso8601.html create mode 100644 actix_web/cookie/time/format_description/well_known/iso8601/type.EncodedConfig.html create mode 100644 actix_web/cookie/time/format_description/well_known/sidebar-items.js create mode 100644 actix_web/cookie/time/format_description/well_known/struct.Iso8601.html create mode 100644 actix_web/cookie/time/format_description/well_known/struct.Rfc2822.html create mode 100644 actix_web/cookie/time/format_description/well_known/struct.Rfc3339.html create mode 100644 actix_web/cookie/time/formatting/index.html create mode 100644 actix_web/cookie/time/formatting/sidebar-items.js create mode 100644 actix_web/cookie/time/formatting/trait.Formattable.html create mode 100644 actix_web/cookie/time/index.html create mode 100644 actix_web/cookie/time/macros/index.html create mode 100644 actix_web/cookie/time/macros/macro.date!.html create mode 100644 actix_web/cookie/time/macros/macro.date.html create mode 100644 actix_web/cookie/time/macros/macro.datetime!.html create mode 100644 actix_web/cookie/time/macros/macro.datetime.html create mode 100644 actix_web/cookie/time/macros/macro.format_description!.html create mode 100644 actix_web/cookie/time/macros/macro.format_description.html create mode 100644 actix_web/cookie/time/macros/macro.offset!.html create mode 100644 actix_web/cookie/time/macros/macro.offset.html create mode 100644 actix_web/cookie/time/macros/macro.time!.html create mode 100644 actix_web/cookie/time/macros/macro.time.html create mode 100644 actix_web/cookie/time/macros/sidebar-items.js create mode 100644 actix_web/cookie/time/parsing/index.html create mode 100644 actix_web/cookie/time/parsing/sidebar-items.js create mode 100644 actix_web/cookie/time/parsing/struct.Parsed.html create mode 100644 actix_web/cookie/time/parsing/trait.Parsable.html create mode 100644 actix_web/cookie/time/sidebar-items.js create mode 100644 actix_web/cookie/time/struct.Date.html create mode 100644 actix_web/cookie/time/struct.Duration.html create mode 100644 actix_web/cookie/time/struct.Instant.html create mode 100644 actix_web/cookie/time/struct.OffsetDateTime.html create mode 100644 actix_web/cookie/time/struct.PrimitiveDateTime.html create mode 100644 actix_web/cookie/time/struct.Time.html create mode 100644 actix_web/cookie/time/struct.UtcOffset.html create mode 100644 actix_web/cookie/time/type.Result.html create mode 100644 actix_web/cookie/time/util/fn.days_in_year.html create mode 100644 actix_web/cookie/time/util/fn.days_in_year_month.html create mode 100644 actix_web/cookie/time/util/fn.is_leap_year.html create mode 100644 actix_web/cookie/time/util/fn.weeks_in_year.html create mode 100644 actix_web/cookie/time/util/index.html create mode 100644 actix_web/cookie/time/util/sidebar-items.js create mode 100644 actix_web/data/struct.Data.html create mode 100644 actix_web/dev/enum.JsonBody.html create mode 100644 actix_web/dev/enum.Payload.html create mode 100644 actix_web/dev/fn.fn_factory.html create mode 100644 actix_web/dev/fn.fn_service.html create mode 100644 actix_web/dev/index.html create mode 100644 actix_web/dev/macro.always_ready!.html create mode 100644 actix_web/dev/macro.always_ready.html create mode 100644 actix_web/dev/macro.forward_ready!.html create mode 100644 actix_web/dev/macro.forward_ready.html create mode 100644 actix_web/dev/sidebar-items.js create mode 100644 actix_web/dev/struct.AppConfig.html create mode 100644 actix_web/dev/struct.AppService.html create mode 100644 actix_web/dev/struct.ConnectionInfo.html create mode 100644 actix_web/dev/struct.Decompress.html create mode 100644 actix_web/dev/struct.Extensions.html create mode 100644 actix_web/dev/struct.Path.html create mode 100644 actix_web/dev/struct.PeerAddr.html create mode 100644 actix_web/dev/struct.Readlines.html create mode 100644 actix_web/dev/struct.RequestHead.html create mode 100644 actix_web/dev/struct.ResourceDef.html create mode 100644 actix_web/dev/struct.ResourceMap.html create mode 100644 actix_web/dev/struct.Response.html create mode 100644 actix_web/dev/struct.ResponseHead.html create mode 100644 actix_web/dev/struct.Server.html create mode 100644 actix_web/dev/struct.ServerHandle.html create mode 100644 actix_web/dev/struct.ServiceRequest.html create mode 100644 actix_web/dev/struct.ServiceResponse.html create mode 100644 actix_web/dev/struct.Url.html create mode 100644 actix_web/dev/struct.UrlEncoded.html create mode 100644 actix_web/dev/struct.WebService.html create mode 100644 actix_web/dev/trait.HttpServiceFactory.html create mode 100644 actix_web/dev/trait.ResourcePath.html create mode 100644 actix_web/dev/trait.Service.html create mode 100644 actix_web/dev/trait.ServiceFactory.html create mode 100644 actix_web/dev/trait.Transform.html create mode 100644 actix_web/enum.Either.html create mode 100644 actix_web/error/enum.ContentTypeError.html create mode 100644 actix_web/error/enum.DispatchError.html create mode 100644 actix_web/error/enum.JsonPayloadError.html create mode 100644 actix_web/error/enum.ParseError.html create mode 100644 actix_web/error/enum.PathError.html create mode 100644 actix_web/error/enum.PayloadError.html create mode 100644 actix_web/error/enum.QueryPayloadError.html create mode 100644 actix_web/error/enum.ReadlinesError.html create mode 100644 actix_web/error/enum.UrlGenerationError.html create mode 100644 actix_web/error/enum.UrlencodedError.html create mode 100644 actix_web/error/error/struct.Error.html create mode 100644 actix_web/error/fn.ErrorBadGateway.html create mode 100644 actix_web/error/fn.ErrorBadRequest.html create mode 100644 actix_web/error/fn.ErrorConflict.html create mode 100644 actix_web/error/fn.ErrorExpectationFailed.html create mode 100644 actix_web/error/fn.ErrorFailedDependency.html create mode 100644 actix_web/error/fn.ErrorForbidden.html create mode 100644 actix_web/error/fn.ErrorGatewayTimeout.html create mode 100644 actix_web/error/fn.ErrorGone.html create mode 100644 actix_web/error/fn.ErrorHttpVersionNotSupported.html create mode 100644 actix_web/error/fn.ErrorImATeapot.html create mode 100644 actix_web/error/fn.ErrorInsufficientStorage.html create mode 100644 actix_web/error/fn.ErrorInternalServerError.html create mode 100644 actix_web/error/fn.ErrorLengthRequired.html create mode 100644 actix_web/error/fn.ErrorLocked.html create mode 100644 actix_web/error/fn.ErrorLoopDetected.html create mode 100644 actix_web/error/fn.ErrorMethodNotAllowed.html create mode 100644 actix_web/error/fn.ErrorMisdirectedRequest.html create mode 100644 actix_web/error/fn.ErrorNetworkAuthenticationRequired.html create mode 100644 actix_web/error/fn.ErrorNotAcceptable.html create mode 100644 actix_web/error/fn.ErrorNotExtended.html create mode 100644 actix_web/error/fn.ErrorNotFound.html create mode 100644 actix_web/error/fn.ErrorNotImplemented.html create mode 100644 actix_web/error/fn.ErrorPayloadTooLarge.html create mode 100644 actix_web/error/fn.ErrorPaymentRequired.html create mode 100644 actix_web/error/fn.ErrorPreconditionFailed.html create mode 100644 actix_web/error/fn.ErrorPreconditionRequired.html create mode 100644 actix_web/error/fn.ErrorProxyAuthenticationRequired.html create mode 100644 actix_web/error/fn.ErrorRangeNotSatisfiable.html create mode 100644 actix_web/error/fn.ErrorRequestHeaderFieldsTooLarge.html create mode 100644 actix_web/error/fn.ErrorRequestTimeout.html create mode 100644 actix_web/error/fn.ErrorServiceUnavailable.html create mode 100644 actix_web/error/fn.ErrorTooManyRequests.html create mode 100644 actix_web/error/fn.ErrorUnauthorized.html create mode 100644 actix_web/error/fn.ErrorUnavailableForLegalReasons.html create mode 100644 actix_web/error/fn.ErrorUnprocessableEntity.html create mode 100644 actix_web/error/fn.ErrorUnsupportedMediaType.html create mode 100644 actix_web/error/fn.ErrorUpgradeRequired.html create mode 100644 actix_web/error/fn.ErrorUriTooLong.html create mode 100644 actix_web/error/fn.ErrorVariantAlsoNegotiates.html create mode 100644 actix_web/error/index.html create mode 100644 actix_web/error/internal/fn.ErrorBadGateway.html create mode 100644 actix_web/error/internal/fn.ErrorBadRequest.html create mode 100644 actix_web/error/internal/fn.ErrorConflict.html create mode 100644 actix_web/error/internal/fn.ErrorExpectationFailed.html create mode 100644 actix_web/error/internal/fn.ErrorFailedDependency.html create mode 100644 actix_web/error/internal/fn.ErrorForbidden.html create mode 100644 actix_web/error/internal/fn.ErrorGatewayTimeout.html create mode 100644 actix_web/error/internal/fn.ErrorGone.html create mode 100644 actix_web/error/internal/fn.ErrorHttpVersionNotSupported.html create mode 100644 actix_web/error/internal/fn.ErrorImATeapot.html create mode 100644 actix_web/error/internal/fn.ErrorInsufficientStorage.html create mode 100644 actix_web/error/internal/fn.ErrorInternalServerError.html create mode 100644 actix_web/error/internal/fn.ErrorLengthRequired.html create mode 100644 actix_web/error/internal/fn.ErrorLocked.html create mode 100644 actix_web/error/internal/fn.ErrorLoopDetected.html create mode 100644 actix_web/error/internal/fn.ErrorMethodNotAllowed.html create mode 100644 actix_web/error/internal/fn.ErrorMisdirectedRequest.html create mode 100644 actix_web/error/internal/fn.ErrorNetworkAuthenticationRequired.html create mode 100644 actix_web/error/internal/fn.ErrorNotAcceptable.html create mode 100644 actix_web/error/internal/fn.ErrorNotExtended.html create mode 100644 actix_web/error/internal/fn.ErrorNotFound.html create mode 100644 actix_web/error/internal/fn.ErrorNotImplemented.html create mode 100644 actix_web/error/internal/fn.ErrorPayloadTooLarge.html create mode 100644 actix_web/error/internal/fn.ErrorPaymentRequired.html create mode 100644 actix_web/error/internal/fn.ErrorPreconditionFailed.html create mode 100644 actix_web/error/internal/fn.ErrorPreconditionRequired.html create mode 100644 actix_web/error/internal/fn.ErrorProxyAuthenticationRequired.html create mode 100644 actix_web/error/internal/fn.ErrorRangeNotSatisfiable.html create mode 100644 actix_web/error/internal/fn.ErrorRequestHeaderFieldsTooLarge.html create mode 100644 actix_web/error/internal/fn.ErrorRequestTimeout.html create mode 100644 actix_web/error/internal/fn.ErrorServiceUnavailable.html create mode 100644 actix_web/error/internal/fn.ErrorTooManyRequests.html create mode 100644 actix_web/error/internal/fn.ErrorUnauthorized.html create mode 100644 actix_web/error/internal/fn.ErrorUnavailableForLegalReasons.html create mode 100644 actix_web/error/internal/fn.ErrorUnprocessableEntity.html create mode 100644 actix_web/error/internal/fn.ErrorUnsupportedMediaType.html create mode 100644 actix_web/error/internal/fn.ErrorUpgradeRequired.html create mode 100644 actix_web/error/internal/fn.ErrorUriTooLong.html create mode 100644 actix_web/error/internal/fn.ErrorVariantAlsoNegotiates.html create mode 100644 actix_web/error/internal/struct.InternalError.html create mode 100644 actix_web/error/response_error/trait.ResponseError.html create mode 100644 actix_web/error/sidebar-items.js create mode 100644 actix_web/error/struct.BlockingError.html create mode 100644 actix_web/error/struct.Error.html create mode 100644 actix_web/error/struct.HttpError.html create mode 100644 actix_web/error/struct.InternalError.html create mode 100644 actix_web/error/trait.ResponseError.html create mode 100644 actix_web/error/type.Result.html create mode 100644 actix_web/extract/trait.FromRequest.html create mode 100644 actix_web/guard/acceptable/struct.Acceptable.html create mode 100644 actix_web/guard/fn.All.html create mode 100644 actix_web/guard/fn.Any.html create mode 100644 actix_web/guard/fn.Connect.html create mode 100644 actix_web/guard/fn.Delete.html create mode 100644 actix_web/guard/fn.Get.html create mode 100644 actix_web/guard/fn.Head.html create mode 100644 actix_web/guard/fn.Header.html create mode 100644 actix_web/guard/fn.Host.html create mode 100644 actix_web/guard/fn.Method.html create mode 100644 actix_web/guard/fn.Options.html create mode 100644 actix_web/guard/fn.Patch.html create mode 100644 actix_web/guard/fn.Post.html create mode 100644 actix_web/guard/fn.Put.html create mode 100644 actix_web/guard/fn.Trace.html create mode 100644 actix_web/guard/fn.fn_guard.html create mode 100644 actix_web/guard/host/fn.Host.html create mode 100644 actix_web/guard/index.html create mode 100644 actix_web/guard/sidebar-items.js create mode 100644 actix_web/guard/struct.Acceptable.html create mode 100644 actix_web/guard/struct.AllGuard.html create mode 100644 actix_web/guard/struct.AnyGuard.html create mode 100644 actix_web/guard/struct.GuardContext.html create mode 100644 actix_web/guard/struct.Not.html create mode 100644 actix_web/guard/trait.Guard.html create mode 100644 actix_web/handler/trait.Handler.html create mode 100644 actix_web/http/enum.ConnectionType.html create mode 100644 actix_web/http/enum.KeepAlive.html create mode 100644 actix_web/http/header/accept/struct.Accept.html create mode 100644 actix_web/http/header/accept_charset/struct.AcceptCharset.html create mode 100644 actix_web/http/header/accept_encoding/struct.AcceptEncoding.html create mode 100644 actix_web/http/header/accept_language/struct.AcceptLanguage.html create mode 100644 actix_web/http/header/allow/struct.Allow.html create mode 100644 actix_web/http/header/cache_control/enum.CacheDirective.html create mode 100644 actix_web/http/header/cache_control/struct.CacheControl.html create mode 100644 actix_web/http/header/constant.ACCEPT.html create mode 100644 actix_web/http/header/constant.ACCEPT_CHARSET.html create mode 100644 actix_web/http/header/constant.ACCEPT_ENCODING.html create mode 100644 actix_web/http/header/constant.ACCEPT_LANGUAGE.html create mode 100644 actix_web/http/header/constant.ACCEPT_RANGES.html create mode 100644 actix_web/http/header/constant.ACCESS_CONTROL_ALLOW_CREDENTIALS.html create mode 100644 actix_web/http/header/constant.ACCESS_CONTROL_ALLOW_HEADERS.html create mode 100644 actix_web/http/header/constant.ACCESS_CONTROL_ALLOW_METHODS.html create mode 100644 actix_web/http/header/constant.ACCESS_CONTROL_ALLOW_ORIGIN.html create mode 100644 actix_web/http/header/constant.ACCESS_CONTROL_EXPOSE_HEADERS.html create mode 100644 actix_web/http/header/constant.ACCESS_CONTROL_MAX_AGE.html create mode 100644 actix_web/http/header/constant.ACCESS_CONTROL_REQUEST_HEADERS.html create mode 100644 actix_web/http/header/constant.ACCESS_CONTROL_REQUEST_METHOD.html create mode 100644 actix_web/http/header/constant.AGE.html create mode 100644 actix_web/http/header/constant.ALLOW.html create mode 100644 actix_web/http/header/constant.ALT_SVC.html create mode 100644 actix_web/http/header/constant.AUTHORIZATION.html create mode 100644 actix_web/http/header/constant.CACHE_CONTROL.html create mode 100644 actix_web/http/header/constant.CACHE_STATUS.html create mode 100644 actix_web/http/header/constant.CDN_CACHE_CONTROL.html create mode 100644 actix_web/http/header/constant.CONNECTION.html create mode 100644 actix_web/http/header/constant.CONTENT_DISPOSITION.html create mode 100644 actix_web/http/header/constant.CONTENT_ENCODING.html create mode 100644 actix_web/http/header/constant.CONTENT_LANGUAGE.html create mode 100644 actix_web/http/header/constant.CONTENT_LENGTH.html create mode 100644 actix_web/http/header/constant.CONTENT_LOCATION.html create mode 100644 actix_web/http/header/constant.CONTENT_RANGE.html create mode 100644 actix_web/http/header/constant.CONTENT_SECURITY_POLICY.html create mode 100644 actix_web/http/header/constant.CONTENT_SECURITY_POLICY_REPORT_ONLY.html create mode 100644 actix_web/http/header/constant.CONTENT_TYPE.html create mode 100644 actix_web/http/header/constant.COOKIE.html create mode 100644 actix_web/http/header/constant.CROSS_ORIGIN_EMBEDDER_POLICY.html create mode 100644 actix_web/http/header/constant.CROSS_ORIGIN_OPENER_POLICY.html create mode 100644 actix_web/http/header/constant.CROSS_ORIGIN_RESOURCE_POLICY.html create mode 100644 actix_web/http/header/constant.DATE.html create mode 100644 actix_web/http/header/constant.DNT.html create mode 100644 actix_web/http/header/constant.ETAG.html create mode 100644 actix_web/http/header/constant.EXPECT.html create mode 100644 actix_web/http/header/constant.EXPIRES.html create mode 100644 actix_web/http/header/constant.FORWARDED.html create mode 100644 actix_web/http/header/constant.FROM.html create mode 100644 actix_web/http/header/constant.HOST.html create mode 100644 actix_web/http/header/constant.IF_MATCH.html create mode 100644 actix_web/http/header/constant.IF_MODIFIED_SINCE.html create mode 100644 actix_web/http/header/constant.IF_NONE_MATCH.html create mode 100644 actix_web/http/header/constant.IF_RANGE.html create mode 100644 actix_web/http/header/constant.IF_UNMODIFIED_SINCE.html create mode 100644 actix_web/http/header/constant.LAST_MODIFIED.html create mode 100644 actix_web/http/header/constant.LINK.html create mode 100644 actix_web/http/header/constant.LOCATION.html create mode 100644 actix_web/http/header/constant.MAX_FORWARDS.html create mode 100644 actix_web/http/header/constant.ORIGIN.html create mode 100644 actix_web/http/header/constant.PERMISSIONS_POLICY.html create mode 100644 actix_web/http/header/constant.PRAGMA.html create mode 100644 actix_web/http/header/constant.PROXY_AUTHENTICATE.html create mode 100644 actix_web/http/header/constant.PROXY_AUTHORIZATION.html create mode 100644 actix_web/http/header/constant.PUBLIC_KEY_PINS.html create mode 100644 actix_web/http/header/constant.PUBLIC_KEY_PINS_REPORT_ONLY.html create mode 100644 actix_web/http/header/constant.RANGE.html create mode 100644 actix_web/http/header/constant.REFERER.html create mode 100644 actix_web/http/header/constant.REFERRER_POLICY.html create mode 100644 actix_web/http/header/constant.REFRESH.html create mode 100644 actix_web/http/header/constant.RETRY_AFTER.html create mode 100644 actix_web/http/header/constant.SEC_WEBSOCKET_ACCEPT.html create mode 100644 actix_web/http/header/constant.SEC_WEBSOCKET_EXTENSIONS.html create mode 100644 actix_web/http/header/constant.SEC_WEBSOCKET_KEY.html create mode 100644 actix_web/http/header/constant.SEC_WEBSOCKET_PROTOCOL.html create mode 100644 actix_web/http/header/constant.SEC_WEBSOCKET_VERSION.html create mode 100644 actix_web/http/header/constant.SERVER.html create mode 100644 actix_web/http/header/constant.SET_COOKIE.html create mode 100644 actix_web/http/header/constant.STRICT_TRANSPORT_SECURITY.html create mode 100644 actix_web/http/header/constant.TE.html create mode 100644 actix_web/http/header/constant.TRAILER.html create mode 100644 actix_web/http/header/constant.TRANSFER_ENCODING.html create mode 100644 actix_web/http/header/constant.UPGRADE.html create mode 100644 actix_web/http/header/constant.UPGRADE_INSECURE_REQUESTS.html create mode 100644 actix_web/http/header/constant.USER_AGENT.html create mode 100644 actix_web/http/header/constant.VARY.html create mode 100644 actix_web/http/header/constant.VIA.html create mode 100644 actix_web/http/header/constant.WARNING.html create mode 100644 actix_web/http/header/constant.WWW_AUTHENTICATE.html create mode 100644 actix_web/http/header/constant.X_CONTENT_TYPE_OPTIONS.html create mode 100644 actix_web/http/header/constant.X_DNS_PREFETCH_CONTROL.html create mode 100644 actix_web/http/header/constant.X_FORWARDED_FOR.html create mode 100644 actix_web/http/header/constant.X_FORWARDED_HOST.html create mode 100644 actix_web/http/header/constant.X_FORWARDED_PROTO.html create mode 100644 actix_web/http/header/constant.X_FRAME_OPTIONS.html create mode 100644 actix_web/http/header/constant.X_XSS_PROTECTION.html create mode 100644 actix_web/http/header/content_disposition/enum.DispositionParam.html create mode 100644 actix_web/http/header/content_disposition/enum.DispositionType.html create mode 100644 actix_web/http/header/content_disposition/struct.ContentDisposition.html create mode 100644 actix_web/http/header/content_language/struct.ContentLanguage.html create mode 100644 actix_web/http/header/content_length/struct.ContentLength.html create mode 100644 actix_web/http/header/content_range/enum.ContentRangeSpec.html create mode 100644 actix_web/http/header/content_range/struct.ContentRange.html create mode 100644 actix_web/http/header/content_type/struct.ContentType.html create mode 100644 actix_web/http/header/date/struct.Date.html create mode 100644 actix_web/http/header/encoding/enum.Encoding.html create mode 100644 actix_web/http/header/entity/struct.EntityTag.html create mode 100644 actix_web/http/header/enum.ByteRangeSpec.html create mode 100644 actix_web/http/header/enum.CacheDirective.html create mode 100644 actix_web/http/header/enum.Charset.html create mode 100644 actix_web/http/header/enum.ContentEncoding.html create mode 100644 actix_web/http/header/enum.ContentRangeSpec.html create mode 100644 actix_web/http/header/enum.DispositionParam.html create mode 100644 actix_web/http/header/enum.DispositionType.html create mode 100644 actix_web/http/header/enum.Encoding.html create mode 100644 actix_web/http/header/enum.IfMatch.html create mode 100644 actix_web/http/header/enum.IfNoneMatch.html create mode 100644 actix_web/http/header/enum.IfRange.html create mode 100644 actix_web/http/header/enum.Preference.html create mode 100644 actix_web/http/header/enum.Range.html create mode 100644 actix_web/http/header/etag/struct.ETag.html create mode 100644 actix_web/http/header/expires/struct.Expires.html create mode 100644 actix_web/http/header/fn.fmt_comma_delimited.html create mode 100644 actix_web/http/header/fn.from_comma_delimited.html create mode 100644 actix_web/http/header/fn.from_one_raw_str.html create mode 100644 actix_web/http/header/fn.http_percent_encode.html create mode 100644 actix_web/http/header/fn.parse_extended_value.html create mode 100644 actix_web/http/header/fn.q.html create mode 100644 actix_web/http/header/if_match/enum.IfMatch.html create mode 100644 actix_web/http/header/if_modified_since/struct.IfModifiedSince.html create mode 100644 actix_web/http/header/if_none_match/enum.IfNoneMatch.html create mode 100644 actix_web/http/header/if_range/enum.IfRange.html create mode 100644 actix_web/http/header/if_unmodified_since/struct.IfUnmodifiedSince.html create mode 100644 actix_web/http/header/index.html create mode 100644 actix_web/http/header/last_modified/struct.LastModified.html create mode 100644 actix_web/http/header/map/index.html create mode 100644 actix_web/http/header/map/sidebar-items.js create mode 100644 actix_web/http/header/map/struct.Drain.html create mode 100644 actix_web/http/header/map/struct.HeaderMap.html create mode 100644 actix_web/http/header/map/struct.IntoIter.html create mode 100644 actix_web/http/header/map/struct.Iter.html create mode 100644 actix_web/http/header/map/struct.Keys.html create mode 100644 actix_web/http/header/map/struct.Removed.html create mode 100644 actix_web/http/header/preference/enum.Preference.html create mode 100644 actix_web/http/header/range/enum.ByteRangeSpec.html create mode 100644 actix_web/http/header/range/enum.Range.html create mode 100644 actix_web/http/header/sidebar-items.js create mode 100644 actix_web/http/header/struct.Accept.html create mode 100644 actix_web/http/header/struct.AcceptCharset.html create mode 100644 actix_web/http/header/struct.AcceptEncoding.html create mode 100644 actix_web/http/header/struct.AcceptLanguage.html create mode 100644 actix_web/http/header/struct.Allow.html create mode 100644 actix_web/http/header/struct.CacheControl.html create mode 100644 actix_web/http/header/struct.ContentDisposition.html create mode 100644 actix_web/http/header/struct.ContentLanguage.html create mode 100644 actix_web/http/header/struct.ContentLength.html create mode 100644 actix_web/http/header/struct.ContentRange.html create mode 100644 actix_web/http/header/struct.ContentType.html create mode 100644 actix_web/http/header/struct.Date.html create mode 100644 actix_web/http/header/struct.ETag.html create mode 100644 actix_web/http/header/struct.EntityTag.html create mode 100644 actix_web/http/header/struct.Expires.html create mode 100644 actix_web/http/header/struct.ExtendedValue.html create mode 100644 actix_web/http/header/struct.HeaderMap.html create mode 100644 actix_web/http/header/struct.HeaderName.html create mode 100644 actix_web/http/header/struct.HeaderValue.html create mode 100644 actix_web/http/header/struct.HttpDate.html create mode 100644 actix_web/http/header/struct.IfModifiedSince.html create mode 100644 actix_web/http/header/struct.IfUnmodifiedSince.html create mode 100644 actix_web/http/header/struct.InvalidHeaderName.html create mode 100644 actix_web/http/header/struct.InvalidHeaderValue.html create mode 100644 actix_web/http/header/struct.LanguageTag.html create mode 100644 actix_web/http/header/struct.LastModified.html create mode 100644 actix_web/http/header/struct.Quality.html create mode 100644 actix_web/http/header/struct.QualityItem.html create mode 100644 actix_web/http/header/struct.ToStrError.html create mode 100644 actix_web/http/header/trait.AsHeaderName.html create mode 100644 actix_web/http/header/trait.Header.html create mode 100644 actix_web/http/header/trait.TryIntoHeaderPair.html create mode 100644 actix_web/http/header/trait.TryIntoHeaderValue.html create mode 100644 actix_web/http/index.html create mode 100644 actix_web/http/sidebar-items.js create mode 100644 actix_web/http/struct.Error.html create mode 100644 actix_web/http/struct.Method.html create mode 100644 actix_web/http/struct.StatusCode.html create mode 100644 actix_web/http/struct.Uri.html create mode 100644 actix_web/http/struct.Version.html create mode 100644 actix_web/http/uri/index.html create mode 100644 actix_web/http/uri/sidebar-items.js create mode 100644 actix_web/http/uri/struct.Authority.html create mode 100644 actix_web/http/uri/struct.Builder.html create mode 100644 actix_web/http/uri/struct.InvalidUri.html create mode 100644 actix_web/http/uri/struct.InvalidUriParts.html create mode 100644 actix_web/http/uri/struct.Parts.html create mode 100644 actix_web/http/uri/struct.PathAndQuery.html create mode 100644 actix_web/http/uri/struct.Port.html create mode 100644 actix_web/http/uri/struct.Scheme.html create mode 100644 actix_web/http/uri/struct.Uri.html create mode 100644 actix_web/index.html create mode 100644 actix_web/info/struct.ConnectionInfo.html create mode 100644 actix_web/info/struct.PeerAddr.html create mode 100644 actix_web/macro.services!.html create mode 100644 actix_web/macro.services.html create mode 100644 actix_web/middleware/compat/struct.Compat.html create mode 100644 actix_web/middleware/compress/struct.Compress.html create mode 100644 actix_web/middleware/condition/struct.Condition.html create mode 100644 actix_web/middleware/default_headers/struct.DefaultHeaders.html create mode 100644 actix_web/middleware/enum.ErrorHandlerResponse.html create mode 100644 actix_web/middleware/enum.TrailingSlash.html create mode 100644 actix_web/middleware/err_handlers/enum.ErrorHandlerResponse.html create mode 100644 actix_web/middleware/err_handlers/struct.ErrorHandlers.html create mode 100644 actix_web/middleware/index.html create mode 100644 actix_web/middleware/logger/struct.Logger.html create mode 100644 actix_web/middleware/normalize/enum.TrailingSlash.html create mode 100644 actix_web/middleware/normalize/struct.NormalizePath.html create mode 100644 actix_web/middleware/sidebar-items.js create mode 100644 actix_web/middleware/struct.Compat.html create mode 100644 actix_web/middleware/struct.Compress.html create mode 100644 actix_web/middleware/struct.Condition.html create mode 100644 actix_web/middleware/struct.DefaultHeaders.html create mode 100644 actix_web/middleware/struct.ErrorHandlers.html create mode 100644 actix_web/middleware/struct.Logger.html create mode 100644 actix_web/middleware/struct.NormalizePath.html create mode 100644 actix_web/redirect/struct.Redirect.html create mode 100644 actix_web/request/struct.HttpRequest.html create mode 100644 actix_web/request_data/struct.ReqData.html create mode 100644 actix_web/resource/struct.Resource.html create mode 100644 actix_web/response/builder/struct.HttpResponseBuilder.html create mode 100644 actix_web/response/customize_responder/struct.CustomizeResponder.html create mode 100644 actix_web/response/responder/trait.Responder.html create mode 100644 actix_web/response/response/struct.HttpResponse.html create mode 100644 actix_web/rmap/struct.ResourceMap.html create mode 100644 actix_web/route/struct.Route.html create mode 100644 actix_web/rt/fn.spawn.html create mode 100644 actix_web/rt/index.html create mode 100644 actix_web/rt/macro.pin!.html create mode 100644 actix_web/rt/macro.pin.html create mode 100644 actix_web/rt/net/index.html create mode 100644 actix_web/rt/net/sidebar-items.js create mode 100644 actix_web/rt/net/struct.Ready.html create mode 100644 actix_web/rt/net/struct.TcpListener.html create mode 100644 actix_web/rt/net/struct.TcpSocket.html create mode 100644 actix_web/rt/net/struct.TcpStream.html create mode 100644 actix_web/rt/net/struct.UdpSocket.html create mode 100644 actix_web/rt/net/struct.UnixDatagram.html create mode 100644 actix_web/rt/net/struct.UnixListener.html create mode 100644 actix_web/rt/net/struct.UnixStream.html create mode 100644 actix_web/rt/sidebar-items.js create mode 100644 actix_web/rt/signal/fn.ctrl_c.html create mode 100644 actix_web/rt/signal/index.html create mode 100644 actix_web/rt/signal/sidebar-items.js create mode 100644 actix_web/rt/signal/unix/fn.signal.html create mode 100644 actix_web/rt/signal/unix/index.html create mode 100644 actix_web/rt/signal/unix/sidebar-items.js create mode 100644 actix_web/rt/signal/unix/struct.Signal.html create mode 100644 actix_web/rt/signal/unix/struct.SignalKind.html create mode 100644 actix_web/rt/struct.Runtime.html create mode 100644 actix_web/rt/struct.System.html create mode 100644 actix_web/rt/struct.SystemRunner.html create mode 100644 actix_web/rt/task/fn.spawn_blocking.html create mode 100644 actix_web/rt/task/fn.yield_now.html create mode 100644 actix_web/rt/task/index.html create mode 100644 actix_web/rt/task/sidebar-items.js create mode 100644 actix_web/rt/task/struct.JoinError.html create mode 100644 actix_web/rt/task/struct.JoinHandle.html create mode 100644 actix_web/rt/time/fn.interval.html create mode 100644 actix_web/rt/time/fn.interval_at.html create mode 100644 actix_web/rt/time/fn.sleep.html create mode 100644 actix_web/rt/time/fn.sleep_until.html create mode 100644 actix_web/rt/time/fn.timeout.html create mode 100644 actix_web/rt/time/index.html create mode 100644 actix_web/rt/time/sidebar-items.js create mode 100644 actix_web/rt/time/struct.Instant.html create mode 100644 actix_web/rt/time/struct.Interval.html create mode 100644 actix_web/rt/time/struct.Sleep.html create mode 100644 actix_web/rt/time/struct.Timeout.html create mode 100644 actix_web/scope/struct.Scope.html create mode 100644 actix_web/server/struct.HttpServer.html create mode 100644 actix_web/service/struct.ServiceRequest.html create mode 100644 actix_web/service/struct.ServiceResponse.html create mode 100644 actix_web/service/struct.WebService.html create mode 100644 actix_web/service/trait.HttpServiceFactory.html create mode 100644 actix_web/sidebar-items.js create mode 100644 actix_web/struct.App.html create mode 100644 actix_web/struct.CustomizeResponder.html create mode 100644 actix_web/struct.HttpRequest.html create mode 100644 actix_web/struct.HttpResponse.html create mode 100644 actix_web/struct.HttpResponseBuilder.html create mode 100644 actix_web/struct.HttpServer.html create mode 100644 actix_web/struct.Resource.html create mode 100644 actix_web/struct.Route.html create mode 100644 actix_web/struct.Scope.html create mode 100644 actix_web/test/fn.call_and_read_body.html create mode 100644 actix_web/test/fn.call_and_read_body_json.html create mode 100644 actix_web/test/fn.call_service.html create mode 100644 actix_web/test/fn.init_service.html create mode 100644 actix_web/test/fn.ok_service.html create mode 100644 actix_web/test/fn.read_body.html create mode 100644 actix_web/test/fn.read_body_json.html create mode 100644 actix_web/test/fn.status_service.html create mode 100644 actix_web/test/fn.try_call_and_read_body_json.html create mode 100644 actix_web/test/fn.try_call_service.html create mode 100644 actix_web/test/fn.try_read_body.html create mode 100644 actix_web/test/fn.try_read_body_json.html create mode 100644 actix_web/test/index.html create mode 100644 actix_web/test/sidebar-items.js create mode 100644 actix_web/test/struct.TestBuffer.html create mode 100644 actix_web/test/struct.TestRequest.html create mode 100644 actix_web/test/test_request/struct.TestRequest.html create mode 100644 actix_web/test/test_services/fn.ok_service.html create mode 100644 actix_web/test/test_services/fn.status_service.html create mode 100644 actix_web/test/test_utils/fn.call_and_read_body.html create mode 100644 actix_web/test/test_utils/fn.call_and_read_body_json.html create mode 100644 actix_web/test/test_utils/fn.call_service.html create mode 100644 actix_web/test/test_utils/fn.init_service.html create mode 100644 actix_web/test/test_utils/fn.read_body.html create mode 100644 actix_web/test/test_utils/fn.read_body_json.html create mode 100644 actix_web/test/test_utils/fn.try_call_and_read_body_json.html create mode 100644 actix_web/test/test_utils/fn.try_call_service.html create mode 100644 actix_web/test/test_utils/fn.try_read_body.html create mode 100644 actix_web/test/test_utils/fn.try_read_body_json.html create mode 100644 actix_web/trait.FromRequest.html create mode 100644 actix_web/trait.Handler.html create mode 100644 actix_web/trait.HttpMessage.html create mode 100644 actix_web/trait.Responder.html create mode 100644 actix_web/type.Result.html create mode 100644 actix_web/types/either/enum.Either.html create mode 100644 actix_web/types/form/struct.Form.html create mode 100644 actix_web/types/form/struct.FormConfig.html create mode 100644 actix_web/types/form/struct.UrlEncoded.html create mode 100644 actix_web/types/header/struct.Header.html create mode 100644 actix_web/types/json/enum.JsonBody.html create mode 100644 actix_web/types/json/struct.Json.html create mode 100644 actix_web/types/json/struct.JsonConfig.html create mode 100644 actix_web/types/path/struct.Path.html create mode 100644 actix_web/types/path/struct.PathConfig.html create mode 100644 actix_web/types/payload/struct.Payload.html create mode 100644 actix_web/types/payload/struct.PayloadConfig.html create mode 100644 actix_web/types/query/struct.Query.html create mode 100644 actix_web/types/query/struct.QueryConfig.html create mode 100644 actix_web/types/readlines/struct.Readlines.html create mode 100644 actix_web/web/enum.Either.html create mode 100644 actix_web/web/enum.JsonBody.html create mode 100644 actix_web/web/fn.block.html create mode 100644 actix_web/web/fn.delete.html create mode 100644 actix_web/web/fn.get.html create mode 100644 actix_web/web/fn.head.html create mode 100644 actix_web/web/fn.method.html create mode 100644 actix_web/web/fn.patch.html create mode 100644 actix_web/web/fn.post.html create mode 100644 actix_web/web/fn.put.html create mode 100644 actix_web/web/fn.redirect.html create mode 100644 actix_web/web/fn.resource.html create mode 100644 actix_web/web/fn.route.html create mode 100644 actix_web/web/fn.scope.html create mode 100644 actix_web/web/fn.service.html create mode 100644 actix_web/web/fn.to.html create mode 100644 actix_web/web/fn.trace.html create mode 100644 actix_web/web/index.html create mode 100644 actix_web/web/sidebar-items.js create mode 100644 actix_web/web/struct.Bytes.html create mode 100644 actix_web/web/struct.BytesMut.html create mode 100644 actix_web/web/struct.Data.html create mode 100644 actix_web/web/struct.Form.html create mode 100644 actix_web/web/struct.FormConfig.html create mode 100644 actix_web/web/struct.Header.html create mode 100644 actix_web/web/struct.Json.html create mode 100644 actix_web/web/struct.JsonConfig.html create mode 100644 actix_web/web/struct.Path.html create mode 100644 actix_web/web/struct.PathConfig.html create mode 100644 actix_web/web/struct.Payload.html create mode 100644 actix_web/web/struct.PayloadConfig.html create mode 100644 actix_web/web/struct.Query.html create mode 100644 actix_web/web/struct.QueryConfig.html create mode 100644 actix_web/web/struct.Readlines.html create mode 100644 actix_web/web/struct.Redirect.html create mode 100644 actix_web/web/struct.ReqData.html create mode 100644 actix_web/web/struct.ServiceConfig.html create mode 100644 actix_web/web/struct.UrlEncoded.html create mode 100644 actix_web/web/trait.Buf.html create mode 100644 actix_web/web/trait.BufMut.html create mode 100644 actix_web_actors/all.html create mode 100644 actix_web_actors/context/struct.HttpContext.html create mode 100644 actix_web_actors/index.html create mode 100644 actix_web_actors/sidebar-items.js create mode 100644 actix_web_actors/struct.HttpContext.html create mode 100644 actix_web_actors/ws/enum.CloseCode.html create mode 100644 actix_web_actors/ws/enum.Frame.html create mode 100644 actix_web_actors/ws/enum.HandshakeError.html create mode 100644 actix_web_actors/ws/enum.Message.html create mode 100644 actix_web_actors/ws/enum.ProtocolError.html create mode 100644 actix_web_actors/ws/fn.handshake.html create mode 100644 actix_web_actors/ws/fn.handshake_with_protocols.html create mode 100644 actix_web_actors/ws/fn.start.html create mode 100644 actix_web_actors/ws/fn.start_with_addr.html create mode 100644 actix_web_actors/ws/fn.start_with_protocols.html create mode 100644 actix_web_actors/ws/index.html create mode 100644 actix_web_actors/ws/sidebar-items.js create mode 100644 actix_web_actors/ws/struct.CloseReason.html create mode 100644 actix_web_actors/ws/struct.WebsocketContext.html create mode 100644 actix_web_actors/ws/struct.WsResponseBuilder.html create mode 100644 actix_web_codegen/all.html create mode 100644 actix_web_codegen/attr.connect.html create mode 100644 actix_web_codegen/attr.delete.html create mode 100644 actix_web_codegen/attr.get.html create mode 100644 actix_web_codegen/attr.head.html create mode 100644 actix_web_codegen/attr.main.html create mode 100644 actix_web_codegen/attr.options.html create mode 100644 actix_web_codegen/attr.patch.html create mode 100644 actix_web_codegen/attr.post.html create mode 100644 actix_web_codegen/attr.put.html create mode 100644 actix_web_codegen/attr.route.html create mode 100644 actix_web_codegen/attr.routes.html create mode 100644 actix_web_codegen/attr.test.html create mode 100644 actix_web_codegen/attr.trace.html create mode 100644 actix_web_codegen/index.html create mode 100644 actix_web_codegen/sidebar-items.js create mode 100644 awc/all.html create mode 100644 awc/body/enum.BodySize.html create mode 100644 awc/body/enum.EitherBody.html create mode 100644 awc/body/fn.to_bytes.html create mode 100644 awc/body/fn.to_bytes_limited.html create mode 100644 awc/body/index.html create mode 100644 awc/body/sidebar-items.js create mode 100644 awc/body/struct.BodyLimitExceeded.html create mode 100644 awc/body/struct.BodyStream.html create mode 100644 awc/body/struct.BoxBody.html create mode 100644 awc/body/struct.None.html create mode 100644 awc/body/struct.SizedStream.html create mode 100644 awc/body/trait.MessageBody.html create mode 100644 awc/builder/struct.ClientBuilder.html create mode 100644 awc/client/connector/struct.Connector.html create mode 100644 awc/client/error/enum.ConnectError.html create mode 100644 awc/client/error/enum.FreezeRequestError.html create mode 100644 awc/client/error/enum.InvalidUrl.html create mode 100644 awc/client/error/enum.SendRequestError.html create mode 100644 awc/client/struct.Client.html create mode 100644 awc/client/struct.Connect.html create mode 100644 awc/connect/enum.ConnectRequest.html create mode 100644 awc/connect/enum.ConnectResponse.html create mode 100644 awc/connect/type.BoxConnectorService.html create mode 100644 awc/connect/type.BoxedSocket.html create mode 100644 awc/enum.ConnectRequest.html create mode 100644 awc/enum.ConnectResponse.html create mode 100644 awc/enum.SendClientRequest.html create mode 100644 awc/error/enum.ConnectError.html create mode 100644 awc/error/enum.FreezeRequestError.html create mode 100644 awc/error/enum.InvalidUrl.html create mode 100644 awc/error/enum.JsonPayloadError.html create mode 100644 awc/error/enum.PayloadError.html create mode 100644 awc/error/enum.SendRequestError.html create mode 100644 awc/error/enum.WsClientError.html create mode 100644 awc/error/enum.WsHandshakeError.html create mode 100644 awc/error/enum.WsProtocolError.html create mode 100644 awc/error/index.html create mode 100644 awc/error/sidebar-items.js create mode 100644 awc/error/struct.HeaderValue.html create mode 100644 awc/error/struct.HttpError.html create mode 100644 awc/error/struct.StatusCode.html create mode 100644 awc/frozen/struct.FrozenClientRequest.html create mode 100644 awc/frozen/struct.FrozenSendBuilder.html create mode 100644 awc/http/enum.ConnectionType.html create mode 100644 awc/http/header/constant.ACCEPT.html create mode 100644 awc/http/header/constant.ACCEPT_CHARSET.html create mode 100644 awc/http/header/constant.ACCEPT_ENCODING.html create mode 100644 awc/http/header/constant.ACCEPT_LANGUAGE.html create mode 100644 awc/http/header/constant.ACCEPT_RANGES.html create mode 100644 awc/http/header/constant.ACCESS_CONTROL_ALLOW_CREDENTIALS.html create mode 100644 awc/http/header/constant.ACCESS_CONTROL_ALLOW_HEADERS.html create mode 100644 awc/http/header/constant.ACCESS_CONTROL_ALLOW_METHODS.html create mode 100644 awc/http/header/constant.ACCESS_CONTROL_ALLOW_ORIGIN.html create mode 100644 awc/http/header/constant.ACCESS_CONTROL_EXPOSE_HEADERS.html create mode 100644 awc/http/header/constant.ACCESS_CONTROL_MAX_AGE.html create mode 100644 awc/http/header/constant.ACCESS_CONTROL_REQUEST_HEADERS.html create mode 100644 awc/http/header/constant.ACCESS_CONTROL_REQUEST_METHOD.html create mode 100644 awc/http/header/constant.AGE.html create mode 100644 awc/http/header/constant.ALLOW.html create mode 100644 awc/http/header/constant.ALT_SVC.html create mode 100644 awc/http/header/constant.AUTHORIZATION.html create mode 100644 awc/http/header/constant.CACHE_CONTROL.html create mode 100644 awc/http/header/constant.CACHE_STATUS.html create mode 100644 awc/http/header/constant.CDN_CACHE_CONTROL.html create mode 100644 awc/http/header/constant.CONNECTION.html create mode 100644 awc/http/header/constant.CONTENT_DISPOSITION.html create mode 100644 awc/http/header/constant.CONTENT_ENCODING.html create mode 100644 awc/http/header/constant.CONTENT_LANGUAGE.html create mode 100644 awc/http/header/constant.CONTENT_LENGTH.html create mode 100644 awc/http/header/constant.CONTENT_LOCATION.html create mode 100644 awc/http/header/constant.CONTENT_RANGE.html create mode 100644 awc/http/header/constant.CONTENT_SECURITY_POLICY.html create mode 100644 awc/http/header/constant.CONTENT_SECURITY_POLICY_REPORT_ONLY.html create mode 100644 awc/http/header/constant.CONTENT_TYPE.html create mode 100644 awc/http/header/constant.COOKIE.html create mode 100644 awc/http/header/constant.CROSS_ORIGIN_EMBEDDER_POLICY.html create mode 100644 awc/http/header/constant.CROSS_ORIGIN_OPENER_POLICY.html create mode 100644 awc/http/header/constant.CROSS_ORIGIN_RESOURCE_POLICY.html create mode 100644 awc/http/header/constant.DATE.html create mode 100644 awc/http/header/constant.DNT.html create mode 100644 awc/http/header/constant.ETAG.html create mode 100644 awc/http/header/constant.EXPECT.html create mode 100644 awc/http/header/constant.EXPIRES.html create mode 100644 awc/http/header/constant.FORWARDED.html create mode 100644 awc/http/header/constant.FROM.html create mode 100644 awc/http/header/constant.HOST.html create mode 100644 awc/http/header/constant.IF_MATCH.html create mode 100644 awc/http/header/constant.IF_MODIFIED_SINCE.html create mode 100644 awc/http/header/constant.IF_NONE_MATCH.html create mode 100644 awc/http/header/constant.IF_RANGE.html create mode 100644 awc/http/header/constant.IF_UNMODIFIED_SINCE.html create mode 100644 awc/http/header/constant.LAST_MODIFIED.html create mode 100644 awc/http/header/constant.LINK.html create mode 100644 awc/http/header/constant.LOCATION.html create mode 100644 awc/http/header/constant.MAX_FORWARDS.html create mode 100644 awc/http/header/constant.ORIGIN.html create mode 100644 awc/http/header/constant.PERMISSIONS_POLICY.html create mode 100644 awc/http/header/constant.PRAGMA.html create mode 100644 awc/http/header/constant.PROXY_AUTHENTICATE.html create mode 100644 awc/http/header/constant.PROXY_AUTHORIZATION.html create mode 100644 awc/http/header/constant.PUBLIC_KEY_PINS.html create mode 100644 awc/http/header/constant.PUBLIC_KEY_PINS_REPORT_ONLY.html create mode 100644 awc/http/header/constant.RANGE.html create mode 100644 awc/http/header/constant.REFERER.html create mode 100644 awc/http/header/constant.REFERRER_POLICY.html create mode 100644 awc/http/header/constant.REFRESH.html create mode 100644 awc/http/header/constant.RETRY_AFTER.html create mode 100644 awc/http/header/constant.SEC_WEBSOCKET_ACCEPT.html create mode 100644 awc/http/header/constant.SEC_WEBSOCKET_EXTENSIONS.html create mode 100644 awc/http/header/constant.SEC_WEBSOCKET_KEY.html create mode 100644 awc/http/header/constant.SEC_WEBSOCKET_PROTOCOL.html create mode 100644 awc/http/header/constant.SEC_WEBSOCKET_VERSION.html create mode 100644 awc/http/header/constant.SERVER.html create mode 100644 awc/http/header/constant.SET_COOKIE.html create mode 100644 awc/http/header/constant.STRICT_TRANSPORT_SECURITY.html create mode 100644 awc/http/header/constant.TE.html create mode 100644 awc/http/header/constant.TRAILER.html create mode 100644 awc/http/header/constant.TRANSFER_ENCODING.html create mode 100644 awc/http/header/constant.UPGRADE.html create mode 100644 awc/http/header/constant.UPGRADE_INSECURE_REQUESTS.html create mode 100644 awc/http/header/constant.USER_AGENT.html create mode 100644 awc/http/header/constant.VARY.html create mode 100644 awc/http/header/constant.VIA.html create mode 100644 awc/http/header/constant.WARNING.html create mode 100644 awc/http/header/constant.WWW_AUTHENTICATE.html create mode 100644 awc/http/header/constant.X_CONTENT_TYPE_OPTIONS.html create mode 100644 awc/http/header/constant.X_DNS_PREFETCH_CONTROL.html create mode 100644 awc/http/header/constant.X_FORWARDED_FOR.html create mode 100644 awc/http/header/constant.X_FORWARDED_HOST.html create mode 100644 awc/http/header/constant.X_FORWARDED_PROTO.html create mode 100644 awc/http/header/constant.X_FRAME_OPTIONS.html create mode 100644 awc/http/header/constant.X_XSS_PROTECTION.html create mode 100644 awc/http/header/enum.Charset.html create mode 100644 awc/http/header/enum.ContentEncoding.html create mode 100644 awc/http/header/fn.fmt_comma_delimited.html create mode 100644 awc/http/header/fn.from_comma_delimited.html create mode 100644 awc/http/header/fn.from_one_raw_str.html create mode 100644 awc/http/header/fn.http_percent_encode.html create mode 100644 awc/http/header/fn.parse_extended_value.html create mode 100644 awc/http/header/fn.q.html create mode 100644 awc/http/header/index.html create mode 100644 awc/http/header/map/index.html create mode 100644 awc/http/header/map/sidebar-items.js create mode 100644 awc/http/header/map/struct.Drain.html create mode 100644 awc/http/header/map/struct.HeaderMap.html create mode 100644 awc/http/header/map/struct.IntoIter.html create mode 100644 awc/http/header/map/struct.Iter.html create mode 100644 awc/http/header/map/struct.Keys.html create mode 100644 awc/http/header/map/struct.Removed.html create mode 100644 awc/http/header/sidebar-items.js create mode 100644 awc/http/header/struct.ExtendedValue.html create mode 100644 awc/http/header/struct.HeaderMap.html create mode 100644 awc/http/header/struct.HeaderName.html create mode 100644 awc/http/header/struct.HeaderValue.html create mode 100644 awc/http/header/struct.HttpDate.html create mode 100644 awc/http/header/struct.InvalidHeaderName.html create mode 100644 awc/http/header/struct.InvalidHeaderValue.html create mode 100644 awc/http/header/struct.LanguageTag.html create mode 100644 awc/http/header/struct.Quality.html create mode 100644 awc/http/header/struct.QualityItem.html create mode 100644 awc/http/header/struct.ToStrError.html create mode 100644 awc/http/header/trait.AsHeaderName.html create mode 100644 awc/http/header/trait.Header.html create mode 100644 awc/http/header/trait.TryIntoHeaderPair.html create mode 100644 awc/http/header/trait.TryIntoHeaderValue.html create mode 100644 awc/http/index.html create mode 100644 awc/http/sidebar-items.js create mode 100644 awc/http/struct.Error.html create mode 100644 awc/http/struct.Method.html create mode 100644 awc/http/struct.StatusCode.html create mode 100644 awc/http/struct.Uri.html create mode 100644 awc/http/struct.Version.html create mode 100644 awc/http/uri/index.html create mode 100644 awc/http/uri/sidebar-items.js create mode 100644 awc/http/uri/struct.Authority.html create mode 100644 awc/http/uri/struct.Builder.html create mode 100644 awc/http/uri/struct.InvalidUri.html create mode 100644 awc/http/uri/struct.InvalidUriParts.html create mode 100644 awc/http/uri/struct.Parts.html create mode 100644 awc/http/uri/struct.PathAndQuery.html create mode 100644 awc/http/uri/struct.Port.html create mode 100644 awc/http/uri/struct.Scheme.html create mode 100644 awc/http/uri/struct.Uri.html create mode 100644 awc/index.html create mode 100644 awc/middleware/index.html create mode 100644 awc/middleware/redirect/struct.Redirect.html create mode 100644 awc/middleware/sidebar-items.js create mode 100644 awc/middleware/struct.Redirect.html create mode 100644 awc/middleware/trait.Transform.html create mode 100644 awc/request/struct.ClientRequest.html create mode 100644 awc/responses/json_body/struct.JsonBody.html create mode 100644 awc/responses/response/struct.ClientResponse.html create mode 100644 awc/responses/response_body/struct.ResponseBody.html create mode 100644 awc/responses/response_body/type.MessageBody.html create mode 100644 awc/sender/enum.SendClientRequest.html create mode 100644 awc/sidebar-items.js create mode 100644 awc/struct.Client.html create mode 100644 awc/struct.ClientBuilder.html create mode 100644 awc/struct.ClientRequest.html create mode 100644 awc/struct.ClientResponse.html create mode 100644 awc/struct.Connect.html create mode 100644 awc/struct.Connector.html create mode 100644 awc/struct.FrozenClientRequest.html create mode 100644 awc/struct.FrozenSendBuilder.html create mode 100644 awc/struct.JsonBody.html create mode 100644 awc/struct.ResponseBody.html create mode 100644 awc/test/index.html create mode 100644 awc/test/sidebar-items.js create mode 100644 awc/test/struct.TestResponse.html create mode 100644 awc/type.BoxConnectorService.html create mode 100644 awc/type.BoxedSocket.html create mode 100644 awc/type.MessageBody.html create mode 100644 awc/ws/enum.CloseCode.html create mode 100644 awc/ws/enum.Frame.html create mode 100644 awc/ws/enum.Message.html create mode 100644 awc/ws/index.html create mode 100644 awc/ws/sidebar-items.js create mode 100644 awc/ws/struct.CloseReason.html create mode 100644 awc/ws/struct.Codec.html create mode 100644 awc/ws/struct.WebsocketsRequest.html create mode 100644 crates.js create mode 100644 help.html create mode 100644 index.html create mode 100644 search-index.js create mode 100644 search.desc/actix_files/actix_files-desc-0-.js create mode 100644 search.desc/actix_http/actix_http-desc-0-.js create mode 100644 search.desc/actix_http_test/actix_http_test-desc-0-.js create mode 100644 search.desc/actix_multipart/actix_multipart-desc-0-.js create mode 100644 search.desc/actix_multipart_derive/actix_multipart_derive-desc-0-.js create mode 100644 search.desc/actix_router/actix_router-desc-0-.js create mode 100644 search.desc/actix_test/actix_test-desc-0-.js create mode 100644 search.desc/actix_web/actix_web-desc-0-.js create mode 100644 search.desc/actix_web/actix_web-desc-1-.js create mode 100644 search.desc/actix_web_actors/actix_web_actors-desc-0-.js create mode 100644 search.desc/actix_web_codegen/actix_web_codegen-desc-0-.js create mode 100644 search.desc/awc/awc-desc-0-.js create mode 100644 settings.html create mode 100644 src-files.js create mode 100644 src/actix_files/chunked.rs.html create mode 100644 src/actix_files/directory.rs.html create mode 100644 src/actix_files/encoding.rs.html create mode 100644 src/actix_files/error.rs.html create mode 100644 src/actix_files/files.rs.html create mode 100644 src/actix_files/lib.rs.html create mode 100644 src/actix_files/named.rs.html create mode 100644 src/actix_files/path_buf.rs.html create mode 100644 src/actix_files/range.rs.html create mode 100644 src/actix_files/service.rs.html create mode 100644 src/actix_http/body/body_stream.rs.html create mode 100644 src/actix_http/body/boxed.rs.html create mode 100644 src/actix_http/body/either.rs.html create mode 100644 src/actix_http/body/message_body.rs.html create mode 100644 src/actix_http/body/mod.rs.html create mode 100644 src/actix_http/body/none.rs.html create mode 100644 src/actix_http/body/size.rs.html create mode 100644 src/actix_http/body/sized_stream.rs.html create mode 100644 src/actix_http/body/utils.rs.html create mode 100644 src/actix_http/builder.rs.html create mode 100644 src/actix_http/config.rs.html create mode 100644 src/actix_http/date.rs.html create mode 100644 src/actix_http/encoding/decoder.rs.html create mode 100644 src/actix_http/encoding/encoder.rs.html create mode 100644 src/actix_http/encoding/mod.rs.html create mode 100644 src/actix_http/error.rs.html create mode 100644 src/actix_http/extensions.rs.html create mode 100644 src/actix_http/h1/chunked.rs.html create mode 100644 src/actix_http/h1/client.rs.html create mode 100644 src/actix_http/h1/codec.rs.html create mode 100644 src/actix_http/h1/decoder.rs.html create mode 100644 src/actix_http/h1/dispatcher.rs.html create mode 100644 src/actix_http/h1/encoder.rs.html create mode 100644 src/actix_http/h1/expect.rs.html create mode 100644 src/actix_http/h1/mod.rs.html create mode 100644 src/actix_http/h1/payload.rs.html create mode 100644 src/actix_http/h1/service.rs.html create mode 100644 src/actix_http/h1/timer.rs.html create mode 100644 src/actix_http/h1/upgrade.rs.html create mode 100644 src/actix_http/h1/utils.rs.html create mode 100644 src/actix_http/h2/dispatcher.rs.html create mode 100644 src/actix_http/h2/mod.rs.html create mode 100644 src/actix_http/h2/service.rs.html create mode 100644 src/actix_http/header/as_name.rs.html create mode 100644 src/actix_http/header/common.rs.html create mode 100644 src/actix_http/header/into_pair.rs.html create mode 100644 src/actix_http/header/into_value.rs.html create mode 100644 src/actix_http/header/map.rs.html create mode 100644 src/actix_http/header/mod.rs.html create mode 100644 src/actix_http/header/shared/charset.rs.html create mode 100644 src/actix_http/header/shared/content_encoding.rs.html create mode 100644 src/actix_http/header/shared/extended.rs.html create mode 100644 src/actix_http/header/shared/http_date.rs.html create mode 100644 src/actix_http/header/shared/mod.rs.html create mode 100644 src/actix_http/header/shared/quality.rs.html create mode 100644 src/actix_http/header/shared/quality_item.rs.html create mode 100644 src/actix_http/header/utils.rs.html create mode 100644 src/actix_http/helpers.rs.html create mode 100644 src/actix_http/http_message.rs.html create mode 100644 src/actix_http/keep_alive.rs.html create mode 100644 src/actix_http/lib.rs.html create mode 100644 src/actix_http/message.rs.html create mode 100644 src/actix_http/payload.rs.html create mode 100644 src/actix_http/requests/head.rs.html create mode 100644 src/actix_http/requests/mod.rs.html create mode 100644 src/actix_http/requests/request.rs.html create mode 100644 src/actix_http/responses/builder.rs.html create mode 100644 src/actix_http/responses/head.rs.html create mode 100644 src/actix_http/responses/mod.rs.html create mode 100644 src/actix_http/responses/response.rs.html create mode 100644 src/actix_http/service.rs.html create mode 100644 src/actix_http/test.rs.html create mode 100644 src/actix_http/ws/codec.rs.html create mode 100644 src/actix_http/ws/dispatcher.rs.html create mode 100644 src/actix_http/ws/frame.rs.html create mode 100644 src/actix_http/ws/mask.rs.html create mode 100644 src/actix_http/ws/mod.rs.html create mode 100644 src/actix_http/ws/proto.rs.html create mode 100644 src/actix_http_test/lib.rs.html create mode 100644 src/actix_multipart/error.rs.html create mode 100644 src/actix_multipart/extractor.rs.html create mode 100644 src/actix_multipart/form/bytes.rs.html create mode 100644 src/actix_multipart/form/json.rs.html create mode 100644 src/actix_multipart/form/mod.rs.html create mode 100644 src/actix_multipart/form/tempfile.rs.html create mode 100644 src/actix_multipart/form/text.rs.html create mode 100644 src/actix_multipart/lib.rs.html create mode 100644 src/actix_multipart/server.rs.html create mode 100644 src/actix_multipart/test.rs.html create mode 100644 src/actix_multipart_derive/lib.rs.html create mode 100644 src/actix_router/de.rs.html create mode 100644 src/actix_router/lib.rs.html create mode 100644 src/actix_router/path.rs.html create mode 100644 src/actix_router/pattern.rs.html create mode 100644 src/actix_router/quoter.rs.html create mode 100644 src/actix_router/regex_set.rs.html create mode 100644 src/actix_router/resource.rs.html create mode 100644 src/actix_router/resource_path.rs.html create mode 100644 src/actix_router/router.rs.html create mode 100644 src/actix_router/url.rs.html create mode 100644 src/actix_test/lib.rs.html create mode 100644 src/actix_web/app.rs.html create mode 100644 src/actix_web/app_service.rs.html create mode 100644 src/actix_web/config.rs.html create mode 100644 src/actix_web/data.rs.html create mode 100644 src/actix_web/dev.rs.html create mode 100644 src/actix_web/error/error.rs.html create mode 100644 src/actix_web/error/internal.rs.html create mode 100644 src/actix_web/error/macros.rs.html create mode 100644 src/actix_web/error/mod.rs.html create mode 100644 src/actix_web/error/response_error.rs.html create mode 100644 src/actix_web/extract.rs.html create mode 100644 src/actix_web/guard/acceptable.rs.html create mode 100644 src/actix_web/guard/host.rs.html create mode 100644 src/actix_web/guard/mod.rs.html create mode 100644 src/actix_web/handler.rs.html create mode 100644 src/actix_web/helpers.rs.html create mode 100644 src/actix_web/http/header/accept.rs.html create mode 100644 src/actix_web/http/header/accept_charset.rs.html create mode 100644 src/actix_web/http/header/accept_encoding.rs.html create mode 100644 src/actix_web/http/header/accept_language.rs.html create mode 100644 src/actix_web/http/header/allow.rs.html create mode 100644 src/actix_web/http/header/cache_control.rs.html create mode 100644 src/actix_web/http/header/content_disposition.rs.html create mode 100644 src/actix_web/http/header/content_language.rs.html create mode 100644 src/actix_web/http/header/content_length.rs.html create mode 100644 src/actix_web/http/header/content_range.rs.html create mode 100644 src/actix_web/http/header/content_type.rs.html create mode 100644 src/actix_web/http/header/date.rs.html create mode 100644 src/actix_web/http/header/encoding.rs.html create mode 100644 src/actix_web/http/header/entity.rs.html create mode 100644 src/actix_web/http/header/etag.rs.html create mode 100644 src/actix_web/http/header/expires.rs.html create mode 100644 src/actix_web/http/header/if_match.rs.html create mode 100644 src/actix_web/http/header/if_modified_since.rs.html create mode 100644 src/actix_web/http/header/if_none_match.rs.html create mode 100644 src/actix_web/http/header/if_range.rs.html create mode 100644 src/actix_web/http/header/if_unmodified_since.rs.html create mode 100644 src/actix_web/http/header/last_modified.rs.html create mode 100644 src/actix_web/http/header/macros.rs.html create mode 100644 src/actix_web/http/header/mod.rs.html create mode 100644 src/actix_web/http/header/preference.rs.html create mode 100644 src/actix_web/http/header/range.rs.html create mode 100644 src/actix_web/http/mod.rs.html create mode 100644 src/actix_web/info.rs.html create mode 100644 src/actix_web/lib.rs.html create mode 100644 src/actix_web/middleware/compat.rs.html create mode 100644 src/actix_web/middleware/compress.rs.html create mode 100644 src/actix_web/middleware/condition.rs.html create mode 100644 src/actix_web/middleware/default_headers.rs.html create mode 100644 src/actix_web/middleware/err_handlers.rs.html create mode 100644 src/actix_web/middleware/logger.rs.html create mode 100644 src/actix_web/middleware/mod.rs.html create mode 100644 src/actix_web/middleware/normalize.rs.html create mode 100644 src/actix_web/redirect.rs.html create mode 100644 src/actix_web/request.rs.html create mode 100644 src/actix_web/request_data.rs.html create mode 100644 src/actix_web/resource.rs.html create mode 100644 src/actix_web/response/builder.rs.html create mode 100644 src/actix_web/response/customize_responder.rs.html create mode 100644 src/actix_web/response/http_codes.rs.html create mode 100644 src/actix_web/response/mod.rs.html create mode 100644 src/actix_web/response/responder.rs.html create mode 100644 src/actix_web/response/response.rs.html create mode 100644 src/actix_web/rmap.rs.html create mode 100644 src/actix_web/route.rs.html create mode 100644 src/actix_web/rt.rs.html create mode 100644 src/actix_web/scope.rs.html create mode 100644 src/actix_web/server.rs.html create mode 100644 src/actix_web/service.rs.html create mode 100644 src/actix_web/test/mod.rs.html create mode 100644 src/actix_web/test/test_request.rs.html create mode 100644 src/actix_web/test/test_services.rs.html create mode 100644 src/actix_web/test/test_utils.rs.html create mode 100644 src/actix_web/types/either.rs.html create mode 100644 src/actix_web/types/form.rs.html create mode 100644 src/actix_web/types/header.rs.html create mode 100644 src/actix_web/types/json.rs.html create mode 100644 src/actix_web/types/mod.rs.html create mode 100644 src/actix_web/types/path.rs.html create mode 100644 src/actix_web/types/payload.rs.html create mode 100644 src/actix_web/types/query.rs.html create mode 100644 src/actix_web/types/readlines.rs.html create mode 100644 src/actix_web/web.rs.html create mode 100644 src/actix_web_actors/context.rs.html create mode 100644 src/actix_web_actors/lib.rs.html create mode 100644 src/actix_web_actors/ws.rs.html create mode 100644 src/actix_web_codegen/lib.rs.html create mode 100644 src/actix_web_codegen/route.rs.html create mode 100644 src/awc/any_body.rs.html create mode 100644 src/awc/builder.rs.html create mode 100644 src/awc/client/config.rs.html create mode 100644 src/awc/client/connection.rs.html create mode 100644 src/awc/client/connector.rs.html create mode 100644 src/awc/client/error.rs.html create mode 100644 src/awc/client/h1proto.rs.html create mode 100644 src/awc/client/h2proto.rs.html create mode 100644 src/awc/client/mod.rs.html create mode 100644 src/awc/client/pool.rs.html create mode 100644 src/awc/connect.rs.html create mode 100644 src/awc/error.rs.html create mode 100644 src/awc/frozen.rs.html create mode 100644 src/awc/lib.rs.html create mode 100644 src/awc/middleware/mod.rs.html create mode 100644 src/awc/middleware/redirect.rs.html create mode 100644 src/awc/request.rs.html create mode 100644 src/awc/responses/json_body.rs.html create mode 100644 src/awc/responses/mod.rs.html create mode 100644 src/awc/responses/read_body.rs.html create mode 100644 src/awc/responses/response.rs.html create mode 100644 src/awc/responses/response_body.rs.html create mode 100644 src/awc/sender.rs.html create mode 100644 src/awc/test.rs.html create mode 100644 src/awc/ws.rs.html create mode 100644 static.files/COPYRIGHT-23e9bde6c69aea69.txt create mode 100644 static.files/FiraSans-LICENSE-db4b642586e02d97.txt create mode 100644 static.files/FiraSans-Medium-8f9a781e4970d388.woff2 create mode 100644 static.files/FiraSans-Regular-018c141bf0843ffd.woff2 create mode 100644 static.files/LICENSE-APACHE-b91fa81cba47b86a.txt create mode 100644 static.files/LICENSE-MIT-65090b722b3f6c56.txt create mode 100644 static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 create mode 100644 static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt create mode 100644 static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 create mode 100644 static.files/SourceCodePro-LICENSE-d180d465a756484a.txt create mode 100644 static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 create mode 100644 static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 create mode 100644 static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 create mode 100644 static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 create mode 100644 static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md create mode 100644 static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 create mode 100644 static.files/favicon-2c020d218678b618.svg create mode 100644 static.files/favicon-32x32-422f7d1d52889060.png create mode 100644 static.files/main-20a3ad099b048cf2.js create mode 100644 static.files/normalize-76eba96aa4d2e634.css create mode 100644 static.files/noscript-df360f571f6edeae.css create mode 100644 static.files/rust-logo-151179464ae7ed46.svg create mode 100644 static.files/rustdoc-dd39b87e5fcfba68.css create mode 100644 static.files/scrape-examples-ef1e698c1d417c0c.js create mode 100644 static.files/search-d52510db62a78183.js create mode 100644 static.files/settings-4313503d2e1961c2.js create mode 100644 static.files/src-script-e66d777a5a92e9b2.js create mode 100644 static.files/storage-118b08c4c78b968e.js create mode 100644 trait.impl/actix/actor/trait.ActorContext.js create mode 100644 trait.impl/actix/actor/trait.AsyncContext.js create mode 100644 trait.impl/actix/address/envelope/trait.ToEnvelope.js create mode 100644 trait.impl/actix/context_impl/trait.AsyncContextParts.js create mode 100644 trait.impl/actix_http/body/message_body/trait.MessageBody.js create mode 100644 trait.impl/actix_http/header/as_name/trait.AsHeaderName.js create mode 100644 trait.impl/actix_http/header/into_pair/trait.TryIntoHeaderPair.js create mode 100644 trait.impl/actix_http/header/into_value/trait.TryIntoHeaderValue.js create mode 100644 trait.impl/actix_http/header/trait.Header.js create mode 100644 trait.impl/actix_http/http_message/trait.HttpMessage.js create mode 100644 trait.impl/actix_multipart/form/trait.FieldReader.js create mode 100644 trait.impl/actix_router/pattern/trait.IntoPatterns.js create mode 100644 trait.impl/actix_router/resource_path/trait.Resource.js create mode 100644 trait.impl/actix_router/resource_path/trait.ResourcePath.js create mode 100644 trait.impl/actix_service/trait.Service.js create mode 100644 trait.impl/actix_service/trait.ServiceFactory.js create mode 100644 trait.impl/actix_service/transform/trait.Transform.js create mode 100644 trait.impl/actix_web/error/response_error/trait.ResponseError.js create mode 100644 trait.impl/actix_web/extract/trait.FromRequest.js create mode 100644 trait.impl/actix_web/guard/trait.Guard.js create mode 100644 trait.impl/actix_web/handler/trait.Handler.js create mode 100644 trait.impl/actix_web/response/responder/trait.Responder.js create mode 100644 trait.impl/actix_web/service/trait.HttpServiceFactory.js create mode 100644 trait.impl/awc/middleware/trait.Transform.js create mode 100644 trait.impl/bytes/buf/buf_impl/trait.Buf.js create mode 100644 trait.impl/bytes/buf/buf_mut/trait.BufMut.js create mode 100644 trait.impl/core/clone/trait.Clone.js create mode 100644 trait.impl/core/cmp/trait.Eq.js create mode 100644 trait.impl/core/cmp/trait.Ord.js create mode 100644 trait.impl/core/cmp/trait.PartialEq.js create mode 100644 trait.impl/core/cmp/trait.PartialOrd.js create mode 100644 trait.impl/core/convert/trait.AsRef.js create mode 100644 trait.impl/core/convert/trait.From.js create mode 100644 trait.impl/core/convert/trait.TryFrom.js create mode 100644 trait.impl/core/default/trait.Default.js create mode 100644 trait.impl/core/error/trait.Error.js create mode 100644 trait.impl/core/fmt/trait.Debug.js create mode 100644 trait.impl/core/fmt/trait.Display.js create mode 100644 trait.impl/core/future/future/trait.Future.js create mode 100644 trait.impl/core/hash/trait.Hash.js create mode 100644 trait.impl/core/iter/traits/collect/trait.IntoIterator.js create mode 100644 trait.impl/core/iter/traits/exact_size/trait.ExactSizeIterator.js create mode 100644 trait.impl/core/iter/traits/iterator/trait.Iterator.js create mode 100644 trait.impl/core/iter/traits/marker/trait.FusedIterator.js create mode 100644 trait.impl/core/marker/trait.Copy.js create mode 100644 trait.impl/core/marker/trait.Freeze.js create mode 100644 trait.impl/core/marker/trait.Send.js create mode 100644 trait.impl/core/marker/trait.StructuralPartialEq.js create mode 100644 trait.impl/core/marker/trait.Sync.js create mode 100644 trait.impl/core/marker/trait.Unpin.js create mode 100644 trait.impl/core/ops/deref/trait.Deref.js create mode 100644 trait.impl/core/ops/deref/trait.DerefMut.js create mode 100644 trait.impl/core/ops/drop/trait.Drop.js create mode 100644 trait.impl/core/ops/index/trait.Index.js create mode 100644 trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js create mode 100644 trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js create mode 100644 trait.impl/core/str/traits/trait.FromStr.js create mode 100644 trait.impl/futures_core/stream/trait.Stream.js create mode 100644 trait.impl/serde/de/trait.Deserialize.js create mode 100644 trait.impl/serde/de/trait.Deserializer.js create mode 100644 trait.impl/serde/ser/trait.Serialize.js create mode 100644 trait.impl/std/io/trait.Read.js create mode 100644 trait.impl/std/io/trait.Write.js create mode 100644 trait.impl/time/ext/instant/trait.InstantExt.js create mode 100644 trait.impl/time/ext/numerical_duration/trait.NumericalDuration.js create mode 100644 trait.impl/time/ext/numerical_std_duration/trait.NumericalStdDuration.js create mode 100644 trait.impl/time/formatting/formattable/trait.Formattable.js create mode 100644 trait.impl/time/parsing/parsable/trait.Parsable.js create mode 100644 trait.impl/tokio/io/async_read/trait.AsyncRead.js create mode 100644 trait.impl/tokio/io/async_write/trait.AsyncWrite.js create mode 100644 trait.impl/tokio_util/codec/decoder/trait.Decoder.js create mode 100644 trait.impl/tokio_util/codec/encoder/trait.Encoder.js create mode 100644 type.impl/alloc/boxed/struct.Box.js create mode 100644 type.impl/alloc/rc/struct.Rc.js create mode 100644 type.impl/awc/struct.ResponseBody.js create mode 100644 type.impl/core/pin/struct.Pin.js create mode 100644 type.impl/core/result/enum.Result.js create mode 100644 type.impl/std/primitive.u128.js diff --git a/.lock b/.lock new file mode 100644 index 000000000..e69de29bb diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/actix_files/all.html b/actix_files/all.html new file mode 100644 index 000000000..ac1f0701e --- /dev/null +++ b/actix_files/all.html @@ -0,0 +1 @@ +List of all items in this crate
\ No newline at end of file diff --git a/actix_files/directory/struct.Directory.html b/actix_files/directory/struct.Directory.html new file mode 100644 index 000000000..6684baf0c --- /dev/null +++ b/actix_files/directory/struct.Directory.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_files/struct.Directory.html...

+ + + \ No newline at end of file diff --git a/actix_files/files/struct.Files.html b/actix_files/files/struct.Files.html new file mode 100644 index 000000000..dd6554249 --- /dev/null +++ b/actix_files/files/struct.Files.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_files/struct.Files.html...

+ + + \ No newline at end of file diff --git a/actix_files/fn.file_extension_to_mime.html b/actix_files/fn.file_extension_to_mime.html new file mode 100644 index 000000000..70613e1f0 --- /dev/null +++ b/actix_files/fn.file_extension_to_mime.html @@ -0,0 +1,4 @@ +file_extension_to_mime in actix_files - Rust

Function actix_files::file_extension_to_mime

source ·
pub fn file_extension_to_mime(ext: &str) -> Mime
Expand description

Return the MIME type associated with a filename extension (case-insensitive). +If ext is empty or no associated type for the extension was found, returns +the type application/octet-stream.

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

Crate actix_files

source ·
Expand description

Static file serving for Actix Web.

+

Provides a non-blocking service for serving static files from disk.

+

§Examples

+
use actix_web::App;
+use actix_files::Files;
+
+let app = App::new()
+    .service(Files::new("/static", ".").prefer_utf8(true));
+

Re-exports§

  • pub use self::chunked::ChunkedReadFile;

Structs§

  • A directory; responds with the generated directory listing.
  • Static files handling service.
  • Assembled file serving service.
  • HTTP Range header representation.
  • A file with an associated name.

Functions§

  • Return the MIME type associated with a filename extension (case-insensitive). +If ext is empty or no associated type for the extension was found, returns +the type application/octet-stream.
\ No newline at end of file diff --git a/actix_files/named/struct.NamedFile.html b/actix_files/named/struct.NamedFile.html new file mode 100644 index 000000000..14294a471 --- /dev/null +++ b/actix_files/named/struct.NamedFile.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_files/struct.NamedFile.html...

+ + + \ No newline at end of file diff --git a/actix_files/range/struct.HttpRange.html b/actix_files/range/struct.HttpRange.html new file mode 100644 index 000000000..4045b72bc --- /dev/null +++ b/actix_files/range/struct.HttpRange.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_files/struct.HttpRange.html...

+ + + \ No newline at end of file diff --git a/actix_files/service/struct.FilesService.html b/actix_files/service/struct.FilesService.html new file mode 100644 index 000000000..f62b63f31 --- /dev/null +++ b/actix_files/service/struct.FilesService.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_files/struct.FilesService.html...

+ + + \ No newline at end of file diff --git a/actix_files/sidebar-items.js b/actix_files/sidebar-items.js new file mode 100644 index 000000000..a044192a4 --- /dev/null +++ b/actix_files/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["file_extension_to_mime"],"struct":["Directory","Files","FilesService","HttpRange","NamedFile"]}; \ No newline at end of file diff --git a/actix_files/struct.Directory.html b/actix_files/struct.Directory.html new file mode 100644 index 000000000..a336c0610 --- /dev/null +++ b/actix_files/struct.Directory.html @@ -0,0 +1,25 @@ +Directory in actix_files - Rust

Struct actix_files::Directory

source ·
pub struct Directory {
+    pub base: PathBuf,
+    pub path: PathBuf,
+}
Expand description

A directory; responds with the generated directory listing.

+

Fields§

§base: PathBuf

Base directory.

+
§path: PathBuf

Path of subdirectory to generate listing for.

+

Implementations§

source§

impl Directory

source

pub fn new(base: PathBuf, path: PathBuf) -> Directory

Create a new directory

+
source

pub fn is_visible(&self, entry: &Result<DirEntry>) -> bool

Is this entry visible from this directory?

+

Trait Implementations§

source§

impl Debug for Directory

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_files/struct.Files.html b/actix_files/struct.Files.html new file mode 100644 index 000000000..245f0a2bb --- /dev/null +++ b/actix_files/struct.Files.html @@ -0,0 +1,131 @@ +Files in actix_files - Rust

Struct actix_files::Files

source ·
pub struct Files { /* private fields */ }
Expand description

Static files handling service.

+

Files service must be registered with App::service() method.

+

§Examples

+
use actix_web::App;
+use actix_files::Files;
+
+let app = App::new()
+    .service(Files::new("/static", "."));
+

Implementations§

source§

impl Files

source

pub fn new<T: Into<PathBuf>>(mount_path: &str, serve_from: T) -> Files

Create new Files instance for a specified base directory.

+
§Argument Order
+

The first argument (mount_path) is the root URL at which the static files are served. +For example, /assets will serve files at example.com/assets/....

+

The second argument (serve_from) is the location on disk at which files are loaded. +This can be a relative path. For example, ./ would serve files from the current +working directory.

+
§Implementation Notes
+

If the mount path is set as the root path /, services registered after this one will +be inaccessible. Register more specific handlers and services first.

+

Files utilizes the existing Tokio thread-pool for blocking filesystem operations. +The number of running threads is adjusted over time as needed, up to a maximum of 512 times +the number of server workers, by default.

+
source

pub fn show_files_listing(self) -> Self

Show files listing for directories.

+

By default show files listing is disabled.

+

When used with Files::index_file(), files listing is shown as a fallback +when the index file is not found.

+
source

pub fn redirect_to_slash_directory(self) -> Self

Redirects to a slash-ended path when browsing a directory.

+

By default never redirect.

+
source

pub fn files_listing_renderer<F>(self, f: F) -> Self
where + for<'r, 's> F: Fn(&'r Directory, &'s HttpRequest) -> Result<ServiceResponse, Error> + 'static,

Set custom directory renderer.

+
source

pub fn mime_override<F>(self, f: F) -> Self
where + F: Fn(&Name<'_>) -> DispositionType + 'static,

Specifies MIME override callback.

+
source

pub fn path_filter<F>(self, f: F) -> Self
where + F: Fn(&Path, &RequestHead) -> bool + 'static,

Sets path filtering closure.

+

The path provided to the closure is relative to serve_from path. +You can safely join this path with the serve_from path to get the real path. +However, the real path may not exist since the filter is called before checking path existence.

+

When a path doesn’t pass the filter, Files::default_handler is called if set, otherwise, +404 Not Found is returned.

+
§Examples
+
use std::path::Path;
+use actix_files::Files;
+
+// prevent searching subdirectories and following symlinks
+let files_service = Files::new("/", "./static").path_filter(|path, _| {
+    path.components().count() == 1
+        && Path::new("./static")
+            .join(path)
+            .symlink_metadata()
+            .map(|m| !m.file_type().is_symlink())
+            .unwrap_or(false)
+});
+
source

pub fn index_file<T: Into<String>>(self, index: T) -> Self

Set index file

+

Shows specific index file for directories instead of +showing files listing.

+

If the index file is not found, files listing is shown as a fallback if +Files::show_files_listing() is set.

+
source

pub fn use_etag(self, value: bool) -> Self

Specifies whether to use ETag or not.

+

Default is true.

+
source

pub fn use_last_modified(self, value: bool) -> Self

Specifies whether to use Last-Modified or not.

+

Default is true.

+
source

pub fn prefer_utf8(self, value: bool) -> Self

Specifies whether text responses should signal a UTF-8 encoding.

+

Default is false (but will default to true in a future version).

+
source

pub fn guard<G: Guard + 'static>(self, guard: G) -> Self

Adds a routing guard.

+

Use this to allow multiple chained file services that respond to strictly different +properties of a request. Due to the way routing works, if a guard check returns true and the +request starts being handled by the file service, it will not be able to back-out and try +the next service, you will simply get a 404 (or 405) error response.

+

To allow POST requests to retrieve files, see Files::method_guard().

+
§Examples
+
use actix_web::{guard::Header, App};
+use actix_files::Files;
+
+App::new().service(
+    Files::new("/","/my/site/files")
+        .guard(Header("Host", "example.com"))
+);
+
source

pub fn method_guard<G: Guard + 'static>(self, guard: G) -> Self

Specifies guard to check before fetching directory listings or files.

+

Note that this guard has no effect on routing; it’s main use is to guard on the request’s +method just before serving the file, only allowing GET and HEAD requests by default. +See Files::guard for routing guards.

+
source

pub fn disable_content_disposition(self) -> Self

Disable Content-Disposition header.

+

By default Content-Disposition` header is enabled.

+
source

pub fn default_handler<F, U>(self, f: F) -> Self
where + F: IntoServiceFactory<U, ServiceRequest>, + U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error> + 'static,

Sets default handler which is used when no matched file could be found.

+
§Examples
+

Setting a fallback static file handler:

+ +
use actix_files::{Files, NamedFile};
+use actix_web::dev::{ServiceRequest, ServiceResponse, fn_service};
+
+let files = Files::new("/", "./static")
+    .index_file("index.html")
+    .default_handler(fn_service(|req: ServiceRequest| async {
+        let (req, _) = req.into_parts();
+        let file = NamedFile::open_async("./static/404.html").await?;
+        let res = file.into_response(&req);
+        Ok(ServiceResponse::new(req, res))
+    }));
+
source

pub fn use_hidden_files(self) -> Self

Enables serving hidden files and directories, allowing a leading dots in url fragments.

+

Trait Implementations§

source§

impl Clone for Files

source§

fn clone(&self) -> Self

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

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

Performs copy-assignment from source. Read more
source§

impl Debug for Files

source§

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

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

impl HttpServiceFactory for Files

source§

fn register(self, config: &mut AppService)

source§

impl ServiceFactory<ServiceRequest> for Files

§

type Response = ServiceResponse

Responses given by the created services.
§

type Error = Error

Errors produced by the created services.
§

type Config = ()

Service factory configuration.
§

type Service = FilesService

The kind of Service created by this factory.
§

type InitError = ()

Errors potentially raised while building a service.
§

type Future = Pin<Box<dyn Future<Output = Result<<Files as ServiceFactory<ServiceRequest>>::Service, <Files as ServiceFactory<ServiceRequest>>::InitError>>>>

The future of the Service instance.g
source§

fn new_service(&self, _: ()) -> Self::Future

Create and return a new service asynchronously.

Auto Trait Implementations§

§

impl Freeze for Files

§

impl !RefUnwindSafe for Files

§

impl !Send for Files

§

impl !Sync for Files

§

impl Unpin for Files

§

impl !UnwindSafe for Files

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
§

impl<SF, Req> IntoServiceFactory<SF, Req> for SF
where + SF: ServiceFactory<Req>,

§

fn into_factory(self) -> SF

Convert Self to a ServiceFactory
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<SF, Req> ServiceFactoryExt<Req> for SF
where + SF: ServiceFactory<Req>,

§

fn map<F, R>(self, f: F) -> MapServiceFactory<Self, F, Req, R>
where + Self: Sized, + F: FnMut(Self::Response) -> R + Clone,

Map this service’s output to a different type, returning a new service +of the resulting type.
§

fn map_err<F, E>(self, f: F) -> MapErrServiceFactory<Self, Req, F, E>
where + Self: Sized, + F: Fn(Self::Error) -> E + Clone,

Map this service’s error to a different error, returning a new service.
§

fn map_init_err<F, E>(self, f: F) -> MapInitErr<Self, F, Req, E>
where + Self: Sized, + F: Fn(Self::InitError) -> E + Clone,

Map this factory’s init error to a different error, returning a new service.
§

fn and_then<I, SF1>(self, factory: I) -> AndThenServiceFactory<Self, SF1, Req>
where + Self: Sized, + Self::Config: Clone, + I: IntoServiceFactory<SF1, Self::Response>, + SF1: ServiceFactory<Self::Response, Config = Self::Config, Error = Self::Error, InitError = Self::InitError>,

Call another service after call to this one has resolved successfully.
source§

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

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

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

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

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_files/struct.FilesService.html b/actix_files/struct.FilesService.html new file mode 100644 index 000000000..4a226d2f6 --- /dev/null +++ b/actix_files/struct.FilesService.html @@ -0,0 +1,29 @@ +FilesService in actix_files - Rust

Struct actix_files::FilesService

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

Assembled file serving service.

+

Trait Implementations§

source§

impl Clone for FilesService

source§

fn clone(&self) -> FilesService

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

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

Performs copy-assignment from source. Read more
source§

impl Debug for FilesService

source§

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

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

impl Deref for FilesService

§

type Target = FilesServiceInner

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl Service<ServiceRequest> for FilesService

§

type Response = ServiceResponse

Responses given by the service.
§

type Error = Error

Errors produced by the service when polling readiness or executing call.
§

type Future = Pin<Box<dyn Future<Output = Result<<FilesService as Service<ServiceRequest>>::Response, <FilesService as Service<ServiceRequest>>::Error>>>>

The future response value.
source§

fn poll_ready(&self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>>

Returns Ready when the service is able to process requests. Read more
source§

fn call(&self, req: ServiceRequest) -> Self::Future

Process the request and return the response asynchronously. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
§

impl<S, Req> IntoService<S, Req> for S
where + S: Service<Req>,

§

fn into_service(self) -> S

Convert to a Service
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<S, Req> ServiceExt<Req> for S
where + S: Service<Req>,

§

fn map<F, R>(self, f: F) -> Map<Self, F, Req, R>
where + Self: Sized, + F: FnMut(Self::Response) -> R,

Map this service’s output to a different type, returning a new service +of the resulting type. Read more
§

fn map_err<F, E>(self, f: F) -> MapErr<Self, Req, F, E>
where + Self: Sized, + F: Fn(Self::Error) -> E,

Map this service’s error to a different error, returning a new service. Read more
§

fn and_then<I, S1>(self, service: I) -> AndThenService<Self, S1, Req>
where + Self: Sized, + I: IntoService<S1, Self::Response>, + S1: Service<Self::Response, Error = Self::Error>,

Call another service after call to this one has resolved successfully. Read more
source§

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

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

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

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

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_files/struct.HttpRange.html b/actix_files/struct.HttpRange.html new file mode 100644 index 000000000..b37385570 --- /dev/null +++ b/actix_files/struct.HttpRange.html @@ -0,0 +1,27 @@ +HttpRange in actix_files - Rust

Struct actix_files::HttpRange

source ·
pub struct HttpRange {
+    pub start: u64,
+    pub length: u64,
+}
Expand description

HTTP Range header representation.

+

Fields§

§start: u64

Start of range.

+
§length: u64

Length of range.

+

Implementations§

source§

impl HttpRange

source

pub fn parse(header: &str, size: u64) -> Result<Vec<HttpRange>, ParseRangeErr>

Parses Range HTTP header string as per RFC 2616.

+

header is HTTP Range header (e.g. bytes=bytes=0-9). +size is full size of response (file).

+

Trait Implementations§

source§

impl Clone for HttpRange

source§

fn clone(&self) -> HttpRange

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

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

Performs copy-assignment from source. Read more
source§

impl Debug for HttpRange

source§

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

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

impl Copy for HttpRange

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

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

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

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_files/struct.NamedFile.html b/actix_files/struct.NamedFile.html new file mode 100644 index 000000000..29878a8cf --- /dev/null +++ b/actix_files/struct.NamedFile.html @@ -0,0 +1,306 @@ +NamedFile in actix_files - Rust

Struct actix_files::NamedFile

source ·
pub struct NamedFile { /* private fields */ }
Expand description

A file with an associated name.

+

NamedFile can be registered as services:

+ +
use actix_web::App;
+use actix_files::NamedFile;
+
+let file = NamedFile::open_async("./static/index.html").await?;
+let app = App::new().service(file);
+

They can also be returned from handlers:

+ +
use actix_web::{Responder, get};
+use actix_files::NamedFile;
+
+#[get("/")]
+async fn index() -> impl Responder {
+    NamedFile::open_async("./static/index.html").await
+}
+

Implementations§

source§

impl NamedFile

source

pub fn from_file<P: AsRef<Path>>(file: File, path: P) -> Result<NamedFile>

Creates an instance from a previously opened file.

+

The given path need not exist and is only used to determine the ContentType and +ContentDisposition headers.

+
§Examples
+
use std::{
+    io::{self, Write as _},
+    env,
+    fs::File
+};
+use actix_files::NamedFile;
+
+let mut file = File::create("foo.txt")?;
+file.write_all(b"Hello, world!")?;
+let named_file = NamedFile::from_file(file, "bar.txt")?;
+Ok(())
+
source

pub async fn open_async<P: AsRef<Path>>(path: P) -> Result<NamedFile>

Attempts to open a file asynchronously in read-only mode.

+

When the experimental-io-uring crate feature is enabled, this will be async. Otherwise, it +will behave just like open.

+
§Examples
+
use actix_files::NamedFile;
+let file = NamedFile::open_async("foo.txt").await.unwrap();
+
source

pub fn file(&self) -> &File

Returns reference to the underlying file object.

+
source

pub fn path(&self) -> &Path

Returns the filesystem path to this file.

+
§Examples
+
use actix_files::NamedFile;
+
+let file = NamedFile::open_async("test.txt").await?;
+assert_eq!(file.path().as_os_str(), "foo.txt");
+
source

pub fn modified(&self) -> Option<SystemTime>

Returns the time the file was last modified.

+

Returns None only on unsupported platforms; see std::fs::Metadata::modified(). +Therefore, it is usually safe to unwrap this.

+
source

pub fn metadata(&self) -> &Metadata

Returns the filesystem metadata associated with this file.

+
source

pub fn content_type(&self) -> &Mime

Returns the Content-Type header that will be used when serving this file.

+
source

pub fn content_disposition(&self) -> &ContentDisposition

Returns the Content-Disposition that will be used when serving this file.

+
source

pub fn content_encoding(&self) -> Option<ContentEncoding>

Returns the Content-Encoding that will be used when serving this file.

+

A return value of None indicates that the content is not already using a compressed +representation and may be subject to compression downstream.

+
source

pub fn set_status_code(self, status: StatusCode) -> Self

👎Deprecated since 0.7.0: Prefer Responder::customize().

Set response status code.

+
source

pub fn set_content_type(self, mime_type: Mime) -> Self

Sets the Content-Type header that will be used when serving this file. By default the +Content-Type is inferred from the filename extension.

+
source

pub fn set_content_disposition(self, cd: ContentDisposition) -> Self

Set the Content-Disposition for serving this file. This allows changing the +inline/attachment disposition as well as the filename sent to the peer.

+

By default the disposition is inline for text/*, image/*, video/* and +application/{javascript, json, wasm} mime types, and attachment otherwise, and the +filename is taken from the path provided in the open method after converting it to UTF-8 +(using to_string_lossy).

+
source

pub fn disable_content_disposition(self) -> Self

Disables Content-Disposition header.

+

By default, the Content-Disposition header is sent.

+
source

pub fn set_content_encoding(self, enc: ContentEncoding) -> Self

Sets content encoding for this file.

+

This prevents the Compress middleware from modifying the file contents and signals to +browsers/clients how to decode it. For example, if serving a compressed HTML file (e.g., +index.html.gz) then use .set_content_encoding(ContentEncoding::Gzip).

+
source

pub fn use_etag(self, value: bool) -> Self

Specifies whether to return ETag header in response.

+

Default is true.

+
source

pub fn use_last_modified(self, value: bool) -> Self

Specifies whether to return Last-Modified header in response.

+

Default is true.

+
source

pub fn prefer_utf8(self, value: bool) -> Self

Specifies whether text responses should signal a UTF-8 encoding.

+

Default is false (but will default to true in a future version).

+
source

pub fn into_response(self, req: &HttpRequest) -> HttpResponse<BoxBody>

Creates an HttpResponse with file as a streaming body.

+

Methods from Deref<Target = File>§

pub async fn read_at<T>(&self, buf: T, pos: u64) -> (Result<usize, Error>, T)
where + T: IoBufMut,

Read some bytes at the specified offset from the file into the specified +buffer, returning how many bytes were read.

+
§Return
+

The method returns the operation result and the same buffer value passed +as an argument.

+

If the method returns [Ok(n)], then the read was successful. A nonzero +n value indicates that the buffer has been filled with n bytes of +data from the file. If n is 0, then one of the following happened:

+
    +
  1. The specified offset is the end of the file.
  2. +
  3. The buffer specified was 0 bytes in length.
  4. +
+

It is not an error if the returned value n is smaller than the buffer +size, even when the file contains enough data to fill the buffer.

+
§Errors
+

If this function encounters any form of I/O or other error, an error +variant will be returned. The buffer is returned on error.

+
§Examples
+
use tokio_uring::fs::File;
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+    tokio_uring::start(async {
+        let f = File::open("foo.txt").await?;
+        let buffer = vec![0; 10];
+
+        // Read up to 10 bytes
+        let (res, buffer) = f.read_at(buffer, 0).await;
+        let n = res?;
+
+        println!("The bytes: {:?}", &buffer[..n]);
+
+        // Close the file
+        f.close().await?;
+        Ok(())
+    })
+}
+

pub async fn readv_at<T>( + &self, + bufs: Vec<T>, + pos: u64 +) -> (Result<usize, Error>, Vec<T>)
where + T: IoBufMut,

Read some bytes at the specified offset from the file into the specified +array of buffers, returning how many bytes were read.

+
§Return
+

The method returns the operation result and the same array of buffers +passed as an argument.

+

If the method returns [Ok(n)], then the read was successful. A nonzero +n value indicates that the buffers have been filled with n bytes of +data from the file. If n is 0, then one of the following happened:

+
    +
  1. The specified offset is the end of the file.
  2. +
  3. The buffers specified were 0 bytes in length.
  4. +
+

It is not an error if the returned value n is smaller than the buffer +size, even when the file contains enough data to fill the buffer.

+
§Errors
+

If this function encounters any form of I/O or other error, an error +variant will be returned. The buffer is returned on error.

+
§Examples
+
use tokio_uring::fs::File;
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+    tokio_uring::start(async {
+        let f = File::open("foo.txt").await?;
+        let buffers = vec![Vec::<u8>::with_capacity(10), Vec::<u8>::with_capacity(10)];
+
+        // Read up to 20 bytes
+        let (res, buffer) = f.readv_at(buffers, 0).await;
+        let n = res?;
+
+        println!("Read {} bytes", n);
+
+        // Close the file
+        f.close().await?;
+        Ok(())
+    })
+}
+

pub async fn writev_at<T>( + &self, + buf: Vec<T>, + pos: u64 +) -> (Result<usize, Error>, Vec<T>)
where + T: IoBuf,

Write data from buffers into this file at the specified offset, +returning how many bytes were written.

+

This function will attempt to write the entire contents of bufs, but +the entire write may not succeed, or the write may also generate an +error. The bytes will be written starting at the specified offset.

+
§Return
+

The method returns the operation result and the same array of buffers passed +in as an argument. A return value of 0 typically means that the +underlying file is no longer able to accept bytes and will likely not be +able to in the future as well, or that the buffer provided is empty.

+
§Errors
+

Each call to write may generate an I/O error indicating that the +operation could not be completed. If an error is returned then no bytes +in the buffer were written to this writer.

+

It is not considered an error if the entire buffer could not be +written to this writer.

+
§Examples
+
use tokio_uring::fs::File;
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+    tokio_uring::start(async {
+        let file = File::create("foo.txt").await?;
+
+        // Writes some prefix of the byte string, not necessarily all of it.
+        let bufs = vec!["some".to_owned().into_bytes(), " bytes".to_owned().into_bytes()];
+        let (res, _) = file.writev_at(bufs, 0).await;
+        let n = res?;
+
+        println!("wrote {} bytes", n);
+
+        // Close the file
+        file.close().await?;
+        Ok(())
+    })
+}
+

pub async fn write_at<T>(&self, buf: T, pos: u64) -> (Result<usize, Error>, T)
where + T: IoBuf,

Write a buffer into this file at the specified offset, returning how +many bytes were written.

+

This function will attempt to write the entire contents of buf, but +the entire write may not succeed, or the write may also generate an +error. The bytes will be written starting at the specified offset.

+
§Return
+

The method returns the operation result and the same buffer value passed +in as an argument. A return value of 0 typically means that the +underlying file is no longer able to accept bytes and will likely not be +able to in the future as well, or that the buffer provided is empty.

+
§Errors
+

Each call to write may generate an I/O error indicating that the +operation could not be completed. If an error is returned then no bytes +in the buffer were written to this writer.

+

It is not considered an error if the entire buffer could not be +written to this writer.

+
§Examples
+
use tokio_uring::fs::File;
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+    tokio_uring::start(async {
+        let file = File::create("foo.txt").await?;
+
+        // Writes some prefix of the byte string, not necessarily all of it.
+        let (res, _) = file.write_at(&b"some bytes"[..], 0).await;
+        let n = res?;
+
+        println!("wrote {} bytes", n);
+
+        // Close the file
+        file.close().await?;
+        Ok(())
+    })
+}
+

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

Attempts to sync all OS-internal metadata to disk.

+

This function will attempt to ensure that all in-memory data reaches the +filesystem before completing.

+

This can be used to handle errors that would otherwise only be caught +when the File is closed. Dropping a file will ignore errors in +synchronizing this in-memory data.

+
§Examples
+
use tokio_uring::fs::File;
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+    tokio_uring::start(async {
+        let f = File::create("foo.txt").await?;
+        let (res, buf) = f.write_at(&b"Hello, world!"[..], 0).await;
+        let n = res?;
+
+        f.sync_all().await?;
+
+        // Close the file
+        f.close().await?;
+        Ok(())
+    })
+}
+

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

Attempts to sync file data to disk.

+

This method is similar to sync_all, except that it may not +synchronize file metadata to the filesystem.

+

This is intended for use cases that must synchronize content, but don’t +need the metadata on disk. The goal of this method is to reduce disk +operations.

+

Note that some platforms may simply implement this in terms of +sync_all.

+
§Examples
+
use tokio_uring::fs::File;
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+    tokio_uring::start(async {
+        let f = File::create("foo.txt").await?;
+        let (res, buf) = f.write_at(&b"Hello, world!"[..], 0).await;
+        let n = res?;
+
+        f.sync_data().await?;
+
+        // Close the file
+        f.close().await?;
+        Ok(())
+    })
+}
+

Trait Implementations§

source§

impl Debug for NamedFile

source§

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

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

impl Deref for NamedFile

§

type Target = File

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for NamedFile

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl HttpServiceFactory for NamedFile

source§

fn register(self, config: &mut AppService)

source§

impl Responder for NamedFile

§

type Body = BoxBody

source§

fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body>

Convert self to HttpResponse.
§

fn customize(self) -> CustomizeResponder<Self>
where + Self: Sized,

Wraps responder to allow alteration of its response. Read more
source§

impl ServiceFactory<ServiceRequest> for NamedFile

§

type Response = ServiceResponse

Responses given by the created services.
§

type Error = Error

Errors produced by the created services.
§

type Config = ()

Service factory configuration.
§

type Service = NamedFileService

The kind of Service created by this factory.
§

type InitError = ()

Errors potentially raised while building a service.
§

type Future = Pin<Box<dyn Future<Output = Result<<NamedFile as ServiceFactory<ServiceRequest>>::Service, <NamedFile as ServiceFactory<ServiceRequest>>::InitError>>>>

The future of the Service instance.g
source§

fn new_service(&self, _: ()) -> Self::Future

Create and return a new service asynchronously.

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
§

impl<SF, Req> IntoServiceFactory<SF, Req> for SF
where + SF: ServiceFactory<Req>,

§

fn into_factory(self) -> SF

Convert Self to a ServiceFactory
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<SF, Req> ServiceFactoryExt<Req> for SF
where + SF: ServiceFactory<Req>,

§

fn map<F, R>(self, f: F) -> MapServiceFactory<Self, F, Req, R>
where + Self: Sized, + F: FnMut(Self::Response) -> R + Clone,

Map this service’s output to a different type, returning a new service +of the resulting type.
§

fn map_err<F, E>(self, f: F) -> MapErrServiceFactory<Self, Req, F, E>
where + Self: Sized, + F: Fn(Self::Error) -> E + Clone,

Map this service’s error to a different error, returning a new service.
§

fn map_init_err<F, E>(self, f: F) -> MapInitErr<Self, F, Req, E>
where + Self: Sized, + F: Fn(Self::InitError) -> E + Clone,

Map this factory’s init error to a different error, returning a new service.
§

fn and_then<I, SF1>(self, factory: I) -> AndThenServiceFactory<Self, SF1, Req>
where + Self: Sized, + Self::Config: Clone, + I: IntoServiceFactory<SF1, Self::Response>, + SF1: ServiceFactory<Self::Response, Config = Self::Config, Error = Self::Error, InitError = Self::InitError>,

Call another service after call to this one has resolved successfully.
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/all.html b/actix_http/all.html new file mode 100644 index 000000000..c30be1f93 --- /dev/null +++ b/actix_http/all.html @@ -0,0 +1 @@ +List of all items in this crate

List of all items

Structs

Enums

Traits

Functions

Type Aliases

Constants

\ No newline at end of file diff --git a/actix_http/body/body_stream/struct.BodyStream.html b/actix_http/body/body_stream/struct.BodyStream.html new file mode 100644 index 000000000..0095494bd --- /dev/null +++ b/actix_http/body/body_stream/struct.BodyStream.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/body/struct.BodyStream.html...

+ + + \ No newline at end of file diff --git a/actix_http/body/boxed/struct.BoxBody.html b/actix_http/body/boxed/struct.BoxBody.html new file mode 100644 index 000000000..309567169 --- /dev/null +++ b/actix_http/body/boxed/struct.BoxBody.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/body/struct.BoxBody.html...

+ + + \ No newline at end of file diff --git a/actix_http/body/either/enum.EitherBody.html b/actix_http/body/either/enum.EitherBody.html new file mode 100644 index 000000000..1d594ae1e --- /dev/null +++ b/actix_http/body/either/enum.EitherBody.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/body/enum.EitherBody.html...

+ + + \ No newline at end of file diff --git a/actix_http/body/enum.BodySize.html b/actix_http/body/enum.BodySize.html new file mode 100644 index 000000000..21717d05d --- /dev/null +++ b/actix_http/body/enum.BodySize.html @@ -0,0 +1,46 @@ +BodySize in actix_http::body - Rust

Enum actix_http::body::BodySize

source ·
pub enum BodySize {
+    None,
+    Sized(u64),
+    Stream,
+}
Expand description

Body size hint.

+

Variants§

§

None

Implicitly empty body.

+

Will omit the Content-Length header. Used for responses to certain methods (e.g., HEAD) or +with particular status codes (e.g., 204 No Content). Consumers that read this as a body size +hint are allowed to make optimizations that skip reading or writing the payload.

+
§

Sized(u64)

Known size body.

+

Will write Content-Length: N header.

+
§

Stream

Unknown size body.

+

Will not write Content-Length header. Can be used with chunked Transfer-Encoding.

+

Implementations§

source§

impl BodySize

source

pub const ZERO: Self = _

Equivalent to BodySize::Sized(0);

+
source

pub fn is_eof(&self) -> bool

Returns true if size hint indicates omitted or empty body.

+

Streams will return false because it cannot be known without reading the stream.

+ +
assert!(BodySize::None.is_eof());
+assert!(BodySize::Sized(0).is_eof());
+
+assert!(!BodySize::Sized(64).is_eof());
+assert!(!BodySize::Stream.is_eof());
+

Trait Implementations§

source§

impl Clone for BodySize

source§

fn clone(&self) -> BodySize

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

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

Performs copy-assignment from source. Read more
source§

impl Debug for BodySize

source§

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

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

impl PartialEq for BodySize

source§

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

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

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

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

impl Copy for BodySize

source§

impl Eq for BodySize

source§

impl StructuralPartialEq for BodySize

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
§

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

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

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

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

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

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

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/body/enum.EitherBody.html b/actix_http/body/enum.EitherBody.html new file mode 100644 index 000000000..d5260db69 --- /dev/null +++ b/actix_http/body/enum.EitherBody.html @@ -0,0 +1,57 @@ +EitherBody in actix_http::body - Rust

Enum actix_http::body::EitherBody

source ·
pub enum EitherBody<L, R = BoxBody> {
+    Left {
+        body: L,
+    },
+    Right {
+        body: R,
+    },
+}
Expand description

An “either” type specialized for body types.

+

It is common, in middleware especially, to conditionally return an inner service’s unknown/ +generic body B type or return early with a new response. This type’s “right” variant +defaults to BoxBody since error responses are the common case.

+

For example, middleware will often have type Response = ServiceResponse<EitherBody<B>>. +This means that the inner service’s response body type maps to the Left variant and the +middleware’s own error responses use the default Right variant of BoxBody. Of course, +there’s no reason it couldn’t use EitherBody<B, String> instead if its alternative +responses have a known type.

+

Variants§

§

Left

A body of type L.

+

Fields

§body: L
§

Right

A body of type R.

+

Fields

§body: R

Implementations§

source§

impl<L> EitherBody<L, BoxBody>

source

pub fn new(body: L) -> Self

Creates new EitherBody left variant with a boxed right variant.

+

If the expected R type will be inferred and is not BoxBody then use the +left constructor instead.

+
source§

impl<L, R> EitherBody<L, R>

source

pub fn left(body: L) -> Self

Creates new EitherBody using left variant.

+
source

pub fn right(body: R) -> Self

Creates new EitherBody using right variant.

+

Trait Implementations§

source§

impl<L: Clone, R: Clone> Clone for EitherBody<L, R>

source§

fn clone(&self) -> EitherBody<L, R>

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

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

Performs copy-assignment from source. Read more
source§

impl<L: Debug, R: Debug> Debug for EitherBody<L, R>

source§

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

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

impl<L, R> MessageBody for EitherBody<L, R>
where + L: MessageBody + 'static, + R: MessageBody + 'static,

§

type Error = Error

The type of error that will be returned if streaming body fails. Read more
source§

fn size(&self) -> BodySize

Body size hint. Read more
source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

Attempt to pull out the next chunk of body bytes. Read more
source§

fn try_into_bytes(self) -> Result<Bytes, Self>

Try to convert into the complete chunk of body bytes. Read more
source§

fn boxed(self) -> BoxBody

Wraps this body into a BoxBody. Read more
source§

impl<'__pin, L, R> Unpin for EitherBody<L, R>
where + __Origin<'__pin, L, R>: Unpin,

Auto Trait Implementations§

§

impl<L, R> Freeze for EitherBody<L, R>
where + L: Freeze, + R: Freeze,

§

impl<L, R> RefUnwindSafe for EitherBody<L, R>
where + L: RefUnwindSafe, + R: RefUnwindSafe,

§

impl<L, R> Send for EitherBody<L, R>
where + L: Send, + R: Send,

§

impl<L, R> Sync for EitherBody<L, R>
where + L: Sync, + R: Sync,

§

impl<L, R> UnwindSafe for EitherBody<L, R>
where + L: UnwindSafe, + R: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

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

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

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/body/fn.to_bytes.html b/actix_http/body/fn.to_bytes.html new file mode 100644 index 000000000..174d18a7b --- /dev/null +++ b/actix_http/body/fn.to_bytes.html @@ -0,0 +1,15 @@ +to_bytes in actix_http::body - Rust

Function actix_http::body::to_bytes

source ·
pub async fn to_bytes<B: MessageBody>(body: B) -> Result<Bytes, B::Error>
Expand description

Collects all the bytes produced by body.

+

Any errors produced by the body stream are returned immediately.

+

Consider using to_bytes_limited instead to protect against memory exhaustion.

+

§Examples

+
use actix_http::body::{self, to_bytes};
+use bytes::Bytes;
+
+let body = body::None::new();
+let bytes = to_bytes(body).await.unwrap();
+assert!(bytes.is_empty());
+
+let body = Bytes::from_static(b"123");
+let bytes = to_bytes(body).await.unwrap();
+assert_eq!(bytes, "123");
+
\ No newline at end of file diff --git a/actix_http/body/fn.to_bytes_limited.html b/actix_http/body/fn.to_bytes_limited.html new file mode 100644 index 000000000..1d9d80de9 --- /dev/null +++ b/actix_http/body/fn.to_bytes_limited.html @@ -0,0 +1,22 @@ +to_bytes_limited in actix_http::body - Rust

Function actix_http::body::to_bytes_limited

source ·
pub async fn to_bytes_limited<B: MessageBody>(
+    body: B,
+    limit: usize
+) -> Result<Result<Bytes, B::Error>, BodyLimitExceeded>
Expand description

Collects the bytes produced by body, up to limit bytes.

+

If a chunk read from poll_next causes the total number of bytes read to exceed limit, an +Err(BodyLimitExceeded) is returned.

+

Any errors produced by the body stream are returned immediately as Ok(Err(B::Error)).

+

§Examples

+
use actix_http::body::{self, to_bytes_limited};
+use bytes::Bytes;
+
+let body = body::None::new();
+let bytes = to_bytes_limited(body, 10).await.unwrap().unwrap();
+assert!(bytes.is_empty());
+
+let body = Bytes::from_static(b"123");
+let bytes = to_bytes_limited(body, 10).await.unwrap().unwrap();
+assert_eq!(bytes, "123");
+
+let body = Bytes::from_static(b"123");
+assert!(to_bytes_limited(body, 2).await.is_err());
+
\ No newline at end of file diff --git a/actix_http/body/index.html b/actix_http/body/index.html new file mode 100644 index 000000000..97d2aaaae --- /dev/null +++ b/actix_http/body/index.html @@ -0,0 +1,3 @@ +actix_http::body - Rust

Module actix_http::body

source ·
Expand description

Traits and structures to aid consuming and writing HTTP payloads.

+

“Body” and “payload” are used somewhat interchangeably in this documentation.

+

Structs§

Enums§

Traits§

  • An interface for types that can be used as a response body.

Functions§

\ No newline at end of file diff --git a/actix_http/body/message_body/trait.MessageBody.html b/actix_http/body/message_body/trait.MessageBody.html new file mode 100644 index 000000000..479ecec28 --- /dev/null +++ b/actix_http/body/message_body/trait.MessageBody.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/body/trait.MessageBody.html...

+ + + \ No newline at end of file diff --git a/actix_http/body/none/struct.None.html b/actix_http/body/none/struct.None.html new file mode 100644 index 000000000..ac34e8492 --- /dev/null +++ b/actix_http/body/none/struct.None.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/body/struct.None.html...

+ + + \ No newline at end of file diff --git a/actix_http/body/sidebar-items.js b/actix_http/body/sidebar-items.js new file mode 100644 index 000000000..02571f400 --- /dev/null +++ b/actix_http/body/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["BodySize","EitherBody"],"fn":["to_bytes","to_bytes_limited"],"struct":["BodyLimitExceeded","BodyStream","BoxBody","None","SizedStream"],"trait":["MessageBody"]}; \ No newline at end of file diff --git a/actix_http/body/size/enum.BodySize.html b/actix_http/body/size/enum.BodySize.html new file mode 100644 index 000000000..f0405a630 --- /dev/null +++ b/actix_http/body/size/enum.BodySize.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/body/enum.BodySize.html...

+ + + \ No newline at end of file diff --git a/actix_http/body/sized_stream/struct.SizedStream.html b/actix_http/body/sized_stream/struct.SizedStream.html new file mode 100644 index 000000000..b11384612 --- /dev/null +++ b/actix_http/body/sized_stream/struct.SizedStream.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/body/struct.SizedStream.html...

+ + + \ No newline at end of file diff --git a/actix_http/body/struct.BodyLimitExceeded.html b/actix_http/body/struct.BodyLimitExceeded.html new file mode 100644 index 000000000..e1e81284a --- /dev/null +++ b/actix_http/body/struct.BodyLimitExceeded.html @@ -0,0 +1,19 @@ +BodyLimitExceeded in actix_http::body - Rust

Struct actix_http::body::BodyLimitExceeded

source ·
#[non_exhaustive]
pub struct BodyLimitExceeded;
Expand description

Error type returned from to_bytes_limited when body produced exceeds limit.

+

Trait Implementations§

source§

impl Debug for BodyLimitExceeded

source§

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

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

impl Display for BodyLimitExceeded

source§

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

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

impl Error for BodyLimitExceeded

1.30.0 · source§

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

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

fn description(&self) -> &str

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

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

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

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

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

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

source§

default fn to_string(&self) -> String

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

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/body/struct.BodyStream.html b/actix_http/body/struct.BodyStream.html new file mode 100644 index 000000000..9109f26b0 --- /dev/null +++ b/actix_http/body/struct.BodyStream.html @@ -0,0 +1,37 @@ +BodyStream in actix_http::body - Rust

Struct actix_http::body::BodyStream

source ·
pub struct BodyStream<S> { /* private fields */ }
Expand description

Streaming response wrapper.

+

Response does not contain Content-Length header and appropriate transfer encoding is used.

+

Implementations§

source§

impl<S, E> BodyStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn StdError>> + 'static,

source

pub fn new(stream: S) -> Self

Trait Implementations§

source§

impl<S, E> MessageBody for BodyStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn StdError>> + 'static,

source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

Attempts to pull out the next value of the underlying [Stream].

+

Empty values are skipped to prevent BodyStream’s transmission being ended on a +zero-length chunk, but rather proceed until the underlying [Stream] ends.

+
§

type Error = E

The type of error that will be returned if streaming body fails. Read more
source§

fn size(&self) -> BodySize

Body size hint. Read more
source§

fn try_into_bytes(self) -> Result<Bytes, Self>
where + Self: Sized,

Try to convert into the complete chunk of body bytes. Read more
source§

fn boxed(self) -> BoxBody
where + Self: Sized + 'static,

Wraps this body into a BoxBody. Read more
source§

impl<'__pin, S> Unpin for BodyStream<S>
where + __Origin<'__pin, S>: Unpin,

Auto Trait Implementations§

§

impl<S> Freeze for BodyStream<S>
where + S: Freeze,

§

impl<S> RefUnwindSafe for BodyStream<S>
where + S: RefUnwindSafe,

§

impl<S> Send for BodyStream<S>
where + S: Send,

§

impl<S> Sync for BodyStream<S>
where + S: Sync,

§

impl<S> UnwindSafe for BodyStream<S>
where + S: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/body/struct.BoxBody.html b/actix_http/body/struct.BoxBody.html new file mode 100644 index 000000000..8a6894ba6 --- /dev/null +++ b/actix_http/body/struct.BoxBody.html @@ -0,0 +1,26 @@ +BoxBody in actix_http::body - Rust

Struct actix_http::body::BoxBody

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

A boxed message body with boxed errors.

+

Implementations§

source§

impl BoxBody

source

pub fn new<B>(body: B) -> Self
where + B: MessageBody + 'static,

Boxes body type, erasing type information.

+

If the body type to wrap is unknown or generic it is better to use MessageBody::boxed to +avoid double boxing.

+
source

pub fn as_pin_mut(&mut self) -> Pin<&mut Self>

Returns a mutable pinned reference to the inner message body type.

+

Trait Implementations§

source§

impl Debug for BoxBody

source§

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

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

impl MessageBody for BoxBody

§

type Error = Box<dyn Error>

The type of error that will be returned if streaming body fails. Read more
source§

fn size(&self) -> BodySize

Body size hint. Read more
source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

Attempt to pull out the next chunk of body bytes. Read more
source§

fn try_into_bytes(self) -> Result<Bytes, Self>

Try to convert into the complete chunk of body bytes. Read more
source§

fn boxed(self) -> BoxBody

Wraps this body into a BoxBody. Read more

Auto Trait Implementations§

§

impl !Freeze for BoxBody

§

impl !RefUnwindSafe for BoxBody

§

impl !Send for BoxBody

§

impl !Sync for BoxBody

§

impl Unpin for BoxBody

§

impl !UnwindSafe for BoxBody

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/body/struct.None.html b/actix_http/body/struct.None.html new file mode 100644 index 000000000..9b7c3f0cf --- /dev/null +++ b/actix_http/body/struct.None.html @@ -0,0 +1,29 @@ +None in actix_http::body - Rust

Struct actix_http::body::None

source ·
#[non_exhaustive]
pub struct None;
Expand description

Body type for responses that forbid payloads.

+

This is distinct from an “empty” response which would contain a Content-Length header. +For an “empty” body, use () or Bytes::new().

+

For example, the HTTP spec forbids a payload to be sent with a 204 No Content response. +In this case, the payload (or lack thereof) is implicit from the status code, so a +Content-Length header is not required.

+

Implementations§

source§

impl None

source

pub fn new() -> Self

Constructs new “none” body.

+

Trait Implementations§

source§

impl Clone for None

source§

fn clone(&self) -> None

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

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

Performs copy-assignment from source. Read more
source§

impl Debug for None

source§

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

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

impl Default for None

source§

fn default() -> None

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

impl MessageBody for None

§

type Error = Infallible

The type of error that will be returned if streaming body fails. Read more
source§

fn size(&self) -> BodySize

Body size hint. Read more
source§

fn poll_next( + self: Pin<&mut Self>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

Attempt to pull out the next chunk of body bytes. Read more
source§

fn try_into_bytes(self) -> Result<Bytes, Self>

Try to convert into the complete chunk of body bytes. Read more
source§

fn boxed(self) -> BoxBody
where + Self: Sized + 'static,

Wraps this body into a BoxBody. Read more
source§

impl Copy for None

Auto Trait Implementations§

§

impl Freeze for None

§

impl RefUnwindSafe for None

§

impl Send for None

§

impl Sync for None

§

impl Unpin for None

§

impl UnwindSafe for None

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

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

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

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/body/struct.SizedStream.html b/actix_http/body/struct.SizedStream.html new file mode 100644 index 000000000..f8319f069 --- /dev/null +++ b/actix_http/body/struct.SizedStream.html @@ -0,0 +1,39 @@ +SizedStream in actix_http::body - Rust

Struct actix_http::body::SizedStream

source ·
pub struct SizedStream<S> { /* private fields */ }
Expand description

Known sized streaming response wrapper.

+

This body implementation should be used if total size of stream is known. Data is sent as-is +without using chunked transfer encoding.

+

Implementations§

source§

impl<S, E> SizedStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn StdError>> + 'static,

source

pub fn new(size: u64, stream: S) -> Self

Trait Implementations§

source§

impl<S, E> MessageBody for SizedStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn StdError>> + 'static,

source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

Attempts to pull out the next value of the underlying [Stream].

+

Empty values are skipped to prevent SizedStream’s transmission being +ended on a zero-length chunk, but rather proceed until the underlying +[Stream] ends.

+
§

type Error = E

The type of error that will be returned if streaming body fails. Read more
source§

fn size(&self) -> BodySize

Body size hint. Read more
source§

fn try_into_bytes(self) -> Result<Bytes, Self>
where + Self: Sized,

Try to convert into the complete chunk of body bytes. Read more
source§

fn boxed(self) -> BoxBody
where + Self: Sized + 'static,

Wraps this body into a BoxBody. Read more
source§

impl<'__pin, S> Unpin for SizedStream<S>
where + __Origin<'__pin, S>: Unpin,

Auto Trait Implementations§

§

impl<S> Freeze for SizedStream<S>
where + S: Freeze,

§

impl<S> RefUnwindSafe for SizedStream<S>
where + S: RefUnwindSafe,

§

impl<S> Send for SizedStream<S>
where + S: Send,

§

impl<S> Sync for SizedStream<S>
where + S: Sync,

§

impl<S> UnwindSafe for SizedStream<S>
where + S: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/body/trait.MessageBody.html b/actix_http/body/trait.MessageBody.html new file mode 100644 index 000000000..e43a0fcea --- /dev/null +++ b/actix_http/body/trait.MessageBody.html @@ -0,0 +1,139 @@ +MessageBody in actix_http::body - Rust

Trait actix_http::body::MessageBody

source ·
pub trait MessageBody {
+    type Error: Into<Box<dyn StdError>>;
+
+    // Required methods
+    fn size(&self) -> BodySize;
+    fn poll_next(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>
+    ) -> Poll<Option<Result<Bytes, Self::Error>>>;
+
+    // Provided methods
+    fn try_into_bytes(self) -> Result<Bytes, Self>
+       where Self: Sized { ... }
+    fn boxed(self) -> BoxBody
+       where Self: Sized + 'static { ... }
+}
Expand description

An interface for types that can be used as a response body.

+

It is not usually necessary to create custom body types, this trait is already implemented for +a large number of sensible body types including:

+ +

§Examples

+
struct Repeat {
+    chunk: String,
+    n_times: usize,
+}
+
+impl MessageBody for Repeat {
+    type Error = Infallible;
+
+    fn size(&self) -> BodySize {
+        BodySize::Sized((self.chunk.len() * self.n_times) as u64)
+    }
+
+    fn poll_next(
+        self: Pin<&mut Self>,
+        _cx: &mut Context<'_>,
+    ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+        let payload_string = self.chunk.repeat(self.n_times);
+        let payload_bytes = Bytes::from(payload_string);
+        Poll::Ready(Some(Ok(payload_bytes)))
+    }
+}
+

Required Associated Types§

source

type Error: Into<Box<dyn StdError>>

The type of error that will be returned if streaming body fails.

+

Since it is not appropriate to generate a response mid-stream, it only requires Error for +internal use and logging.

+

Required Methods§

source

fn size(&self) -> BodySize

Body size hint.

+

If BodySize::None is returned, optimizations that skip reading the body are allowed.

+
source

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

Attempt to pull out the next chunk of body bytes.

+
§Return Value
+

Similar to the Stream interface, there are several possible return values, each indicating +a distinct state:

+
    +
  • Poll::Pending means that this body’s next chunk is not ready yet. Implementations must +ensure that the current task will be notified when the next chunk may be ready.
  • +
  • Poll::Ready(Some(val)) means that the body has successfully produced a chunk, val, +and may produce further values on subsequent poll_next calls.
  • +
  • Poll::Ready(None) means that the body is complete, and poll_next should not be +invoked again.
  • +
+
§Panics
+

Once a body is complete (i.e., poll_next returned Ready(None)), calling its poll_next +method again may panic, block forever, or cause other kinds of problems; this trait places +no requirements on the effects of such a call. However, as the poll_next method is not +marked unsafe, Rust’s usual rules apply: calls must never cause UB, regardless of its state.

+

Provided Methods§

source

fn try_into_bytes(self) -> Result<Bytes, Self>
where + Self: Sized,

Try to convert into the complete chunk of body bytes.

+

Override this method if the complete body can be trivially extracted. This is useful for +optimizations where poll_next calls can be avoided.

+

Body types with BodySize::None are allowed to return empty Bytes. Although, if calling +this method, it is recommended to check size first and return early.

+
§Errors
+

The default implementation will error and return the original type back to the caller for +further use.

+
source

fn boxed(self) -> BoxBody
where + Self: Sized + 'static,

Wraps this body into a BoxBody.

+

No-op when called on a BoxBody, meaning there is no risk of double boxing when calling +this on a generic MessageBody. Prefer this over BoxBody::new when a boxed body +is required.

+

Implementations on Foreign Types§

source§

impl MessageBody for &'static str

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Self>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

source§

fn try_into_bytes(self) -> Result<Bytes, Self>

source§

impl MessageBody for &'static [u8]

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Self>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

source§

fn try_into_bytes(self) -> Result<Bytes, Self>

source§

impl MessageBody for Cow<'static, str>

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Self>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

source§

fn try_into_bytes(self) -> Result<Bytes, Self>

source§

impl MessageBody for Cow<'static, [u8]>

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Self>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

source§

fn try_into_bytes(self) -> Result<Bytes, Self>

source§

impl MessageBody for Infallible

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Self>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

source§

impl MessageBody for ()

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Self>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

source§

fn try_into_bytes(self) -> Result<Bytes, Self>

source§

impl MessageBody for String

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Self>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

source§

fn try_into_bytes(self) -> Result<Bytes, Self>

source§

impl MessageBody for Vec<u8>

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Self>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

source§

fn try_into_bytes(self) -> Result<Bytes, Self>

source§

impl MessageBody for ByteString

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Self>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

source§

fn try_into_bytes(self) -> Result<Bytes, Self>

source§

impl MessageBody for Bytes

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Self>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

source§

fn try_into_bytes(self) -> Result<Bytes, Self>

source§

impl MessageBody for BytesMut

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Self>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

source§

fn try_into_bytes(self) -> Result<Bytes, Self>

source§

impl<B> MessageBody for &mut B
where + B: MessageBody + Unpin + ?Sized,

§

type Error = <B as MessageBody>::Error

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

source§

impl<B> MessageBody for Box<B>
where + B: MessageBody + Unpin + ?Sized,

§

type Error = <B as MessageBody>::Error

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

source§

impl<T, B> MessageBody for Pin<T>
where + T: DerefMut<Target = B> + Unpin, + B: MessageBody + ?Sized,

§

type Error = <B as MessageBody>::Error

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

Implementors§

source§

impl MessageBody for BoxBody

§

type Error = Box<dyn Error>

source§

impl MessageBody for None

source§

impl<B> MessageBody for Encoder<B>
where + B: MessageBody,

Available on crate feature __compress only.
§

type Error = EncoderError

source§

impl<L, R> MessageBody for EitherBody<L, R>
where + L: MessageBody + 'static, + R: MessageBody + 'static,

§

type Error = Error

source§

impl<S, E> MessageBody for BodyStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn StdError>> + 'static,

§

type Error = E

source§

impl<S, E> MessageBody for SizedStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn StdError>> + 'static,

§

type Error = E

\ No newline at end of file diff --git a/actix_http/body/utils/fn.to_bytes.html b/actix_http/body/utils/fn.to_bytes.html new file mode 100644 index 000000000..eb969e67b --- /dev/null +++ b/actix_http/body/utils/fn.to_bytes.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/body/fn.to_bytes.html...

+ + + \ No newline at end of file diff --git a/actix_http/body/utils/fn.to_bytes_limited.html b/actix_http/body/utils/fn.to_bytes_limited.html new file mode 100644 index 000000000..c6548a824 --- /dev/null +++ b/actix_http/body/utils/fn.to_bytes_limited.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/body/fn.to_bytes_limited.html...

+ + + \ No newline at end of file diff --git a/actix_http/body/utils/struct.BodyLimitExceeded.html b/actix_http/body/utils/struct.BodyLimitExceeded.html new file mode 100644 index 000000000..09bf7f273 --- /dev/null +++ b/actix_http/body/utils/struct.BodyLimitExceeded.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/body/struct.BodyLimitExceeded.html...

+ + + \ No newline at end of file diff --git a/actix_http/builder/struct.HttpServiceBuilder.html b/actix_http/builder/struct.HttpServiceBuilder.html new file mode 100644 index 000000000..abff93e92 --- /dev/null +++ b/actix_http/builder/struct.HttpServiceBuilder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_http/struct.HttpServiceBuilder.html...

+ + + \ No newline at end of file diff --git a/actix_http/config/struct.ServiceConfig.html b/actix_http/config/struct.ServiceConfig.html new file mode 100644 index 000000000..fe9407838 --- /dev/null +++ b/actix_http/config/struct.ServiceConfig.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_http/struct.ServiceConfig.html...

+ + + \ No newline at end of file diff --git a/actix_http/encoding/decoder/struct.Decoder.html b/actix_http/encoding/decoder/struct.Decoder.html new file mode 100644 index 000000000..02e3deb3a --- /dev/null +++ b/actix_http/encoding/decoder/struct.Decoder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/encoding/struct.Decoder.html...

+ + + \ No newline at end of file diff --git a/actix_http/encoding/encoder/struct.Encoder.html b/actix_http/encoding/encoder/struct.Encoder.html new file mode 100644 index 000000000..da23d4a03 --- /dev/null +++ b/actix_http/encoding/encoder/struct.Encoder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/encoding/struct.Encoder.html...

+ + + \ No newline at end of file diff --git a/actix_http/encoding/index.html b/actix_http/encoding/index.html new file mode 100644 index 000000000..534c260fb --- /dev/null +++ b/actix_http/encoding/index.html @@ -0,0 +1,2 @@ +actix_http::encoding - Rust

Module actix_http::encoding

source ·
Available on crate feature __compress only.
Expand description

Content-Encoding support.

+

Structs§

\ No newline at end of file diff --git a/actix_http/encoding/sidebar-items.js b/actix_http/encoding/sidebar-items.js new file mode 100644 index 000000000..9e35cb693 --- /dev/null +++ b/actix_http/encoding/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Decoder","Encoder"]}; \ No newline at end of file diff --git a/actix_http/encoding/struct.Decoder.html b/actix_http/encoding/struct.Decoder.html new file mode 100644 index 000000000..67a424b65 --- /dev/null +++ b/actix_http/encoding/struct.Decoder.html @@ -0,0 +1,260 @@ +Decoder in actix_http::encoding - Rust

Struct actix_http::encoding::Decoder

source ·
pub struct Decoder<S> { /* private fields */ }
Available on crate feature __compress only.

Implementations§

source§

impl<S> Decoder<S>
where + S: Stream<Item = Result<Bytes, PayloadError>>,

source

pub fn new(stream: S, encoding: ContentEncoding) -> Decoder<S>

Construct a decoder.

+
source

pub fn from_headers(stream: S, headers: &HeaderMap) -> Decoder<S>

Construct decoder based on headers.

+

Trait Implementations§

source§

impl<S> Stream for Decoder<S>
where + S: Stream<Item = Result<Bytes, PayloadError>>,

§

type Item = Result<Bytes, PayloadError>

Values yielded by the stream.
source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Self::Item>>

Attempt to pull out the next value of this stream, registering the +current task for wakeup if the value is not yet available, and returning +None if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more
source§

impl<'__pin, S> Unpin for Decoder<S>
where + __Origin<'__pin, S>: Unpin,

Auto Trait Implementations§

§

impl<S> Freeze for Decoder<S>
where + S: Freeze,

§

impl<S> !RefUnwindSafe for Decoder<S>

§

impl<S> Send for Decoder<S>
where + S: Send,

§

impl<S> Sync for Decoder<S>
where + S: Sync,

§

impl<S> !UnwindSafe for Decoder<S>

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<T> StreamExt for T
where + T: Stream + ?Sized,

§

fn next(&mut self) -> Next<'_, Self>
where + Self: Unpin,

Creates a future that resolves to the next item in the stream. Read more
§

fn into_future(self) -> StreamFuture<Self>
where + Self: Sized + Unpin,

Converts this stream into a future of (next_item, tail_of_stream). +If the stream terminates, then the next item is None. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + F: FnMut(Self::Item) -> T, + Self: Sized,

Maps this stream’s items to a different type, returning a new stream of +the resulting type. Read more
§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates a stream which gives the current iteration count as well as +the next value. Read more
§

fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Filters the values produced by this stream according to the provided +asynchronous predicate. Read more
§

fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = Option<T>>, + Self: Sized,

Filters the values produced by this stream while simultaneously mapping +them to a different type according to the provided asynchronous closure. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized,

Computes from this stream’s items new items of a different type using +an asynchronous closure. Read more
§

fn collect<C>(self) -> Collect<Self, C>
where + C: Default + Extend<Self::Item>, + Self: Sized,

Transforms a stream into a collection, returning a +future representing the result of that computation. Read more
§

fn unzip<A, B, FromA, FromB>(self) -> Unzip<Self, FromA, FromB>
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Stream<Item = (A, B)>,

Converts a stream of pairs into a future, which +resolves to pair of containers. Read more
§

fn concat(self) -> Concat<Self>
where + Self: Sized, + Self::Item: Extend<<Self::Item as IntoIterator>::Item> + IntoIterator + Default,

Concatenate all items of a stream into a single extendable +destination, returning a future representing the end result. Read more
§

fn count(self) -> Count<Self>
where + Self: Sized,

Drives the stream to completion, counting the number of items. Read more
§

fn cycle(self) -> Cycle<Self>
where + Self: Sized + Clone,

Repeats a stream endlessly. Read more
§

fn fold<T, Fut, F>(self, init: T, f: F) -> Fold<Self, Fut, T, F>
where + F: FnMut(T, Self::Item) -> Fut, + Fut: Future<Output = T>, + Self: Sized,

Execute an accumulating asynchronous computation over a stream, +collecting all the values into one final result. Read more
§

fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if any element in stream satisfied a predicate. Read more
§

fn all<Fut, F>(self, f: F) -> All<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if all element in stream satisfied a predicate. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Item: Stream, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> FlattenUnorderedWithFlowController<Self, ()>
where + Self::Item: Stream + Unpin, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Polls +inner streams produced by the base stream concurrently. Read more
§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + F: FnMut(Self::Item) -> U, + U: Stream, + Self: Sized,

Maps a stream like [StreamExt::map] but flattens nested Streams. Read more
§

fn flat_map_unordered<U, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> FlatMapUnordered<Self, U, F>
where + U: Stream + Unpin, + F: FnMut(Self::Item) -> U, + Self: Sized,

Available on crate feature alloc only.
Maps a stream like [StreamExt::map] but flattens nested Streams +and polls them concurrently, yielding items in any order, as they made +available. Read more
§

fn scan<S, B, Fut, F>(self, initial_state: S, f: F) -> Scan<Self, S, Fut, F>
where + F: FnMut(&mut S, Self::Item) -> Fut, + Fut: Future<Output = Option<B>>, + Self: Sized,

Combinator similar to [StreamExt::fold] that holds internal state +and produces a new stream. Read more
§

fn skip_while<Fut, F>(self, f: F) -> SkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_while<Fut, F>(self, f: F) -> TakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Take elements from this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_until<Fut>(self, fut: Fut) -> TakeUntil<Self, Fut>
where + Fut: Future, + Self: Sized,

Take elements from this stream until the provided future resolves. Read more
§

fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream. Read more
§

fn for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> ForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Available on crate feature alloc only.
Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates a new stream of at most n items of the underlying stream. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates a new stream which skips n items of the underlying stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a stream such that poll_next will never +again be called once it has finished. This method can be used to turn +any Stream into a FusedStream. Read more
§

fn by_ref(&mut self) -> &mut Self

Borrows a stream, rather than consuming it. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the stream. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn buffered(self, n: usize) -> Buffered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures. Read more
§

fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures (unordered). Read more
§

fn zip<St>(self, other: St) -> Zip<Self, St>
where + St: Stream, + Self: Sized,

An adapter for zipping two streams together. Read more
§

fn chain<St>(self, other: St) -> Chain<Self, St>
where + St: Stream<Item = Self::Item>, + Self: Sized,

Adapter for chaining two streams. Read more
§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates a new stream which exposes a peek method. Read more
§

fn chunks(self, capacity: usize) -> Chunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up items of the stream inside a vector. Read more
§

fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up ready items of the stream inside a vector. Read more
§

fn forward<S>(self, sink: S) -> Forward<Self, S>
where + S: Sink<Self::Ok, Error = Self::Error>, + Self: Sized + TryStream,

Available on crate feature sink only.
A future that completes after the given stream has been fully processed +into the sink and the sink has been flushed and closed. Read more
§

fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
where + Self: Sized + Sink<Item>,

Available on crate features sink and alloc only.
Splits this Stream + Sink object into separate Sink and Stream +objects. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnMut(&Self::Item), + Self: Sized,

Do something with each item of this stream, afterwards passing it on. Read more
§

fn left_stream<B>(self) -> Either<Self, B>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the left-hand variant +of that Either. Read more
§

fn right_stream<B>(self) -> Either<B, Self>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the right-hand variant +of that Either. Read more
§

fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>
where + Self: Unpin,

A convenience method for calling [Stream::poll_next] on Unpin +stream types.
§

fn select_next_some(&mut self) -> SelectNextSome<'_, Self>
where + Self: Unpin + FusedStream,

Returns a Future that resolves when the next item in this stream is +ready. Read more
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

impl<S, T, E> TryStream for S
where + S: Stream<Item = 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
§

fn try_poll_next( + self: Pin<&mut S>, + cx: &mut Context<'_> +) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>>

Poll this TryStream as if it were a Stream. Read more
§

impl<S> TryStreamExt for S
where + S: TryStream + ?Sized,

§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Wraps the current stream in a new stream which converts the error type +into the one provided. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> T,

Wraps the current stream in a new stream which maps the success value +using the provided closure. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + Self: Sized, + F: FnMut(Self::Error) -> E,

Wraps the current stream in a new stream which maps the error value +using the provided closure. Read more
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Chain on a computation for when a value is ready, passing the successful +results to the provided closure f. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnMut(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Chain on a computation for when an error happens, passing the +erroneous result to the provided closure f. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnMut(&Self::Ok), + Self: Sized,

Do something with the success value of this stream, afterwards passing +it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnMut(&Self::Error), + Self: Sized,

Do something with the error value of this stream, afterwards passing it on. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Wraps a [TryStream] into a type that implements +Stream Read more
§

fn try_next(&mut self) -> TryNext<'_, Self>
where + Self: Unpin,

Creates a future that attempts to resolve the next item in the stream. +If an error is encountered before the next item, the error is returned +instead. Read more
§

fn try_for_each<Fut, F>(self, f: F) -> TryForEach<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Ok = (), Error = Self::Error>, + Self: Sized,

Attempts to run this stream to completion, executing the provided +asynchronous closure for each element on the stream. Read more
§

fn try_skip_while<Fut, F>(self, f: F) -> TrySkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_take_while<Fut, F>(self, f: F) -> TryTakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Take elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> TryForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = Result<(), Self::Error>>, + Self: Sized,

Available on crate feature alloc only.
Attempts to run this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available, exiting as soon as an error occurs. Read more
§

fn try_collect<C>(self) -> TryCollect<Self, C>
where + C: Default + Extend<Self::Ok>, + Self: Sized,

Attempt to transform a stream into a collection, +returning a future representing the result of that computation. Read more
§

fn try_chunks(self, capacity: usize) -> TryChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful items of the stream inside a vector. Read more
§

fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful, ready items of the stream inside a vector. Read more
§

fn try_filter<Fut, F>(self, f: F) -> TryFilter<Self, Fut, F>
where + Fut: Future<Output = bool>, + F: FnMut(&Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream according to the +provided asynchronous closure. Read more
§

fn try_filter_map<Fut, F, T>(self, f: F) -> TryFilterMap<Self, Fut, F>
where + Fut: TryFuture<Ok = Option<T>, Error = Self::Error>, + F: FnMut(Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream while +simultaneously mapping them to a different type according to the +provided asynchronous closure. Read more
§

fn try_flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> TryFlattenUnordered<Self>
where + Self::Ok: TryStream + Unpin, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Produced streams +will be polled concurrently and any errors will be passed through without looking at them. +If the underlying base stream returns an error, it will be immediately propagated. Read more
§

fn try_flatten(self) -> TryFlatten<Self>
where + Self::Ok: TryStream, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn try_fold<T, Fut, F>(self, init: T, f: F) -> TryFold<Self, Fut, T, F>
where + F: FnMut(T, Self::Ok) -> Fut, + Fut: TryFuture<Ok = T, Error = Self::Error>, + Self: Sized,

Attempt to execute an accumulating asynchronous computation over a +stream, collecting all the values into one final result. Read more
§

fn try_concat(self) -> TryConcat<Self>
where + Self: Sized, + Self::Ok: Extend<<Self::Ok as IntoIterator>::Item> + IntoIterator + Default,

Attempt to concatenate all items of a stream into a single +extendable destination, returning a future representing the end result. Read more
§

fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently (unordered). Read more
§

fn try_buffered(self, n: usize) -> TryBuffered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently. Read more
§

fn try_poll_next_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Option<Result<Self::Ok, Self::Error>>>
where + Self: Unpin,

A convenience method for calling [TryStream::try_poll_next] on Unpin +stream types.
§

fn try_all<Fut, F>(self, f: F) -> TryAll<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if all items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that does not satisfy the predicate. Read more
§

fn try_any<Fut, F>(self, f: F) -> TryAny<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if any items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that satisfies the predicate. Read more
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/encoding/struct.Encoder.html b/actix_http/encoding/struct.Encoder.html new file mode 100644 index 000000000..b8cb00db0 --- /dev/null +++ b/actix_http/encoding/struct.Encoder.html @@ -0,0 +1,30 @@ +Encoder in actix_http::encoding - Rust

Struct actix_http::encoding::Encoder

source ·
pub struct Encoder<B> { /* private fields */ }
Available on crate feature __compress only.

Implementations§

source§

impl<B: MessageBody> Encoder<B>

source

pub fn response( + encoding: ContentEncoding, + head: &mut ResponseHead, + body: B +) -> Self

Trait Implementations§

source§

impl<B> MessageBody for Encoder<B>
where + B: MessageBody,

§

type Error = EncoderError

The type of error that will be returned if streaming body fails. Read more
source§

fn size(&self) -> BodySize

Body size hint. Read more
source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

Attempt to pull out the next chunk of body bytes. Read more
source§

fn try_into_bytes(self) -> Result<Bytes, Self>
where + Self: Sized,

Try to convert into the complete chunk of body bytes. Read more
source§

fn boxed(self) -> BoxBody
where + Self: Sized + 'static,

Wraps this body into a BoxBody. Read more
source§

impl<'__pin, B> Unpin for Encoder<B>
where + __Origin<'__pin, B>: Unpin,

Auto Trait Implementations§

§

impl<B> !Freeze for Encoder<B>

§

impl<B> !RefUnwindSafe for Encoder<B>

§

impl<B> Send for Encoder<B>
where + B: Send,

§

impl<B> Sync for Encoder<B>
where + B: Sync,

§

impl<B> !UnwindSafe for Encoder<B>

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/enum.ConnectionType.html b/actix_http/enum.ConnectionType.html new file mode 100644 index 000000000..911b9e82b --- /dev/null +++ b/actix_http/enum.ConnectionType.html @@ -0,0 +1,32 @@ +ConnectionType in actix_http - Rust

Enum actix_http::ConnectionType

source ·
pub enum ConnectionType {
+    Close,
+    KeepAlive,
+    Upgrade,
+}
Expand description

Represents various types of connection

+

Variants§

§

Close

Close connection after response.

+
§

KeepAlive

Keep connection alive after response.

+
§

Upgrade

Connection is upgraded to different type.

+

Trait Implementations§

source§

impl Clone for ConnectionType

source§

fn clone(&self) -> ConnectionType

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

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

Performs copy-assignment from source. Read more
source§

impl Debug for ConnectionType

source§

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

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

impl PartialEq for ConnectionType

source§

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

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

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

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

impl Copy for ConnectionType

source§

impl Eq for ConnectionType

source§

impl StructuralPartialEq for ConnectionType

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
§

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

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

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

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

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

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

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/enum.KeepAlive.html b/actix_http/enum.KeepAlive.html new file mode 100644 index 000000000..ce49f0d58 --- /dev/null +++ b/actix_http/enum.KeepAlive.html @@ -0,0 +1,35 @@ +KeepAlive in actix_http - Rust

Enum actix_http::KeepAlive

source ·
pub enum KeepAlive {
+    Timeout(Duration),
+    Os,
+    Disabled,
+}
Expand description

Connection keep-alive config.

+

Variants§

§

Timeout(Duration)

Keep-alive duration.

+

KeepAlive::Timeout(Duration::ZERO) is mapped to KeepAlive::Disabled.

+
§

Os

Rely on OS to shutdown TCP connection.

+

Some defaults can be very long, check your OS documentation.

+
§

Disabled

Keep-alive is disabled.

+

Connections will be closed immediately.

+

Trait Implementations§

source§

impl Clone for KeepAlive

source§

fn clone(&self) -> KeepAlive

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

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

Performs copy-assignment from source. Read more
source§

impl Debug for KeepAlive

source§

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

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

impl Default for KeepAlive

source§

fn default() -> Self

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

impl From<Duration> for KeepAlive

source§

fn from(dur: Duration) -> Self

Converts to this type from the input type.
source§

impl From<Option<Duration>> for KeepAlive

source§

fn from(ka_dur: Option<Duration>) -> Self

Converts to this type from the input type.
source§

impl PartialEq for KeepAlive

source§

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

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

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

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

impl Copy for KeepAlive

source§

impl Eq for KeepAlive

source§

impl StructuralPartialEq for KeepAlive

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
§

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

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

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

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

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

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

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/enum.Payload.html b/actix_http/enum.Payload.html new file mode 100644 index 000000000..5c29a8514 --- /dev/null +++ b/actix_http/enum.Payload.html @@ -0,0 +1,268 @@ +Payload in actix_http - Rust

Enum actix_http::Payload

source ·
pub enum Payload<S = BoxedPayloadStream> {
+    None,
+    H1 {
+        payload: Payload,
+    },
+    H2 {
+        payload: Payload,
+    },
+    Stream {
+        payload: S,
+    },
+}
Expand description

A streaming payload.

+

Variants§

§

None

§

H1

Fields

§payload: Payload
§

H2

Fields

§payload: Payload
§

Stream

Fields

§payload: S

Implementations§

source§

impl<S> Payload<S>

source

pub fn take(&mut self) -> Payload<S>

Takes current payload and replaces it with None value

+

Trait Implementations§

source§

impl<S> From<Payload> for Payload<S>

Available on crate feature http2 only.
source§

fn from(payload: Payload) -> Self

Converts to this type from the input type.
source§

impl<S> From<Payload> for Payload<S>

source§

fn from(payload: Payload) -> Self

Converts to this type from the input type.
source§

impl From<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> for Payload

source§

fn from(payload: BoxedPayloadStream) -> Self

Converts to this type from the input type.
source§

impl<S> From<RecvStream> for Payload<S>

Available on crate feature http2 only.
source§

fn from(stream: RecvStream) -> Self

Converts to this type from the input type.
source§

impl<S> Stream for Payload<S>
where + S: Stream<Item = Result<Bytes, PayloadError>>,

§

type Item = Result<Bytes, PayloadError>

Values yielded by the stream.
source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Self::Item>>

Attempt to pull out the next value of this stream, registering the +current task for wakeup if the value is not yet available, and returning +None if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more
source§

impl<'__pin, S> Unpin for Payload<S>
where + __Origin<'__pin, S>: Unpin,

Auto Trait Implementations§

§

impl<S> Freeze for Payload<S>
where + S: Freeze,

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !RefUnwindSafe for Payload<S>

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Send for Payload<S>

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Sync for Payload<S>

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !UnwindSafe for Payload<S>

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<T> StreamExt for T
where + T: Stream + ?Sized,

§

fn next(&mut self) -> Next<'_, Self>
where + Self: Unpin,

Creates a future that resolves to the next item in the stream. Read more
§

fn into_future(self) -> StreamFuture<Self>
where + Self: Sized + Unpin,

Converts this stream into a future of (next_item, tail_of_stream). +If the stream terminates, then the next item is None. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + F: FnMut(Self::Item) -> T, + Self: Sized,

Maps this stream’s items to a different type, returning a new stream of +the resulting type. Read more
§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates a stream which gives the current iteration count as well as +the next value. Read more
§

fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Filters the values produced by this stream according to the provided +asynchronous predicate. Read more
§

fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = Option<T>>, + Self: Sized,

Filters the values produced by this stream while simultaneously mapping +them to a different type according to the provided asynchronous closure. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized,

Computes from this stream’s items new items of a different type using +an asynchronous closure. Read more
§

fn collect<C>(self) -> Collect<Self, C>
where + C: Default + Extend<Self::Item>, + Self: Sized,

Transforms a stream into a collection, returning a +future representing the result of that computation. Read more
§

fn unzip<A, B, FromA, FromB>(self) -> Unzip<Self, FromA, FromB>
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Stream<Item = (A, B)>,

Converts a stream of pairs into a future, which +resolves to pair of containers. Read more
§

fn concat(self) -> Concat<Self>
where + Self: Sized, + Self::Item: Extend<<Self::Item as IntoIterator>::Item> + IntoIterator + Default,

Concatenate all items of a stream into a single extendable +destination, returning a future representing the end result. Read more
§

fn count(self) -> Count<Self>
where + Self: Sized,

Drives the stream to completion, counting the number of items. Read more
§

fn cycle(self) -> Cycle<Self>
where + Self: Sized + Clone,

Repeats a stream endlessly. Read more
§

fn fold<T, Fut, F>(self, init: T, f: F) -> Fold<Self, Fut, T, F>
where + F: FnMut(T, Self::Item) -> Fut, + Fut: Future<Output = T>, + Self: Sized,

Execute an accumulating asynchronous computation over a stream, +collecting all the values into one final result. Read more
§

fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if any element in stream satisfied a predicate. Read more
§

fn all<Fut, F>(self, f: F) -> All<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if all element in stream satisfied a predicate. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Item: Stream, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> FlattenUnorderedWithFlowController<Self, ()>
where + Self::Item: Stream + Unpin, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Polls +inner streams produced by the base stream concurrently. Read more
§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + F: FnMut(Self::Item) -> U, + U: Stream, + Self: Sized,

Maps a stream like [StreamExt::map] but flattens nested Streams. Read more
§

fn flat_map_unordered<U, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> FlatMapUnordered<Self, U, F>
where + U: Stream + Unpin, + F: FnMut(Self::Item) -> U, + Self: Sized,

Available on crate feature alloc only.
Maps a stream like [StreamExt::map] but flattens nested Streams +and polls them concurrently, yielding items in any order, as they made +available. Read more
§

fn scan<S, B, Fut, F>(self, initial_state: S, f: F) -> Scan<Self, S, Fut, F>
where + F: FnMut(&mut S, Self::Item) -> Fut, + Fut: Future<Output = Option<B>>, + Self: Sized,

Combinator similar to [StreamExt::fold] that holds internal state +and produces a new stream. Read more
§

fn skip_while<Fut, F>(self, f: F) -> SkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_while<Fut, F>(self, f: F) -> TakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Take elements from this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_until<Fut>(self, fut: Fut) -> TakeUntil<Self, Fut>
where + Fut: Future, + Self: Sized,

Take elements from this stream until the provided future resolves. Read more
§

fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream. Read more
§

fn for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> ForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Available on crate feature alloc only.
Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates a new stream of at most n items of the underlying stream. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates a new stream which skips n items of the underlying stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a stream such that poll_next will never +again be called once it has finished. This method can be used to turn +any Stream into a FusedStream. Read more
§

fn by_ref(&mut self) -> &mut Self

Borrows a stream, rather than consuming it. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the stream. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn buffered(self, n: usize) -> Buffered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures. Read more
§

fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures (unordered). Read more
§

fn zip<St>(self, other: St) -> Zip<Self, St>
where + St: Stream, + Self: Sized,

An adapter for zipping two streams together. Read more
§

fn chain<St>(self, other: St) -> Chain<Self, St>
where + St: Stream<Item = Self::Item>, + Self: Sized,

Adapter for chaining two streams. Read more
§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates a new stream which exposes a peek method. Read more
§

fn chunks(self, capacity: usize) -> Chunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up items of the stream inside a vector. Read more
§

fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up ready items of the stream inside a vector. Read more
§

fn forward<S>(self, sink: S) -> Forward<Self, S>
where + S: Sink<Self::Ok, Error = Self::Error>, + Self: Sized + TryStream,

Available on crate feature sink only.
A future that completes after the given stream has been fully processed +into the sink and the sink has been flushed and closed. Read more
§

fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
where + Self: Sized + Sink<Item>,

Available on crate features sink and alloc only.
Splits this Stream + Sink object into separate Sink and Stream +objects. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnMut(&Self::Item), + Self: Sized,

Do something with each item of this stream, afterwards passing it on. Read more
§

fn left_stream<B>(self) -> Either<Self, B>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the left-hand variant +of that Either. Read more
§

fn right_stream<B>(self) -> Either<B, Self>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the right-hand variant +of that Either. Read more
§

fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>
where + Self: Unpin,

A convenience method for calling [Stream::poll_next] on Unpin +stream types.
§

fn select_next_some(&mut self) -> SelectNextSome<'_, Self>
where + Self: Unpin + FusedStream,

Returns a Future that resolves when the next item in this stream is +ready. Read more
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

impl<S, T, E> TryStream for S
where + S: Stream<Item = 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
§

fn try_poll_next( + self: Pin<&mut S>, + cx: &mut Context<'_> +) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>>

Poll this TryStream as if it were a Stream. Read more
§

impl<S> TryStreamExt for S
where + S: TryStream + ?Sized,

§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Wraps the current stream in a new stream which converts the error type +into the one provided. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> T,

Wraps the current stream in a new stream which maps the success value +using the provided closure. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + Self: Sized, + F: FnMut(Self::Error) -> E,

Wraps the current stream in a new stream which maps the error value +using the provided closure. Read more
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Chain on a computation for when a value is ready, passing the successful +results to the provided closure f. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnMut(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Chain on a computation for when an error happens, passing the +erroneous result to the provided closure f. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnMut(&Self::Ok), + Self: Sized,

Do something with the success value of this stream, afterwards passing +it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnMut(&Self::Error), + Self: Sized,

Do something with the error value of this stream, afterwards passing it on. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Wraps a [TryStream] into a type that implements +Stream Read more
§

fn try_next(&mut self) -> TryNext<'_, Self>
where + Self: Unpin,

Creates a future that attempts to resolve the next item in the stream. +If an error is encountered before the next item, the error is returned +instead. Read more
§

fn try_for_each<Fut, F>(self, f: F) -> TryForEach<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Ok = (), Error = Self::Error>, + Self: Sized,

Attempts to run this stream to completion, executing the provided +asynchronous closure for each element on the stream. Read more
§

fn try_skip_while<Fut, F>(self, f: F) -> TrySkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_take_while<Fut, F>(self, f: F) -> TryTakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Take elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> TryForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = Result<(), Self::Error>>, + Self: Sized,

Available on crate feature alloc only.
Attempts to run this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available, exiting as soon as an error occurs. Read more
§

fn try_collect<C>(self) -> TryCollect<Self, C>
where + C: Default + Extend<Self::Ok>, + Self: Sized,

Attempt to transform a stream into a collection, +returning a future representing the result of that computation. Read more
§

fn try_chunks(self, capacity: usize) -> TryChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful items of the stream inside a vector. Read more
§

fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful, ready items of the stream inside a vector. Read more
§

fn try_filter<Fut, F>(self, f: F) -> TryFilter<Self, Fut, F>
where + Fut: Future<Output = bool>, + F: FnMut(&Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream according to the +provided asynchronous closure. Read more
§

fn try_filter_map<Fut, F, T>(self, f: F) -> TryFilterMap<Self, Fut, F>
where + Fut: TryFuture<Ok = Option<T>, Error = Self::Error>, + F: FnMut(Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream while +simultaneously mapping them to a different type according to the +provided asynchronous closure. Read more
§

fn try_flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> TryFlattenUnordered<Self>
where + Self::Ok: TryStream + Unpin, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Produced streams +will be polled concurrently and any errors will be passed through without looking at them. +If the underlying base stream returns an error, it will be immediately propagated. Read more
§

fn try_flatten(self) -> TryFlatten<Self>
where + Self::Ok: TryStream, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn try_fold<T, Fut, F>(self, init: T, f: F) -> TryFold<Self, Fut, T, F>
where + F: FnMut(T, Self::Ok) -> Fut, + Fut: TryFuture<Ok = T, Error = Self::Error>, + Self: Sized,

Attempt to execute an accumulating asynchronous computation over a +stream, collecting all the values into one final result. Read more
§

fn try_concat(self) -> TryConcat<Self>
where + Self: Sized, + Self::Ok: Extend<<Self::Ok as IntoIterator>::Item> + IntoIterator + Default,

Attempt to concatenate all items of a stream into a single +extendable destination, returning a future representing the end result. Read more
§

fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently (unordered). Read more
§

fn try_buffered(self, n: usize) -> TryBuffered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently. Read more
§

fn try_poll_next_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Option<Result<Self::Ok, Self::Error>>>
where + Self: Unpin,

A convenience method for calling [TryStream::try_poll_next] on Unpin +stream types.
§

fn try_all<Fut, F>(self, f: F) -> TryAll<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if all items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that does not satisfy the predicate. Read more
§

fn try_any<Fut, F>(self, f: F) -> TryAny<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if any items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that satisfies the predicate. Read more
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/enum.Protocol.html b/actix_http/enum.Protocol.html new file mode 100644 index 000000000..55d8821a8 --- /dev/null +++ b/actix_http/enum.Protocol.html @@ -0,0 +1,31 @@ +Protocol in actix_http - Rust

Enum actix_http::Protocol

source ·
#[non_exhaustive]
pub enum Protocol { + Http1, + Http2, + Http3, +}
Expand description

A major HTTP protocol version.

+

Variants (Non-exhaustive)§

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

Http1

§

Http2

§

Http3

Trait Implementations§

source§

impl Clone for Protocol

source§

fn clone(&self) -> Protocol

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

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

Performs copy-assignment from source. Read more
source§

impl Debug for Protocol

source§

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

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

impl Hash for Protocol

source§

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

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

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

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

impl PartialEq for Protocol

source§

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

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

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

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

impl Copy for Protocol

source§

impl Eq for Protocol

source§

impl StructuralPartialEq for Protocol

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
§

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

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

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

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

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

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

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/enum.RequestHeadType.html b/actix_http/enum.RequestHeadType.html new file mode 100644 index 000000000..01a87b005 --- /dev/null +++ b/actix_http/enum.RequestHeadType.html @@ -0,0 +1,20 @@ +RequestHeadType in actix_http - Rust

Enum actix_http::RequestHeadType

source ·
pub enum RequestHeadType {
+    Owned(RequestHead),
+    Rc(Rc<RequestHead>, Option<HeaderMap>),
+}

Variants§

Implementations§

Trait Implementations§

source§

impl AsRef<RequestHead> for RequestHeadType

source§

fn as_ref(&self) -> &RequestHead

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

impl Debug for RequestHeadType

source§

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

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

impl From<RequestHead> for RequestHeadType

source§

fn from(head: RequestHead) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/error/enum.ContentTypeError.html b/actix_http/error/enum.ContentTypeError.html new file mode 100644 index 000000000..fc7d9461e --- /dev/null +++ b/actix_http/error/enum.ContentTypeError.html @@ -0,0 +1,24 @@ +ContentTypeError in actix_http::error - Rust

Enum actix_http::error::ContentTypeError

source ·
#[non_exhaustive]
pub enum ContentTypeError { + ParseError, + UnknownEncoding, +}
Expand description

A set of error that can occur during parsing content type.

+

Variants (Non-exhaustive)§

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

ParseError

Can not parse content type.

+
§

UnknownEncoding

Unknown content encoding.

+

Trait Implementations§

source§

impl Debug for ContentTypeError

source§

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

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

impl Display for ContentTypeError

source§

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

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

impl Error for ContentTypeError

1.30.0 · source§

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

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

fn description(&self) -> &str

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

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

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

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

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

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

source§

default fn to_string(&self) -> String

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

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/error/enum.DispatchError.html b/actix_http/error/enum.DispatchError.html new file mode 100644 index 000000000..3659079af --- /dev/null +++ b/actix_http/error/enum.DispatchError.html @@ -0,0 +1,40 @@ +DispatchError in actix_http::error - Rust

Enum actix_http::error::DispatchError

source ·
#[non_exhaustive]
pub enum DispatchError { + Service(Response<BoxBody>), + Body(Box<dyn StdError>), + Upgrade, + Io(Error), + Parse(ParseError), + H2(Error), + SlowRequestTimeout, + DisconnectTimeout, + HandlerDroppedPayload, + InternalError, +}
Expand description

A set of errors that can occur during dispatching HTTP requests.

+

Variants (Non-exhaustive)§

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

Service(Response<BoxBody>)

Service error.

+
§

Body(Box<dyn StdError>)

Body streaming error.

+
§

Upgrade

Upgrade service error.

+
§

Io(Error)

An io::Error that occurred while trying to read or write to a network stream.

+
§

Parse(ParseError)

Request parse error.

+
§

H2(Error)

Available on crate feature http2 only.

HTTP/2 error.

+
§

SlowRequestTimeout

The first request did not complete within the specified timeout.

+
§

DisconnectTimeout

Disconnect timeout. Makes sense for TLS streams.

+
§

HandlerDroppedPayload

Handler dropped payload before reading EOF.

+
§

InternalError

Internal error.

+

Trait Implementations§

source§

impl Debug for DispatchError

source§

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

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

impl Display for DispatchError

source§

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

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

impl Error for DispatchError

source§

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

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

fn description(&self) -> &str

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

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

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

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

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

impl From<Box<dyn Error>> for DispatchError

source§

fn from(original: Box<dyn StdError>) -> DispatchError

Converts to this type from the input type.
source§

impl From<Error> for DispatchError

source§

fn from(original: Error) -> DispatchError

Converts to this type from the input type.
source§

impl From<Error> for DispatchError

source§

fn from(original: Error) -> DispatchError

Converts to this type from the input type.
source§

impl From<ParseError> for DispatchError

source§

fn from(original: ParseError) -> DispatchError

Converts to this type from the input type.
source§

impl From<Response<BoxBody>> for DispatchError

source§

fn from(original: Response<BoxBody>) -> DispatchError

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

source§

default fn to_string(&self) -> String

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

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/error/enum.ParseError.html b/actix_http/error/enum.ParseError.html new file mode 100644 index 000000000..db822496c --- /dev/null +++ b/actix_http/error/enum.ParseError.html @@ -0,0 +1,40 @@ +ParseError in actix_http::error - Rust

Enum actix_http::error::ParseError

source ·
#[non_exhaustive]
pub enum ParseError { + Method, + Uri(InvalidUri), + Version, + Header, + TooLarge, + Incomplete, + Status, + Timeout, + Io(Error), + Utf8(Utf8Error), +}
Expand description

A set of errors that can occur during parsing HTTP streams.

+

Variants (Non-exhaustive)§

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

Method

An invalid Method, such as GE.T.

+
§

Uri(InvalidUri)

An invalid Uri, such as exam ple.domain.

+
§

Version

An invalid HttpVersion, such as HTP/1.1

+
§

Header

An invalid Header.

+
§

TooLarge

A message head is too large to be reasonable.

+
§

Incomplete

A message reached EOF, but is not complete.

+
§

Status

An invalid Status, such as 1337 ELITE.

+
§

Timeout

A timeout occurred waiting for an IO event.

+
§

Io(Error)

An I/O error that occurred while trying to read or write to a network stream.

+
§

Utf8(Utf8Error)

Parsing a field as string failed.

+

Trait Implementations§

source§

impl Debug for ParseError

source§

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

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

impl Display for ParseError

source§

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

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

impl Error for ParseError

source§

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

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

fn description(&self) -> &str

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

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

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

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

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

impl From<Error> for ParseError

source§

fn from(err: Error) -> ParseError

Converts to this type from the input type.
source§

impl From<Error> for ParseError

source§

fn from(err: Error) -> ParseError

Converts to this type from the input type.
source§

impl From<FromUtf8Error> for ParseError

source§

fn from(err: FromUtf8Error) -> ParseError

Converts to this type from the input type.
source§

impl From<InvalidUri> for ParseError

source§

fn from(err: InvalidUri) -> ParseError

Converts to this type from the input type.
source§

impl From<ParseError> for DispatchError

source§

fn from(original: ParseError) -> DispatchError

Converts to this type from the input type.
source§

impl From<ParseError> for Error

source§

fn from(err: ParseError) -> Self

Converts to this type from the input type.
source§

impl From<ParseError> for Response<BoxBody>

source§

fn from(err: ParseError) -> Self

Converts to this type from the input type.
source§

impl From<Utf8Error> for ParseError

source§

fn from(err: Utf8Error) -> ParseError

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

source§

default fn to_string(&self) -> String

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

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/error/enum.PayloadError.html b/actix_http/error/enum.PayloadError.html new file mode 100644 index 000000000..e1584b7b2 --- /dev/null +++ b/actix_http/error/enum.PayloadError.html @@ -0,0 +1,32 @@ +PayloadError in actix_http::error - Rust

Enum actix_http::error::PayloadError

source ·
#[non_exhaustive]
pub enum PayloadError { + Incomplete(Option<Error>), + EncodingCorrupted, + Overflow, + UnknownLength, + Http2Payload(Error), + Io(Error), +}
Expand description

A set of errors that can occur during payload parsing.

+

Variants (Non-exhaustive)§

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

Incomplete(Option<Error>)

A payload reached EOF, but is not complete.

+
§

EncodingCorrupted

Content encoding stream corruption.

+
§

Overflow

Payload reached size limit.

+
§

UnknownLength

Payload length is unknown.

+
§

Http2Payload(Error)

Available on crate feature http2 only.

HTTP/2 payload error.

+
§

Io(Error)

Generic I/O error.

+

Trait Implementations§

source§

impl Debug for PayloadError

source§

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

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

impl Display for PayloadError

source§

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

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

impl Error for PayloadError

source§

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

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

fn description(&self) -> &str

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

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

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

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

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

impl From<Error> for PayloadError

source§

fn from(err: Error) -> Self

Converts to this type from the input type.
source§

impl From<Error> for PayloadError

Available on crate feature http2 only.
source§

fn from(err: Error) -> Self

Converts to this type from the input type.
source§

impl From<Option<Error>> for PayloadError

source§

fn from(err: Option<Error>) -> Self

Converts to this type from the input type.
source§

impl From<PayloadError> for Error

source§

fn from(err: PayloadError) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

source§

default fn to_string(&self) -> String

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

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/error/index.html b/actix_http/error/index.html new file mode 100644 index 000000000..8553f6c05 --- /dev/null +++ b/actix_http/error/index.html @@ -0,0 +1,2 @@ +actix_http::error - Rust

Module actix_http::error

source ·
Expand description

Error and Result module

+

Structs§

Enums§

  • A set of error that can occur during parsing content type.
  • A set of errors that can occur during dispatching HTTP requests.
  • A set of errors that can occur during parsing HTTP streams.
  • A set of errors that can occur during payload parsing.
\ No newline at end of file diff --git a/actix_http/error/sidebar-items.js b/actix_http/error/sidebar-items.js new file mode 100644 index 000000000..694a4a62f --- /dev/null +++ b/actix_http/error/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["ContentTypeError","DispatchError","ParseError","PayloadError"],"struct":["Error","HttpError"]}; \ No newline at end of file diff --git a/actix_http/error/struct.Error.html b/actix_http/error/struct.Error.html new file mode 100644 index 000000000..ca469de13 --- /dev/null +++ b/actix_http/error/struct.Error.html @@ -0,0 +1,18 @@ +Error in actix_http::error - Rust

Struct actix_http::error::Error

source ·
pub struct Error { /* private fields */ }

Trait Implementations§

source§

impl Debug for Error

source§

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

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

impl Display for Error

source§

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

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

impl Error for Error

source§

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

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

fn description(&self) -> &str

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

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

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

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

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

impl From<Error> for Error

source§

fn from(err: HttpError) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Response<BoxBody>

source§

fn from(err: Error) -> Self

Converts to this type from the input type.
source§

impl From<HandshakeError> for Error

Available on crate feature ws only.
source§

fn from(err: HandshakeError) -> Self

Converts to this type from the input type.
source§

impl From<Infallible> for Error

source§

fn from(err: Infallible) -> Self

Converts to this type from the input type.
source§

impl From<ParseError> for Error

source§

fn from(err: ParseError) -> Self

Converts to this type from the input type.
source§

impl From<PayloadError> for Error

source§

fn from(err: PayloadError) -> Self

Converts to this type from the input type.
source§

impl From<ProtocolError> for Error

Available on crate feature ws only.
source§

fn from(err: ProtocolError) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl Freeze for Error

§

impl !RefUnwindSafe for Error

§

impl !Send for Error

§

impl !Sync for Error

§

impl Unpin for Error

§

impl !UnwindSafe for Error

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

source§

default fn to_string(&self) -> String

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

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/error/struct.HttpError.html b/actix_http/error/struct.HttpError.html new file mode 100644 index 000000000..8f5c54b16 --- /dev/null +++ b/actix_http/error/struct.HttpError.html @@ -0,0 +1,26 @@ +HttpError in actix_http::error - Rust

Struct actix_http::error::HttpError

source ·
pub struct HttpError { /* private fields */ }
Expand description

A generic “error” for HTTP connections

+

This error type is less specific than the error returned from other +functions in this crate, but all other errors can be converted to this +error. Consumers of this crate can typically consume and work with this form +of error for conversions with the ? operator.

+

Implementations§

source§

impl Error

source

pub fn is<T>(&self) -> bool
where + T: Error + 'static,

Return true if the underlying error has the same type as T.

+
source

pub fn get_ref(&self) -> &(dyn Error + 'static)

Return a reference to the lower level, inner error.

+

Trait Implementations§

source§

impl Debug for Error

source§

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

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

impl Display for Error

source§

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

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

impl Error for Error

source§

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

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

fn description(&self) -> &str

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

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

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

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

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

impl From<Error> for Error

source§

fn from(err: HttpError) -> Self

Converts to this type from the input type.
source§

impl From<Infallible> for Error

source§

fn from(err: Infallible) -> Error

Converts to this type from the input type.
source§

impl From<InvalidHeaderName> for Error

source§

fn from(err: InvalidHeaderName) -> Error

Converts to this type from the input type.
source§

impl From<InvalidHeaderValue> for Error

source§

fn from(err: InvalidHeaderValue) -> Error

Converts to this type from the input type.
source§

impl From<InvalidMethod> for Error

source§

fn from(err: InvalidMethod) -> Error

Converts to this type from the input type.
source§

impl From<InvalidStatusCode> for Error

source§

fn from(err: InvalidStatusCode) -> Error

Converts to this type from the input type.
source§

impl From<InvalidUri> for Error

source§

fn from(err: InvalidUri) -> Error

Converts to this type from the input type.
source§

impl From<InvalidUriParts> for Error

source§

fn from(err: InvalidUriParts) -> Error

Converts to this type from the input type.
source§

impl From<MaxSizeReached> for Error

source§

fn from(err: MaxSizeReached) -> Error

Converts to this type from the input type.

Auto Trait Implementations§

§

impl Freeze for Error

§

impl RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl UnwindSafe for Error

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

source§

default fn to_string(&self) -> String

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

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/extensions/struct.Extensions.html b/actix_http/extensions/struct.Extensions.html new file mode 100644 index 000000000..518cfcfd1 --- /dev/null +++ b/actix_http/extensions/struct.Extensions.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_http/struct.Extensions.html...

+ + + \ No newline at end of file diff --git a/actix_http/h1/client/struct.ClientCodec.html b/actix_http/h1/client/struct.ClientCodec.html new file mode 100644 index 000000000..969b5e85d --- /dev/null +++ b/actix_http/h1/client/struct.ClientCodec.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/h1/struct.ClientCodec.html...

+ + + \ No newline at end of file diff --git a/actix_http/h1/client/struct.ClientPayloadCodec.html b/actix_http/h1/client/struct.ClientPayloadCodec.html new file mode 100644 index 000000000..31e9f6893 --- /dev/null +++ b/actix_http/h1/client/struct.ClientPayloadCodec.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/h1/struct.ClientPayloadCodec.html...

+ + + \ No newline at end of file diff --git a/actix_http/h1/codec/struct.Codec.html b/actix_http/h1/codec/struct.Codec.html new file mode 100644 index 000000000..6b762c0b0 --- /dev/null +++ b/actix_http/h1/codec/struct.Codec.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/h1/struct.Codec.html...

+ + + \ No newline at end of file diff --git a/actix_http/h1/dispatcher/struct.Dispatcher.html b/actix_http/h1/dispatcher/struct.Dispatcher.html new file mode 100644 index 000000000..7fc7cacb9 --- /dev/null +++ b/actix_http/h1/dispatcher/struct.Dispatcher.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/h1/struct.Dispatcher.html...

+ + + \ No newline at end of file diff --git a/actix_http/h1/enum.Message.html b/actix_http/h1/enum.Message.html new file mode 100644 index 000000000..76fec50bf --- /dev/null +++ b/actix_http/h1/enum.Message.html @@ -0,0 +1,36 @@ +Message in actix_http::h1 - Rust

Enum actix_http::h1::Message

source ·
pub enum Message<T> {
+    Item(T),
+    Chunk(Option<Bytes>),
+}
Expand description

Codec message

+

Variants§

§

Item(T)

HTTP message.

+
§

Chunk(Option<Bytes>)

Payload chunk.

+

Trait Implementations§

source§

impl<T: Debug> Debug for Message<T>

source§

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

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

impl Encoder<Message<(RequestHeadType, BodySize)>> for ClientCodec

§

type Error = Error

The type of encoding errors. Read more
source§

fn encode( + &mut self, + item: Message<(RequestHeadType, BodySize)>, + dst: &mut BytesMut +) -> Result<(), Self::Error>

Encodes a frame into the buffer provided. Read more
source§

impl Encoder<Message<(Response<()>, BodySize)>> for Codec

§

type Error = Error

The type of encoding errors. Read more
source§

fn encode( + &mut self, + item: Message<(Response<()>, BodySize)>, + dst: &mut BytesMut +) -> Result<(), Self::Error>

Encodes a frame into the buffer provided. Read more
source§

impl<T> From<T> for Message<T>

source§

fn from(item: T) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl<T> !Freeze for Message<T>

§

impl<T> RefUnwindSafe for Message<T>
where + T: RefUnwindSafe,

§

impl<T> Send for Message<T>
where + T: Send,

§

impl<T> Sync for Message<T>
where + T: Sync,

§

impl<T> Unpin for Message<T>
where + T: Unpin,

§

impl<T> UnwindSafe for Message<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<!> for T

source§

fn from(t: !) -> T

Converts to this type from the input type.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/h1/enum.MessageType.html b/actix_http/h1/enum.MessageType.html new file mode 100644 index 000000000..0fb74cef0 --- /dev/null +++ b/actix_http/h1/enum.MessageType.html @@ -0,0 +1,29 @@ +MessageType in actix_http::h1 - Rust

Enum actix_http::h1::MessageType

source ·
pub enum MessageType {
+    None,
+    Payload,
+    Stream,
+}
Expand description

Incoming request type

+

Variants§

§

None

§

Payload

§

Stream

Trait Implementations§

source§

impl Clone for MessageType

source§

fn clone(&self) -> MessageType

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

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

Performs copy-assignment from source. Read more
source§

impl Debug for MessageType

source§

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

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

impl PartialEq for MessageType

source§

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

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

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

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

impl Copy for MessageType

source§

impl Eq for MessageType

source§

impl StructuralPartialEq for MessageType

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
§

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

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

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

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

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

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

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

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/h1/expect/struct.ExpectHandler.html b/actix_http/h1/expect/struct.ExpectHandler.html new file mode 100644 index 000000000..14924c24e --- /dev/null +++ b/actix_http/h1/expect/struct.ExpectHandler.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/h1/struct.ExpectHandler.html...

+ + + \ No newline at end of file diff --git a/actix_http/h1/index.html b/actix_http/h1/index.html new file mode 100644 index 000000000..0702d51cf --- /dev/null +++ b/actix_http/h1/index.html @@ -0,0 +1,2 @@ +actix_http::h1 - Rust

Module actix_http::h1

source ·
Expand description

HTTP/1 protocol implementation.

+

Structs§

Enums§

Type Aliases§

\ No newline at end of file diff --git a/actix_http/h1/payload/struct.Payload.html b/actix_http/h1/payload/struct.Payload.html new file mode 100644 index 000000000..37a18fb33 --- /dev/null +++ b/actix_http/h1/payload/struct.Payload.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/h1/struct.Payload.html...

+ + + \ No newline at end of file diff --git a/actix_http/h1/service/struct.H1Service.html b/actix_http/h1/service/struct.H1Service.html new file mode 100644 index 000000000..34658bc2a --- /dev/null +++ b/actix_http/h1/service/struct.H1Service.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/h1/struct.H1Service.html...

+ + + \ No newline at end of file diff --git a/actix_http/h1/service/type.H1ServiceHandler.html b/actix_http/h1/service/type.H1ServiceHandler.html new file mode 100644 index 000000000..ece3ac9e3 --- /dev/null +++ b/actix_http/h1/service/type.H1ServiceHandler.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/h1/type.H1ServiceHandler.html...

+ + + \ No newline at end of file diff --git a/actix_http/h1/sidebar-items.js b/actix_http/h1/sidebar-items.js new file mode 100644 index 000000000..e1ef907c7 --- /dev/null +++ b/actix_http/h1/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Message","MessageType"],"struct":["ClientCodec","ClientPayloadCodec","Codec","Dispatcher","ExpectHandler","H1Service","Payload","SendResponse","UpgradeHandler"],"type":["H1ServiceHandler"]}; \ No newline at end of file diff --git a/actix_http/h1/struct.ClientCodec.html b/actix_http/h1/struct.ClientCodec.html new file mode 100644 index 000000000..ba89f7958 --- /dev/null +++ b/actix_http/h1/struct.ClientCodec.html @@ -0,0 +1,38 @@ +ClientCodec in actix_http::h1 - Rust

Struct actix_http::h1::ClientCodec

source ·
pub struct ClientCodec { /* private fields */ }
Expand description

HTTP/1 Codec

+

Implementations§

source§

impl ClientCodec

source

pub fn new(config: ServiceConfig) -> Self

Create HTTP/1 codec.

+

keepalive_enabled how response connection header get generated.

+
source

pub fn upgrade(&self) -> bool

Check if request is upgrade

+
source

pub fn keep_alive(&self) -> bool

Check if last response is keep-alive

+
source

pub fn message_type(&self) -> MessageType

Check last request’s message type

+
source

pub fn into_payload_codec(self) -> ClientPayloadCodec

Convert message codec to a payload codec

+

Trait Implementations§

source§

impl Debug for ClientCodec

source§

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

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

impl Decoder for ClientCodec

§

type Item = ResponseHead

The type of decoded frames.
§

type Error = ParseError

The type of unrecoverable frame decoding errors. Read more
source§

fn decode( + &mut self, + src: &mut BytesMut +) -> Result<Option<Self::Item>, Self::Error>

Attempts to decode a frame from the provided buffer of bytes. Read more
§

fn decode_eof( + &mut self, + buf: &mut BytesMut +) -> Result<Option<Self::Item>, Self::Error>

A default method available to be called when there are no more bytes +available to be read from the underlying I/O. Read more
§

fn framed<T>(self, io: T) -> Framed<T, Self>
where + T: AsyncRead + AsyncWrite, + Self: Sized,

Provides a Stream and Sink interface for reading and writing to this +Io object, using Decode and Encode to read and write the raw data. Read more
source§

impl Default for ClientCodec

source§

fn default() -> Self

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

impl Encoder<Message<(RequestHeadType, BodySize)>> for ClientCodec

§

type Error = Error

The type of encoding errors. Read more
source§

fn encode( + &mut self, + item: Message<(RequestHeadType, BodySize)>, + dst: &mut BytesMut +) -> Result<(), Self::Error>

Encodes a frame into the buffer provided. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/h1/struct.ClientPayloadCodec.html b/actix_http/h1/struct.ClientPayloadCodec.html new file mode 100644 index 000000000..91525ebc8 --- /dev/null +++ b/actix_http/h1/struct.ClientPayloadCodec.html @@ -0,0 +1,30 @@ +ClientPayloadCodec in actix_http::h1 - Rust

Struct actix_http::h1::ClientPayloadCodec

source ·
pub struct ClientPayloadCodec { /* private fields */ }
Expand description

HTTP/1 Payload Codec

+

Implementations§

source§

impl ClientPayloadCodec

source

pub fn keep_alive(&self) -> bool

Check if last response is keep-alive

+
source

pub fn into_message_codec(self) -> ClientCodec

Transform payload codec to a message codec

+

Trait Implementations§

source§

impl Decoder for ClientPayloadCodec

§

type Item = Option<Bytes>

The type of decoded frames.
§

type Error = PayloadError

The type of unrecoverable frame decoding errors. Read more
source§

fn decode( + &mut self, + src: &mut BytesMut +) -> Result<Option<Self::Item>, Self::Error>

Attempts to decode a frame from the provided buffer of bytes. Read more
§

fn decode_eof( + &mut self, + buf: &mut BytesMut +) -> Result<Option<Self::Item>, Self::Error>

A default method available to be called when there are no more bytes +available to be read from the underlying I/O. Read more
§

fn framed<T>(self, io: T) -> Framed<T, Self>
where + T: AsyncRead + AsyncWrite, + Self: Sized,

Provides a Stream and Sink interface for reading and writing to this +Io object, using Decode and Encode to read and write the raw data. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/h1/struct.Codec.html b/actix_http/h1/struct.Codec.html new file mode 100644 index 000000000..a08dd10de --- /dev/null +++ b/actix_http/h1/struct.Codec.html @@ -0,0 +1,38 @@ +Codec in actix_http::h1 - Rust

Struct actix_http::h1::Codec

source ·
pub struct Codec { /* private fields */ }
Expand description

HTTP/1 Codec

+

Implementations§

source§

impl Codec

source

pub fn new(config: ServiceConfig) -> Self

Create HTTP/1 codec.

+

keepalive_enabled how response connection header get generated.

+
source

pub fn upgrade(&self) -> bool

Check if request is upgrade.

+
source

pub fn keep_alive(&self) -> bool

Check if last response is keep-alive.

+
source

pub fn keep_alive_enabled(&self) -> bool

Check if keep-alive enabled on server level.

+
source

pub fn message_type(&self) -> MessageType

Check last request’s message type.

+
source

pub fn config(&self) -> &ServiceConfig

Trait Implementations§

source§

impl Debug for Codec

source§

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

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

impl Decoder for Codec

§

type Item = Message<Request>

The type of decoded frames.
§

type Error = ParseError

The type of unrecoverable frame decoding errors. Read more
source§

fn decode( + &mut self, + src: &mut BytesMut +) -> Result<Option<Self::Item>, Self::Error>

Attempts to decode a frame from the provided buffer of bytes. Read more
§

fn decode_eof( + &mut self, + buf: &mut BytesMut +) -> Result<Option<Self::Item>, Self::Error>

A default method available to be called when there are no more bytes +available to be read from the underlying I/O. Read more
§

fn framed<T>(self, io: T) -> Framed<T, Self>
where + T: AsyncRead + AsyncWrite, + Self: Sized,

Provides a Stream and Sink interface for reading and writing to this +Io object, using Decode and Encode to read and write the raw data. Read more
source§

impl Default for Codec

source§

fn default() -> Self

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

impl Encoder<Message<(Response<()>, BodySize)>> for Codec

§

type Error = Error

The type of encoding errors. Read more
source§

fn encode( + &mut self, + item: Message<(Response<()>, BodySize)>, + dst: &mut BytesMut +) -> Result<(), Self::Error>

Encodes a frame into the buffer provided. Read more

Auto Trait Implementations§

§

impl Freeze for Codec

§

impl !RefUnwindSafe for Codec

§

impl !Send for Codec

§

impl !Sync for Codec

§

impl Unpin for Codec

§

impl !UnwindSafe for Codec

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/h1/struct.Dispatcher.html b/actix_http/h1/struct.Dispatcher.html new file mode 100644 index 000000000..4cc4b9c35 --- /dev/null +++ b/actix_http/h1/struct.Dispatcher.html @@ -0,0 +1,136 @@ +Dispatcher in actix_http::h1 - Rust

Struct actix_http::h1::Dispatcher

source ·
pub struct Dispatcher<T, S, B, X, U>
where + S: Service<Request>, + S::Error: Into<Response<BoxBody>>, + B: MessageBody, + X: Service<Request, Response = Request>, + X::Error: Into<Response<BoxBody>>, + U: Service<(Request, Framed<T, Codec>), Response = ()>, + U::Error: Display,
{ /* private fields */ }
Expand description

Dispatcher for HTTP/1.1 protocol

+

Trait Implementations§

source§

impl<T, S, B, X, U> Future for Dispatcher<T, S, B, X, U>
where + T: AsyncRead + AsyncWrite + Unpin, + S: Service<Request>, + S::Error: Into<Response<BoxBody>>, + S::Response: Into<Response<B>>, + B: MessageBody, + X: Service<Request, Response = Request>, + X::Error: Into<Response<BoxBody>>, + U: Service<(Request, Framed<T, Codec>), Response = ()>, + U::Error: Display,

§

type Output = Result<(), DispatchError>

The type of value produced on completion.
source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
source§

impl<'__pin, T, S, B, X, U> Unpin for Dispatcher<T, S, B, X, U>
where + __Origin<'__pin, T, S, B, X, U>: Unpin, + S: Service<Request>, + S::Error: Into<Response<BoxBody>>, + B: MessageBody, + X: Service<Request, Response = Request>, + X::Error: Into<Response<BoxBody>>, + U: Service<(Request, Framed<T, Codec>), Response = ()>, + U::Error: Display,

Auto Trait Implementations§

§

impl<T, S, B, X, U> !Freeze for Dispatcher<T, S, B, X, U>

§

impl<T, S, B, X, U> !RefUnwindSafe for Dispatcher<T, S, B, X, U>

§

impl<T, S, B, X, U> !Send for Dispatcher<T, S, B, X, U>

§

impl<T, S, B, X, U> !Sync for Dispatcher<T, S, B, X, U>

§

impl<T, S, B, X, U> !UnwindSafe for Dispatcher<T, S, B, X, U>

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

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

§

fn map<U, F>(self, f: F) -> Map<Self, F>
where + F: FnOnce(Self::Output) -> U, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn map_into<U>(self) -> MapInto<Self, U>
where + Self::Output: Into<U>, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnOnce(Self::Output) -> Fut, + Fut: Future, + Self: Sized,

Chain on a computation for when a future finished, passing the result of +the future to the provided closure f. Read more
§

fn left_future<B>(self) -> Either<Self, B>
where + B: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the left-hand variant +of that Either. Read more
§

fn right_future<A>(self) -> Either<A, Self>
where + A: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the right-hand variant +of that Either. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Convert this future into a single element stream. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Output: Future, + Self: Sized,

Flatten the execution of this future when the output of this +future is itself another future. Read more
§

fn flatten_stream(self) -> FlattenStream<Self>
where + Self::Output: Stream, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a future such that poll will never again be called once it has +completed. This method can be used to turn any Future into a +FusedFuture. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnOnce(&Self::Output), + Self: Sized,

Do something with the output of a future before passing it on. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the future. Read more
§

fn shared(self) -> Shared<Self>
where + Self: Sized, + Self::Output: Clone,

Available on crate feature std only.
Create a cloneable handle to this future where all handles will resolve +to the same result. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn unit_error(self) -> UnitError<Self>
where + Self: Sized,

§

fn never_error(self) -> NeverError<Self>
where + Self: Sized,

§

fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where + Self: Unpin,

A convenience for calling Future::poll on Unpin future types.
§

fn now_or_never(self) -> Option<Self::Output>
where + Self: Sized,

Evaluates and consumes the future, returning the resulting output if +the future is ready after the first call to Future::poll. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<F> IntoFuture for F
where + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
§

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
§

fn try_poll( + self: Pin<&mut F>, + cx: &mut Context<'_> +) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
§

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

§

fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>
where + Self::Ok: Sink<Item, Error = Self::Error>, + Self: Sized,

Available on crate feature sink only.
Flattens the execution of this future when the successful result of this +future is a [Sink]. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + F: FnOnce(Self::Ok) -> T, + Self: Sized,

Maps this future’s success value to a different value. Read more
§

fn map_ok_or_else<T, E, F>(self, e: E, f: F) -> MapOkOrElse<Self, F, E>
where + F: FnOnce(Self::Ok) -> T, + E: FnOnce(Self::Error) -> T, + Self: Sized,

Maps this future’s success value to a different value, and permits for error handling resulting in the same type. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + F: FnOnce(Self::Error) -> E, + Self: Sized,

Maps this future’s error value to a different value. Read more
§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Maps this future’s Error to a new error type +using the Into trait. Read more
§

fn ok_into<U>(self) -> OkInto<Self, U>
where + Self: Sized, + Self::Ok: Into<U>,

Maps this future’s Ok to a new type +using the Into trait.
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnOnce(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Executes another future after this one resolves successfully. The +success value is passed to a closure to create this subsequent future. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnOnce(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Executes another future if this one resolves to an error. The +error value is passed to a closure to create this subsequent future. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnOnce(&Self::Ok), + Self: Sized,

Do something with the success value of a future before passing it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnOnce(&Self::Error), + Self: Sized,

Do something with the error value of a future before passing it on. Read more
§

fn try_flatten(self) -> TryFlatten<Self, Self::Ok>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is another future. Read more
§

fn try_flatten_stream(self) -> TryFlattenStream<Self>
where + Self::Ok: TryStream<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F>
where + Self: Sized, + F: FnOnce(Self::Error) -> Self::Ok,

Unwraps this future’s output, producing a future with this future’s +Ok type as its +Output type. Read more
§

fn into_future(self) -> IntoFuture<Self>
where + Self: Sized,

Wraps a [TryFuture] into a type that implements +Future. Read more
§

fn try_poll_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Result<Self::Ok, Self::Error>>
where + Self: Unpin,

A convenience method for calling [TryFuture::try_poll] on Unpin +future types.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/h1/struct.ExpectHandler.html b/actix_http/h1/struct.ExpectHandler.html new file mode 100644 index 000000000..45d6b73c5 --- /dev/null +++ b/actix_http/h1/struct.ExpectHandler.html @@ -0,0 +1,40 @@ +ExpectHandler in actix_http::h1 - Rust

Struct actix_http::h1::ExpectHandler

source ·
pub struct ExpectHandler;

Trait Implementations§

source§

impl Service<Request> for ExpectHandler

§

type Response = Request

Responses given by the service.
§

type Error = Error

Errors produced by the service when polling readiness or executing call.
§

type Future = Ready<Result<<ExpectHandler as Service<Request>>::Response, <ExpectHandler as Service<Request>>::Error>>

The future response value.
source§

fn poll_ready(&self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>>

Returns Ready when the service is able to process requests. Read more
source§

fn call(&self, req: Request) -> Self::Future

Process the request and return the response asynchronously. Read more
source§

impl ServiceFactory<Request> for ExpectHandler

§

type Response = Request

Responses given by the created services.
§

type Error = Error

Errors produced by the created services.
§

type Config = ()

Service factory configuration.
§

type Service = ExpectHandler

The kind of Service created by this factory.
§

type InitError = Error

Errors potentially raised while building a service.
§

type Future = Ready<Result<<ExpectHandler as ServiceFactory<Request>>::Service, <ExpectHandler as ServiceFactory<Request>>::InitError>>

The future of the Service instance.g
source§

fn new_service(&self, _: Self::Config) -> Self::Future

Create and return a new service asynchronously.

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
§

impl<S, Req> IntoService<S, Req> for S
where + S: Service<Req>,

§

fn into_service(self) -> S

Convert to a Service
§

impl<SF, Req> IntoServiceFactory<SF, Req> for SF
where + SF: ServiceFactory<Req>,

§

fn into_factory(self) -> SF

Convert Self to a ServiceFactory
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<S, Req> ServiceExt<Req> for S
where + S: Service<Req>,

§

fn map<F, R>(self, f: F) -> Map<Self, F, Req, R>
where + Self: Sized, + F: FnMut(Self::Response) -> R,

Map this service’s output to a different type, returning a new service +of the resulting type. Read more
§

fn map_err<F, E>(self, f: F) -> MapErr<Self, Req, F, E>
where + Self: Sized, + F: Fn(Self::Error) -> E,

Map this service’s error to a different error, returning a new service. Read more
§

fn and_then<I, S1>(self, service: I) -> AndThenService<Self, S1, Req>
where + Self: Sized, + I: IntoService<S1, Self::Response>, + S1: Service<Self::Response, Error = Self::Error>,

Call another service after call to this one has resolved successfully. Read more
§

impl<SF, Req> ServiceFactoryExt<Req> for SF
where + SF: ServiceFactory<Req>,

§

fn map<F, R>(self, f: F) -> MapServiceFactory<Self, F, Req, R>
where + Self: Sized, + F: FnMut(Self::Response) -> R + Clone,

Map this service’s output to a different type, returning a new service +of the resulting type.
§

fn map_err<F, E>(self, f: F) -> MapErrServiceFactory<Self, Req, F, E>
where + Self: Sized, + F: Fn(Self::Error) -> E + Clone,

Map this service’s error to a different error, returning a new service.
§

fn map_init_err<F, E>(self, f: F) -> MapInitErr<Self, F, Req, E>
where + Self: Sized, + F: Fn(Self::InitError) -> E + Clone,

Map this factory’s init error to a different error, returning a new service.
§

fn and_then<I, SF1>(self, factory: I) -> AndThenServiceFactory<Self, SF1, Req>
where + Self: Sized, + Self::Config: Clone, + I: IntoServiceFactory<SF1, Self::Response>, + SF1: ServiceFactory<Self::Response, Config = Self::Config, Error = Self::Error, InitError = Self::InitError>,

Call another service after call to this one has resolved successfully.
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/h1/struct.H1Service.html b/actix_http/h1/struct.H1Service.html new file mode 100644 index 000000000..d74a2b6fc --- /dev/null +++ b/actix_http/h1/struct.H1Service.html @@ -0,0 +1,171 @@ +H1Service in actix_http::h1 - Rust

Struct actix_http::h1::H1Service

source ·
pub struct H1Service<T, S, B, X = ExpectHandler, U = UpgradeHandler> { /* private fields */ }
Expand description

ServiceFactory implementation for HTTP1 transport

+

Implementations§

source§

impl<S, B, X, U> H1Service<TlsStream<TcpStream>, S, B, X, U>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>>, + S::InitError: Debug, + S::Response: Into<Response<B>>, + B: MessageBody, + X: ServiceFactory<Request, Config = (), Response = Request>, + X::Future: 'static, + X::Error: Into<Response<BoxBody>>, + X::InitError: Debug, + U: ServiceFactory<(Request, Framed<TlsStream<TcpStream>, Codec>), Config = (), Response = ()>, + U::Future: 'static, + U::Error: Display + Into<Response<BoxBody>>, + U::InitError: Debug,

source

pub fn openssl( + self, + acceptor: SslAcceptor +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<SslError, DispatchError>, InitError = ()>

Available on crate feature openssl only.

Create OpenSSL based service.

+
source§

impl<S, B, X, U> H1Service<TlsStream<TcpStream>, S, B, X, U>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>>, + S::InitError: Debug, + S::Response: Into<Response<B>>, + B: MessageBody, + X: ServiceFactory<Request, Config = (), Response = Request>, + X::Future: 'static, + X::Error: Into<Response<BoxBody>>, + X::InitError: Debug, + U: ServiceFactory<(Request, Framed<TlsStream<TcpStream>, Codec>), Config = (), Response = ()>, + U::Future: 'static, + U::Error: Display + Into<Response<BoxBody>>, + U::InitError: Debug,

source

pub fn rustls( + self, + config: ServerConfig +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<Error, DispatchError>, InitError = ()>

Available on crate feature rustls-0_20 only.

Create Rustls v0.20 based service.

+
source§

impl<S, B, X, U> H1Service<TlsStream<TcpStream>, S, B, X, U>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>>, + S::InitError: Debug, + S::Response: Into<Response<B>>, + B: MessageBody, + X: ServiceFactory<Request, Config = (), Response = Request>, + X::Future: 'static, + X::Error: Into<Response<BoxBody>>, + X::InitError: Debug, + U: ServiceFactory<(Request, Framed<TlsStream<TcpStream>, Codec>), Config = (), Response = ()>, + U::Future: 'static, + U::Error: Display + Into<Response<BoxBody>>, + U::InitError: Debug,

source

pub fn rustls_021( + self, + config: ServerConfig +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<Error, DispatchError>, InitError = ()>

Available on crate feature rustls-0_21 only.

Create Rustls v0.21 based service.

+
source§

impl<S, B, X, U> H1Service<TlsStream<TcpStream>, S, B, X, U>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>>, + S::InitError: Debug, + S::Response: Into<Response<B>>, + B: MessageBody, + X: ServiceFactory<Request, Config = (), Response = Request>, + X::Future: 'static, + X::Error: Into<Response<BoxBody>>, + X::InitError: Debug, + U: ServiceFactory<(Request, Framed<TlsStream<TcpStream>, Codec>), Config = (), Response = ()>, + U::Future: 'static, + U::Error: Display + Into<Response<BoxBody>>, + U::InitError: Debug,

source

pub fn rustls_0_22( + self, + config: ServerConfig +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<Error, DispatchError>, InitError = ()>

Available on crate feature rustls-0_22 only.

Create Rustls v0.22 based service.

+
source§

impl<S, B, X, U> H1Service<TlsStream<TcpStream>, S, B, X, U>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>>, + S::InitError: Debug, + S::Response: Into<Response<B>>, + B: MessageBody, + X: ServiceFactory<Request, Config = (), Response = Request>, + X::Future: 'static, + X::Error: Into<Response<BoxBody>>, + X::InitError: Debug, + U: ServiceFactory<(Request, Framed<TlsStream<TcpStream>, Codec>), Config = (), Response = ()>, + U::Future: 'static, + U::Error: Display + Into<Response<BoxBody>>, + U::InitError: Debug,

source

pub fn rustls_0_23( + self, + config: ServerConfig +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<Error, DispatchError>, InitError = ()>

Available on crate feature rustls-0_23 only.

Create Rustls v0.23 based service.

+
source§

impl<S, B, X, U> H1Service<TcpStream, S, B, X, U>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>>, + S::InitError: Debug, + S::Response: Into<Response<B>>, + B: MessageBody, + X: ServiceFactory<Request, Config = (), Response = Request>, + X::Future: 'static, + X::Error: Into<Response<BoxBody>>, + X::InitError: Debug, + U: ServiceFactory<(Request, Framed<TcpStream, Codec>), Config = (), Response = ()>, + U::Future: 'static, + U::Error: Display + Into<Response<BoxBody>>, + U::InitError: Debug,

source

pub fn tcp( + self +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = DispatchError, InitError = ()>

Create simple tcp stream service

+
source§

impl<T, S, B, X, U> H1Service<T, S, B, X, U>
where + S: ServiceFactory<Request, Config = ()>, + S::Error: Into<Response<BoxBody>>, + S::Response: Into<Response<B>>, + S::InitError: Debug, + B: MessageBody,

source

pub fn expect<X1>(self, expect: X1) -> H1Service<T, S, B, X1, U>
where + X1: ServiceFactory<Request, Response = Request>, + X1::Error: Into<Response<BoxBody>>, + X1::InitError: Debug,

source

pub fn upgrade<U1>(self, upgrade: Option<U1>) -> H1Service<T, S, B, X, U1>
where + U1: ServiceFactory<(Request, Framed<T, Codec>), Response = ()>, + U1::Error: Display, + U1::InitError: Debug,

Trait Implementations§

source§

impl<T, S, B, X, U> ServiceFactory<(T, Option<SocketAddr>)> for H1Service<T, S, B, X, U>
where + T: AsyncRead + AsyncWrite + Unpin + 'static, + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>>, + S::Response: Into<Response<B>>, + S::InitError: Debug, + B: MessageBody, + X: ServiceFactory<Request, Config = (), Response = Request>, + X::Future: 'static, + X::Error: Into<Response<BoxBody>>, + X::InitError: Debug, + U: ServiceFactory<(Request, Framed<T, Codec>), Config = (), Response = ()>, + U::Future: 'static, + U::Error: Display + Into<Response<BoxBody>>, + U::InitError: Debug,

§

type Response = ()

Responses given by the created services.
§

type Error = DispatchError

Errors produced by the created services.
§

type Config = ()

Service factory configuration.
§

type Service = HttpServiceHandler<T, <S as ServiceFactory<Request>>::Service, B, <X as ServiceFactory<Request>>::Service, <U as ServiceFactory<(Request, Framed<T, Codec>)>>::Service>

The kind of Service created by this factory.
§

type InitError = ()

Errors potentially raised while building a service.
§

type Future = Pin<Box<dyn Future<Output = Result<<H1Service<T, S, B, X, U> as ServiceFactory<(T, Option<SocketAddr>)>>::Service, <H1Service<T, S, B, X, U> as ServiceFactory<(T, Option<SocketAddr>)>>::InitError>>>>

The future of the Service instance.g
source§

fn new_service(&self, _: ()) -> Self::Future

Create and return a new service asynchronously.

Auto Trait Implementations§

§

impl<T, S, B, X, U> Freeze for H1Service<T, S, B, X, U>
where + S: Freeze, + X: Freeze, + U: Freeze,

§

impl<T, S, B, X = ExpectHandler, U = UpgradeHandler> !RefUnwindSafe for H1Service<T, S, B, X, U>

§

impl<T, S, B, X = ExpectHandler, U = UpgradeHandler> !Send for H1Service<T, S, B, X, U>

§

impl<T, S, B, X = ExpectHandler, U = UpgradeHandler> !Sync for H1Service<T, S, B, X, U>

§

impl<T, S, B, X, U> Unpin for H1Service<T, S, B, X, U>
where + S: Unpin, + X: Unpin, + U: Unpin, + B: Unpin,

§

impl<T, S, B, X = ExpectHandler, U = UpgradeHandler> !UnwindSafe for H1Service<T, S, B, X, U>

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
§

impl<SF, Req> IntoServiceFactory<SF, Req> for SF
where + SF: ServiceFactory<Req>,

§

fn into_factory(self) -> SF

Convert Self to a ServiceFactory
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<SF, Req> ServiceFactoryExt<Req> for SF
where + SF: ServiceFactory<Req>,

§

fn map<F, R>(self, f: F) -> MapServiceFactory<Self, F, Req, R>
where + Self: Sized, + F: FnMut(Self::Response) -> R + Clone,

Map this service’s output to a different type, returning a new service +of the resulting type.
§

fn map_err<F, E>(self, f: F) -> MapErrServiceFactory<Self, Req, F, E>
where + Self: Sized, + F: Fn(Self::Error) -> E + Clone,

Map this service’s error to a different error, returning a new service.
§

fn map_init_err<F, E>(self, f: F) -> MapInitErr<Self, F, Req, E>
where + Self: Sized, + F: Fn(Self::InitError) -> E + Clone,

Map this factory’s init error to a different error, returning a new service.
§

fn and_then<I, SF1>(self, factory: I) -> AndThenServiceFactory<Self, SF1, Req>
where + Self: Sized, + Self::Config: Clone, + I: IntoServiceFactory<SF1, Self::Response>, + SF1: ServiceFactory<Self::Response, Config = Self::Config, Error = Self::Error, InitError = Self::InitError>,

Call another service after call to this one has resolved successfully.
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/h1/struct.Payload.html b/actix_http/h1/struct.Payload.html new file mode 100644 index 000000000..8c2132d4b --- /dev/null +++ b/actix_http/h1/struct.Payload.html @@ -0,0 +1,263 @@ +Payload in actix_http::h1 - Rust

Struct actix_http::h1::Payload

source ·
pub struct Payload { /* private fields */ }
Expand description

Buffered stream of bytes chunks

+

Payload stores chunks in a vector. First chunk can be received with poll_next. Payload does +not notify current task when new data is available.

+

Payload can be used as Response body stream.

+

Implementations§

source§

impl Payload

source

pub fn create(eof: bool) -> (PayloadSender, Payload)

Creates a payload stream.

+

This method construct two objects responsible for bytes stream generation:

+
    +
  • PayloadSender - Sender side of the stream
  • +
  • Payload - Receiver side of the stream
  • +
+
source

pub fn unread_data(&mut self, data: Bytes)

Put unused data back to payload

+

Trait Implementations§

source§

impl Debug for Payload

source§

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

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

impl<S> From<Payload> for Payload<S>

source§

fn from(payload: Payload) -> Self

Converts to this type from the input type.
source§

impl Stream for Payload

§

type Item = Result<Bytes, PayloadError>

Values yielded by the stream.
source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, PayloadError>>>

Attempt to pull out the next value of this stream, registering the +current task for wakeup if the value is not yet available, and returning +None if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more

Auto Trait Implementations§

§

impl Freeze for Payload

§

impl !RefUnwindSafe for Payload

§

impl !Send for Payload

§

impl !Sync for Payload

§

impl Unpin for Payload

§

impl !UnwindSafe for Payload

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<T> StreamExt for T
where + T: Stream + ?Sized,

§

fn next(&mut self) -> Next<'_, Self>
where + Self: Unpin,

Creates a future that resolves to the next item in the stream. Read more
§

fn into_future(self) -> StreamFuture<Self>
where + Self: Sized + Unpin,

Converts this stream into a future of (next_item, tail_of_stream). +If the stream terminates, then the next item is None. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + F: FnMut(Self::Item) -> T, + Self: Sized,

Maps this stream’s items to a different type, returning a new stream of +the resulting type. Read more
§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates a stream which gives the current iteration count as well as +the next value. Read more
§

fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Filters the values produced by this stream according to the provided +asynchronous predicate. Read more
§

fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = Option<T>>, + Self: Sized,

Filters the values produced by this stream while simultaneously mapping +them to a different type according to the provided asynchronous closure. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized,

Computes from this stream’s items new items of a different type using +an asynchronous closure. Read more
§

fn collect<C>(self) -> Collect<Self, C>
where + C: Default + Extend<Self::Item>, + Self: Sized,

Transforms a stream into a collection, returning a +future representing the result of that computation. Read more
§

fn unzip<A, B, FromA, FromB>(self) -> Unzip<Self, FromA, FromB>
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Stream<Item = (A, B)>,

Converts a stream of pairs into a future, which +resolves to pair of containers. Read more
§

fn concat(self) -> Concat<Self>
where + Self: Sized, + Self::Item: Extend<<Self::Item as IntoIterator>::Item> + IntoIterator + Default,

Concatenate all items of a stream into a single extendable +destination, returning a future representing the end result. Read more
§

fn count(self) -> Count<Self>
where + Self: Sized,

Drives the stream to completion, counting the number of items. Read more
§

fn cycle(self) -> Cycle<Self>
where + Self: Sized + Clone,

Repeats a stream endlessly. Read more
§

fn fold<T, Fut, F>(self, init: T, f: F) -> Fold<Self, Fut, T, F>
where + F: FnMut(T, Self::Item) -> Fut, + Fut: Future<Output = T>, + Self: Sized,

Execute an accumulating asynchronous computation over a stream, +collecting all the values into one final result. Read more
§

fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if any element in stream satisfied a predicate. Read more
§

fn all<Fut, F>(self, f: F) -> All<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if all element in stream satisfied a predicate. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Item: Stream, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> FlattenUnorderedWithFlowController<Self, ()>
where + Self::Item: Stream + Unpin, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Polls +inner streams produced by the base stream concurrently. Read more
§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + F: FnMut(Self::Item) -> U, + U: Stream, + Self: Sized,

Maps a stream like [StreamExt::map] but flattens nested Streams. Read more
§

fn flat_map_unordered<U, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> FlatMapUnordered<Self, U, F>
where + U: Stream + Unpin, + F: FnMut(Self::Item) -> U, + Self: Sized,

Available on crate feature alloc only.
Maps a stream like [StreamExt::map] but flattens nested Streams +and polls them concurrently, yielding items in any order, as they made +available. Read more
§

fn scan<S, B, Fut, F>(self, initial_state: S, f: F) -> Scan<Self, S, Fut, F>
where + F: FnMut(&mut S, Self::Item) -> Fut, + Fut: Future<Output = Option<B>>, + Self: Sized,

Combinator similar to [StreamExt::fold] that holds internal state +and produces a new stream. Read more
§

fn skip_while<Fut, F>(self, f: F) -> SkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_while<Fut, F>(self, f: F) -> TakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Take elements from this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_until<Fut>(self, fut: Fut) -> TakeUntil<Self, Fut>
where + Fut: Future, + Self: Sized,

Take elements from this stream until the provided future resolves. Read more
§

fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream. Read more
§

fn for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> ForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Available on crate feature alloc only.
Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates a new stream of at most n items of the underlying stream. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates a new stream which skips n items of the underlying stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a stream such that poll_next will never +again be called once it has finished. This method can be used to turn +any Stream into a FusedStream. Read more
§

fn by_ref(&mut self) -> &mut Self

Borrows a stream, rather than consuming it. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the stream. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn buffered(self, n: usize) -> Buffered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures. Read more
§

fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures (unordered). Read more
§

fn zip<St>(self, other: St) -> Zip<Self, St>
where + St: Stream, + Self: Sized,

An adapter for zipping two streams together. Read more
§

fn chain<St>(self, other: St) -> Chain<Self, St>
where + St: Stream<Item = Self::Item>, + Self: Sized,

Adapter for chaining two streams. Read more
§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates a new stream which exposes a peek method. Read more
§

fn chunks(self, capacity: usize) -> Chunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up items of the stream inside a vector. Read more
§

fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up ready items of the stream inside a vector. Read more
§

fn forward<S>(self, sink: S) -> Forward<Self, S>
where + S: Sink<Self::Ok, Error = Self::Error>, + Self: Sized + TryStream,

Available on crate feature sink only.
A future that completes after the given stream has been fully processed +into the sink and the sink has been flushed and closed. Read more
§

fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
where + Self: Sized + Sink<Item>,

Available on crate features sink and alloc only.
Splits this Stream + Sink object into separate Sink and Stream +objects. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnMut(&Self::Item), + Self: Sized,

Do something with each item of this stream, afterwards passing it on. Read more
§

fn left_stream<B>(self) -> Either<Self, B>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the left-hand variant +of that Either. Read more
§

fn right_stream<B>(self) -> Either<B, Self>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the right-hand variant +of that Either. Read more
§

fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>
where + Self: Unpin,

A convenience method for calling [Stream::poll_next] on Unpin +stream types.
§

fn select_next_some(&mut self) -> SelectNextSome<'_, Self>
where + Self: Unpin + FusedStream,

Returns a Future that resolves when the next item in this stream is +ready. Read more
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

impl<S, T, E> TryStream for S
where + S: Stream<Item = 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
§

fn try_poll_next( + self: Pin<&mut S>, + cx: &mut Context<'_> +) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>>

Poll this TryStream as if it were a Stream. Read more
§

impl<S> TryStreamExt for S
where + S: TryStream + ?Sized,

§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Wraps the current stream in a new stream which converts the error type +into the one provided. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> T,

Wraps the current stream in a new stream which maps the success value +using the provided closure. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + Self: Sized, + F: FnMut(Self::Error) -> E,

Wraps the current stream in a new stream which maps the error value +using the provided closure. Read more
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Chain on a computation for when a value is ready, passing the successful +results to the provided closure f. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnMut(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Chain on a computation for when an error happens, passing the +erroneous result to the provided closure f. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnMut(&Self::Ok), + Self: Sized,

Do something with the success value of this stream, afterwards passing +it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnMut(&Self::Error), + Self: Sized,

Do something with the error value of this stream, afterwards passing it on. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Wraps a [TryStream] into a type that implements +Stream Read more
§

fn try_next(&mut self) -> TryNext<'_, Self>
where + Self: Unpin,

Creates a future that attempts to resolve the next item in the stream. +If an error is encountered before the next item, the error is returned +instead. Read more
§

fn try_for_each<Fut, F>(self, f: F) -> TryForEach<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Ok = (), Error = Self::Error>, + Self: Sized,

Attempts to run this stream to completion, executing the provided +asynchronous closure for each element on the stream. Read more
§

fn try_skip_while<Fut, F>(self, f: F) -> TrySkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_take_while<Fut, F>(self, f: F) -> TryTakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Take elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> TryForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = Result<(), Self::Error>>, + Self: Sized,

Available on crate feature alloc only.
Attempts to run this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available, exiting as soon as an error occurs. Read more
§

fn try_collect<C>(self) -> TryCollect<Self, C>
where + C: Default + Extend<Self::Ok>, + Self: Sized,

Attempt to transform a stream into a collection, +returning a future representing the result of that computation. Read more
§

fn try_chunks(self, capacity: usize) -> TryChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful items of the stream inside a vector. Read more
§

fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful, ready items of the stream inside a vector. Read more
§

fn try_filter<Fut, F>(self, f: F) -> TryFilter<Self, Fut, F>
where + Fut: Future<Output = bool>, + F: FnMut(&Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream according to the +provided asynchronous closure. Read more
§

fn try_filter_map<Fut, F, T>(self, f: F) -> TryFilterMap<Self, Fut, F>
where + Fut: TryFuture<Ok = Option<T>, Error = Self::Error>, + F: FnMut(Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream while +simultaneously mapping them to a different type according to the +provided asynchronous closure. Read more
§

fn try_flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> TryFlattenUnordered<Self>
where + Self::Ok: TryStream + Unpin, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Produced streams +will be polled concurrently and any errors will be passed through without looking at them. +If the underlying base stream returns an error, it will be immediately propagated. Read more
§

fn try_flatten(self) -> TryFlatten<Self>
where + Self::Ok: TryStream, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn try_fold<T, Fut, F>(self, init: T, f: F) -> TryFold<Self, Fut, T, F>
where + F: FnMut(T, Self::Ok) -> Fut, + Fut: TryFuture<Ok = T, Error = Self::Error>, + Self: Sized,

Attempt to execute an accumulating asynchronous computation over a +stream, collecting all the values into one final result. Read more
§

fn try_concat(self) -> TryConcat<Self>
where + Self: Sized, + Self::Ok: Extend<<Self::Ok as IntoIterator>::Item> + IntoIterator + Default,

Attempt to concatenate all items of a stream into a single +extendable destination, returning a future representing the end result. Read more
§

fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently (unordered). Read more
§

fn try_buffered(self, n: usize) -> TryBuffered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently. Read more
§

fn try_poll_next_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Option<Result<Self::Ok, Self::Error>>>
where + Self: Unpin,

A convenience method for calling [TryStream::try_poll_next] on Unpin +stream types.
§

fn try_all<Fut, F>(self, f: F) -> TryAll<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if all items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that does not satisfy the predicate. Read more
§

fn try_any<Fut, F>(self, f: F) -> TryAny<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if any items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that satisfies the predicate. Read more
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/h1/struct.SendResponse.html b/actix_http/h1/struct.SendResponse.html new file mode 100644 index 000000000..12759d911 --- /dev/null +++ b/actix_http/h1/struct.SendResponse.html @@ -0,0 +1,118 @@ +SendResponse in actix_http::h1 - Rust

Struct actix_http::h1::SendResponse

source ·
pub struct SendResponse<T, B> { /* private fields */ }
Expand description

Send HTTP/1 response

+

Implementations§

source§

impl<T, B> SendResponse<T, B>
where + B: MessageBody, + B::Error: Into<Error>,

source

pub fn new(framed: Framed<T, Codec>, response: Response<B>) -> Self

Trait Implementations§

source§

impl<T, B> Future for SendResponse<T, B>
where + T: AsyncRead + AsyncWrite + Unpin, + B: MessageBody, + B::Error: Into<Error>,

§

type Output = Result<Framed<T, Codec>, Error>

The type of value produced on completion.
source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
source§

impl<'__pin, T, B> Unpin for SendResponse<T, B>
where + __Origin<'__pin, T, B>: Unpin,

Auto Trait Implementations§

§

impl<T, B> !Freeze for SendResponse<T, B>

§

impl<T, B> !RefUnwindSafe for SendResponse<T, B>

§

impl<T, B> !Send for SendResponse<T, B>

§

impl<T, B> !Sync for SendResponse<T, B>

§

impl<T, B> !UnwindSafe for SendResponse<T, B>

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

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

§

fn map<U, F>(self, f: F) -> Map<Self, F>
where + F: FnOnce(Self::Output) -> U, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn map_into<U>(self) -> MapInto<Self, U>
where + Self::Output: Into<U>, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnOnce(Self::Output) -> Fut, + Fut: Future, + Self: Sized,

Chain on a computation for when a future finished, passing the result of +the future to the provided closure f. Read more
§

fn left_future<B>(self) -> Either<Self, B>
where + B: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the left-hand variant +of that Either. Read more
§

fn right_future<A>(self) -> Either<A, Self>
where + A: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the right-hand variant +of that Either. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Convert this future into a single element stream. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Output: Future, + Self: Sized,

Flatten the execution of this future when the output of this +future is itself another future. Read more
§

fn flatten_stream(self) -> FlattenStream<Self>
where + Self::Output: Stream, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a future such that poll will never again be called once it has +completed. This method can be used to turn any Future into a +FusedFuture. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnOnce(&Self::Output), + Self: Sized,

Do something with the output of a future before passing it on. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the future. Read more
§

fn shared(self) -> Shared<Self>
where + Self: Sized, + Self::Output: Clone,

Available on crate feature std only.
Create a cloneable handle to this future where all handles will resolve +to the same result. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn unit_error(self) -> UnitError<Self>
where + Self: Sized,

§

fn never_error(self) -> NeverError<Self>
where + Self: Sized,

§

fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where + Self: Unpin,

A convenience for calling Future::poll on Unpin future types.
§

fn now_or_never(self) -> Option<Self::Output>
where + Self: Sized,

Evaluates and consumes the future, returning the resulting output if +the future is ready after the first call to Future::poll. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<F> IntoFuture for F
where + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
§

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
§

fn try_poll( + self: Pin<&mut F>, + cx: &mut Context<'_> +) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
§

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

§

fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>
where + Self::Ok: Sink<Item, Error = Self::Error>, + Self: Sized,

Available on crate feature sink only.
Flattens the execution of this future when the successful result of this +future is a [Sink]. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + F: FnOnce(Self::Ok) -> T, + Self: Sized,

Maps this future’s success value to a different value. Read more
§

fn map_ok_or_else<T, E, F>(self, e: E, f: F) -> MapOkOrElse<Self, F, E>
where + F: FnOnce(Self::Ok) -> T, + E: FnOnce(Self::Error) -> T, + Self: Sized,

Maps this future’s success value to a different value, and permits for error handling resulting in the same type. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + F: FnOnce(Self::Error) -> E, + Self: Sized,

Maps this future’s error value to a different value. Read more
§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Maps this future’s Error to a new error type +using the Into trait. Read more
§

fn ok_into<U>(self) -> OkInto<Self, U>
where + Self: Sized, + Self::Ok: Into<U>,

Maps this future’s Ok to a new type +using the Into trait.
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnOnce(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Executes another future after this one resolves successfully. The +success value is passed to a closure to create this subsequent future. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnOnce(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Executes another future if this one resolves to an error. The +error value is passed to a closure to create this subsequent future. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnOnce(&Self::Ok), + Self: Sized,

Do something with the success value of a future before passing it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnOnce(&Self::Error), + Self: Sized,

Do something with the error value of a future before passing it on. Read more
§

fn try_flatten(self) -> TryFlatten<Self, Self::Ok>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is another future. Read more
§

fn try_flatten_stream(self) -> TryFlattenStream<Self>
where + Self::Ok: TryStream<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F>
where + Self: Sized, + F: FnOnce(Self::Error) -> Self::Ok,

Unwraps this future’s output, producing a future with this future’s +Ok type as its +Output type. Read more
§

fn into_future(self) -> IntoFuture<Self>
where + Self: Sized,

Wraps a [TryFuture] into a type that implements +Future. Read more
§

fn try_poll_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Result<Self::Ok, Self::Error>>
where + Self: Unpin,

A convenience method for calling [TryFuture::try_poll] on Unpin +future types.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/h1/struct.UpgradeHandler.html b/actix_http/h1/struct.UpgradeHandler.html new file mode 100644 index 000000000..d6f341c06 --- /dev/null +++ b/actix_http/h1/struct.UpgradeHandler.html @@ -0,0 +1,40 @@ +UpgradeHandler in actix_http::h1 - Rust

Struct actix_http::h1::UpgradeHandler

source ·
pub struct UpgradeHandler;

Trait Implementations§

source§

impl<T> Service<(Request, Framed<T, Codec>)> for UpgradeHandler

§

type Response = ()

Responses given by the service.
§

type Error = Error

Errors produced by the service when polling readiness or executing call.
§

type Future = Pin<Box<dyn Future<Output = Result<<UpgradeHandler as Service<(Request, Framed<T, Codec>)>>::Response, <UpgradeHandler as Service<(Request, Framed<T, Codec>)>>::Error>>>>

The future response value.
source§

fn poll_ready(&self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>>

Returns Ready when the service is able to process requests. Read more
source§

fn call(&self, _: (Request, Framed<T, Codec>)) -> Self::Future

Process the request and return the response asynchronously. Read more
source§

impl<T> ServiceFactory<(Request, Framed<T, Codec>)> for UpgradeHandler

§

type Response = ()

Responses given by the created services.
§

type Error = Error

Errors produced by the created services.
§

type Config = ()

Service factory configuration.
§

type Service = UpgradeHandler

The kind of Service created by this factory.
§

type InitError = Error

Errors potentially raised while building a service.
§

type Future = Pin<Box<dyn Future<Output = Result<<UpgradeHandler as ServiceFactory<(Request, Framed<T, Codec>)>>::Service, <UpgradeHandler as ServiceFactory<(Request, Framed<T, Codec>)>>::InitError>>>>

The future of the Service instance.g
source§

fn new_service(&self, _: ()) -> Self::Future

Create and return a new service asynchronously.

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
§

impl<S, Req> IntoService<S, Req> for S
where + S: Service<Req>,

§

fn into_service(self) -> S

Convert to a Service
§

impl<SF, Req> IntoServiceFactory<SF, Req> for SF
where + SF: ServiceFactory<Req>,

§

fn into_factory(self) -> SF

Convert Self to a ServiceFactory
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<S, Req> ServiceExt<Req> for S
where + S: Service<Req>,

§

fn map<F, R>(self, f: F) -> Map<Self, F, Req, R>
where + Self: Sized, + F: FnMut(Self::Response) -> R,

Map this service’s output to a different type, returning a new service +of the resulting type. Read more
§

fn map_err<F, E>(self, f: F) -> MapErr<Self, Req, F, E>
where + Self: Sized, + F: Fn(Self::Error) -> E,

Map this service’s error to a different error, returning a new service. Read more
§

fn and_then<I, S1>(self, service: I) -> AndThenService<Self, S1, Req>
where + Self: Sized, + I: IntoService<S1, Self::Response>, + S1: Service<Self::Response, Error = Self::Error>,

Call another service after call to this one has resolved successfully. Read more
§

impl<SF, Req> ServiceFactoryExt<Req> for SF
where + SF: ServiceFactory<Req>,

§

fn map<F, R>(self, f: F) -> MapServiceFactory<Self, F, Req, R>
where + Self: Sized, + F: FnMut(Self::Response) -> R + Clone,

Map this service’s output to a different type, returning a new service +of the resulting type.
§

fn map_err<F, E>(self, f: F) -> MapErrServiceFactory<Self, Req, F, E>
where + Self: Sized, + F: Fn(Self::Error) -> E + Clone,

Map this service’s error to a different error, returning a new service.
§

fn map_init_err<F, E>(self, f: F) -> MapInitErr<Self, F, Req, E>
where + Self: Sized, + F: Fn(Self::InitError) -> E + Clone,

Map this factory’s init error to a different error, returning a new service.
§

fn and_then<I, SF1>(self, factory: I) -> AndThenServiceFactory<Self, SF1, Req>
where + Self: Sized, + Self::Config: Clone, + I: IntoServiceFactory<SF1, Self::Response>, + SF1: ServiceFactory<Self::Response, Config = Self::Config, Error = Self::Error, InitError = Self::InitError>,

Call another service after call to this one has resolved successfully.
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/h1/type.H1ServiceHandler.html b/actix_http/h1/type.H1ServiceHandler.html new file mode 100644 index 000000000..5354ceb65 --- /dev/null +++ b/actix_http/h1/type.H1ServiceHandler.html @@ -0,0 +1,2 @@ +H1ServiceHandler in actix_http::h1 - Rust

Type Alias actix_http::h1::H1ServiceHandler

source ·
pub type H1ServiceHandler<T, S, B, X, U> = HttpServiceHandler<T, S, B, X, U>;
Expand description

Service implementation for HTTP/1 transport

+

Aliased Type§

struct H1ServiceHandler<T, S, B, X, U> { /* private fields */ }
\ No newline at end of file diff --git a/actix_http/h1/upgrade/struct.UpgradeHandler.html b/actix_http/h1/upgrade/struct.UpgradeHandler.html new file mode 100644 index 000000000..bf0101bc8 --- /dev/null +++ b/actix_http/h1/upgrade/struct.UpgradeHandler.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/h1/struct.UpgradeHandler.html...

+ + + \ No newline at end of file diff --git a/actix_http/h1/utils/struct.SendResponse.html b/actix_http/h1/utils/struct.SendResponse.html new file mode 100644 index 000000000..1637442d8 --- /dev/null +++ b/actix_http/h1/utils/struct.SendResponse.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/h1/struct.SendResponse.html...

+ + + \ No newline at end of file diff --git a/actix_http/h2/dispatcher/struct.Dispatcher.html b/actix_http/h2/dispatcher/struct.Dispatcher.html new file mode 100644 index 000000000..ed89d9f3c --- /dev/null +++ b/actix_http/h2/dispatcher/struct.Dispatcher.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/h2/struct.Dispatcher.html...

+ + + \ No newline at end of file diff --git a/actix_http/h2/index.html b/actix_http/h2/index.html new file mode 100644 index 000000000..9297f2618 --- /dev/null +++ b/actix_http/h2/index.html @@ -0,0 +1,2 @@ +actix_http::h2 - Rust

Module actix_http::h2

source ·
Available on crate feature http2 only.
Expand description

HTTP/2 protocol.

+

Structs§

\ No newline at end of file diff --git a/actix_http/h2/service/struct.H2Service.html b/actix_http/h2/service/struct.H2Service.html new file mode 100644 index 000000000..b2988ab1c --- /dev/null +++ b/actix_http/h2/service/struct.H2Service.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/h2/struct.H2Service.html...

+ + + \ No newline at end of file diff --git a/actix_http/h2/sidebar-items.js b/actix_http/h2/sidebar-items.js new file mode 100644 index 000000000..bbc6338f1 --- /dev/null +++ b/actix_http/h2/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Dispatcher","H2Service","Payload"]}; \ No newline at end of file diff --git a/actix_http/h2/struct.Dispatcher.html b/actix_http/h2/struct.Dispatcher.html new file mode 100644 index 000000000..64ad24d4f --- /dev/null +++ b/actix_http/h2/struct.Dispatcher.html @@ -0,0 +1,119 @@ +Dispatcher in actix_http::h2 - Rust

Struct actix_http::h2::Dispatcher

source ·
pub struct Dispatcher<T, S, B, X, U> { /* private fields */ }
Available on crate feature http2 only.
Expand description

Dispatcher for HTTP/2 protocol.

+

Trait Implementations§

source§

impl<T, S, B, X, U> Future for Dispatcher<T, S, B, X, U>
where + T: AsyncRead + AsyncWrite + Unpin, + S: Service<Request>, + S::Error: Into<Response<BoxBody>>, + S::Future: 'static, + S::Response: Into<Response<B>>, + B: MessageBody,

§

type Output = Result<(), DispatchError>

The type of value produced on completion.
source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
source§

impl<'__pin, T, S, B, X, U> Unpin for Dispatcher<T, S, B, X, U>
where + __Origin<'__pin, T, S, B, X, U>: Unpin,

Auto Trait Implementations§

§

impl<T, S, B, X, U> !Freeze for Dispatcher<T, S, B, X, U>

§

impl<T, S, B, X, U> !RefUnwindSafe for Dispatcher<T, S, B, X, U>

§

impl<T, S, B, X, U> !Send for Dispatcher<T, S, B, X, U>

§

impl<T, S, B, X, U> !Sync for Dispatcher<T, S, B, X, U>

§

impl<T, S, B, X, U> !UnwindSafe for Dispatcher<T, S, B, X, U>

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

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

§

fn map<U, F>(self, f: F) -> Map<Self, F>
where + F: FnOnce(Self::Output) -> U, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn map_into<U>(self) -> MapInto<Self, U>
where + Self::Output: Into<U>, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnOnce(Self::Output) -> Fut, + Fut: Future, + Self: Sized,

Chain on a computation for when a future finished, passing the result of +the future to the provided closure f. Read more
§

fn left_future<B>(self) -> Either<Self, B>
where + B: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the left-hand variant +of that Either. Read more
§

fn right_future<A>(self) -> Either<A, Self>
where + A: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the right-hand variant +of that Either. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Convert this future into a single element stream. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Output: Future, + Self: Sized,

Flatten the execution of this future when the output of this +future is itself another future. Read more
§

fn flatten_stream(self) -> FlattenStream<Self>
where + Self::Output: Stream, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a future such that poll will never again be called once it has +completed. This method can be used to turn any Future into a +FusedFuture. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnOnce(&Self::Output), + Self: Sized,

Do something with the output of a future before passing it on. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the future. Read more
§

fn shared(self) -> Shared<Self>
where + Self: Sized, + Self::Output: Clone,

Available on crate feature std only.
Create a cloneable handle to this future where all handles will resolve +to the same result. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn unit_error(self) -> UnitError<Self>
where + Self: Sized,

§

fn never_error(self) -> NeverError<Self>
where + Self: Sized,

§

fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where + Self: Unpin,

A convenience for calling Future::poll on Unpin future types.
§

fn now_or_never(self) -> Option<Self::Output>
where + Self: Sized,

Evaluates and consumes the future, returning the resulting output if +the future is ready after the first call to Future::poll. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<F> IntoFuture for F
where + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
§

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
§

fn try_poll( + self: Pin<&mut F>, + cx: &mut Context<'_> +) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
§

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

§

fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>
where + Self::Ok: Sink<Item, Error = Self::Error>, + Self: Sized,

Available on crate feature sink only.
Flattens the execution of this future when the successful result of this +future is a [Sink]. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + F: FnOnce(Self::Ok) -> T, + Self: Sized,

Maps this future’s success value to a different value. Read more
§

fn map_ok_or_else<T, E, F>(self, e: E, f: F) -> MapOkOrElse<Self, F, E>
where + F: FnOnce(Self::Ok) -> T, + E: FnOnce(Self::Error) -> T, + Self: Sized,

Maps this future’s success value to a different value, and permits for error handling resulting in the same type. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + F: FnOnce(Self::Error) -> E, + Self: Sized,

Maps this future’s error value to a different value. Read more
§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Maps this future’s Error to a new error type +using the Into trait. Read more
§

fn ok_into<U>(self) -> OkInto<Self, U>
where + Self: Sized, + Self::Ok: Into<U>,

Maps this future’s Ok to a new type +using the Into trait.
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnOnce(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Executes another future after this one resolves successfully. The +success value is passed to a closure to create this subsequent future. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnOnce(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Executes another future if this one resolves to an error. The +error value is passed to a closure to create this subsequent future. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnOnce(&Self::Ok), + Self: Sized,

Do something with the success value of a future before passing it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnOnce(&Self::Error), + Self: Sized,

Do something with the error value of a future before passing it on. Read more
§

fn try_flatten(self) -> TryFlatten<Self, Self::Ok>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is another future. Read more
§

fn try_flatten_stream(self) -> TryFlattenStream<Self>
where + Self::Ok: TryStream<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F>
where + Self: Sized, + F: FnOnce(Self::Error) -> Self::Ok,

Unwraps this future’s output, producing a future with this future’s +Ok type as its +Output type. Read more
§

fn into_future(self) -> IntoFuture<Self>
where + Self: Sized,

Wraps a [TryFuture] into a type that implements +Future. Read more
§

fn try_poll_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Result<Self::Ok, Self::Error>>
where + Self: Unpin,

A convenience method for calling [TryFuture::try_poll] on Unpin +future types.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/h2/struct.H2Service.html b/actix_http/h2/struct.H2Service.html new file mode 100644 index 000000000..a1853d613 --- /dev/null +++ b/actix_http/h2/struct.H2Service.html @@ -0,0 +1,101 @@ +H2Service in actix_http::h2 - Rust

Struct actix_http::h2::H2Service

source ·
pub struct H2Service<T, S, B> { /* private fields */ }
Available on crate feature http2 only.
Expand description

ServiceFactory implementation for HTTP/2 transport

+

Implementations§

source§

impl<S, B> H2Service<TlsStream<TcpStream>, S, B>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>> + 'static, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static,

source

pub fn openssl( + self, + acceptor: SslAcceptor +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<SslError, DispatchError>, InitError = S::InitError>

Available on crate feature openssl only.

Create OpenSSL based service.

+
source§

impl<S, B> H2Service<TlsStream<TcpStream>, S, B>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>> + 'static, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static,

source

pub fn rustls( + self, + config: ServerConfig +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<Error, DispatchError>, InitError = S::InitError>

Available on crate feature rustls-0_20 only.

Create Rustls v0.20 based service.

+
source§

impl<S, B> H2Service<TlsStream<TcpStream>, S, B>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>> + 'static, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static,

source

pub fn rustls_021( + self, + config: ServerConfig +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<Error, DispatchError>, InitError = S::InitError>

Available on crate feature rustls-0_21 only.

Create Rustls v0.21 based service.

+
source§

impl<S, B> H2Service<TlsStream<TcpStream>, S, B>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>> + 'static, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static,

source

pub fn rustls_0_22( + self, + config: ServerConfig +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<Error, DispatchError>, InitError = S::InitError>

Available on crate feature rustls-0_22 only.

Create Rustls v0.22 based service.

+
source§

impl<S, B> H2Service<TlsStream<TcpStream>, S, B>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>> + 'static, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static,

source

pub fn rustls_0_23( + self, + config: ServerConfig +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<Error, DispatchError>, InitError = S::InitError>

Available on crate feature rustls-0_23 only.

Create Rustls v0.23 based service.

+
source§

impl<S, B> H2Service<TcpStream, S, B>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>> + 'static, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static,

source

pub fn tcp( + self +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = DispatchError, InitError = S::InitError>

Create plain TCP based service

+

Trait Implementations§

source§

impl<T, S, B> ServiceFactory<(T, Option<SocketAddr>)> for H2Service<T, S, B>
where + T: AsyncRead + AsyncWrite + Unpin + 'static, + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>> + 'static, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static,

§

type Response = ()

Responses given by the created services.
§

type Error = DispatchError

Errors produced by the created services.
§

type Config = ()

Service factory configuration.
§

type Service = H2ServiceHandler<T, <S as ServiceFactory<Request>>::Service, B>

The kind of Service created by this factory.
§

type InitError = <S as ServiceFactory<Request>>::InitError

Errors potentially raised while building a service.
§

type Future = Pin<Box<dyn Future<Output = Result<<H2Service<T, S, B> as ServiceFactory<(T, Option<SocketAddr>)>>::Service, <H2Service<T, S, B> as ServiceFactory<(T, Option<SocketAddr>)>>::InitError>>>>

The future of the Service instance.g
source§

fn new_service(&self, _: ()) -> Self::Future

Create and return a new service asynchronously.

Auto Trait Implementations§

§

impl<T, S, B> Freeze for H2Service<T, S, B>
where + S: Freeze,

§

impl<T, S, B> !RefUnwindSafe for H2Service<T, S, B>

§

impl<T, S, B> !Send for H2Service<T, S, B>

§

impl<T, S, B> !Sync for H2Service<T, S, B>

§

impl<T, S, B> Unpin for H2Service<T, S, B>
where + S: Unpin, + T: Unpin, + B: Unpin,

§

impl<T, S, B> !UnwindSafe for H2Service<T, S, B>

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
§

impl<SF, Req> IntoServiceFactory<SF, Req> for SF
where + SF: ServiceFactory<Req>,

§

fn into_factory(self) -> SF

Convert Self to a ServiceFactory
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<SF, Req> ServiceFactoryExt<Req> for SF
where + SF: ServiceFactory<Req>,

§

fn map<F, R>(self, f: F) -> MapServiceFactory<Self, F, Req, R>
where + Self: Sized, + F: FnMut(Self::Response) -> R + Clone,

Map this service’s output to a different type, returning a new service +of the resulting type.
§

fn map_err<F, E>(self, f: F) -> MapErrServiceFactory<Self, Req, F, E>
where + Self: Sized, + F: Fn(Self::Error) -> E + Clone,

Map this service’s error to a different error, returning a new service.
§

fn map_init_err<F, E>(self, f: F) -> MapInitErr<Self, F, Req, E>
where + Self: Sized, + F: Fn(Self::InitError) -> E + Clone,

Map this factory’s init error to a different error, returning a new service.
§

fn and_then<I, SF1>(self, factory: I) -> AndThenServiceFactory<Self, SF1, Req>
where + Self: Sized, + Self::Config: Clone, + I: IntoServiceFactory<SF1, Self::Response>, + SF1: ServiceFactory<Self::Response, Config = Self::Config, Error = Self::Error, InitError = Self::InitError>,

Call another service after call to this one has resolved successfully.
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/h2/struct.Payload.html b/actix_http/h2/struct.Payload.html new file mode 100644 index 000000000..c76b93735 --- /dev/null +++ b/actix_http/h2/struct.Payload.html @@ -0,0 +1,253 @@ +Payload in actix_http::h2 - Rust

Struct actix_http::h2::Payload

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

HTTP/2 peer stream.

+

Trait Implementations§

source§

impl<S> From<Payload> for Payload<S>

source§

fn from(payload: Payload) -> Self

Converts to this type from the input type.
source§

impl Stream for Payload

§

type Item = Result<Bytes, PayloadError>

Values yielded by the stream.
source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Self::Item>>

Attempt to pull out the next value of this stream, registering the +current task for wakeup if the value is not yet available, and returning +None if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

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

source§

fn into(self) -> U

Calls U::from(self).

+

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

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<T> StreamExt for T
where + T: Stream + ?Sized,

§

fn next(&mut self) -> Next<'_, Self>
where + Self: Unpin,

Creates a future that resolves to the next item in the stream. Read more
§

fn into_future(self) -> StreamFuture<Self>
where + Self: Sized + Unpin,

Converts this stream into a future of (next_item, tail_of_stream). +If the stream terminates, then the next item is None. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + F: FnMut(Self::Item) -> T, + Self: Sized,

Maps this stream’s items to a different type, returning a new stream of +the resulting type. Read more
§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates a stream which gives the current iteration count as well as +the next value. Read more
§

fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Filters the values produced by this stream according to the provided +asynchronous predicate. Read more
§

fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = Option<T>>, + Self: Sized,

Filters the values produced by this stream while simultaneously mapping +them to a different type according to the provided asynchronous closure. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized,

Computes from this stream’s items new items of a different type using +an asynchronous closure. Read more
§

fn collect<C>(self) -> Collect<Self, C>
where + C: Default + Extend<Self::Item>, + Self: Sized,

Transforms a stream into a collection, returning a +future representing the result of that computation. Read more
§

fn unzip<A, B, FromA, FromB>(self) -> Unzip<Self, FromA, FromB>
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Stream<Item = (A, B)>,

Converts a stream of pairs into a future, which +resolves to pair of containers. Read more
§

fn concat(self) -> Concat<Self>
where + Self: Sized, + Self::Item: Extend<<Self::Item as IntoIterator>::Item> + IntoIterator + Default,

Concatenate all items of a stream into a single extendable +destination, returning a future representing the end result. Read more
§

fn count(self) -> Count<Self>
where + Self: Sized,

Drives the stream to completion, counting the number of items. Read more
§

fn cycle(self) -> Cycle<Self>
where + Self: Sized + Clone,

Repeats a stream endlessly. Read more
§

fn fold<T, Fut, F>(self, init: T, f: F) -> Fold<Self, Fut, T, F>
where + F: FnMut(T, Self::Item) -> Fut, + Fut: Future<Output = T>, + Self: Sized,

Execute an accumulating asynchronous computation over a stream, +collecting all the values into one final result. Read more
§

fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if any element in stream satisfied a predicate. Read more
§

fn all<Fut, F>(self, f: F) -> All<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if all element in stream satisfied a predicate. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Item: Stream, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> FlattenUnorderedWithFlowController<Self, ()>
where + Self::Item: Stream + Unpin, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Polls +inner streams produced by the base stream concurrently. Read more
§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + F: FnMut(Self::Item) -> U, + U: Stream, + Self: Sized,

Maps a stream like [StreamExt::map] but flattens nested Streams. Read more
§

fn flat_map_unordered<U, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> FlatMapUnordered<Self, U, F>
where + U: Stream + Unpin, + F: FnMut(Self::Item) -> U, + Self: Sized,

Available on crate feature alloc only.
Maps a stream like [StreamExt::map] but flattens nested Streams +and polls them concurrently, yielding items in any order, as they made +available. Read more
§

fn scan<S, B, Fut, F>(self, initial_state: S, f: F) -> Scan<Self, S, Fut, F>
where + F: FnMut(&mut S, Self::Item) -> Fut, + Fut: Future<Output = Option<B>>, + Self: Sized,

Combinator similar to [StreamExt::fold] that holds internal state +and produces a new stream. Read more
§

fn skip_while<Fut, F>(self, f: F) -> SkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_while<Fut, F>(self, f: F) -> TakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Take elements from this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_until<Fut>(self, fut: Fut) -> TakeUntil<Self, Fut>
where + Fut: Future, + Self: Sized,

Take elements from this stream until the provided future resolves. Read more
§

fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream. Read more
§

fn for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> ForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Available on crate feature alloc only.
Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates a new stream of at most n items of the underlying stream. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates a new stream which skips n items of the underlying stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a stream such that poll_next will never +again be called once it has finished. This method can be used to turn +any Stream into a FusedStream. Read more
§

fn by_ref(&mut self) -> &mut Self

Borrows a stream, rather than consuming it. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the stream. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn buffered(self, n: usize) -> Buffered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures. Read more
§

fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures (unordered). Read more
§

fn zip<St>(self, other: St) -> Zip<Self, St>
where + St: Stream, + Self: Sized,

An adapter for zipping two streams together. Read more
§

fn chain<St>(self, other: St) -> Chain<Self, St>
where + St: Stream<Item = Self::Item>, + Self: Sized,

Adapter for chaining two streams. Read more
§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates a new stream which exposes a peek method. Read more
§

fn chunks(self, capacity: usize) -> Chunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up items of the stream inside a vector. Read more
§

fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up ready items of the stream inside a vector. Read more
§

fn forward<S>(self, sink: S) -> Forward<Self, S>
where + S: Sink<Self::Ok, Error = Self::Error>, + Self: Sized + TryStream,

Available on crate feature sink only.
A future that completes after the given stream has been fully processed +into the sink and the sink has been flushed and closed. Read more
§

fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
where + Self: Sized + Sink<Item>,

Available on crate features sink and alloc only.
Splits this Stream + Sink object into separate Sink and Stream +objects. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnMut(&Self::Item), + Self: Sized,

Do something with each item of this stream, afterwards passing it on. Read more
§

fn left_stream<B>(self) -> Either<Self, B>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the left-hand variant +of that Either. Read more
§

fn right_stream<B>(self) -> Either<B, Self>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the right-hand variant +of that Either. Read more
§

fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>
where + Self: Unpin,

A convenience method for calling [Stream::poll_next] on Unpin +stream types.
§

fn select_next_some(&mut self) -> SelectNextSome<'_, Self>
where + Self: Unpin + FusedStream,

Returns a Future that resolves when the next item in this stream is +ready. Read more
source§

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

§

type Error = Infallible

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

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

Performs the conversion.
source§

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

§

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

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

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

Performs the conversion.
§

impl<S, T, E> TryStream for S
where + S: Stream<Item = 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
§

fn try_poll_next( + self: Pin<&mut S>, + cx: &mut Context<'_> +) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>>

Poll this TryStream as if it were a Stream. Read more
§

impl<S> TryStreamExt for S
where + S: TryStream + ?Sized,

§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Wraps the current stream in a new stream which converts the error type +into the one provided. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> T,

Wraps the current stream in a new stream which maps the success value +using the provided closure. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + Self: Sized, + F: FnMut(Self::Error) -> E,

Wraps the current stream in a new stream which maps the error value +using the provided closure. Read more
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Chain on a computation for when a value is ready, passing the successful +results to the provided closure f. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnMut(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Chain on a computation for when an error happens, passing the +erroneous result to the provided closure f. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnMut(&Self::Ok), + Self: Sized,

Do something with the success value of this stream, afterwards passing +it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnMut(&Self::Error), + Self: Sized,

Do something with the error value of this stream, afterwards passing it on. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Wraps a [TryStream] into a type that implements +Stream Read more
§

fn try_next(&mut self) -> TryNext<'_, Self>
where + Self: Unpin,

Creates a future that attempts to resolve the next item in the stream. +If an error is encountered before the next item, the error is returned +instead. Read more
§

fn try_for_each<Fut, F>(self, f: F) -> TryForEach<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Ok = (), Error = Self::Error>, + Self: Sized,

Attempts to run this stream to completion, executing the provided +asynchronous closure for each element on the stream. Read more
§

fn try_skip_while<Fut, F>(self, f: F) -> TrySkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_take_while<Fut, F>(self, f: F) -> TryTakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Take elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> TryForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = Result<(), Self::Error>>, + Self: Sized,

Available on crate feature alloc only.
Attempts to run this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available, exiting as soon as an error occurs. Read more
§

fn try_collect<C>(self) -> TryCollect<Self, C>
where + C: Default + Extend<Self::Ok>, + Self: Sized,

Attempt to transform a stream into a collection, +returning a future representing the result of that computation. Read more
§

fn try_chunks(self, capacity: usize) -> TryChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful items of the stream inside a vector. Read more
§

fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful, ready items of the stream inside a vector. Read more
§

fn try_filter<Fut, F>(self, f: F) -> TryFilter<Self, Fut, F>
where + Fut: Future<Output = bool>, + F: FnMut(&Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream according to the +provided asynchronous closure. Read more
§

fn try_filter_map<Fut, F, T>(self, f: F) -> TryFilterMap<Self, Fut, F>
where + Fut: TryFuture<Ok = Option<T>, Error = Self::Error>, + F: FnMut(Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream while +simultaneously mapping them to a different type according to the +provided asynchronous closure. Read more
§

fn try_flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> TryFlattenUnordered<Self>
where + Self::Ok: TryStream + Unpin, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Produced streams +will be polled concurrently and any errors will be passed through without looking at them. +If the underlying base stream returns an error, it will be immediately propagated. Read more
§

fn try_flatten(self) -> TryFlatten<Self>
where + Self::Ok: TryStream, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn try_fold<T, Fut, F>(self, init: T, f: F) -> TryFold<Self, Fut, T, F>
where + F: FnMut(T, Self::Ok) -> Fut, + Fut: TryFuture<Ok = T, Error = Self::Error>, + Self: Sized,

Attempt to execute an accumulating asynchronous computation over a +stream, collecting all the values into one final result. Read more
§

fn try_concat(self) -> TryConcat<Self>
where + Self: Sized, + Self::Ok: Extend<<Self::Ok as IntoIterator>::Item> + IntoIterator + Default,

Attempt to concatenate all items of a stream into a single +extendable destination, returning a future representing the end result. Read more
§

fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently (unordered). Read more
§

fn try_buffered(self, n: usize) -> TryBuffered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently. Read more
§

fn try_poll_next_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Option<Result<Self::Ok, Self::Error>>>
where + Self: Unpin,

A convenience method for calling [TryStream::try_poll_next] on Unpin +stream types.
§

fn try_all<Fut, F>(self, f: F) -> TryAll<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if all items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that does not satisfy the predicate. Read more
§

fn try_any<Fut, F>(self, f: F) -> TryAny<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if any items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that satisfies the predicate. Read more
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/as_name/trait.AsHeaderName.html b/actix_http/header/as_name/trait.AsHeaderName.html new file mode 100644 index 000000000..5abd50c97 --- /dev/null +++ b/actix_http/header/as_name/trait.AsHeaderName.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/header/trait.AsHeaderName.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/common/constant.CACHE_STATUS.html b/actix_http/header/common/constant.CACHE_STATUS.html new file mode 100644 index 000000000..1e367b71e --- /dev/null +++ b/actix_http/header/common/constant.CACHE_STATUS.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/header/constant.CACHE_STATUS.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/common/constant.CDN_CACHE_CONTROL.html b/actix_http/header/common/constant.CDN_CACHE_CONTROL.html new file mode 100644 index 000000000..346704272 --- /dev/null +++ b/actix_http/header/common/constant.CDN_CACHE_CONTROL.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/header/constant.CDN_CACHE_CONTROL.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/common/constant.CROSS_ORIGIN_EMBEDDER_POLICY.html b/actix_http/header/common/constant.CROSS_ORIGIN_EMBEDDER_POLICY.html new file mode 100644 index 000000000..2daa89cf4 --- /dev/null +++ b/actix_http/header/common/constant.CROSS_ORIGIN_EMBEDDER_POLICY.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/header/constant.CROSS_ORIGIN_EMBEDDER_POLICY.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/common/constant.CROSS_ORIGIN_OPENER_POLICY.html b/actix_http/header/common/constant.CROSS_ORIGIN_OPENER_POLICY.html new file mode 100644 index 000000000..ec97e7caa --- /dev/null +++ b/actix_http/header/common/constant.CROSS_ORIGIN_OPENER_POLICY.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/header/constant.CROSS_ORIGIN_OPENER_POLICY.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/common/constant.CROSS_ORIGIN_RESOURCE_POLICY.html b/actix_http/header/common/constant.CROSS_ORIGIN_RESOURCE_POLICY.html new file mode 100644 index 000000000..086dbcf78 --- /dev/null +++ b/actix_http/header/common/constant.CROSS_ORIGIN_RESOURCE_POLICY.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/header/constant.CROSS_ORIGIN_RESOURCE_POLICY.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/common/constant.PERMISSIONS_POLICY.html b/actix_http/header/common/constant.PERMISSIONS_POLICY.html new file mode 100644 index 000000000..927eca366 --- /dev/null +++ b/actix_http/header/common/constant.PERMISSIONS_POLICY.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/header/constant.PERMISSIONS_POLICY.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/common/constant.X_FORWARDED_FOR.html b/actix_http/header/common/constant.X_FORWARDED_FOR.html new file mode 100644 index 000000000..1b96587a2 --- /dev/null +++ b/actix_http/header/common/constant.X_FORWARDED_FOR.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/header/constant.X_FORWARDED_FOR.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/common/constant.X_FORWARDED_HOST.html b/actix_http/header/common/constant.X_FORWARDED_HOST.html new file mode 100644 index 000000000..ea69d3fc0 --- /dev/null +++ b/actix_http/header/common/constant.X_FORWARDED_HOST.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/header/constant.X_FORWARDED_HOST.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/common/constant.X_FORWARDED_PROTO.html b/actix_http/header/common/constant.X_FORWARDED_PROTO.html new file mode 100644 index 000000000..a01c1d47f --- /dev/null +++ b/actix_http/header/common/constant.X_FORWARDED_PROTO.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/header/constant.X_FORWARDED_PROTO.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/constant.ACCEPT.html b/actix_http/header/constant.ACCEPT.html new file mode 100644 index 000000000..2665ca573 --- /dev/null +++ b/actix_http/header/constant.ACCEPT.html @@ -0,0 +1,10 @@ +ACCEPT in actix_http::header - Rust

Constant actix_http::header::ACCEPT

source ·
pub const ACCEPT: HeaderName;
Expand description

Advertises which content types the client is able to understand.

+

The Accept request HTTP header advertises which content types, expressed +as MIME types, the client is able to understand. Using content +negotiation, the server then selects one of the proposals, uses it and +informs the client of its choice with the Content-Type response header. +Browsers set adequate values for this header depending of the context +where the request is done: when fetching a CSS stylesheet a different +value is set for the request than when fetching an image, video or a +script.

+
\ No newline at end of file diff --git a/actix_http/header/constant.ACCEPT_CHARSET.html b/actix_http/header/constant.ACCEPT_CHARSET.html new file mode 100644 index 000000000..9fe33216d --- /dev/null +++ b/actix_http/header/constant.ACCEPT_CHARSET.html @@ -0,0 +1,12 @@ +ACCEPT_CHARSET in actix_http::header - Rust

Constant actix_http::header::ACCEPT_CHARSET

source ·
pub const ACCEPT_CHARSET: HeaderName;
Expand description

Advertises which character set the client is able to understand.

+

The Accept-Charset request HTTP header advertises which character set +the client is able to understand. Using content negotiation, the server +then selects one of the proposals, uses it and informs the client of its +choice within the Content-Type response header. Browsers usually don’t +set this header as the default value for each content type is usually +correct and transmitting it would allow easier fingerprinting.

+

If the server cannot serve any matching character set, it can +theoretically send back a 406 (Not Acceptable) error code. But, for a +better user experience, this is rarely done and the more common way is +to ignore the Accept-Charset header in this case.

+
\ No newline at end of file diff --git a/actix_http/header/constant.ACCEPT_ENCODING.html b/actix_http/header/constant.ACCEPT_ENCODING.html new file mode 100644 index 000000000..f0931b6af --- /dev/null +++ b/actix_http/header/constant.ACCEPT_ENCODING.html @@ -0,0 +1,28 @@ +ACCEPT_ENCODING in actix_http::header - Rust

Constant actix_http::header::ACCEPT_ENCODING

source ·
pub const ACCEPT_ENCODING: HeaderName;
Expand description

Advertises which content encoding the client is able to understand.

+

The Accept-Encoding request HTTP header advertises which content +encoding, usually a compression algorithm, the client is able to +understand. Using content negotiation, the server selects one of the +proposals, uses it and informs the client of its choice with the +Content-Encoding response header.

+

Even if both the client and the server supports the same compression +algorithms, the server may choose not to compress the body of a +response, if the identity value is also acceptable. Two common cases +lead to this:

+
    +
  • +

    The data to be sent is already compressed and a second compression +won’t lead to smaller data to be transmitted. This may the case with +some image formats;

    +
  • +
  • +

    The server is overloaded and cannot afford the computational overhead +induced by the compression requirement. Typically, Microsoft recommends +not to compress if a server use more than 80 % of its computational +power.

    +
  • +
+

As long as the identity value, meaning no encryption, is not explicitly +forbidden, by an identity;q=0 or a *;q=0 without another explicitly set +value for identity, the server must never send back a 406 Not Acceptable +error.

+
\ No newline at end of file diff --git a/actix_http/header/constant.ACCEPT_LANGUAGE.html b/actix_http/header/constant.ACCEPT_LANGUAGE.html new file mode 100644 index 000000000..48d6730ef --- /dev/null +++ b/actix_http/header/constant.ACCEPT_LANGUAGE.html @@ -0,0 +1,21 @@ +ACCEPT_LANGUAGE in actix_http::header - Rust

Constant actix_http::header::ACCEPT_LANGUAGE

source ·
pub const ACCEPT_LANGUAGE: HeaderName;
Expand description

Advertises which languages the client is able to understand.

+

The Accept-Language request HTTP header advertises which languages the +client is able to understand, and which locale variant is preferred. +Using content negotiation, the server then selects one of the proposals, +uses it and informs the client of its choice with the Content-Language +response header. Browsers set adequate values for this header according +their user interface language and even if a user can change it, this +happens rarely (and is frown upon as it leads to fingerprinting).

+

This header is a hint to be used when the server has no way of +determining the language via another way, like a specific URL, that is +controlled by an explicit user decision. It is recommended that the +server never overrides an explicit decision. The content of the +Accept-Language is often out of the control of the user (like when +traveling and using an Internet Cafe in a different country); the user +may also want to visit a page in another language than the locale of +their user interface.

+

If the server cannot serve any matching language, it can theoretically +send back a 406 (Not Acceptable) error code. But, for a better user +experience, this is rarely done and more common way is to ignore the +Accept-Language header in this case.

+
\ No newline at end of file diff --git a/actix_http/header/constant.ACCEPT_RANGES.html b/actix_http/header/constant.ACCEPT_RANGES.html new file mode 100644 index 000000000..a7a598ca0 --- /dev/null +++ b/actix_http/header/constant.ACCEPT_RANGES.html @@ -0,0 +1,7 @@ +ACCEPT_RANGES in actix_http::header - Rust

Constant actix_http::header::ACCEPT_RANGES

source ·
pub const ACCEPT_RANGES: HeaderName;
Expand description

Marker used by the server to advertise partial request support.

+

The Accept-Ranges response HTTP header is a marker used by the server to +advertise its support of partial requests. The value of this field +indicates the unit that can be used to define a range.

+

In presence of an Accept-Ranges header, the browser may try to resume an +interrupted download, rather than to start it from the start again.

+
\ No newline at end of file diff --git a/actix_http/header/constant.ACCESS_CONTROL_ALLOW_CREDENTIALS.html b/actix_http/header/constant.ACCESS_CONTROL_ALLOW_CREDENTIALS.html new file mode 100644 index 000000000..e74f75500 --- /dev/null +++ b/actix_http/header/constant.ACCESS_CONTROL_ALLOW_CREDENTIALS.html @@ -0,0 +1,20 @@ +ACCESS_CONTROL_ALLOW_CREDENTIALS in actix_http::header - Rust

Constant actix_http::header::ACCESS_CONTROL_ALLOW_CREDENTIALS

source ·
pub const ACCESS_CONTROL_ALLOW_CREDENTIALS: HeaderName;
Expand description

Preflight response indicating if the response to the request can be +exposed to the page.

+

The Access-Control-Allow-Credentials response header indicates whether +or not the response to the request can be exposed to the page. It can be +exposed when the true value is returned; it can’t in other cases.

+

Credentials are cookies, authorization headers or TLS client +certificates.

+

When used as part of a response to a preflight request, this indicates +whether or not the actual request can be made using credentials. Note +that simple GET requests are not preflighted, and so if a request is +made for a resource with credentials, if this header is not returned +with the resource, the response is ignored by the browser and not +returned to web content.

+

The Access-Control-Allow-Credentials header works in conjunction with +the XMLHttpRequest.withCredentials property or with the credentials +option in the Request() constructor of the Fetch API. Credentials must +be set on both sides (the Access-Control-Allow-Credentials header and in +the XHR or Fetch request) in order for the CORS request with credentials +to succeed.

+
\ No newline at end of file diff --git a/actix_http/header/constant.ACCESS_CONTROL_ALLOW_HEADERS.html b/actix_http/header/constant.ACCESS_CONTROL_ALLOW_HEADERS.html new file mode 100644 index 000000000..f3402f0f5 --- /dev/null +++ b/actix_http/header/constant.ACCESS_CONTROL_ALLOW_HEADERS.html @@ -0,0 +1,12 @@ +ACCESS_CONTROL_ALLOW_HEADERS in actix_http::header - Rust

Constant actix_http::header::ACCESS_CONTROL_ALLOW_HEADERS

source ·
pub const ACCESS_CONTROL_ALLOW_HEADERS: HeaderName;
Expand description

Preflight response indicating permitted HTTP headers.

+

The Access-Control-Allow-Headers response header is used in response to +a preflight request to indicate which HTTP headers will be available via +Access-Control-Expose-Headers when making the actual request.

+

The simple headers, Accept, Accept-Language, Content-Language, +Content-Type (but only with a MIME type of its parsed value (ignoring +parameters) of either application/x-www-form-urlencoded, +multipart/form-data, or text/plain), are always available and don’t need +to be listed by this header.

+

This header is required if the request has an +Access-Control-Request-Headers header.

+
\ No newline at end of file diff --git a/actix_http/header/constant.ACCESS_CONTROL_ALLOW_METHODS.html b/actix_http/header/constant.ACCESS_CONTROL_ALLOW_METHODS.html new file mode 100644 index 000000000..b9f61dd98 --- /dev/null +++ b/actix_http/header/constant.ACCESS_CONTROL_ALLOW_METHODS.html @@ -0,0 +1,5 @@ +ACCESS_CONTROL_ALLOW_METHODS in actix_http::header - Rust

Constant actix_http::header::ACCESS_CONTROL_ALLOW_METHODS

source ·
pub const ACCESS_CONTROL_ALLOW_METHODS: HeaderName;
Expand description

Preflight header response indicating permitted access methods.

+

The Access-Control-Allow-Methods response header specifies the method or +methods allowed when accessing the resource in response to a preflight +request.

+
\ No newline at end of file diff --git a/actix_http/header/constant.ACCESS_CONTROL_ALLOW_ORIGIN.html b/actix_http/header/constant.ACCESS_CONTROL_ALLOW_ORIGIN.html new file mode 100644 index 000000000..304c765c9 --- /dev/null +++ b/actix_http/header/constant.ACCESS_CONTROL_ALLOW_ORIGIN.html @@ -0,0 +1,3 @@ +ACCESS_CONTROL_ALLOW_ORIGIN in actix_http::header - Rust

Constant actix_http::header::ACCESS_CONTROL_ALLOW_ORIGIN

source ·
pub const ACCESS_CONTROL_ALLOW_ORIGIN: HeaderName;
Expand description

Indicates whether the response can be shared with resources with the +given origin.

+
\ No newline at end of file diff --git a/actix_http/header/constant.ACCESS_CONTROL_EXPOSE_HEADERS.html b/actix_http/header/constant.ACCESS_CONTROL_EXPOSE_HEADERS.html new file mode 100644 index 000000000..113a3af3e --- /dev/null +++ b/actix_http/header/constant.ACCESS_CONTROL_EXPOSE_HEADERS.html @@ -0,0 +1,3 @@ +ACCESS_CONTROL_EXPOSE_HEADERS in actix_http::header - Rust

Constant actix_http::header::ACCESS_CONTROL_EXPOSE_HEADERS

source ·
pub const ACCESS_CONTROL_EXPOSE_HEADERS: HeaderName;
Expand description

Indicates which headers can be exposed as part of the response by +listing their names.

+
\ No newline at end of file diff --git a/actix_http/header/constant.ACCESS_CONTROL_MAX_AGE.html b/actix_http/header/constant.ACCESS_CONTROL_MAX_AGE.html new file mode 100644 index 000000000..26272d22d --- /dev/null +++ b/actix_http/header/constant.ACCESS_CONTROL_MAX_AGE.html @@ -0,0 +1,2 @@ +ACCESS_CONTROL_MAX_AGE in actix_http::header - Rust

Constant actix_http::header::ACCESS_CONTROL_MAX_AGE

source ·
pub const ACCESS_CONTROL_MAX_AGE: HeaderName;
Expand description

Indicates how long the results of a preflight request can be cached.

+
\ No newline at end of file diff --git a/actix_http/header/constant.ACCESS_CONTROL_REQUEST_HEADERS.html b/actix_http/header/constant.ACCESS_CONTROL_REQUEST_HEADERS.html new file mode 100644 index 000000000..f1ef59a1a --- /dev/null +++ b/actix_http/header/constant.ACCESS_CONTROL_REQUEST_HEADERS.html @@ -0,0 +1,3 @@ +ACCESS_CONTROL_REQUEST_HEADERS in actix_http::header - Rust

Constant actix_http::header::ACCESS_CONTROL_REQUEST_HEADERS

source ·
pub const ACCESS_CONTROL_REQUEST_HEADERS: HeaderName;
Expand description

Informs the server which HTTP headers will be used when an actual +request is made.

+
\ No newline at end of file diff --git a/actix_http/header/constant.ACCESS_CONTROL_REQUEST_METHOD.html b/actix_http/header/constant.ACCESS_CONTROL_REQUEST_METHOD.html new file mode 100644 index 000000000..33e879200 --- /dev/null +++ b/actix_http/header/constant.ACCESS_CONTROL_REQUEST_METHOD.html @@ -0,0 +1,3 @@ +ACCESS_CONTROL_REQUEST_METHOD in actix_http::header - Rust

Constant actix_http::header::ACCESS_CONTROL_REQUEST_METHOD

source ·
pub const ACCESS_CONTROL_REQUEST_METHOD: HeaderName;
Expand description

Informs the server know which HTTP method will be used when the actual +request is made.

+
\ No newline at end of file diff --git a/actix_http/header/constant.AGE.html b/actix_http/header/constant.AGE.html new file mode 100644 index 000000000..84c48819c --- /dev/null +++ b/actix_http/header/constant.AGE.html @@ -0,0 +1,6 @@ +AGE in actix_http::header - Rust

Constant actix_http::header::AGE

source ·
pub const AGE: HeaderName;
Expand description

Indicates the time in seconds the object has been in a proxy cache.

+

The Age header is usually close to zero. If it is Age: 0, it was +probably just fetched from the origin server; otherwise It is usually +calculated as a difference between the proxy’s current date and the Date +general header included in the HTTP response.

+
\ No newline at end of file diff --git a/actix_http/header/constant.ALLOW.html b/actix_http/header/constant.ALLOW.html new file mode 100644 index 000000000..fff8d8b43 --- /dev/null +++ b/actix_http/header/constant.ALLOW.html @@ -0,0 +1,7 @@ +ALLOW in actix_http::header - Rust

Constant actix_http::header::ALLOW

source ·
pub const ALLOW: HeaderName;
Expand description

Lists the set of methods support by a resource.

+

This header must be sent if the server responds with a 405 Method Not +Allowed status code to indicate which request methods can be used. An +empty Allow header indicates that the resource allows no request +methods, which might occur temporarily for a given resource, for +example.

+
\ No newline at end of file diff --git a/actix_http/header/constant.ALT_SVC.html b/actix_http/header/constant.ALT_SVC.html new file mode 100644 index 000000000..9fc1a05f4 --- /dev/null +++ b/actix_http/header/constant.ALT_SVC.html @@ -0,0 +1,2 @@ +ALT_SVC in actix_http::header - Rust

Constant actix_http::header::ALT_SVC

source ·
pub const ALT_SVC: HeaderName;
Expand description

Advertises the availability of alternate services to clients.

+
\ No newline at end of file diff --git a/actix_http/header/constant.AUTHORIZATION.html b/actix_http/header/constant.AUTHORIZATION.html new file mode 100644 index 000000000..017eb7ce8 --- /dev/null +++ b/actix_http/header/constant.AUTHORIZATION.html @@ -0,0 +1,4 @@ +AUTHORIZATION in actix_http::header - Rust

Constant actix_http::header::AUTHORIZATION

source ·
pub const AUTHORIZATION: HeaderName;
Expand description

Contains the credentials to authenticate a user agent with a server.

+

Usually this header is included after the server has responded with a +401 Unauthorized status and the WWW-Authenticate header.

+
\ No newline at end of file diff --git a/actix_http/header/constant.CACHE_CONTROL.html b/actix_http/header/constant.CACHE_CONTROL.html new file mode 100644 index 000000000..fc6c31bda --- /dev/null +++ b/actix_http/header/constant.CACHE_CONTROL.html @@ -0,0 +1,6 @@ +CACHE_CONTROL in actix_http::header - Rust

Constant actix_http::header::CACHE_CONTROL

source ·
pub const CACHE_CONTROL: HeaderName;
Expand description

Specifies directives for caching mechanisms in both requests and +responses.

+

Caching directives are unidirectional, meaning that a given directive in +a request is not implying that the same directive is to be given in the +response.

+
\ No newline at end of file diff --git a/actix_http/header/constant.CACHE_STATUS.html b/actix_http/header/constant.CACHE_STATUS.html new file mode 100644 index 000000000..ab441d3e7 --- /dev/null +++ b/actix_http/header/constant.CACHE_STATUS.html @@ -0,0 +1,4 @@ +CACHE_STATUS in actix_http::header - Rust

Constant actix_http::header::CACHE_STATUS

source ·
pub const CACHE_STATUS: HeaderName;
Expand description

Response header field that indicates how caches have handled that response and its corresponding +request.

+

See RFC 9211 for full semantics.

+
\ No newline at end of file diff --git a/actix_http/header/constant.CDN_CACHE_CONTROL.html b/actix_http/header/constant.CDN_CACHE_CONTROL.html new file mode 100644 index 000000000..04c3b39e2 --- /dev/null +++ b/actix_http/header/constant.CDN_CACHE_CONTROL.html @@ -0,0 +1,4 @@ +CDN_CACHE_CONTROL in actix_http::header - Rust

Constant actix_http::header::CDN_CACHE_CONTROL

source ·
pub const CDN_CACHE_CONTROL: HeaderName;
Expand description

Response header field that allows origin servers to control the behavior of CDN caches +interposed between them and clients separately from other caches that might handle the response.

+

See RFC 9213 for full semantics.

+
\ No newline at end of file diff --git a/actix_http/header/constant.CONNECTION.html b/actix_http/header/constant.CONNECTION.html new file mode 100644 index 000000000..1cd4b7cf0 --- /dev/null +++ b/actix_http/header/constant.CONNECTION.html @@ -0,0 +1,12 @@ +CONNECTION in actix_http::header - Rust

Constant actix_http::header::CONNECTION

source ·
pub const CONNECTION: HeaderName;
Expand description

Controls whether or not the network connection stays open after the +current transaction finishes.

+

If the value sent is keep-alive, the connection is persistent and not +closed, allowing for subsequent requests to the same server to be done.

+

Except for the standard hop-by-hop headers (Keep-Alive, +Transfer-Encoding, TE, Connection, Trailer, Upgrade, Proxy-Authorization +and Proxy-Authenticate), any hop-by-hop headers used by the message must +be listed in the Connection header, so that the first proxy knows he has +to consume them and not to forward them further. Standard hop-by-hop +headers can be listed too (it is often the case of Keep-Alive, but this +is not mandatory.

+
\ No newline at end of file diff --git a/actix_http/header/constant.CONTENT_DISPOSITION.html b/actix_http/header/constant.CONTENT_DISPOSITION.html new file mode 100644 index 000000000..2d1f615d1 --- /dev/null +++ b/actix_http/header/constant.CONTENT_DISPOSITION.html @@ -0,0 +1,16 @@ +CONTENT_DISPOSITION in actix_http::header - Rust

Constant actix_http::header::CONTENT_DISPOSITION

source ·
pub const CONTENT_DISPOSITION: HeaderName;
Expand description

Indicates if the content is expected to be displayed inline.

+

In a regular HTTP response, the Content-Disposition response header is a +header indicating if the content is expected to be displayed inline in +the browser, that is, as a Web page or as part of a Web page, or as an +attachment, that is downloaded and saved locally.

+

In a multipart/form-data body, the HTTP Content-Disposition general +header is a header that can be used on the subpart of a multipart body +to give information about the field it applies to. The subpart is +delimited by the boundary defined in the Content-Type header. Used on +the body itself, Content-Disposition has no effect.

+

The Content-Disposition header is defined in the larger context of MIME +messages for e-mail, but only a subset of the possible parameters apply +to HTTP forms and POST requests. Only the value form-data, as well as +the optional directive name and filename, can be used in the HTTP +context.

+
\ No newline at end of file diff --git a/actix_http/header/constant.CONTENT_ENCODING.html b/actix_http/header/constant.CONTENT_ENCODING.html new file mode 100644 index 000000000..c2f389f57 --- /dev/null +++ b/actix_http/header/constant.CONTENT_ENCODING.html @@ -0,0 +1,9 @@ +CONTENT_ENCODING in actix_http::header - Rust

Constant actix_http::header::CONTENT_ENCODING

source ·
pub const CONTENT_ENCODING: HeaderName;
Expand description

Used to compress the media-type.

+

When present, its value indicates what additional content encoding has +been applied to the entity-body. It lets the client know, how to decode +in order to obtain the media-type referenced by the Content-Type header.

+

It is recommended to compress data as much as possible and therefore to +use this field, but some types of resources, like jpeg images, are +already compressed. Sometimes using additional compression doesn’t +reduce payload size and can even make the payload longer.

+
\ No newline at end of file diff --git a/actix_http/header/constant.CONTENT_LANGUAGE.html b/actix_http/header/constant.CONTENT_LANGUAGE.html new file mode 100644 index 000000000..c127f110b --- /dev/null +++ b/actix_http/header/constant.CONTENT_LANGUAGE.html @@ -0,0 +1,12 @@ +CONTENT_LANGUAGE in actix_http::header - Rust

Constant actix_http::header::CONTENT_LANGUAGE

source ·
pub const CONTENT_LANGUAGE: HeaderName;
Expand description

Used to describe the languages intended for the audience.

+

This header allows a user to differentiate according to the users’ own +preferred language. For example, if “Content-Language: de-DE” is set, it +says that the document is intended for German language speakers +(however, it doesn’t indicate the document is written in German. For +example, it might be written in English as part of a language course for +German speakers).

+

If no Content-Language is specified, the default is that the content is +intended for all language audiences. Multiple language tags are also +possible, as well as applying the Content-Language header to various +media types and not only to textual documents.

+
\ No newline at end of file diff --git a/actix_http/header/constant.CONTENT_LENGTH.html b/actix_http/header/constant.CONTENT_LENGTH.html new file mode 100644 index 000000000..cfaeebece --- /dev/null +++ b/actix_http/header/constant.CONTENT_LENGTH.html @@ -0,0 +1,4 @@ +CONTENT_LENGTH in actix_http::header - Rust

Constant actix_http::header::CONTENT_LENGTH

source ·
pub const CONTENT_LENGTH: HeaderName;
Expand description

Indicates the size of the entity-body.

+

The header value must be a decimal indicating the number of octets sent +to the recipient.

+
\ No newline at end of file diff --git a/actix_http/header/constant.CONTENT_LOCATION.html b/actix_http/header/constant.CONTENT_LOCATION.html new file mode 100644 index 000000000..9bc0371a3 --- /dev/null +++ b/actix_http/header/constant.CONTENT_LOCATION.html @@ -0,0 +1,10 @@ +CONTENT_LOCATION in actix_http::header - Rust

Constant actix_http::header::CONTENT_LOCATION

source ·
pub const CONTENT_LOCATION: HeaderName;
Expand description

Indicates an alternate location for the returned data.

+

The principal use case is to indicate the URL of the resource +transmitted as the result of content negotiation.

+

Location and Content-Location are different: Location indicates the +target of a redirection (or the URL of a newly created document), while +Content-Location indicates the direct URL to use to access the resource, +without the need of further content negotiation. Location is a header +associated with the response, while Content-Location is associated with +the entity returned.

+
\ No newline at end of file diff --git a/actix_http/header/constant.CONTENT_RANGE.html b/actix_http/header/constant.CONTENT_RANGE.html new file mode 100644 index 000000000..541dfacb8 --- /dev/null +++ b/actix_http/header/constant.CONTENT_RANGE.html @@ -0,0 +1,2 @@ +CONTENT_RANGE in actix_http::header - Rust

Constant actix_http::header::CONTENT_RANGE

source ·
pub const CONTENT_RANGE: HeaderName;
Expand description

Indicates where in a full body message a partial message belongs.

+
\ No newline at end of file diff --git a/actix_http/header/constant.CONTENT_SECURITY_POLICY.html b/actix_http/header/constant.CONTENT_SECURITY_POLICY.html new file mode 100644 index 000000000..cd97ae362 --- /dev/null +++ b/actix_http/header/constant.CONTENT_SECURITY_POLICY.html @@ -0,0 +1,6 @@ +CONTENT_SECURITY_POLICY in actix_http::header - Rust

Constant actix_http::header::CONTENT_SECURITY_POLICY

source ·
pub const CONTENT_SECURITY_POLICY: HeaderName;
Expand description

Allows controlling resources the user agent is allowed to load for a +given page.

+

With a few exceptions, policies mostly involve specifying server origins +and script endpoints. This helps guard against cross-site scripting +attacks (XSS).

+
\ No newline at end of file diff --git a/actix_http/header/constant.CONTENT_SECURITY_POLICY_REPORT_ONLY.html b/actix_http/header/constant.CONTENT_SECURITY_POLICY_REPORT_ONLY.html new file mode 100644 index 000000000..37320e2a9 --- /dev/null +++ b/actix_http/header/constant.CONTENT_SECURITY_POLICY_REPORT_ONLY.html @@ -0,0 +1,6 @@ +CONTENT_SECURITY_POLICY_REPORT_ONLY in actix_http::header - Rust
pub const CONTENT_SECURITY_POLICY_REPORT_ONLY: HeaderName;
Expand description

Allows experimenting with policies by monitoring their effects.

+

The HTTP Content-Security-Policy-Report-Only response header allows web +developers to experiment with policies by monitoring (but not enforcing) +their effects. These violation reports consist of JSON documents sent +via an HTTP POST request to the specified URI.

+
\ No newline at end of file diff --git a/actix_http/header/constant.CONTENT_TYPE.html b/actix_http/header/constant.CONTENT_TYPE.html new file mode 100644 index 000000000..7e945cb0f --- /dev/null +++ b/actix_http/header/constant.CONTENT_TYPE.html @@ -0,0 +1,9 @@ +CONTENT_TYPE in actix_http::header - Rust

Constant actix_http::header::CONTENT_TYPE

source ·
pub const CONTENT_TYPE: HeaderName;
Expand description

Used to indicate the media type of the resource.

+

In responses, a Content-Type header tells the client what the content +type of the returned content actually is. Browsers will do MIME sniffing +in some cases and will not necessarily follow the value of this header; +to prevent this behavior, the header X-Content-Type-Options can be set +to nosniff.

+

In requests, (such as POST or PUT), the client tells the server what +type of data is actually sent.

+
\ No newline at end of file diff --git a/actix_http/header/constant.COOKIE.html b/actix_http/header/constant.COOKIE.html new file mode 100644 index 000000000..bdf29cf36 --- /dev/null +++ b/actix_http/header/constant.COOKIE.html @@ -0,0 +1,5 @@ +COOKIE in actix_http::header - Rust

Constant actix_http::header::COOKIE

source ·
pub const COOKIE: HeaderName;
Expand description

Contains stored HTTP cookies previously sent by the server with the +Set-Cookie header.

+

The Cookie header might be omitted entirely, if the privacy setting of +the browser are set to block them, for example.

+
\ No newline at end of file diff --git a/actix_http/header/constant.CROSS_ORIGIN_EMBEDDER_POLICY.html b/actix_http/header/constant.CROSS_ORIGIN_EMBEDDER_POLICY.html new file mode 100644 index 000000000..14332a909 --- /dev/null +++ b/actix_http/header/constant.CROSS_ORIGIN_EMBEDDER_POLICY.html @@ -0,0 +1,3 @@ +CROSS_ORIGIN_EMBEDDER_POLICY in actix_http::header - Rust

Constant actix_http::header::CROSS_ORIGIN_EMBEDDER_POLICY

source ·
pub const CROSS_ORIGIN_EMBEDDER_POLICY: HeaderName;
Expand description

Response header that prevents a document from loading any cross-origin resources that don’t +explicitly grant the document permission (using CORP or CORS).

+
\ No newline at end of file diff --git a/actix_http/header/constant.CROSS_ORIGIN_OPENER_POLICY.html b/actix_http/header/constant.CROSS_ORIGIN_OPENER_POLICY.html new file mode 100644 index 000000000..b6a84b8f4 --- /dev/null +++ b/actix_http/header/constant.CROSS_ORIGIN_OPENER_POLICY.html @@ -0,0 +1,3 @@ +CROSS_ORIGIN_OPENER_POLICY in actix_http::header - Rust

Constant actix_http::header::CROSS_ORIGIN_OPENER_POLICY

source ·
pub const CROSS_ORIGIN_OPENER_POLICY: HeaderName;
Expand description

Response header that allows you to ensure a top-level document does not share a browsing context +group with cross-origin documents.

+
\ No newline at end of file diff --git a/actix_http/header/constant.CROSS_ORIGIN_RESOURCE_POLICY.html b/actix_http/header/constant.CROSS_ORIGIN_RESOURCE_POLICY.html new file mode 100644 index 000000000..cc9956eb4 --- /dev/null +++ b/actix_http/header/constant.CROSS_ORIGIN_RESOURCE_POLICY.html @@ -0,0 +1,3 @@ +CROSS_ORIGIN_RESOURCE_POLICY in actix_http::header - Rust

Constant actix_http::header::CROSS_ORIGIN_RESOURCE_POLICY

source ·
pub const CROSS_ORIGIN_RESOURCE_POLICY: HeaderName;
Expand description

Response header that conveys a desire that the browser blocks no-cors cross-origin/cross-site +requests to the given resource.

+
\ No newline at end of file diff --git a/actix_http/header/constant.DATE.html b/actix_http/header/constant.DATE.html new file mode 100644 index 000000000..2b1ae7950 --- /dev/null +++ b/actix_http/header/constant.DATE.html @@ -0,0 +1,2 @@ +DATE in actix_http::header - Rust

Constant actix_http::header::DATE

source ·
pub const DATE: HeaderName;
Expand description

Contains the date and time at which the message was originated.

+
\ No newline at end of file diff --git a/actix_http/header/constant.DNT.html b/actix_http/header/constant.DNT.html new file mode 100644 index 000000000..f42268a2c --- /dev/null +++ b/actix_http/header/constant.DNT.html @@ -0,0 +1,4 @@ +DNT in actix_http::header - Rust

Constant actix_http::header::DNT

source ·
pub const DNT: HeaderName;
Expand description

Indicates the client’s tracking preference.

+

This header lets users indicate whether they would prefer privacy rather +than personalized content.

+
\ No newline at end of file diff --git a/actix_http/header/constant.ETAG.html b/actix_http/header/constant.ETAG.html new file mode 100644 index 000000000..c53ed5eff --- /dev/null +++ b/actix_http/header/constant.ETAG.html @@ -0,0 +1,13 @@ +ETAG in actix_http::header - Rust

Constant actix_http::header::ETAG

source ·
pub const ETAG: HeaderName;
Expand description

Identifier for a specific version of a resource.

+

This header allows caches to be more efficient, and saves bandwidth, as +a web server does not need to send a full response if the content has +not changed. On the other side, if the content has changed, etags are +useful to help prevent simultaneous updates of a resource from +overwriting each other (“mid-air collisions”).

+

If the resource at a given URL changes, a new Etag value must be +generated. Etags are therefore similar to fingerprints and might also be +used for tracking purposes by some servers. A comparison of them allows +to quickly determine whether two representations of a resource are the +same, but they might also be set to persist indefinitely by a tracking +server.

+
\ No newline at end of file diff --git a/actix_http/header/constant.EXPECT.html b/actix_http/header/constant.EXPECT.html new file mode 100644 index 000000000..1332738de --- /dev/null +++ b/actix_http/header/constant.EXPECT.html @@ -0,0 +1,19 @@ +EXPECT in actix_http::header - Rust

Constant actix_http::header::EXPECT

source ·
pub const EXPECT: HeaderName;
Expand description

Indicates expectations that need to be fulfilled by the server in order +to properly handle the request.

+

The only expectation defined in the specification is Expect: +100-continue, to which the server shall respond with:

+
    +
  • +

    100 if the information contained in the header is sufficient to cause +an immediate success,

    +
  • +
  • +

    417 (Expectation Failed) if it cannot meet the expectation; or any +other 4xx status otherwise.

    +
  • +
+

For example, the server may reject a request if its Content-Length is +too large.

+

No common browsers send the Expect header, but some other clients such +as cURL do so by default.

+
\ No newline at end of file diff --git a/actix_http/header/constant.EXPIRES.html b/actix_http/header/constant.EXPIRES.html new file mode 100644 index 000000000..410b45610 --- /dev/null +++ b/actix_http/header/constant.EXPIRES.html @@ -0,0 +1,6 @@ +EXPIRES in actix_http::header - Rust

Constant actix_http::header::EXPIRES

source ·
pub const EXPIRES: HeaderName;
Expand description

Contains the date/time after which the response is considered stale.

+

Invalid dates, like the value 0, represent a date in the past and mean +that the resource is already expired.

+

If there is a Cache-Control header with the “max-age” or “s-max-age” +directive in the response, the Expires header is ignored.

+
\ No newline at end of file diff --git a/actix_http/header/constant.FORWARDED.html b/actix_http/header/constant.FORWARDED.html new file mode 100644 index 000000000..9a61239b5 --- /dev/null +++ b/actix_http/header/constant.FORWARDED.html @@ -0,0 +1,9 @@ +FORWARDED in actix_http::header - Rust

Constant actix_http::header::FORWARDED

source ·
pub const FORWARDED: HeaderName;
Expand description

Contains information from the client-facing side of proxy servers that +is altered or lost when a proxy is involved in the path of the request.

+

The alternative and de-facto standard versions of this header are the +X-Forwarded-For, X-Forwarded-Host and X-Forwarded-Proto headers.

+

This header is used for debugging, statistics, and generating +location-dependent content and by design it exposes privacy sensitive +information, such as the IP address of the client. Therefore the user’s +privacy must be kept in mind when deploying this header.

+
\ No newline at end of file diff --git a/actix_http/header/constant.FROM.html b/actix_http/header/constant.FROM.html new file mode 100644 index 000000000..a9d9bd899 --- /dev/null +++ b/actix_http/header/constant.FROM.html @@ -0,0 +1,7 @@ +FROM in actix_http::header - Rust

Constant actix_http::header::FROM

source ·
pub const FROM: HeaderName;
Expand description

Contains an Internet email address for a human user who controls the +requesting user agent.

+

If you are running a robotic user agent (e.g. a crawler), the From +header should be sent, so you can be contacted if problems occur on +servers, such as if the robot is sending excessive, unwanted, or invalid +requests.

+
\ No newline at end of file diff --git a/actix_http/header/constant.HOST.html b/actix_http/header/constant.HOST.html new file mode 100644 index 000000000..e5a61e1ff --- /dev/null +++ b/actix_http/header/constant.HOST.html @@ -0,0 +1,8 @@ +HOST in actix_http::header - Rust

Constant actix_http::header::HOST

source ·
pub const HOST: HeaderName;
Expand description

Specifies the domain name of the server and (optionally) the TCP port +number on which the server is listening.

+

If no port is given, the default port for the service requested (e.g., +“80” for an HTTP URL) is implied.

+

A Host header field must be sent in all HTTP/1.1 request messages. A 400 +(Bad Request) status code will be sent to any HTTP/1.1 request message +that lacks a Host header field or contains more than one.

+
\ No newline at end of file diff --git a/actix_http/header/constant.IF_MATCH.html b/actix_http/header/constant.IF_MATCH.html new file mode 100644 index 000000000..30e84b519 --- /dev/null +++ b/actix_http/header/constant.IF_MATCH.html @@ -0,0 +1,25 @@ +IF_MATCH in actix_http::header - Rust

Constant actix_http::header::IF_MATCH

source ·
pub const IF_MATCH: HeaderName;
Expand description

Makes a request conditional based on the E-Tag.

+

For GET and HEAD methods, the server will send back the requested +resource only if it matches one of the listed ETags. For PUT and other +non-safe methods, it will only upload the resource in this case.

+

The comparison with the stored ETag uses the strong comparison +algorithm, meaning two files are considered identical byte to byte only. +This is weakened when the W/ prefix is used in front of the ETag.

+

There are two common use cases:

+
    +
  • +

    For GET and HEAD methods, used in combination with an Range header, it +can guarantee that the new ranges requested comes from the same resource +than the previous one. If it doesn’t match, then a 416 (Range Not +Satisfiable) response is returned.

    +
  • +
  • +

    For other methods, and in particular for PUT, If-Match can be used to +prevent the lost update problem. It can check if the modification of a +resource that the user wants to upload will not override another change +that has been done since the original resource was fetched. If the +request cannot be fulfilled, the 412 (Precondition Failed) response is +returned.

    +
  • +
+
\ No newline at end of file diff --git a/actix_http/header/constant.IF_MODIFIED_SINCE.html b/actix_http/header/constant.IF_MODIFIED_SINCE.html new file mode 100644 index 000000000..d515db37b --- /dev/null +++ b/actix_http/header/constant.IF_MODIFIED_SINCE.html @@ -0,0 +1,13 @@ +IF_MODIFIED_SINCE in actix_http::header - Rust

Constant actix_http::header::IF_MODIFIED_SINCE

source ·
pub const IF_MODIFIED_SINCE: HeaderName;
Expand description

Makes a request conditional based on the modification date.

+

The If-Modified-Since request HTTP header makes the request conditional: +the server will send back the requested resource, with a 200 status, +only if it has been last modified after the given date. If the request +has not been modified since, the response will be a 304 without any +body; the Last-Modified header will contain the date of last +modification. Unlike If-Unmodified-Since, If-Modified-Since can only be +used with a GET or HEAD.

+

When used in combination with If-None-Match, it is ignored, unless the +server doesn’t support If-None-Match.

+

The most common use case is to update a cached entity that has no +associated ETag.

+
\ No newline at end of file diff --git a/actix_http/header/constant.IF_NONE_MATCH.html b/actix_http/header/constant.IF_NONE_MATCH.html new file mode 100644 index 000000000..103c188df --- /dev/null +++ b/actix_http/header/constant.IF_NONE_MATCH.html @@ -0,0 +1,31 @@ +IF_NONE_MATCH in actix_http::header - Rust

Constant actix_http::header::IF_NONE_MATCH

source ·
pub const IF_NONE_MATCH: HeaderName;
Expand description

Makes a request conditional based on the E-Tag.

+

The If-None-Match HTTP request header makes the request conditional. For +GET and HEAD methods, the server will send back the requested resource, +with a 200 status, only if it doesn’t have an ETag matching the given +ones. For other methods, the request will be processed only if the +eventually existing resource’s ETag doesn’t match any of the values +listed.

+

When the condition fails for GET and HEAD methods, then the server must +return HTTP status code 304 (Not Modified). For methods that apply +server-side changes, the status code 412 (Precondition Failed) is used. +Note that the server generating a 304 response MUST generate any of the +following header fields that would have been sent in a 200 (OK) response +to the same request: Cache-Control, Content-Location, Date, ETag, +Expires, and Vary.

+

The comparison with the stored ETag uses the weak comparison algorithm, +meaning two files are considered identical not only if they are +identical byte to byte, but if the content is equivalent. For example, +two pages that would differ only by the date of generation in the footer +would be considered as identical.

+

When used in combination with If-Modified-Since, it has precedence (if +the server supports it).

+

There are two common use cases:

+
    +
  • For GET and HEAD methods, to update a cached entity that has an associated ETag.
  • +
  • For other methods, and in particular for PUT, If-None-Match used with +the * value can be used to save a file not known to exist, +guaranteeing that another upload didn’t happen before, losing the data +of the previous put; this problems is the variation of the lost update +problem.
  • +
+
\ No newline at end of file diff --git a/actix_http/header/constant.IF_RANGE.html b/actix_http/header/constant.IF_RANGE.html new file mode 100644 index 000000000..b3794d575 --- /dev/null +++ b/actix_http/header/constant.IF_RANGE.html @@ -0,0 +1,12 @@ +IF_RANGE in actix_http::header - Rust

Constant actix_http::header::IF_RANGE

source ·
pub const IF_RANGE: HeaderName;
Expand description

Makes a request conditional based on range.

+

The If-Range HTTP request header makes a range request conditional: if +the condition is fulfilled, the range request will be issued and the +server sends back a 206 Partial Content answer with the appropriate +body. If the condition is not fulfilled, the full resource is sent back, +with a 200 OK status.

+

This header can be used either with a Last-Modified validator, or with +an ETag, but not with both.

+

The most common use case is to resume a download, to guarantee that the +stored resource has not been modified since the last fragment has been +received.

+
\ No newline at end of file diff --git a/actix_http/header/constant.IF_UNMODIFIED_SINCE.html b/actix_http/header/constant.IF_UNMODIFIED_SINCE.html new file mode 100644 index 000000000..9c852f830 --- /dev/null +++ b/actix_http/header/constant.IF_UNMODIFIED_SINCE.html @@ -0,0 +1,22 @@ +IF_UNMODIFIED_SINCE in actix_http::header - Rust

Constant actix_http::header::IF_UNMODIFIED_SINCE

source ·
pub const IF_UNMODIFIED_SINCE: HeaderName;
Expand description

Makes the request conditional based on the last modification date.

+

The If-Unmodified-Since request HTTP header makes the request +conditional: the server will send back the requested resource, or accept +it in the case of a POST or another non-safe method, only if it has not +been last modified after the given date. If the request has been +modified after the given date, the response will be a 412 (Precondition +Failed) error.

+

There are two common use cases:

+
    +
  • +

    In conjunction non-safe methods, like POST, it can be used to +implement an optimistic concurrency control, like done by some wikis: +editions are rejected if the stored document has been modified since the +original has been retrieved.

    +
  • +
  • +

    In conjunction with a range request with a If-Range header, it can be +used to ensure that the new fragment requested comes from an unmodified +document.

    +
  • +
+
\ No newline at end of file diff --git a/actix_http/header/constant.LAST_MODIFIED.html b/actix_http/header/constant.LAST_MODIFIED.html new file mode 100644 index 000000000..16b71c949 --- /dev/null +++ b/actix_http/header/constant.LAST_MODIFIED.html @@ -0,0 +1,2 @@ +LAST_MODIFIED in actix_http::header - Rust

Constant actix_http::header::LAST_MODIFIED

source ·
pub const LAST_MODIFIED: HeaderName;
Expand description

Content-Types that are acceptable for the response.

+
\ No newline at end of file diff --git a/actix_http/header/constant.LINK.html b/actix_http/header/constant.LINK.html new file mode 100644 index 000000000..be9e4a9d2 --- /dev/null +++ b/actix_http/header/constant.LINK.html @@ -0,0 +1,3 @@ +LINK in actix_http::header - Rust

Constant actix_http::header::LINK

source ·
pub const LINK: HeaderName;
Expand description

Allows the server to point an interested client to another resource +containing metadata about the requested resource.

+
\ No newline at end of file diff --git a/actix_http/header/constant.LOCATION.html b/actix_http/header/constant.LOCATION.html new file mode 100644 index 000000000..4e3653066 --- /dev/null +++ b/actix_http/header/constant.LOCATION.html @@ -0,0 +1,29 @@ +LOCATION in actix_http::header - Rust

Constant actix_http::header::LOCATION

source ·
pub const LOCATION: HeaderName;
Expand description

Indicates the URL to redirect a page to.

+

The Location response header indicates the URL to redirect a page to. It +only provides a meaning when served with a 3xx status response.

+

The HTTP method used to make the new request to fetch the page pointed +to by Location depends of the original method and of the kind of +redirection:

+
    +
  • +

    If 303 (See Also) responses always lead to the use of a GET method, +307 (Temporary Redirect) and 308 (Permanent Redirect) don’t change the +method used in the original request;

    +
  • +
  • +

    301 (Permanent Redirect) and 302 (Found) doesn’t change the method +most of the time, though older user-agents may (so you basically don’t +know).

    +
  • +
+

All responses with one of these status codes send a Location header.

+

Beside redirect response, messages with 201 (Created) status also +include the Location header. It indicates the URL to the newly created +resource.

+

Location and Content-Location are different: Location indicates the +target of a redirection (or the URL of a newly created resource), while +Content-Location indicates the direct URL to use to access the resource +when content negotiation happened, without the need of further content +negotiation. Location is a header associated with the response, while +Content-Location is associated with the entity returned.

+
\ No newline at end of file diff --git a/actix_http/header/constant.MAX_FORWARDS.html b/actix_http/header/constant.MAX_FORWARDS.html new file mode 100644 index 000000000..6f31dec57 --- /dev/null +++ b/actix_http/header/constant.MAX_FORWARDS.html @@ -0,0 +1,3 @@ +MAX_FORWARDS in actix_http::header - Rust

Constant actix_http::header::MAX_FORWARDS

source ·
pub const MAX_FORWARDS: HeaderName;
Expand description

Indicates the max number of intermediaries the request should be sent +through.

+
\ No newline at end of file diff --git a/actix_http/header/constant.ORIGIN.html b/actix_http/header/constant.ORIGIN.html new file mode 100644 index 000000000..4c20fac49 --- /dev/null +++ b/actix_http/header/constant.ORIGIN.html @@ -0,0 +1,6 @@ +ORIGIN in actix_http::header - Rust

Constant actix_http::header::ORIGIN

source ·
pub const ORIGIN: HeaderName;
Expand description

Indicates where a fetch originates from.

+

It doesn’t include any path information, but only the server name. It is +sent with CORS requests, as well as with POST requests. It is similar to +the Referer header, but, unlike this header, it doesn’t disclose the +whole path.

+
\ No newline at end of file diff --git a/actix_http/header/constant.PERMISSIONS_POLICY.html b/actix_http/header/constant.PERMISSIONS_POLICY.html new file mode 100644 index 000000000..618545372 --- /dev/null +++ b/actix_http/header/constant.PERMISSIONS_POLICY.html @@ -0,0 +1,3 @@ +PERMISSIONS_POLICY in actix_http::header - Rust

Constant actix_http::header::PERMISSIONS_POLICY

source ·
pub const PERMISSIONS_POLICY: HeaderName;
Expand description

Response header that provides a mechanism to allow and deny the use of browser features in a +document or within any <iframe> elements in the document.

+
\ No newline at end of file diff --git a/actix_http/header/constant.PRAGMA.html b/actix_http/header/constant.PRAGMA.html new file mode 100644 index 000000000..0897a3a8d --- /dev/null +++ b/actix_http/header/constant.PRAGMA.html @@ -0,0 +1,6 @@ +PRAGMA in actix_http::header - Rust

Constant actix_http::header::PRAGMA

source ·
pub const PRAGMA: HeaderName;
Expand description

HTTP/1.0 header usually used for backwards compatibility.

+

The Pragma HTTP/1.0 general header is an implementation-specific header +that may have various effects along the request-response chain. It is +used for backwards compatibility with HTTP/1.0 caches where the +Cache-Control HTTP/1.1 header is not yet present.

+
\ No newline at end of file diff --git a/actix_http/header/constant.PROXY_AUTHENTICATE.html b/actix_http/header/constant.PROXY_AUTHENTICATE.html new file mode 100644 index 000000000..24f45e555 --- /dev/null +++ b/actix_http/header/constant.PROXY_AUTHENTICATE.html @@ -0,0 +1,14 @@ +PROXY_AUTHENTICATE in actix_http::header - Rust

Constant actix_http::header::PROXY_AUTHENTICATE

source ·
pub const PROXY_AUTHENTICATE: HeaderName;
Expand description

Defines the authentication method that should be used to gain access to +a proxy.

+

Unlike www-authenticate, the proxy-authenticate header field applies +only to the next outbound client on the response chain. This is because +only the client that chose a given proxy is likely to have the +credentials necessary for authentication. However, when multiple proxies +are used within the same administrative domain, such as office and +regional caching proxies within a large corporate network, it is common +for credentials to be generated by the user agent and passed through the +hierarchy until consumed. Hence, in such a configuration, it will appear +as if Proxy-Authenticate is being forwarded because each proxy will send +the same challenge set.

+

The proxy-authenticate header is sent along with a 407 Proxy Authentication Required.

+
\ No newline at end of file diff --git a/actix_http/header/constant.PROXY_AUTHORIZATION.html b/actix_http/header/constant.PROXY_AUTHORIZATION.html new file mode 100644 index 000000000..53c325832 --- /dev/null +++ b/actix_http/header/constant.PROXY_AUTHORIZATION.html @@ -0,0 +1,5 @@ +PROXY_AUTHORIZATION in actix_http::header - Rust

Constant actix_http::header::PROXY_AUTHORIZATION

source ·
pub const PROXY_AUTHORIZATION: HeaderName;
Expand description

Contains the credentials to authenticate a user agent to a proxy server.

+

This header is usually included after the server has responded with a +407 Proxy Authentication Required status and the Proxy-Authenticate +header.

+
\ No newline at end of file diff --git a/actix_http/header/constant.PUBLIC_KEY_PINS.html b/actix_http/header/constant.PUBLIC_KEY_PINS.html new file mode 100644 index 000000000..f48363f9f --- /dev/null +++ b/actix_http/header/constant.PUBLIC_KEY_PINS.html @@ -0,0 +1,6 @@ +PUBLIC_KEY_PINS in actix_http::header - Rust

Constant actix_http::header::PUBLIC_KEY_PINS

source ·
pub const PUBLIC_KEY_PINS: HeaderName;
Expand description

Associates a specific cryptographic public key with a certain server.

+

This decreases the risk of MITM attacks with forged certificates. If one +or several keys are pinned and none of them are used by the server, the +browser will not accept the response as legitimate, and will not display +it.

+
\ No newline at end of file diff --git a/actix_http/header/constant.PUBLIC_KEY_PINS_REPORT_ONLY.html b/actix_http/header/constant.PUBLIC_KEY_PINS_REPORT_ONLY.html new file mode 100644 index 000000000..d087777d0 --- /dev/null +++ b/actix_http/header/constant.PUBLIC_KEY_PINS_REPORT_ONLY.html @@ -0,0 +1,5 @@ +PUBLIC_KEY_PINS_REPORT_ONLY in actix_http::header - Rust

Constant actix_http::header::PUBLIC_KEY_PINS_REPORT_ONLY

source ·
pub const PUBLIC_KEY_PINS_REPORT_ONLY: HeaderName;
Expand description

Sends reports of pinning violation to the report-uri specified in the +header.

+

Unlike Public-Key-Pins, this header still allows browsers to connect +to the server if the pinning is violated.

+
\ No newline at end of file diff --git a/actix_http/header/constant.RANGE.html b/actix_http/header/constant.RANGE.html new file mode 100644 index 000000000..4863586cd --- /dev/null +++ b/actix_http/header/constant.RANGE.html @@ -0,0 +1,8 @@ +RANGE in actix_http::header - Rust

Constant actix_http::header::RANGE

source ·
pub const RANGE: HeaderName;
Expand description

Indicates the part of a document that the server should return.

+

Several parts can be requested with one Range header at once, and the +server may send back these ranges in a multipart document. If the server +sends back ranges, it uses the 206 Partial Content for the response. If +the ranges are invalid, the server returns the 416 Range Not Satisfiable +error. The server can also ignore the Range header and return the whole +document with a 200 status code.

+
\ No newline at end of file diff --git a/actix_http/header/constant.REFERER.html b/actix_http/header/constant.REFERER.html new file mode 100644 index 000000000..36a4e50a2 --- /dev/null +++ b/actix_http/header/constant.REFERER.html @@ -0,0 +1,6 @@ +REFERER in actix_http::header - Rust

Constant actix_http::header::REFERER

source ·
pub const REFERER: HeaderName;
Expand description

Contains the address of the previous web page from which a link to the +currently requested page was followed.

+

The Referer header allows servers to identify where people are visiting +them from and may use that data for analytics, logging, or optimized +caching, for example.

+
\ No newline at end of file diff --git a/actix_http/header/constant.REFERRER_POLICY.html b/actix_http/header/constant.REFERRER_POLICY.html new file mode 100644 index 000000000..1f696add5 --- /dev/null +++ b/actix_http/header/constant.REFERRER_POLICY.html @@ -0,0 +1,3 @@ +REFERRER_POLICY in actix_http::header - Rust

Constant actix_http::header::REFERRER_POLICY

source ·
pub const REFERRER_POLICY: HeaderName;
Expand description

Governs which referrer information should be included with requests +made.

+
\ No newline at end of file diff --git a/actix_http/header/constant.REFRESH.html b/actix_http/header/constant.REFRESH.html new file mode 100644 index 000000000..a2f370166 --- /dev/null +++ b/actix_http/header/constant.REFRESH.html @@ -0,0 +1,3 @@ +REFRESH in actix_http::header - Rust

Constant actix_http::header::REFRESH

source ·
pub const REFRESH: HeaderName;
Expand description

Informs the web browser that the current page or frame should be +refreshed.

+
\ No newline at end of file diff --git a/actix_http/header/constant.RETRY_AFTER.html b/actix_http/header/constant.RETRY_AFTER.html new file mode 100644 index 000000000..2e4ee9fee --- /dev/null +++ b/actix_http/header/constant.RETRY_AFTER.html @@ -0,0 +1,15 @@ +RETRY_AFTER in actix_http::header - Rust

Constant actix_http::header::RETRY_AFTER

source ·
pub const RETRY_AFTER: HeaderName;
Expand description

The Retry-After response HTTP header indicates how long the user agent +should wait before making a follow-up request. There are two main cases +this header is used:

+
    +
  • +

    When sent with a 503 (Service Unavailable) response, it indicates how +long the service is expected to be unavailable.

    +
  • +
  • +

    When sent with a redirect response, such as 301 (Moved Permanently), +it indicates the minimum time that the user agent is asked to wait +before issuing the redirected request.

    +
  • +
+
\ No newline at end of file diff --git a/actix_http/header/constant.SEC_WEBSOCKET_ACCEPT.html b/actix_http/header/constant.SEC_WEBSOCKET_ACCEPT.html new file mode 100644 index 000000000..911734613 --- /dev/null +++ b/actix_http/header/constant.SEC_WEBSOCKET_ACCEPT.html @@ -0,0 +1,5 @@ +SEC_WEBSOCKET_ACCEPT in actix_http::header - Rust

Constant actix_http::header::SEC_WEBSOCKET_ACCEPT

source ·
pub const SEC_WEBSOCKET_ACCEPT: HeaderName;
Expand description

The |Sec-WebSocket-Accept| header field is used in the WebSocket +opening handshake. It is sent from the server to the client to +confirm that the server is willing to initiate the WebSocket +connection.

+
\ No newline at end of file diff --git a/actix_http/header/constant.SEC_WEBSOCKET_EXTENSIONS.html b/actix_http/header/constant.SEC_WEBSOCKET_EXTENSIONS.html new file mode 100644 index 000000000..45b71e3e1 --- /dev/null +++ b/actix_http/header/constant.SEC_WEBSOCKET_EXTENSIONS.html @@ -0,0 +1,6 @@ +SEC_WEBSOCKET_EXTENSIONS in actix_http::header - Rust

Constant actix_http::header::SEC_WEBSOCKET_EXTENSIONS

source ·
pub const SEC_WEBSOCKET_EXTENSIONS: HeaderName;
Expand description

The |Sec-WebSocket-Extensions| header field is used in the WebSocket +opening handshake. It is initially sent from the client to the +server, and then subsequently sent from the server to the client, to +agree on a set of protocol-level extensions to use for the duration +of the connection.

+
\ No newline at end of file diff --git a/actix_http/header/constant.SEC_WEBSOCKET_KEY.html b/actix_http/header/constant.SEC_WEBSOCKET_KEY.html new file mode 100644 index 000000000..98d09325f --- /dev/null +++ b/actix_http/header/constant.SEC_WEBSOCKET_KEY.html @@ -0,0 +1,8 @@ +SEC_WEBSOCKET_KEY in actix_http::header - Rust

Constant actix_http::header::SEC_WEBSOCKET_KEY

source ·
pub const SEC_WEBSOCKET_KEY: HeaderName;
Expand description

The |Sec-WebSocket-Key| header field is used in the WebSocket opening +handshake. It is sent from the client to the server to provide part +of the information used by the server to prove that it received a +valid WebSocket opening handshake. This helps ensure that the server +does not accept connections from non-WebSocket clients (e.g., HTTP +clients) that are being abused to send data to unsuspecting WebSocket +servers.

+
\ No newline at end of file diff --git a/actix_http/header/constant.SEC_WEBSOCKET_PROTOCOL.html b/actix_http/header/constant.SEC_WEBSOCKET_PROTOCOL.html new file mode 100644 index 000000000..3783276a4 --- /dev/null +++ b/actix_http/header/constant.SEC_WEBSOCKET_PROTOCOL.html @@ -0,0 +1,6 @@ +SEC_WEBSOCKET_PROTOCOL in actix_http::header - Rust

Constant actix_http::header::SEC_WEBSOCKET_PROTOCOL

source ·
pub const SEC_WEBSOCKET_PROTOCOL: HeaderName;
Expand description

The |Sec-WebSocket-Protocol| header field is used in the WebSocket +opening handshake. It is sent from the client to the server and back +from the server to the client to confirm the subprotocol of the +connection. This enables scripts to both select a subprotocol and be +sure that the server agreed to serve that subprotocol.

+
\ No newline at end of file diff --git a/actix_http/header/constant.SEC_WEBSOCKET_VERSION.html b/actix_http/header/constant.SEC_WEBSOCKET_VERSION.html new file mode 100644 index 000000000..ec5013d05 --- /dev/null +++ b/actix_http/header/constant.SEC_WEBSOCKET_VERSION.html @@ -0,0 +1,7 @@ +SEC_WEBSOCKET_VERSION in actix_http::header - Rust

Constant actix_http::header::SEC_WEBSOCKET_VERSION

source ·
pub const SEC_WEBSOCKET_VERSION: HeaderName;
Expand description

The |Sec-WebSocket-Version| header field is used in the WebSocket +opening handshake. It is sent from the client to the server to +indicate the protocol version of the connection. This enables +servers to correctly interpret the opening handshake and subsequent +data being sent from the data, and close the connection if the server +cannot interpret that data in a safe manner.

+
\ No newline at end of file diff --git a/actix_http/header/constant.SERVER.html b/actix_http/header/constant.SERVER.html new file mode 100644 index 000000000..661d450a3 --- /dev/null +++ b/actix_http/header/constant.SERVER.html @@ -0,0 +1,7 @@ +SERVER in actix_http::header - Rust

Constant actix_http::header::SERVER

source ·
pub const SERVER: HeaderName;
Expand description

Contains information about the software used by the origin server to +handle the request.

+

Overly long and detailed Server values should be avoided as they +potentially reveal internal implementation details that might make it +(slightly) easier for attackers to find and exploit known security +holes.

+
\ No newline at end of file diff --git a/actix_http/header/constant.SET_COOKIE.html b/actix_http/header/constant.SET_COOKIE.html new file mode 100644 index 000000000..a4b62e1bd --- /dev/null +++ b/actix_http/header/constant.SET_COOKIE.html @@ -0,0 +1,2 @@ +SET_COOKIE in actix_http::header - Rust

Constant actix_http::header::SET_COOKIE

source ·
pub const SET_COOKIE: HeaderName;
Expand description

Used to send cookies from the server to the user agent.

+
\ No newline at end of file diff --git a/actix_http/header/constant.STRICT_TRANSPORT_SECURITY.html b/actix_http/header/constant.STRICT_TRANSPORT_SECURITY.html new file mode 100644 index 000000000..5b2835f46 --- /dev/null +++ b/actix_http/header/constant.STRICT_TRANSPORT_SECURITY.html @@ -0,0 +1,2 @@ +STRICT_TRANSPORT_SECURITY in actix_http::header - Rust

Constant actix_http::header::STRICT_TRANSPORT_SECURITY

source ·
pub const STRICT_TRANSPORT_SECURITY: HeaderName;
Expand description

Tells the client to communicate with HTTPS instead of using HTTP.

+
\ No newline at end of file diff --git a/actix_http/header/constant.TE.html b/actix_http/header/constant.TE.html new file mode 100644 index 000000000..66ecba8ed --- /dev/null +++ b/actix_http/header/constant.TE.html @@ -0,0 +1,8 @@ +TE in actix_http::header - Rust

Constant actix_http::header::TE

source ·
pub const TE: HeaderName;
Expand description

Informs the server of transfer encodings willing to be accepted as part +of the response.

+

See also the Transfer-Encoding response header for more details on +transfer encodings. Note that chunked is always acceptable for HTTP/1.1 +recipients and you that don’t have to specify “chunked” using the TE +header. However, it is useful for setting if the client is accepting +trailer fields in a chunked transfer coding using the “trailers” value.

+
\ No newline at end of file diff --git a/actix_http/header/constant.TRAILER.html b/actix_http/header/constant.TRAILER.html new file mode 100644 index 000000000..9b3b68b1f --- /dev/null +++ b/actix_http/header/constant.TRAILER.html @@ -0,0 +1,3 @@ +TRAILER in actix_http::header - Rust

Constant actix_http::header::TRAILER

source ·
pub const TRAILER: HeaderName;
Expand description

Allows the sender to include additional fields at the end of chunked +messages.

+
\ No newline at end of file diff --git a/actix_http/header/constant.TRANSFER_ENCODING.html b/actix_http/header/constant.TRANSFER_ENCODING.html new file mode 100644 index 000000000..20f730710 --- /dev/null +++ b/actix_http/header/constant.TRANSFER_ENCODING.html @@ -0,0 +1,11 @@ +TRANSFER_ENCODING in actix_http::header - Rust

Constant actix_http::header::TRANSFER_ENCODING

source ·
pub const TRANSFER_ENCODING: HeaderName;
Expand description

Specifies the form of encoding used to safely transfer the entity to the +client.

+

transfer-encoding is a hop-by-hop header, that is applying to a +message between two nodes, not to a resource itself. Each segment of a +multi-node connection can use different transfer-encoding values. If +you want to compress data over the whole connection, use the end-to-end +header content-encoding header instead.

+

When present on a response to a HEAD request that has no body, it +indicates the value that would have applied to the corresponding GET +message.

+
\ No newline at end of file diff --git a/actix_http/header/constant.UPGRADE.html b/actix_http/header/constant.UPGRADE.html new file mode 100644 index 000000000..fe753bfdd --- /dev/null +++ b/actix_http/header/constant.UPGRADE.html @@ -0,0 +1,2 @@ +UPGRADE in actix_http::header - Rust

Constant actix_http::header::UPGRADE

source ·
pub const UPGRADE: HeaderName;
Expand description

Used as part of the exchange to upgrade the protocol.

+
\ No newline at end of file diff --git a/actix_http/header/constant.UPGRADE_INSECURE_REQUESTS.html b/actix_http/header/constant.UPGRADE_INSECURE_REQUESTS.html new file mode 100644 index 000000000..edd6c4c55 --- /dev/null +++ b/actix_http/header/constant.UPGRADE_INSECURE_REQUESTS.html @@ -0,0 +1,3 @@ +UPGRADE_INSECURE_REQUESTS in actix_http::header - Rust

Constant actix_http::header::UPGRADE_INSECURE_REQUESTS

source ·
pub const UPGRADE_INSECURE_REQUESTS: HeaderName;
Expand description

Sends a signal to the server expressing the client’s preference for an +encrypted and authenticated response.

+
\ No newline at end of file diff --git a/actix_http/header/constant.USER_AGENT.html b/actix_http/header/constant.USER_AGENT.html new file mode 100644 index 000000000..a87d9c97b --- /dev/null +++ b/actix_http/header/constant.USER_AGENT.html @@ -0,0 +1,3 @@ +USER_AGENT in actix_http::header - Rust

Constant actix_http::header::USER_AGENT

source ·
pub const USER_AGENT: HeaderName;
Expand description

Contains a string that allows identifying the requesting client’s +software.

+
\ No newline at end of file diff --git a/actix_http/header/constant.VARY.html b/actix_http/header/constant.VARY.html new file mode 100644 index 000000000..dcf8313bd --- /dev/null +++ b/actix_http/header/constant.VARY.html @@ -0,0 +1,9 @@ +VARY in actix_http::header - Rust

Constant actix_http::header::VARY

source ·
pub const VARY: HeaderName;
Expand description

Determines how to match future requests with cached responses.

+

The vary HTTP response header determines how to match future request +headers to decide whether a cached response can be used rather than +requesting a fresh one from the origin server. It is used by the server +to indicate which headers it used when selecting a representation of a +resource in a content negotiation algorithm.

+

The vary header should be set on a 304 Not Modified response exactly +like it would have been set on an equivalent 200 OK response.

+
\ No newline at end of file diff --git a/actix_http/header/constant.VIA.html b/actix_http/header/constant.VIA.html new file mode 100644 index 000000000..86c29fb14 --- /dev/null +++ b/actix_http/header/constant.VIA.html @@ -0,0 +1,7 @@ +VIA in actix_http::header - Rust

Constant actix_http::header::VIA

source ·
pub const VIA: HeaderName;
Expand description

Added by proxies to track routing.

+

The via general header is added by proxies, both forward and reverse +proxies, and can appear in the request headers and the response headers. +It is used for tracking message forwards, avoiding request loops, and +identifying the protocol capabilities of senders along the +request/response chain.

+
\ No newline at end of file diff --git a/actix_http/header/constant.WARNING.html b/actix_http/header/constant.WARNING.html new file mode 100644 index 000000000..3bd4a7ded --- /dev/null +++ b/actix_http/header/constant.WARNING.html @@ -0,0 +1,6 @@ +WARNING in actix_http::header - Rust

Constant actix_http::header::WARNING

source ·
pub const WARNING: HeaderName;
Expand description

General HTTP header contains information about possible problems with +the status of the message.

+

More than one warning header may appear in a response. Warning header +fields can in general be applied to any message, however some warn-codes +are specific to caches and can only be applied to response messages.

+
\ No newline at end of file diff --git a/actix_http/header/constant.WWW_AUTHENTICATE.html b/actix_http/header/constant.WWW_AUTHENTICATE.html new file mode 100644 index 000000000..4b6fc0821 --- /dev/null +++ b/actix_http/header/constant.WWW_AUTHENTICATE.html @@ -0,0 +1,3 @@ +WWW_AUTHENTICATE in actix_http::header - Rust

Constant actix_http::header::WWW_AUTHENTICATE

source ·
pub const WWW_AUTHENTICATE: HeaderName;
Expand description

Defines the authentication method that should be used to gain access to +a resource.

+
\ No newline at end of file diff --git a/actix_http/header/constant.X_CONTENT_TYPE_OPTIONS.html b/actix_http/header/constant.X_CONTENT_TYPE_OPTIONS.html new file mode 100644 index 000000000..3a33b2310 --- /dev/null +++ b/actix_http/header/constant.X_CONTENT_TYPE_OPTIONS.html @@ -0,0 +1,11 @@ +X_CONTENT_TYPE_OPTIONS in actix_http::header - Rust

Constant actix_http::header::X_CONTENT_TYPE_OPTIONS

source ·
pub const X_CONTENT_TYPE_OPTIONS: HeaderName;
Expand description

Marker used by the server to indicate that the MIME types advertised in +the content-type headers should not be changed and be followed.

+

This allows to opt-out of MIME type sniffing, or, in other words, it is +a way to say that the webmasters knew what they were doing.

+

This header was introduced by Microsoft in IE 8 as a way for webmasters +to block content sniffing that was happening and could transform +non-executable MIME types into executable MIME types. Since then, other +browsers have introduced it, even if their MIME sniffing algorithms were +less aggressive.

+

Site security testers usually expect this header to be set.

+
\ No newline at end of file diff --git a/actix_http/header/constant.X_DNS_PREFETCH_CONTROL.html b/actix_http/header/constant.X_DNS_PREFETCH_CONTROL.html new file mode 100644 index 000000000..746fa134d --- /dev/null +++ b/actix_http/header/constant.X_DNS_PREFETCH_CONTROL.html @@ -0,0 +1,10 @@ +X_DNS_PREFETCH_CONTROL in actix_http::header - Rust

Constant actix_http::header::X_DNS_PREFETCH_CONTROL

source ·
pub const X_DNS_PREFETCH_CONTROL: HeaderName;
Expand description

Controls DNS prefetching.

+

The x-dns-prefetch-control HTTP response header controls DNS +prefetching, a feature by which browsers proactively perform domain name +resolution on both links that the user may choose to follow as well as +URLs for items referenced by the document, including images, CSS, +JavaScript, and so forth.

+

This prefetching is performed in the background, so that the DNS is +likely to have been resolved by the time the referenced items are +needed. This reduces latency when the user clicks a link.

+
\ No newline at end of file diff --git a/actix_http/header/constant.X_FORWARDED_FOR.html b/actix_http/header/constant.X_FORWARDED_FOR.html new file mode 100644 index 000000000..365ba4444 --- /dev/null +++ b/actix_http/header/constant.X_FORWARDED_FOR.html @@ -0,0 +1,3 @@ +X_FORWARDED_FOR in actix_http::header - Rust

Constant actix_http::header::X_FORWARDED_FOR

source ·
pub const X_FORWARDED_FOR: HeaderName;
Expand description

Request header (de-facto standard) for identifying the originating IP address of a client +connecting to a web server through a proxy server.

+
\ No newline at end of file diff --git a/actix_http/header/constant.X_FORWARDED_HOST.html b/actix_http/header/constant.X_FORWARDED_HOST.html new file mode 100644 index 000000000..f86f1c447 --- /dev/null +++ b/actix_http/header/constant.X_FORWARDED_HOST.html @@ -0,0 +1,3 @@ +X_FORWARDED_HOST in actix_http::header - Rust

Constant actix_http::header::X_FORWARDED_HOST

source ·
pub const X_FORWARDED_HOST: HeaderName;
Expand description

Request header (de-facto standard) for identifying the original host requested by the client in +the Host HTTP request header.

+
\ No newline at end of file diff --git a/actix_http/header/constant.X_FORWARDED_PROTO.html b/actix_http/header/constant.X_FORWARDED_PROTO.html new file mode 100644 index 000000000..ce099fe70 --- /dev/null +++ b/actix_http/header/constant.X_FORWARDED_PROTO.html @@ -0,0 +1,3 @@ +X_FORWARDED_PROTO in actix_http::header - Rust

Constant actix_http::header::X_FORWARDED_PROTO

source ·
pub const X_FORWARDED_PROTO: HeaderName;
Expand description

Request header (de-facto standard) for identifying the protocol that a client used to connect to +your proxy or load balancer.

+
\ No newline at end of file diff --git a/actix_http/header/constant.X_FRAME_OPTIONS.html b/actix_http/header/constant.X_FRAME_OPTIONS.html new file mode 100644 index 000000000..09d8813ef --- /dev/null +++ b/actix_http/header/constant.X_FRAME_OPTIONS.html @@ -0,0 +1,7 @@ +X_FRAME_OPTIONS in actix_http::header - Rust

Constant actix_http::header::X_FRAME_OPTIONS

source ·
pub const X_FRAME_OPTIONS: HeaderName;
Expand description

Indicates whether or not a browser should be allowed to render a page in +a frame.

+

Sites can use this to avoid clickjacking attacks, by ensuring that their +content is not embedded into other sites.

+

The added security is only provided if the user accessing the document +is using a browser supporting x-frame-options.

+
\ No newline at end of file diff --git a/actix_http/header/constant.X_XSS_PROTECTION.html b/actix_http/header/constant.X_XSS_PROTECTION.html new file mode 100644 index 000000000..5f6713c9e --- /dev/null +++ b/actix_http/header/constant.X_XSS_PROTECTION.html @@ -0,0 +1,9 @@ +X_XSS_PROTECTION in actix_http::header - Rust

Constant actix_http::header::X_XSS_PROTECTION

source ·
pub const X_XSS_PROTECTION: HeaderName;
Expand description

Stop pages from loading when an XSS attack is detected.

+

The HTTP X-XSS-Protection response header is a feature of Internet +Explorer, Chrome and Safari that stops pages from loading when they +detect reflected cross-site scripting (XSS) attacks. Although these +protections are largely unnecessary in modern browsers when sites +implement a strong Content-Security-Policy that disables the use of +inline JavaScript (‘unsafe-inline’), they can still provide protections +for users of older web browsers that don’t yet support CSP.

+
\ No newline at end of file diff --git a/actix_http/header/enum.Charset.html b/actix_http/header/enum.Charset.html new file mode 100644 index 000000000..912df6286 --- /dev/null +++ b/actix_http/header/enum.Charset.html @@ -0,0 +1,79 @@ +Charset in actix_http::header - Rust

Enum actix_http::header::Charset

source ·
pub enum Charset {
+
Show 25 variants Us_Ascii, + Iso_8859_1, + Iso_8859_2, + Iso_8859_3, + Iso_8859_4, + Iso_8859_5, + Iso_8859_6, + Iso_8859_7, + Iso_8859_8, + Iso_8859_9, + Iso_8859_10, + Shift_Jis, + Euc_Jp, + Iso_2022_Kr, + Euc_Kr, + Iso_2022_Jp, + Iso_2022_Jp_2, + Iso_8859_6_E, + Iso_8859_6_I, + Iso_8859_8_E, + Iso_8859_8_I, + Gb2312, + Big5, + Koi8_R, + Ext(String), +
}
Expand description

A MIME character set.

+

The string representation is normalized to upper case.

+

See http://www.iana.org/assignments/character-sets/character-sets.xhtml.

+

Variants§

§

Us_Ascii

US ASCII

+
§

Iso_8859_1

ISO-8859-1

+
§

Iso_8859_2

ISO-8859-2

+
§

Iso_8859_3

ISO-8859-3

+
§

Iso_8859_4

ISO-8859-4

+
§

Iso_8859_5

ISO-8859-5

+
§

Iso_8859_6

ISO-8859-6

+
§

Iso_8859_7

ISO-8859-7

+
§

Iso_8859_8

ISO-8859-8

+
§

Iso_8859_9

ISO-8859-9

+
§

Iso_8859_10

ISO-8859-10

+
§

Shift_Jis

Shift_JIS

+
§

Euc_Jp

EUC-JP

+
§

Iso_2022_Kr

ISO-2022-KR

+
§

Euc_Kr

EUC-KR

+
§

Iso_2022_Jp

ISO-2022-JP

+
§

Iso_2022_Jp_2

ISO-2022-JP-2

+
§

Iso_8859_6_E

ISO-8859-6-E

+
§

Iso_8859_6_I

ISO-8859-6-I

+
§

Iso_8859_8_E

ISO-8859-8-E

+
§

Iso_8859_8_I

ISO-8859-8-I

+
§

Gb2312

GB2312

+
§

Big5

Big5

+
§

Koi8_R

KOI8-R

+
§

Ext(String)

An arbitrary charset specified as a string

+

Trait Implementations§

source§

impl Clone for Charset

source§

fn clone(&self) -> Charset

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

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

Performs copy-assignment from source. Read more
source§

impl Debug for Charset

source§

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

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

impl Display for Charset

source§

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

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

impl FromStr for Charset

§

type Err = Error

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

fn from_str(s: &str) -> Result<Charset, Error>

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

impl PartialEq for Charset

source§

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

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

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

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

impl Eq for Charset

source§

impl StructuralPartialEq for Charset

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/enum.ContentEncoding.html b/actix_http/header/enum.ContentEncoding.html new file mode 100644 index 000000000..faf8fa093 --- /dev/null +++ b/actix_http/header/enum.ContentEncoding.html @@ -0,0 +1,46 @@ +ContentEncoding in actix_http::header - Rust

Enum actix_http::header::ContentEncoding

source ·
#[non_exhaustive]
pub enum ContentEncoding { + Identity, + Brotli, + Deflate, + Gzip, + Zstd, +}
Expand description

Represents a supported content encoding.

+

Includes a commonly-used subset of media types appropriate for use as HTTP content encodings. +See IANA HTTP Content Coding Registry.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Identity

Indicates the no-op identity encoding.

+

I.e., no compression or modification.

+
§

Brotli

A format using the Brotli algorithm.

+
§

Deflate

A format using the zlib structure with deflate algorithm.

+
§

Gzip

Gzip algorithm.

+
§

Zstd

Zstd algorithm.

+

Implementations§

source§

impl ContentEncoding

source

pub const fn as_str(self) -> &'static str

Convert content encoding to string.

+
source

pub const fn to_header_value(self) -> HeaderValue

Convert content encoding to header value.

+

Trait Implementations§

source§

impl Clone for ContentEncoding

source§

fn clone(&self) -> ContentEncoding

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ContentEncoding

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for ContentEncoding

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl FromStr for ContentEncoding

§

type Err = ContentEncodingParseError

The associated error which can be returned from parsing.
source§

fn from_str(enc: &str) -> Result<Self, Self::Err>

Parses a string s to return a value of this type. Read more
source§

impl Hash for ContentEncoding

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Header for ContentEncoding

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<T: HttpMessage>(msg: &T) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for ContentEncoding

source§

fn eq(&self, other: &ContentEncoding) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryFrom<&str> for ContentEncoding

§

type Error = ContentEncodingParseError

The type returned in the event of a conversion error.
source§

fn try_from(val: &str) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl TryIntoHeaderValue for ContentEncoding

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Copy for ContentEncoding

source§

impl Eq for ContentEncoding

source§

impl StructuralPartialEq for ContentEncoding

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/fn.fmt_comma_delimited.html b/actix_http/header/fn.fmt_comma_delimited.html new file mode 100644 index 000000000..3837041d3 --- /dev/null +++ b/actix_http/header/fn.fmt_comma_delimited.html @@ -0,0 +1,3 @@ +fmt_comma_delimited in actix_http::header - Rust

Function actix_http::header::fmt_comma_delimited

source ·
pub fn fmt_comma_delimited<T>(f: &mut Formatter<'_>, parts: &[T]) -> Result
where + T: Display,
Expand description

Format an array into a comma-delimited string.

+
\ No newline at end of file diff --git a/actix_http/header/fn.from_comma_delimited.html b/actix_http/header/fn.from_comma_delimited.html new file mode 100644 index 000000000..406b20efa --- /dev/null +++ b/actix_http/header/fn.from_comma_delimited.html @@ -0,0 +1,4 @@ +from_comma_delimited in actix_http::header - Rust

Function actix_http::header::from_comma_delimited

source ·
pub fn from_comma_delimited<'a, I, T>(all: I) -> Result<Vec<T>, ParseError>
where + I: Iterator<Item = &'a HeaderValue> + 'a, + T: FromStr,
Expand description

Reads a comma-delimited raw header into a Vec.

+
\ No newline at end of file diff --git a/actix_http/header/fn.from_one_raw_str.html b/actix_http/header/fn.from_one_raw_str.html new file mode 100644 index 000000000..28b5438d5 --- /dev/null +++ b/actix_http/header/fn.from_one_raw_str.html @@ -0,0 +1,4 @@ +from_one_raw_str in actix_http::header - Rust

Function actix_http::header::from_one_raw_str

source ·
pub fn from_one_raw_str<T: FromStr>(
+    val: Option<&HeaderValue>
+) -> Result<T, ParseError>
Expand description

Reads a single string when parsing a header.

+
\ No newline at end of file diff --git a/actix_http/header/fn.http_percent_encode.html b/actix_http/header/fn.http_percent_encode.html new file mode 100644 index 000000000..7d5dea3e5 --- /dev/null +++ b/actix_http/header/fn.http_percent_encode.html @@ -0,0 +1,2 @@ +http_percent_encode in actix_http::header - Rust

Function actix_http::header::http_percent_encode

source ·
pub fn http_percent_encode(f: &mut Formatter<'_>, bytes: &[u8]) -> Result
Expand description

Percent encode a sequence of bytes with a character set defined in RFC 5987 §3.2.

+
\ No newline at end of file diff --git a/actix_http/header/fn.parse_extended_value.html b/actix_http/header/fn.parse_extended_value.html new file mode 100644 index 000000000..7745f65d4 --- /dev/null +++ b/actix_http/header/fn.parse_extended_value.html @@ -0,0 +1,30 @@ +parse_extended_value in actix_http::header - Rust

Function actix_http::header::parse_extended_value

source ·
pub fn parse_extended_value(val: &str) -> Result<ExtendedValue, ParseError>
Expand description

Parses extended header parameter values (ext-value), as defined +in RFC 5987 §3.2.

+

Extended values are denoted by parameter names that end with *.

+

§ABNF

ext-value     = charset  "'" [ language ] "'" value-chars
+              ; like RFC 2231's <extended-initial-value>
+              ; (see [RFC 2231 §7])
+
+charset       = "UTF-8" / "ISO-8859-1" / mime-charset
+
+mime-charset  = 1*mime-charsetc
+mime-charsetc = ALPHA / DIGIT
+              / "!" / "#" / "$" / "%" / "&"
+              / "+" / "-" / "^" / "_" / "`"
+              / "{" / "}" / "~"
+              ; as <mime-charset> in [RFC 2978 §2.3]
+              ; except that the single quote is not included
+              ; SHOULD be registered in the IANA charset registry
+
+language      = <Language-Tag, defined in [RFC 5646 §2.1]>
+
+value-chars   = *( pct-encoded / attr-char )
+
+pct-encoded   = "%" HEXDIG HEXDIG
+              ; see [RFC 3986 §2.1]
+
+attr-char     = ALPHA / DIGIT
+              / "!" / "#" / "$" / "&" / "+" / "-" / "."
+              / "^" / "_" / "`" / "|" / "~"
+              ; token except ( "*" / "'" / "%" )
+
\ No newline at end of file diff --git a/actix_http/header/fn.q.html b/actix_http/header/fn.q.html new file mode 100644 index 000000000..716f89eac --- /dev/null +++ b/actix_http/header/fn.q.html @@ -0,0 +1,21 @@ +q in actix_http::header - Rust

Function actix_http::header::q

source ·
pub fn q<T>(quality: T) -> Quality
where + T: TryInto<Quality>, + T::Error: Debug,
Expand description

Convenience function to create a Quality from an f32 (0.0–1.0).

+

Not recommended for use with user input. Rely on the TryFrom impls where possible.

+

§Panics

+

Panics if value is out of range.

+

§Examples

+
let q1 = q(1.0);
+assert_eq!(q1, Quality::MAX);
+
+let q2 = q(0.001);
+assert_eq!(q2, Quality::MIN);
+
+let q3 = q(0.0);
+assert_eq!(q3, Quality::ZERO);
+
+let q4 = q(0.42);
+

An out-of-range f32 quality will panic.

+ +
let _q2 = q(1.42);
+
\ No newline at end of file diff --git a/actix_http/header/index.html b/actix_http/header/index.html new file mode 100644 index 000000000..8a77efe79 --- /dev/null +++ b/actix_http/header/index.html @@ -0,0 +1,69 @@ +actix_http::header - Rust

Module actix_http::header

source ·
Expand description

Pre-defined HeaderNames, traits for parsing and conversion, and other header utility methods.

+

Re-exports§

Modules§

Structs§

Enums§

Constants§

  • Advertises which content types the client is able to understand.
  • Advertises which character set the client is able to understand.
  • Advertises which content encoding the client is able to understand.
  • Advertises which languages the client is able to understand.
  • Marker used by the server to advertise partial request support.
  • Preflight response indicating if the response to the request can be +exposed to the page.
  • Preflight response indicating permitted HTTP headers.
  • Preflight header response indicating permitted access methods.
  • Indicates whether the response can be shared with resources with the +given origin.
  • Indicates which headers can be exposed as part of the response by +listing their names.
  • Indicates how long the results of a preflight request can be cached.
  • Informs the server which HTTP headers will be used when an actual +request is made.
  • Informs the server know which HTTP method will be used when the actual +request is made.
  • Indicates the time in seconds the object has been in a proxy cache.
  • Lists the set of methods support by a resource.
  • Advertises the availability of alternate services to clients.
  • Contains the credentials to authenticate a user agent with a server.
  • Specifies directives for caching mechanisms in both requests and +responses.
  • Response header field that indicates how caches have handled that response and its corresponding +request.
  • Response header field that allows origin servers to control the behavior of CDN caches +interposed between them and clients separately from other caches that might handle the response.
  • Controls whether or not the network connection stays open after the +current transaction finishes.
  • Indicates if the content is expected to be displayed inline.
  • Used to compress the media-type.
  • Used to describe the languages intended for the audience.
  • Indicates the size of the entity-body.
  • Indicates an alternate location for the returned data.
  • Indicates where in a full body message a partial message belongs.
  • Allows controlling resources the user agent is allowed to load for a +given page.
  • Allows experimenting with policies by monitoring their effects.
  • Used to indicate the media type of the resource.
  • Contains stored HTTP cookies previously sent by the server with the +Set-Cookie header.
  • Response header that prevents a document from loading any cross-origin resources that don’t +explicitly grant the document permission (using CORP or CORS).
  • Response header that allows you to ensure a top-level document does not share a browsing context +group with cross-origin documents.
  • Response header that conveys a desire that the browser blocks no-cors cross-origin/cross-site +requests to the given resource.
  • Contains the date and time at which the message was originated.
  • Indicates the client’s tracking preference.
  • Identifier for a specific version of a resource.
  • Indicates expectations that need to be fulfilled by the server in order +to properly handle the request.
  • Contains the date/time after which the response is considered stale.
  • Contains information from the client-facing side of proxy servers that +is altered or lost when a proxy is involved in the path of the request.
  • Contains an Internet email address for a human user who controls the +requesting user agent.
  • Specifies the domain name of the server and (optionally) the TCP port +number on which the server is listening.
  • Makes a request conditional based on the E-Tag.
  • Makes a request conditional based on the modification date.
  • Makes a request conditional based on the E-Tag.
  • Makes a request conditional based on range.
  • Makes the request conditional based on the last modification date.
  • Content-Types that are acceptable for the response.
  • Allows the server to point an interested client to another resource +containing metadata about the requested resource.
  • Indicates the URL to redirect a page to.
  • Indicates the max number of intermediaries the request should be sent +through.
  • Indicates where a fetch originates from.
  • Response header that provides a mechanism to allow and deny the use of browser features in a +document or within any <iframe> elements in the document.
  • HTTP/1.0 header usually used for backwards compatibility.
  • Defines the authentication method that should be used to gain access to +a proxy.
  • Contains the credentials to authenticate a user agent to a proxy server.
  • Associates a specific cryptographic public key with a certain server.
  • Sends reports of pinning violation to the report-uri specified in the +header.
  • Indicates the part of a document that the server should return.
  • Contains the address of the previous web page from which a link to the +currently requested page was followed.
  • Governs which referrer information should be included with requests +made.
  • Informs the web browser that the current page or frame should be +refreshed.
  • The Retry-After response HTTP header indicates how long the user agent +should wait before making a follow-up request. There are two main cases +this header is used:
  • The |Sec-WebSocket-Accept| header field is used in the WebSocket +opening handshake. It is sent from the server to the client to +confirm that the server is willing to initiate the WebSocket +connection.
  • The |Sec-WebSocket-Extensions| header field is used in the WebSocket +opening handshake. It is initially sent from the client to the +server, and then subsequently sent from the server to the client, to +agree on a set of protocol-level extensions to use for the duration +of the connection.
  • The |Sec-WebSocket-Key| header field is used in the WebSocket opening +handshake. It is sent from the client to the server to provide part +of the information used by the server to prove that it received a +valid WebSocket opening handshake. This helps ensure that the server +does not accept connections from non-WebSocket clients (e.g., HTTP +clients) that are being abused to send data to unsuspecting WebSocket +servers.
  • The |Sec-WebSocket-Protocol| header field is used in the WebSocket +opening handshake. It is sent from the client to the server and back +from the server to the client to confirm the subprotocol of the +connection. This enables scripts to both select a subprotocol and be +sure that the server agreed to serve that subprotocol.
  • The |Sec-WebSocket-Version| header field is used in the WebSocket +opening handshake. It is sent from the client to the server to +indicate the protocol version of the connection. This enables +servers to correctly interpret the opening handshake and subsequent +data being sent from the data, and close the connection if the server +cannot interpret that data in a safe manner.
  • Contains information about the software used by the origin server to +handle the request.
  • Used to send cookies from the server to the user agent.
  • Tells the client to communicate with HTTPS instead of using HTTP.
  • Informs the server of transfer encodings willing to be accepted as part +of the response.
  • Allows the sender to include additional fields at the end of chunked +messages.
  • Specifies the form of encoding used to safely transfer the entity to the +client.
  • Used as part of the exchange to upgrade the protocol.
  • Sends a signal to the server expressing the client’s preference for an +encrypted and authenticated response.
  • Contains a string that allows identifying the requesting client’s +software.
  • Determines how to match future requests with cached responses.
  • Added by proxies to track routing.
  • General HTTP header contains information about possible problems with +the status of the message.
  • Defines the authentication method that should be used to gain access to +a resource.
  • Marker used by the server to indicate that the MIME types advertised in +the content-type headers should not be changed and be followed.
  • Controls DNS prefetching.
  • Request header (de-facto standard) for identifying the originating IP address of a client +connecting to a web server through a proxy server.
  • Request header (de-facto standard) for identifying the original host requested by the client in +the Host HTTP request header.
  • Request header (de-facto standard) for identifying the protocol that a client used to connect to +your proxy or load balancer.
  • Indicates whether or not a browser should be allowed to render a page in +a frame.
  • Stop pages from loading when an XSS attack is detected.

Traits§

Functions§

\ No newline at end of file diff --git a/actix_http/header/into_pair/trait.TryIntoHeaderPair.html b/actix_http/header/into_pair/trait.TryIntoHeaderPair.html new file mode 100644 index 000000000..cdf9cb11b --- /dev/null +++ b/actix_http/header/into_pair/trait.TryIntoHeaderPair.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/header/trait.TryIntoHeaderPair.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/into_value/trait.TryIntoHeaderValue.html b/actix_http/header/into_value/trait.TryIntoHeaderValue.html new file mode 100644 index 000000000..cd3147d98 --- /dev/null +++ b/actix_http/header/into_value/trait.TryIntoHeaderValue.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/header/trait.TryIntoHeaderValue.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/map/index.html b/actix_http/header/map/index.html new file mode 100644 index 000000000..b3bc8b1f4 --- /dev/null +++ b/actix_http/header/map/index.html @@ -0,0 +1,2 @@ +actix_http::header::map - Rust

Module actix_http::header::map

source ·
Expand description

A multi-value HeaderMap and its iterators.

+

Structs§

  • Iterator over drained name-value pairs.
  • A multi-map of HTTP headers.
  • Iterator over owned name-value pairs.
  • Iterator over borrowed name-value pairs.
  • Iterator over all names in the map.
  • Iterator over removed, owned values with the same associated name.
\ No newline at end of file diff --git a/actix_http/header/map/sidebar-items.js b/actix_http/header/map/sidebar-items.js new file mode 100644 index 000000000..d8f41164a --- /dev/null +++ b/actix_http/header/map/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Drain","HeaderMap","IntoIter","Iter","Keys","Removed"]}; \ No newline at end of file diff --git a/actix_http/header/map/struct.Drain.html b/actix_http/header/map/struct.Drain.html new file mode 100644 index 000000000..4d54b9f69 --- /dev/null +++ b/actix_http/header/map/struct.Drain.html @@ -0,0 +1,203 @@ +Drain in actix_http::header::map - Rust

Struct actix_http::header::map::Drain

source ·
pub struct Drain<'a> { /* private fields */ }
Expand description

Iterator over drained name-value pairs.

+

Iterator items are (Option<HeaderName>, HeaderValue) to avoid cloning.

+

Trait Implementations§

source§

impl<'a> Debug for Drain<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl ExactSizeIterator for Drain<'_>

1.0.0 · source§

fn len(&self) -> usize

Returns the exact remaining length of the iterator. Read more
source§

fn is_empty(&self) -> bool

🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
source§

impl<'a> Iterator for Drain<'a>

§

type Item = (Option<HeaderName>, HeaderValue)

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<Self::Item>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usize
where + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>
where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl FusedIterator for Drain<'_>

Auto Trait Implementations§

§

impl<'a> !Freeze for Drain<'a>

§

impl<'a> RefUnwindSafe for Drain<'a>

§

impl<'a> Send for Drain<'a>

§

impl<'a> Sync for Drain<'a>

§

impl<'a> Unpin for Drain<'a>

§

impl<'a> UnwindSafe for Drain<'a>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for I
where + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<I> IteratorRandom for I
where + I: Iterator,

source§

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where + R: Rng + ?Sized,

Collects values at random from the iterator into a supplied buffer +until that buffer is filled. Read more
source§

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where + R: Rng + ?Sized,

Available on crate feature alloc only.
Collects amount values at random from the iterator into a vector. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/map/struct.HeaderMap.html b/actix_http/header/map/struct.HeaderMap.html new file mode 100644 index 000000000..2817cb8fe --- /dev/null +++ b/actix_http/header/map/struct.HeaderMap.html @@ -0,0 +1,332 @@ +HeaderMap in actix_http::header::map - Rust

Struct actix_http::header::map::HeaderMap

source ·
pub struct HeaderMap { /* private fields */ }
Expand description

A multi-map of HTTP headers.

+

HeaderMap is a “multi-map” of HeaderName to one or more HeaderValues.

+

§Examples

+
use actix_http::header::{self, HeaderMap, HeaderValue};
+
+let mut map = HeaderMap::new();
+
+map.insert(header::CONTENT_TYPE, HeaderValue::from_static("text/plain"));
+map.insert(header::ORIGIN, HeaderValue::from_static("example.com"));
+
+assert!(map.contains_key(header::CONTENT_TYPE));
+assert!(map.contains_key(header::ORIGIN));
+
+let mut removed = map.remove(header::ORIGIN);
+assert_eq!(removed.next().unwrap(), "example.com");
+
+assert!(!map.contains_key(header::ORIGIN));
+

Implementations§

source§

impl HeaderMap

source

pub fn new() -> Self

Create an empty HeaderMap.

+

The map will be created without any capacity; this function will not allocate.

+
§Examples
+
let map = HeaderMap::new();
+
+assert!(map.is_empty());
+assert_eq!(0, map.capacity());
+
source

pub fn with_capacity(capacity: usize) -> Self

Create an empty HeaderMap with the specified capacity.

+

The map will be able to hold at least capacity elements without needing to reallocate. +If capacity is 0, the map will be created without allocating.

+
§Examples
+
let map = HeaderMap::with_capacity(16);
+
+assert!(map.is_empty());
+assert!(map.capacity() >= 16);
+
source

pub fn len(&self) -> usize

Returns the number of values stored in the map.

+

See also: len_keys.

+
§Examples
+
let mut map = HeaderMap::new();
+assert_eq!(map.len(), 0);
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+assert_eq!(map.len(), 2);
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+assert_eq!(map.len(), 3);
+
source

pub fn len_keys(&self) -> usize

Returns the number of keys stored in the map.

+

The number of values stored will be at least this number. See also: Self::len.

+
§Examples
+
let mut map = HeaderMap::new();
+assert_eq!(map.len_keys(), 0);
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+assert_eq!(map.len_keys(), 2);
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+assert_eq!(map.len_keys(), 2);
+
source

pub fn is_empty(&self) -> bool

Returns true if the map contains no elements.

+
§Examples
+
let mut map = HeaderMap::new();
+assert!(map.is_empty());
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(!map.is_empty());
+
source

pub fn clear(&mut self)

Clears the map, removing all name-value pairs.

+

Keeps the allocated memory for reuse.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+assert_eq!(map.len(), 2);
+
+map.clear();
+assert!(map.is_empty());
+
source

pub fn get(&self, key: impl AsHeaderName) -> Option<&HeaderValue>

Returns a reference to the first value associated with a header name.

+

Returns None if there is no value associated with the key.

+

Even when multiple values are associated with the key, the “first” one is returned but is +not guaranteed to be chosen with any particular order; though, the returned item will be +consistent for each call to get if the map has not changed.

+

See also: get_all.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+
+let cookie = map.get(header::SET_COOKIE).unwrap();
+assert_eq!(cookie, "one=1");
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+assert_eq!(map.get(header::SET_COOKIE).unwrap(), "one=1");
+
+assert_eq!(map.get(header::SET_COOKIE), map.get("set-cookie"));
+assert_eq!(map.get(header::SET_COOKIE), map.get("Set-Cookie"));
+
+assert!(map.get(header::HOST).is_none());
+assert!(map.get("INVALID HEADER NAME").is_none());
+
source

pub fn get_mut(&mut self, key: impl AsHeaderName) -> Option<&mut HeaderValue>

Returns a mutable reference to the first value associated a header name.

+

Returns None if there is no value associated with the key.

+

Even when multiple values are associated with the key, the “first” one is returned but is +not guaranteed to be chosen with any particular order; though, the returned item will be +consistent for each call to get_mut if the map has not changed.

+

See also: get_all.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+
+let mut cookie = map.get_mut(header::SET_COOKIE).unwrap();
+assert_eq!(cookie, "one=1");
+
+*cookie = HeaderValue::from_static("three=3");
+assert_eq!(map.get(header::SET_COOKIE).unwrap(), "three=3");
+
+assert!(map.get(header::HOST).is_none());
+assert!(map.get("INVALID HEADER NAME").is_none());
+
source

pub fn get_all(&self, key: impl AsHeaderName) -> Iter<'_, HeaderValue>

Returns an iterator over all values associated with a header name.

+

The returned iterator does not incur any allocations and will yield no items if there are no +values associated with the key. Iteration order is guaranteed to be the same as +insertion order.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut none_iter = map.get_all(header::ORIGIN);
+assert!(none_iter.next().is_none());
+
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let mut set_cookies_iter = map.get_all(header::SET_COOKIE);
+assert_eq!(set_cookies_iter.next().unwrap(), "one=1");
+assert_eq!(set_cookies_iter.next().unwrap(), "two=2");
+assert!(set_cookies_iter.next().is_none());
+
source

pub fn contains_key(&self, key: impl AsHeaderName) -> bool

Returns true if the map contains a value for the specified key.

+

Invalid header names will simply return false.

+
§Examples
+
let mut map = HeaderMap::new();
+assert!(!map.contains_key(header::ACCEPT));
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(map.contains_key(header::ACCEPT));
+
source

pub fn insert(&mut self, key: HeaderName, val: HeaderValue) -> Removed

Inserts (overrides) a name-value pair in the map.

+

If the map already contained this key, the new value is associated with the key and all +previous values are removed and returned as a Removed iterator. The key is not updated; +this matters for types that can be == without being identical.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(map.contains_key(header::ACCEPT));
+assert_eq!(map.len(), 1);
+
+let mut removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/csv"));
+assert_eq!(removed.next().unwrap(), "text/plain");
+assert!(removed.next().is_none());
+
+assert_eq!(map.len(), 1);
+

A convenience method is provided on the returned iterator to check if the insertion replaced +any values.

+ +
let mut map = HeaderMap::new();
+
+let removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(removed.is_empty());
+
+let removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/html"));
+assert!(!removed.is_empty());
+
source

pub fn append(&mut self, key: HeaderName, value: HeaderValue)

Appends a name-value pair to the map.

+

If the map already contained this key, the new value is added to the list of values +currently associated with the key. The key is not updated; this matters for types that can +be == without being identical.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.append(header::HOST, HeaderValue::from_static("example.com"));
+assert_eq!(map.len(), 1);
+
+map.append(header::ACCEPT, HeaderValue::from_static("text/csv"));
+assert_eq!(map.len(), 2);
+
+map.append(header::ACCEPT, HeaderValue::from_static("text/html"));
+assert_eq!(map.len(), 3);
+
source

pub fn remove(&mut self, key: impl AsHeaderName) -> Removed

Removes all headers for a particular header name from the map.

+

Providing an invalid header names (as a string argument) will have no effect and return +without error.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=2"));
+
+assert_eq!(map.len(), 2);
+
+let mut removed = map.remove(header::SET_COOKIE);
+assert_eq!(removed.next().unwrap(), "one=1");
+assert_eq!(removed.next().unwrap(), "one=2");
+assert!(removed.next().is_none());
+
+assert!(map.is_empty());
+

A convenience method is provided on the returned iterator to check if the remove call +actually removed any values.

+ +
let mut map = HeaderMap::new();
+
+let removed = map.remove("accept");
+assert!(removed.is_empty());
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/html"));
+let removed = map.remove("accept");
+assert!(!removed.is_empty());
+
source

pub fn capacity(&self) -> usize

Returns the number of single-value headers the map can hold without needing to reallocate.

+

Since this is a multi-value map, the actual capacity is much larger when considering +each header name can be associated with an arbitrary number of values. The effect is that +the size of len may be greater than capacity since it counts all the values. +Conversely, len_keys will never be larger than capacity.

+
§Examples
+
let map = HeaderMap::with_capacity(16);
+
+assert!(map.is_empty());
+assert!(map.capacity() >= 16);
+
source

pub fn reserve(&mut self, additional: usize)

Reserves capacity for at least additional more headers to be inserted in the map.

+

The header map may reserve more space to avoid frequent reallocations. Additional capacity +only considers single-value headers.

+
§Panics
+

Panics if the new allocation size overflows usize.

+
§Examples
+
let mut map = HeaderMap::with_capacity(2);
+assert!(map.capacity() >= 2);
+
+map.reserve(100);
+assert!(map.capacity() >= 102);
+
+assert!(map.is_empty());
+
source

pub fn iter(&self) -> Iter<'_>

An iterator over all name-value pairs.

+

Names will be yielded for each associated value. So, if a key has 3 associated values, it +will be yielded 3 times. The iteration order should be considered arbitrary.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut iter = map.iter();
+assert!(iter.next().is_none());
+
+map.append(header::HOST, HeaderValue::from_static("duck.com"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let mut iter = map.iter();
+assert!(iter.next().is_some());
+assert!(iter.next().is_some());
+assert!(iter.next().is_some());
+assert!(iter.next().is_none());
+
+let pairs = map.iter().collect::<Vec<_>>();
+assert!(pairs.contains(&(&header::HOST, &HeaderValue::from_static("duck.com"))));
+assert!(pairs.contains(&(&header::SET_COOKIE, &HeaderValue::from_static("one=1"))));
+assert!(pairs.contains(&(&header::SET_COOKIE, &HeaderValue::from_static("two=2"))));
+
source

pub fn keys(&self) -> Keys<'_>

An iterator over all contained header names.

+

Each name will only be yielded once even if it has multiple associated values. The iteration +order should be considered arbitrary.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut iter = map.keys();
+assert!(iter.next().is_none());
+
+map.append(header::HOST, HeaderValue::from_static("duck.com"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let keys = map.keys().cloned().collect::<Vec<_>>();
+assert_eq!(keys.len(), 2);
+assert!(keys.contains(&header::HOST));
+assert!(keys.contains(&header::SET_COOKIE));
+
source

pub fn retain<F>(&mut self, retain_fn: F)
where + F: FnMut(&HeaderName, &mut HeaderValue) -> bool,

Retains only the headers specified by the predicate.

+

In other words, removes all headers (name, val) for which retain_fn(&name, &mut val) +returns false.

+

The order in which headers are visited should be considered arbitrary.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.append(header::HOST, HeaderValue::from_static("duck.com"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+map.retain(|name, val| val.as_bytes().starts_with(b"one"));
+
+assert_eq!(map.len(), 1);
+assert!(map.contains_key(&header::SET_COOKIE));
+
source

pub fn drain(&mut self) -> Drain<'_>

Clears the map, returning all name-value sets as an iterator.

+

Header names will only be yielded for the first value in each set. All items that are +yielded without a name and after an item with a name are associated with that same name. +The first item will always contain a name.

+

Keeps the allocated memory for reuse.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut iter = map.drain();
+assert!(iter.next().is_none());
+drop(iter);
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let mut iter = map.drain();
+assert_eq!(iter.next().unwrap(), (Some(header::SET_COOKIE), HeaderValue::from_static("one=1")));
+assert_eq!(iter.next().unwrap(), (None, HeaderValue::from_static("two=2")));
+drop(iter);
+
+assert!(map.is_empty());
+

Trait Implementations§

source§

impl Clone for HeaderMap

source§

fn clone(&self) -> HeaderMap

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for HeaderMap

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for HeaderMap

source§

fn default() -> HeaderMap

Returns the “default value” for a type. Read more
source§

impl From<&HeaderMap> for HeaderMap

Convert our &HeaderMap to a http::HeaderMap.

+
source§

fn from(map: &HeaderMap) -> Self

Converts to this type from the input type.
source§

impl From<HeaderMap> for HeaderMap

Convert a http::HeaderMap to our HeaderMap.

+
source§

fn from(map: HeaderMap) -> Self

Converts to this type from the input type.
source§

impl From<HeaderMap> for HeaderMap

Convert our HeaderMap to a http::HeaderMap.

+
source§

fn from(map: HeaderMap) -> Self

Converts to this type from the input type.
source§

impl<'a> IntoIterator for &'a HeaderMap

§

type Item = (&'a HeaderName, &'a HeaderValue)

The type of the elements being iterated over.
§

type IntoIter = Iter<'a>

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl IntoIterator for HeaderMap

Note that this implementation will clone a HeaderName for each value. Consider using +drain to control header name cloning.

+
§

type Item = (HeaderName, HeaderValue)

The type of the elements being iterated over.
§

type IntoIter = IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/map/struct.IntoIter.html b/actix_http/header/map/struct.IntoIter.html new file mode 100644 index 000000000..f981f1ead --- /dev/null +++ b/actix_http/header/map/struct.IntoIter.html @@ -0,0 +1,206 @@ +IntoIter in actix_http::header::map - Rust

Struct actix_http::header::map::IntoIter

source ·
pub struct IntoIter { /* private fields */ }
Expand description

Iterator over owned name-value pairs.

+

Implementation necessarily clones header names for each value.

+

Trait Implementations§

source§

impl Debug for IntoIter

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl ExactSizeIterator for IntoIter

1.0.0 · source§

fn len(&self) -> usize

Returns the exact remaining length of the iterator. Read more
source§

fn is_empty(&self) -> bool

🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
source§

impl Iterator for IntoIter

§

type Item = (HeaderName, HeaderValue)

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<Self::Item>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usize
where + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>
where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
where + Self: Sized, + Self::Item: Clone,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places a copy of separator between adjacent +items of the original iterator. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl FusedIterator for IntoIter

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for I
where + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<I> IteratorRandom for I
where + I: Iterator,

source§

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where + R: Rng + ?Sized,

Collects values at random from the iterator into a supplied buffer +until that buffer is filled. Read more
source§

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where + R: Rng + ?Sized,

Available on crate feature alloc only.
Collects amount values at random from the iterator into a vector. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/map/struct.Iter.html b/actix_http/header/map/struct.Iter.html new file mode 100644 index 000000000..519a4f29b --- /dev/null +++ b/actix_http/header/map/struct.Iter.html @@ -0,0 +1,202 @@ +Iter in actix_http::header::map - Rust

Struct actix_http::header::map::Iter

source ·
pub struct Iter<'a> { /* private fields */ }
Expand description

Iterator over borrowed name-value pairs.

+

Trait Implementations§

source§

impl<'a> Debug for Iter<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl ExactSizeIterator for Iter<'_>

1.0.0 · source§

fn len(&self) -> usize

Returns the exact remaining length of the iterator. Read more
source§

fn is_empty(&self) -> bool

🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
source§

impl<'a> Iterator for Iter<'a>

§

type Item = (&'a HeaderName, &'a HeaderValue)

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<Self::Item>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usize
where + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>
where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl FusedIterator for Iter<'_>

Auto Trait Implementations§

§

impl<'a> Freeze for Iter<'a>

§

impl<'a> RefUnwindSafe for Iter<'a>

§

impl<'a> Send for Iter<'a>

§

impl<'a> Sync for Iter<'a>

§

impl<'a> Unpin for Iter<'a>

§

impl<'a> UnwindSafe for Iter<'a>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for I
where + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<I> IteratorRandom for I
where + I: Iterator,

source§

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where + R: Rng + ?Sized,

Collects values at random from the iterator into a supplied buffer +until that buffer is filled. Read more
source§

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where + R: Rng + ?Sized,

Available on crate feature alloc only.
Collects amount values at random from the iterator into a vector. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/map/struct.Keys.html b/actix_http/header/map/struct.Keys.html new file mode 100644 index 000000000..b7d6c9f88 --- /dev/null +++ b/actix_http/header/map/struct.Keys.html @@ -0,0 +1,202 @@ +Keys in actix_http::header::map - Rust

Struct actix_http::header::map::Keys

source ·
pub struct Keys<'a>(/* private fields */);
Expand description

Iterator over all names in the map.

+

Trait Implementations§

source§

impl<'a> Debug for Keys<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl ExactSizeIterator for Keys<'_>

1.0.0 · source§

fn len(&self) -> usize

Returns the exact remaining length of the iterator. Read more
source§

fn is_empty(&self) -> bool

🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
source§

impl<'a> Iterator for Keys<'a>

§

type Item = &'a HeaderName

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<Self::Item>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usize
where + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>
where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl FusedIterator for Keys<'_>

Auto Trait Implementations§

§

impl<'a> Freeze for Keys<'a>

§

impl<'a> RefUnwindSafe for Keys<'a>

§

impl<'a> Send for Keys<'a>

§

impl<'a> Sync for Keys<'a>

§

impl<'a> Unpin for Keys<'a>

§

impl<'a> UnwindSafe for Keys<'a>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for I
where + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<I> IteratorRandom for I
where + I: Iterator,

source§

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where + R: Rng + ?Sized,

Collects values at random from the iterator into a supplied buffer +until that buffer is filled. Read more
source§

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where + R: Rng + ?Sized,

Available on crate feature alloc only.
Collects amount values at random from the iterator into a vector. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/map/struct.Removed.html b/actix_http/header/map/struct.Removed.html new file mode 100644 index 000000000..23c0ce6e0 --- /dev/null +++ b/actix_http/header/map/struct.Removed.html @@ -0,0 +1,220 @@ +Removed in actix_http::header::map - Rust

Struct actix_http::header::map::Removed

source ·
pub struct Removed { /* private fields */ }
Expand description

Iterator over removed, owned values with the same associated name.

+

Returned from methods that remove or replace items. See HeaderMap::insert +and HeaderMap::remove.

+

Implementations§

source§

impl Removed

source

pub fn is_empty(&self) -> bool

Returns true if iterator contains no elements, without consuming it.

+

If called immediately after HeaderMap::insert or HeaderMap::remove, it will indicate +whether any items were actually replaced or removed, respectively.

+

Trait Implementations§

source§

impl Debug for Removed

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl ExactSizeIterator for Removed

1.0.0 · source§

fn len(&self) -> usize

Returns the exact remaining length of the iterator. Read more
source§

fn is_empty(&self) -> bool

🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
source§

impl Iterator for Removed

§

type Item = HeaderValue

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<Self::Item>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usize
where + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>
where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
where + Self: Sized, + Self::Item: Clone,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places a copy of separator between adjacent +items of the original iterator. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.0.0 · source§

fn max(self) -> Option<Self::Item>
where + Self: Sized, + Self::Item: Ord,

Returns the maximum element of an iterator. Read more
1.0.0 · source§

fn min(self) -> Option<Self::Item>
where + Self: Sized, + Self::Item: Ord,

Returns the minimum element of an iterator. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
1.5.0 · source§

fn cmp<I>(self, other: I) -> Ordering
where + I: IntoIterator<Item = Self::Item>, + Self::Item: Ord, + Self: Sized,

Lexicographically compares the elements of this Iterator with those +of another. Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted(self) -> bool
where + Self: Sized, + Self::Item: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl FusedIterator for Removed

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for I
where + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<I> IteratorRandom for I
where + I: Iterator,

source§

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where + R: Rng + ?Sized,

Collects values at random from the iterator into a supplied buffer +until that buffer is filled. Read more
source§

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where + R: Rng + ?Sized,

Available on crate feature alloc only.
Collects amount values at random from the iterator into a vector. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/shared/charset/enum.Charset.html b/actix_http/header/shared/charset/enum.Charset.html new file mode 100644 index 000000000..f7fe4e063 --- /dev/null +++ b/actix_http/header/shared/charset/enum.Charset.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_http/header/enum.Charset.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/shared/content_encoding/enum.ContentEncoding.html b/actix_http/header/shared/content_encoding/enum.ContentEncoding.html new file mode 100644 index 000000000..448beeb34 --- /dev/null +++ b/actix_http/header/shared/content_encoding/enum.ContentEncoding.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_http/header/enum.ContentEncoding.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/shared/extended/fn.parse_extended_value.html b/actix_http/header/shared/extended/fn.parse_extended_value.html new file mode 100644 index 000000000..0f84eb3ab --- /dev/null +++ b/actix_http/header/shared/extended/fn.parse_extended_value.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_http/header/fn.parse_extended_value.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/shared/extended/struct.ExtendedValue.html b/actix_http/header/shared/extended/struct.ExtendedValue.html new file mode 100644 index 000000000..4dd4a6893 --- /dev/null +++ b/actix_http/header/shared/extended/struct.ExtendedValue.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_http/header/struct.ExtendedValue.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/shared/http_date/struct.HttpDate.html b/actix_http/header/shared/http_date/struct.HttpDate.html new file mode 100644 index 000000000..e3eff4944 --- /dev/null +++ b/actix_http/header/shared/http_date/struct.HttpDate.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_http/header/struct.HttpDate.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/shared/quality/fn.q.html b/actix_http/header/shared/quality/fn.q.html new file mode 100644 index 000000000..baece559d --- /dev/null +++ b/actix_http/header/shared/quality/fn.q.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_http/header/fn.q.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/shared/quality/struct.Quality.html b/actix_http/header/shared/quality/struct.Quality.html new file mode 100644 index 000000000..ab94b9e43 --- /dev/null +++ b/actix_http/header/shared/quality/struct.Quality.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_http/header/struct.Quality.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/shared/quality_item/struct.QualityItem.html b/actix_http/header/shared/quality_item/struct.QualityItem.html new file mode 100644 index 000000000..7432f9e90 --- /dev/null +++ b/actix_http/header/shared/quality_item/struct.QualityItem.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_http/header/struct.QualityItem.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/shared/struct.LanguageTag.html b/actix_http/header/shared/struct.LanguageTag.html new file mode 100644 index 000000000..c6d2b4398 --- /dev/null +++ b/actix_http/header/shared/struct.LanguageTag.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/header/struct.LanguageTag.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/sidebar-items.js b/actix_http/header/sidebar-items.js new file mode 100644 index 000000000..f715f9819 --- /dev/null +++ b/actix_http/header/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"constant":["ACCEPT","ACCEPT_CHARSET","ACCEPT_ENCODING","ACCEPT_LANGUAGE","ACCEPT_RANGES","ACCESS_CONTROL_ALLOW_CREDENTIALS","ACCESS_CONTROL_ALLOW_HEADERS","ACCESS_CONTROL_ALLOW_METHODS","ACCESS_CONTROL_ALLOW_ORIGIN","ACCESS_CONTROL_EXPOSE_HEADERS","ACCESS_CONTROL_MAX_AGE","ACCESS_CONTROL_REQUEST_HEADERS","ACCESS_CONTROL_REQUEST_METHOD","AGE","ALLOW","ALT_SVC","AUTHORIZATION","CACHE_CONTROL","CACHE_STATUS","CDN_CACHE_CONTROL","CONNECTION","CONTENT_DISPOSITION","CONTENT_ENCODING","CONTENT_LANGUAGE","CONTENT_LENGTH","CONTENT_LOCATION","CONTENT_RANGE","CONTENT_SECURITY_POLICY","CONTENT_SECURITY_POLICY_REPORT_ONLY","CONTENT_TYPE","COOKIE","CROSS_ORIGIN_EMBEDDER_POLICY","CROSS_ORIGIN_OPENER_POLICY","CROSS_ORIGIN_RESOURCE_POLICY","DATE","DNT","ETAG","EXPECT","EXPIRES","FORWARDED","FROM","HOST","IF_MATCH","IF_MODIFIED_SINCE","IF_NONE_MATCH","IF_RANGE","IF_UNMODIFIED_SINCE","LAST_MODIFIED","LINK","LOCATION","MAX_FORWARDS","ORIGIN","PERMISSIONS_POLICY","PRAGMA","PROXY_AUTHENTICATE","PROXY_AUTHORIZATION","PUBLIC_KEY_PINS","PUBLIC_KEY_PINS_REPORT_ONLY","RANGE","REFERER","REFERRER_POLICY","REFRESH","RETRY_AFTER","SEC_WEBSOCKET_ACCEPT","SEC_WEBSOCKET_EXTENSIONS","SEC_WEBSOCKET_KEY","SEC_WEBSOCKET_PROTOCOL","SEC_WEBSOCKET_VERSION","SERVER","SET_COOKIE","STRICT_TRANSPORT_SECURITY","TE","TRAILER","TRANSFER_ENCODING","UPGRADE","UPGRADE_INSECURE_REQUESTS","USER_AGENT","VARY","VIA","WARNING","WWW_AUTHENTICATE","X_CONTENT_TYPE_OPTIONS","X_DNS_PREFETCH_CONTROL","X_FORWARDED_FOR","X_FORWARDED_HOST","X_FORWARDED_PROTO","X_FRAME_OPTIONS","X_XSS_PROTECTION"],"enum":["Charset","ContentEncoding"],"fn":["fmt_comma_delimited","from_comma_delimited","from_one_raw_str","http_percent_encode","parse_extended_value","q"],"mod":["map"],"struct":["ExtendedValue","HeaderName","HeaderValue","HttpDate","InvalidHeaderName","InvalidHeaderValue","LanguageTag","Quality","QualityItem","ToStrError"],"trait":["AsHeaderName","Header","TryIntoHeaderPair","TryIntoHeaderValue"]}; \ No newline at end of file diff --git a/actix_http/header/struct.ExtendedValue.html b/actix_http/header/struct.ExtendedValue.html new file mode 100644 index 000000000..c3a58249e --- /dev/null +++ b/actix_http/header/struct.ExtendedValue.html @@ -0,0 +1,39 @@ +ExtendedValue in actix_http::header - Rust

Struct actix_http::header::ExtendedValue

source ·
pub struct ExtendedValue {
+    pub charset: Charset,
+    pub language_tag: Option<LanguageTag>,
+    pub value: Vec<u8>,
+}
Expand description

The value part of an extended parameter consisting of three parts:

+
    +
  • The REQUIRED character set name (charset).
  • +
  • The OPTIONAL language information (language_tag).
  • +
  • A character sequence representing the actual value (value), separated by single quotes.
  • +
+

It is defined in RFC 5987 §3.2.

+

Fields§

§charset: Charset

The character set that is used to encode the value to a string.

+
§language_tag: Option<LanguageTag>

The human language details of the value, if available.

+
§value: Vec<u8>

The parameter value, as expressed in octets.

+

Trait Implementations§

source§

impl Clone for ExtendedValue

source§

fn clone(&self) -> ExtendedValue

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ExtendedValue

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for ExtendedValue

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq for ExtendedValue

source§

fn eq(&self, other: &ExtendedValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for ExtendedValue

source§

impl StructuralPartialEq for ExtendedValue

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/struct.HeaderName.html b/actix_http/header/struct.HeaderName.html new file mode 100644 index 000000000..646c9111b --- /dev/null +++ b/actix_http/header/struct.HeaderName.html @@ -0,0 +1,136 @@ +HeaderName in actix_http::header - Rust

Struct actix_http::header::HeaderName

source ·
pub struct HeaderName { /* private fields */ }
Expand description

Represents an HTTP header field name

+

Header field names identify the header. Header sets may include multiple +headers with the same name. The HTTP specification defines a number of +standard headers, but HTTP messages may include non-standard header names as +well as long as they adhere to the specification.

+

HeaderName is used as the HeaderMap key. Constants are available for +all standard header names in the header module.

+

§Representation

+

HeaderName represents standard header names using an enum, as such they +will not require an allocation for storage. All custom header names are +lower cased upon conversion to a HeaderName value. This avoids the +overhead of dynamically doing lower case conversion during the hash code +computation and the comparison operation.

+

Implementations§

source§

impl HeaderName

source

pub fn from_bytes(src: &[u8]) -> Result<HeaderName, InvalidHeaderName>

Converts a slice of bytes to an HTTP header name.

+

This function normalizes the input.

+
source

pub fn from_lowercase(src: &[u8]) -> Result<HeaderName, InvalidHeaderName>

Converts a slice of bytes to an HTTP header name.

+

This function expects the input to only contain lowercase characters. +This is useful when decoding HTTP/2.0 or HTTP/3.0 headers. Both +require that all headers be represented in lower case.

+
§Examples
+

+// Parsing a lower case header
+let hdr = HeaderName::from_lowercase(b"content-length").unwrap();
+assert_eq!(CONTENT_LENGTH, hdr);
+
+// Parsing a header that contains uppercase characters
+assert!(HeaderName::from_lowercase(b"Content-Length").is_err());
+
source

pub const fn from_static(src: &'static str) -> HeaderName

Converts a static string to a HTTP header name.

+

This function requires the static string to only contain lowercase +characters, numerals and symbols, as per the HTTP/2.0 specification +and header names internal representation within this library.

+
§Panics
+

This function panics when the static string is a invalid header.

+

Until Allow panicking in constants +makes its way into stable, the panic message at compile-time is +going to look cryptic, but should at least point at your header value:

+
error: any use of this value will cause an error
+    --> http/src/header/name.rs:1241:13
+     |
+1241 |             ([] as [u8; 0])[0]; // Invalid header name
+     |             ^^^^^^^^^^^^^^^^^^
+     |             |
+     |             index out of bounds: the length is 0 but the index is 0
+     |             inside `http::HeaderName::from_static` at http/src/header/name.rs:1241:13
+     |             inside `INVALID_NAME` at src/main.rs:3:34
+     |
+    ::: src/main.rs:3:1
+     |
+3    | const INVALID_NAME: HeaderName = HeaderName::from_static("Capitalized");
+     | ------------------------------------------------------------------------
+
§Examples
+
// Parsing a standard header
+let hdr = HeaderName::from_static("content-length");
+assert_eq!(CONTENT_LENGTH, hdr);
+
+// Parsing a custom header
+let CUSTOM_HEADER: &'static str = "custom-header";
+
+let a = HeaderName::from_lowercase(b"custom-header").unwrap();
+let b = HeaderName::from_static(CUSTOM_HEADER);
+assert_eq!(a, b);
+ +
// Parsing a header that contains invalid symbols(s):
+HeaderName::from_static("content{}{}length"); // This line panics!
+
+// Parsing a header that contains invalid uppercase characters.
+let a = HeaderName::from_static("foobar");
+let b = HeaderName::from_static("FOOBAR"); // This line panics!
+
source

pub fn as_str(&self) -> &str

Returns a str representation of the header.

+

The returned string will always be lower case.

+

Trait Implementations§

source§

impl AsRef<[u8]> for HeaderName

source§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl AsRef<str> for HeaderName

source§

fn as_ref(&self) -> &str

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Borrow<str> for HeaderName

source§

fn borrow(&self) -> &str

Immutably borrows from an owned value. Read more
source§

impl Clone for HeaderName

source§

fn clone(&self) -> HeaderName

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for HeaderName

source§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for HeaderName

source§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a HeaderName> for HeaderName

source§

fn from(src: &'a HeaderName) -> HeaderName

Converts to this type from the input type.
source§

impl From<HeaderName> for HeaderValue

source§

fn from(h: HeaderName) -> HeaderValue

Converts to this type from the input type.
source§

impl FromStr for HeaderName

§

type Err = InvalidHeaderName

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<HeaderName, InvalidHeaderName>

Parses a string s to return a value of this type. Read more
source§

impl Hash for HeaderName

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<'a> PartialEq<&'a HeaderName> for HeaderName

source§

fn eq(&self, other: &&'a HeaderName) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<&'a str> for HeaderName

source§

fn eq(&self, other: &&'a str) -> bool

Performs a case-insensitive comparison of the string against the header +name

+
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<HeaderName> for &'a HeaderName

source§

fn eq(&self, other: &HeaderName) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<HeaderName> for &'a str

source§

fn eq(&self, other: &HeaderName) -> bool

Performs a case-insensitive comparison of the string against the header +name

+
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<HeaderName> for str

source§

fn eq(&self, other: &HeaderName) -> bool

Performs a case-insensitive comparison of the string against the header +name

+
§Examples
+
use http::header::CONTENT_LENGTH;
+
+assert_eq!(CONTENT_LENGTH, "content-length");
+assert_eq!(CONTENT_LENGTH, "Content-Length");
+assert_ne!(CONTENT_LENGTH, "content length");
+
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for HeaderName

source§

fn eq(&self, other: &str) -> bool

Performs a case-insensitive comparison of the string against the header +name

+
§Examples
+
use http::header::CONTENT_LENGTH;
+
+assert_eq!(CONTENT_LENGTH, "content-length");
+assert_eq!(CONTENT_LENGTH, "Content-Length");
+assert_ne!(CONTENT_LENGTH, "content length");
+
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for HeaderName

source§

fn eq(&self, other: &HeaderName) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> TryFrom<&'a [u8]> for HeaderName

§

type Error = InvalidHeaderName

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a [u8] +) -> Result<HeaderName, <HeaderName as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a String> for HeaderName

§

type Error = InvalidHeaderName

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a String +) -> Result<HeaderName, <HeaderName as TryFrom<&'a String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for HeaderName

§

type Error = InvalidHeaderName

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a str +) -> Result<HeaderName, <HeaderName as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for HeaderName

§

type Error = InvalidHeaderName

The type returned in the event of a conversion error.
source§

fn try_from( + s: String +) -> Result<HeaderName, <HeaderName as TryFrom<String>>::Error>

Performs the conversion.
source§

impl TryFrom<Vec<u8>> for HeaderName

§

type Error = InvalidHeaderName

The type returned in the event of a conversion error.
source§

fn try_from( + vec: Vec<u8> +) -> Result<HeaderName, <HeaderName as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
source§

impl<'a> AsHeaderName for &'a HeaderName

source§

impl AsHeaderName for &HeaderName

source§

impl AsHeaderName for HeaderName

source§

impl AsHeaderName for HeaderName

source§

impl Eq for HeaderName

source§

impl<'a> IntoHeaderName for &'a HeaderName

source§

impl IntoHeaderName for HeaderName

source§

impl StructuralPartialEq for HeaderName

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/struct.HeaderValue.html b/actix_http/header/struct.HeaderValue.html new file mode 100644 index 000000000..6fe7ea352 --- /dev/null +++ b/actix_http/header/struct.HeaderValue.html @@ -0,0 +1,204 @@ +HeaderValue in actix_http::header - Rust

Struct actix_http::header::HeaderValue

source ·
pub struct HeaderValue { /* private fields */ }
Expand description

Represents an HTTP header field value.

+

In practice, HTTP header field values are usually valid ASCII. However, the +HTTP spec allows for a header value to contain opaque bytes as well. In this +case, the header field value is not able to be represented as a string.

+

To handle this, the HeaderValue is useable as a type and can be compared +with strings and implements Debug. A to_str fn is provided that returns +an Err if the header value contains non visible ascii characters.

+

Implementations§

source§

impl HeaderValue

source

pub const fn from_static(src: &'static str) -> HeaderValue

Convert a static string to a HeaderValue.

+

This function will not perform any copying, however the string is +checked to ensure that no invalid characters are present. Only visible +ASCII characters (32-127) are permitted.

+
§Panics
+

This function panics if the argument contains invalid header value +characters.

+

Until Allow panicking in constants +makes its way into stable, the panic message at compile-time is +going to look cryptic, but should at least point at your header value:

+
error: any use of this value will cause an error
+  --> http/src/header/value.rs:67:17
+   |
+67 |                 ([] as [u8; 0])[0]; // Invalid header value
+   |                 ^^^^^^^^^^^^^^^^^^
+   |                 |
+   |                 index out of bounds: the length is 0 but the index is 0
+   |                 inside `HeaderValue::from_static` at http/src/header/value.rs:67:17
+   |                 inside `INVALID_HEADER` at src/main.rs:73:33
+   |
+  ::: src/main.rs:73:1
+   |
+73 | const INVALID_HEADER: HeaderValue = HeaderValue::from_static("жsome value");
+   | ----------------------------------------------------------------------------
+
§Examples
+
let val = HeaderValue::from_static("hello");
+assert_eq!(val, "hello");
+
source

pub fn from_str(src: &str) -> Result<HeaderValue, InvalidHeaderValue>

Attempt to convert a string to a HeaderValue.

+

If the argument contains invalid header value characters, an error is +returned. Only visible ASCII characters (32-127) are permitted. Use +from_bytes to create a HeaderValue that includes opaque octets +(128-255).

+

This function is intended to be replaced in the future by a TryFrom +implementation once the trait is stabilized in std.

+
§Examples
+
let val = HeaderValue::from_str("hello").unwrap();
+assert_eq!(val, "hello");
+

An invalid value

+ +
let val = HeaderValue::from_str("\n");
+assert!(val.is_err());
+
source

pub fn from_name(name: HeaderName) -> HeaderValue

Converts a HeaderName into a HeaderValue

+

Since every valid HeaderName is a valid HeaderValue this is done infallibly.

+
§Examples
+
let val = HeaderValue::from_name(ACCEPT);
+assert_eq!(val, HeaderValue::from_bytes(b"accept").unwrap());
+
source

pub fn from_bytes(src: &[u8]) -> Result<HeaderValue, InvalidHeaderValue>

Attempt to convert a byte slice to a HeaderValue.

+

If the argument contains invalid header value bytes, an error is +returned. Only byte values between 32 and 255 (inclusive) are permitted, +excluding byte 127 (DEL).

+

This function is intended to be replaced in the future by a TryFrom +implementation once the trait is stabilized in std.

+
§Examples
+
let val = HeaderValue::from_bytes(b"hello\xfa").unwrap();
+assert_eq!(val, &b"hello\xfa"[..]);
+

An invalid value

+ +
let val = HeaderValue::from_bytes(b"\n");
+assert!(val.is_err());
+
source

pub fn from_maybe_shared<T>(src: T) -> Result<HeaderValue, InvalidHeaderValue>
where + T: AsRef<[u8]> + 'static,

Attempt to convert a Bytes buffer to a HeaderValue.

+

This will try to prevent a copy if the type passed is the type used +internally, and will copy the data if it is not.

+
source

pub unsafe fn from_maybe_shared_unchecked<T>(src: T) -> HeaderValue
where + T: AsRef<[u8]> + 'static,

Convert a Bytes directly into a HeaderValue without validating.

+

This function does NOT validate that illegal bytes are not contained +within the buffer.

+
source

pub fn to_str(&self) -> Result<&str, ToStrError>

Yields a &str slice if the HeaderValue only contains visible ASCII +chars.

+

This function will perform a scan of the header value, checking all the +characters.

+
§Examples
+
let val = HeaderValue::from_static("hello");
+assert_eq!(val.to_str().unwrap(), "hello");
+
source

pub fn len(&self) -> usize

Returns the length of self.

+

This length is in bytes.

+
§Examples
+
let val = HeaderValue::from_static("hello");
+assert_eq!(val.len(), 5);
+
source

pub fn is_empty(&self) -> bool

Returns true if the HeaderValue has a length of zero bytes.

+
§Examples
+
let val = HeaderValue::from_static("");
+assert!(val.is_empty());
+
+let val = HeaderValue::from_static("hello");
+assert!(!val.is_empty());
+
source

pub fn as_bytes(&self) -> &[u8]

Converts a HeaderValue to a byte slice.

+
§Examples
+
let val = HeaderValue::from_static("hello");
+assert_eq!(val.as_bytes(), b"hello");
+
source

pub fn set_sensitive(&mut self, val: bool)

Mark that the header value represents sensitive information.

+
§Examples
+
let mut val = HeaderValue::from_static("my secret");
+
+val.set_sensitive(true);
+assert!(val.is_sensitive());
+
+val.set_sensitive(false);
+assert!(!val.is_sensitive());
+
source

pub fn is_sensitive(&self) -> bool

Returns true if the value represents sensitive data.

+

Sensitive data could represent passwords or other data that should not +be stored on disk or in memory. By marking header values as sensitive, +components using this crate can be instructed to treat them with special +care for security reasons. For example, caches can avoid storing +sensitive values, and HPACK encoders used by HTTP/2.0 implementations +can choose not to compress them.

+

Additionally, sensitive values will be masked by the Debug +implementation of HeaderValue.

+

Note that sensitivity is not factored into equality or ordering.

+
§Examples
+
let mut val = HeaderValue::from_static("my secret");
+
+val.set_sensitive(true);
+assert!(val.is_sensitive());
+
+val.set_sensitive(false);
+assert!(!val.is_sensitive());
+

Trait Implementations§

source§

impl AsRef<[u8]> for HeaderValue

source§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for HeaderValue

source§

fn clone(&self) -> HeaderValue

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for HeaderValue

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a HeaderValue> for HeaderValue

source§

fn from(t: &'a HeaderValue) -> HeaderValue

Converts to this type from the input type.
source§

impl From<HeaderName> for HeaderValue

source§

fn from(h: HeaderName) -> HeaderValue

Converts to this type from the input type.
source§

impl From<i16> for HeaderValue

source§

fn from(num: i16) -> HeaderValue

Converts to this type from the input type.
source§

impl From<i32> for HeaderValue

source§

fn from(num: i32) -> HeaderValue

Converts to this type from the input type.
source§

impl From<i64> for HeaderValue

source§

fn from(num: i64) -> HeaderValue

Converts to this type from the input type.
source§

impl From<isize> for HeaderValue

source§

fn from(num: isize) -> HeaderValue

Converts to this type from the input type.
source§

impl From<u16> for HeaderValue

source§

fn from(num: u16) -> HeaderValue

Converts to this type from the input type.
source§

impl From<u32> for HeaderValue

source§

fn from(num: u32) -> HeaderValue

Converts to this type from the input type.
source§

impl From<u64> for HeaderValue

source§

fn from(num: u64) -> HeaderValue

Converts to this type from the input type.
source§

impl From<usize> for HeaderValue

source§

fn from(num: usize) -> HeaderValue

Converts to this type from the input type.
source§

impl FromStr for HeaderValue

§

type Err = InvalidHeaderValue

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<HeaderValue, <HeaderValue as FromStr>::Err>

Parses a string s to return a value of this type. Read more
source§

impl Hash for HeaderValue

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for HeaderValue

source§

fn cmp(&self, other: &HeaderValue) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl<'a, T> PartialEq<&'a T> for HeaderValue
where + HeaderValue: PartialEq<T>, + T: ?Sized,

source§

fn eq(&self, other: &&'a T) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<[u8]> for HeaderValue

source§

fn eq(&self, other: &[u8]) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<HeaderValue> for &'a HeaderValue

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<HeaderValue> for &'a str

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<HeaderValue> for [u8]

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<HeaderValue> for str

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<String> for HeaderValue

source§

fn eq(&self, other: &String) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for HeaderValue

source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for HeaderValue

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a, T> PartialOrd<&'a T> for HeaderValue
where + HeaderValue: PartialOrd<T>, + T: ?Sized,

source§

fn partial_cmp(&self, other: &&'a T) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<[u8]> for HeaderValue

source§

fn partial_cmp(&self, other: &[u8]) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> PartialOrd<HeaderValue> for &'a HeaderValue

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> PartialOrd<HeaderValue> for &'a str

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<HeaderValue> for [u8]

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<HeaderValue> for str

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<String> for HeaderValue

source§

fn partial_cmp(&self, other: &String) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<str> for HeaderValue

source§

fn partial_cmp(&self, other: &str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for HeaderValue

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> TryFrom<&'a [u8]> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + t: &'a [u8] +) -> Result<HeaderValue, <HeaderValue as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a String> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a String +) -> Result<HeaderValue, <HeaderValue as TryFrom<&'a String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + t: &'a str +) -> Result<HeaderValue, <HeaderValue as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + t: String +) -> Result<HeaderValue, <HeaderValue as TryFrom<String>>::Error>

Performs the conversion.
source§

impl TryFrom<Vec<u8>> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + vec: Vec<u8> +) -> Result<HeaderValue, <HeaderValue as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
source§

impl TryIntoHeaderValue for &HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl TryIntoHeaderValue for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for HeaderValue

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/struct.HttpDate.html b/actix_http/header/struct.HttpDate.html new file mode 100644 index 000000000..41887cfb7 --- /dev/null +++ b/actix_http/header/struct.HttpDate.html @@ -0,0 +1,33 @@ +HttpDate in actix_http::header - Rust

Struct actix_http::header::HttpDate

source ·
pub struct HttpDate(/* private fields */);
Expand description

A timestamp with HTTP-style formatting and parsing.

+

Trait Implementations§

source§

impl Clone for HttpDate

source§

fn clone(&self) -> HttpDate

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for HttpDate

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for HttpDate

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl From<HttpDate> for SystemTime

source§

fn from(HttpDate: HttpDate) -> SystemTime

Converts to this type from the input type.
source§

impl From<SystemTime> for HttpDate

source§

fn from(sys_time: SystemTime) -> HttpDate

Converts to this type from the input type.
source§

impl FromStr for HttpDate

§

type Err = ParseError

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<HttpDate, ParseError>

Parses a string s to return a value of this type. Read more
source§

impl Ord for HttpDate

source§

fn cmp(&self, other: &HttpDate) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq for HttpDate

source§

fn eq(&self, other: &HttpDate) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for HttpDate

source§

fn partial_cmp(&self, other: &HttpDate) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl TryIntoHeaderValue for HttpDate

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Copy for HttpDate

source§

impl Eq for HttpDate

source§

impl StructuralPartialEq for HttpDate

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/struct.InvalidHeaderName.html b/actix_http/header/struct.InvalidHeaderName.html new file mode 100644 index 000000000..07a2d0553 --- /dev/null +++ b/actix_http/header/struct.InvalidHeaderName.html @@ -0,0 +1,19 @@ +InvalidHeaderName in actix_http::header - Rust

Struct actix_http::header::InvalidHeaderName

source ·
pub struct InvalidHeaderName { /* private fields */ }
Expand description

A possible error when converting a HeaderName from another type.

+

Trait Implementations§

source§

impl Debug for InvalidHeaderName

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for InvalidHeaderName

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for InvalidHeaderName

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<InvalidHeaderName> for Error

source§

fn from(err: InvalidHeaderName) -> Error

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/struct.InvalidHeaderValue.html b/actix_http/header/struct.InvalidHeaderValue.html new file mode 100644 index 000000000..f9f9828aa --- /dev/null +++ b/actix_http/header/struct.InvalidHeaderValue.html @@ -0,0 +1,20 @@ +InvalidHeaderValue in actix_http::header - Rust

Struct actix_http::header::InvalidHeaderValue

source ·
pub struct InvalidHeaderValue { /* private fields */ }
Expand description

A possible error when converting a HeaderValue from a string or byte +slice.

+

Trait Implementations§

source§

impl Debug for InvalidHeaderValue

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for InvalidHeaderValue

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for InvalidHeaderValue

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<InvalidHeaderValue> for Error

source§

fn from(err: InvalidHeaderValue) -> Error

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/struct.LanguageTag.html b/actix_http/header/struct.LanguageTag.html new file mode 100644 index 000000000..33fe72f3b --- /dev/null +++ b/actix_http/header/struct.LanguageTag.html @@ -0,0 +1,177 @@ +LanguageTag in actix_http::header - Rust

Struct actix_http::header::LanguageTag

pub struct LanguageTag { /* private fields */ }
Expand description

A language tag as described in RFC 5646.

+

Language tags are used to help identify languages, whether spoken, +written, signed, or otherwise signaled, for the purpose of +communication. This includes constructed and artificial languages +but excludes languages not intended primarily for human +communication, such as programming languages.

+

Implementations§

§

impl LanguageTag

pub fn as_str(&self) -> &str

Return the serialization of this language tag.

+

This is fast since that serialization is already stored in the LanguageTag struct.

+

pub fn into_string(self) -> String

Return the serialization of this language tag.

+

This consumes the LanguageTag and takes ownership of the String stored in it.

+

pub fn primary_language(&self) -> &str

Return the primary language subtag.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.primary_language(), "zh");
+

pub fn extended_language(&self) -> Option<&str>

Return the extended language subtags.

+

Valid language tags have at most one extended language.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.extended_language(), Some("cmn"));
+

pub fn extended_language_subtags(&self) -> impl Iterator<Item = &str>

Iterate on the extended language subtags.

+

Valid language tags have at most one extended language.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.extended_language_subtags().collect::<Vec<_>>(), vec!["cmn"]);
+

pub fn full_language(&self) -> &str

Return the primary language subtag +and its extended language subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.full_language(), "zh-cmn");
+

pub fn script(&self) -> Option<&str>

Return the script subtag.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.script(), Some("Hans"));
+

pub fn region(&self) -> Option<&str>

Return the region subtag.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.region(), Some("CN"));
+

pub fn variant(&self) -> Option<&str>

Return the variant subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-Latn-TW-pinyin").unwrap();
+assert_eq!(language_tag.variant(), Some("pinyin"));
+

pub fn variant_subtags(&self) -> impl Iterator<Item = &str>

Iterate on the variant subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-Latn-TW-pinyin").unwrap();
+assert_eq!(language_tag.variant_subtags().collect::<Vec<_>>(), vec!["pinyin"]);
+

pub fn extension(&self) -> Option<&str>

Return the extension subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("de-DE-u-co-phonebk").unwrap();
+assert_eq!(language_tag.extension(), Some("u-co-phonebk"));
+

pub fn extension_subtags(&self) -> impl Iterator<Item = (char, &str)>

Iterate on the extension subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("de-DE-u-co-phonebk").unwrap();
+assert_eq!(language_tag.extension_subtags().collect::<Vec<_>>(), vec![('u', "co-phonebk")]);
+

pub fn private_use(&self) -> Option<&str>

Return the private use subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("de-x-foo-bar").unwrap();
+assert_eq!(language_tag.private_use(), Some("x-foo-bar"));
+

pub fn private_use_subtags(&self) -> impl Iterator<Item = &str>

Iterate on the private use subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("de-x-foo-bar").unwrap();
+assert_eq!(language_tag.private_use_subtags().collect::<Vec<_>>(), vec!["foo", "bar"]);
+

pub fn parse(input: &str) -> Result<LanguageTag, ParseError>

Create a LanguageTag from its serialization.

+

This parser accepts the language tags that are “well-formed” according to +RFC 5646. +Full validation could be done with the validate method.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("en-us").unwrap();
+assert_eq!(language_tag.into_string(), "en-US")
+
§Errors
+

If the language tag is not “well-formed” a ParseError variant will be returned.

+

pub fn validate(&self) -> Result<(), ValidationError>

Check if the language tag is “valid” according to +RFC 5646.

+

It applies the following steps:

+
    +
  • grandfathereds and private use tags are valid
  • +
  • There should be no more than one extended language subtag +(c.f. errata 5457).
  • +
  • Primary language, extended language, script, region and variants should appear +in the IANA Language Subtag Registry.
  • +
  • Extended language and variants should have a correct prefix as set +in the IANA Language Subtag Registry.
  • +
  • There should be no duplicate variant and singleton (extension) subtags.
  • +
+
§Errors
+

If the language tag is not “valid” a ValidationError variant will be returned.

+

pub fn is_valid(&self) -> bool

Check if the language tag is valid according to +RFC 5646.

+

pub fn canonicalize(&self) -> Result<LanguageTag, ValidationError>

Returns the canonical version of the language tag following +RFC 5646 4.5.

+

It currently applies the following steps:

+
    +
  • Grandfathered tags are replaced with the canonical version if possible.
  • +
  • Redundant tags are replaced with the canonical version if possible.
  • +
  • Extension languages are promoted to primary language.
  • +
  • Deprecated languages, scripts, regions and variants are replaced with modern equivalents.
  • +
  • Suppress-Script is applied to remove default script for a language (e.g. “en-Latn” is canonicalized as “en”).
  • +
  • Variants are deduplicated
  • +
+
§Errors
+

If there is not a unique way to canonicalize the language tag +a ValidationError variant will be returned.

+

pub fn matches(&self, other: &LanguageTag) -> bool

Matches language tags. The first language acts as a language range, the second one is used +as a normal language tag. None fields in the language range are ignored. If the language +tag has more extlangs than the range these extlangs are ignored. Matches are +case-insensitive.

+

For example the range en-GB matches only en-GB and en-Arab-GB but not en. +The range en matches all language tags starting with en including en, en-GB, +en-Arab and en-Arab-GB.

+
§Panics
+

If the language range has extensions or private use tags.

+
§Examples
+
use language_tags::LanguageTag;
+
+let range_italian = LanguageTag::parse("it").unwrap();
+let tag_german = LanguageTag::parse("de").unwrap();
+let tag_italian_switzerland = LanguageTag::parse("it-CH").unwrap();
+assert!(!range_italian.matches(&tag_german));
+assert!(range_italian.matches(&tag_italian_switzerland));
+
+let range_spanish_brazil = LanguageTag::parse("es-BR").unwrap();
+let tag_spanish = LanguageTag::parse("es").unwrap();
+assert!(!range_spanish_brazil.matches(&tag_spanish));
+

pub fn is_language_range(&self) -> bool

Checks if it is a language range, meaning that there are no extension and privateuse tags.

+

Trait Implementations§

§

impl Clone for LanguageTag

§

fn clone(&self) -> LanguageTag

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for LanguageTag

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for LanguageTag

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl FromStr for LanguageTag

§

type Err = ParseError

The associated error which can be returned from parsing.
§

fn from_str(input: &str) -> Result<LanguageTag, ParseError>

Parses a string s to return a value of this type. Read more
§

impl Hash for LanguageTag

§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl PartialEq for LanguageTag

§

fn eq(&self, other: &LanguageTag) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Eq for LanguageTag

§

impl StructuralPartialEq for LanguageTag

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/struct.Quality.html b/actix_http/header/struct.Quality.html new file mode 100644 index 000000000..50cef29fe --- /dev/null +++ b/actix_http/header/struct.Quality.html @@ -0,0 +1,52 @@ +Quality in actix_http::header - Rust

Struct actix_http::header::Quality

source ·
pub struct Quality(/* private fields */);
Expand description

Represents a quality used in q-factor values.

+

The default value is equivalent to q=1.0 (the max value).

+

§Implementation notes

+

The quality value is defined as a number between 0.0 and 1.0 with three decimal places. +This means there are 1001 possible values. Since floating point numbers are not exact and the +smallest floating point data type (f32) consumes four bytes, we use an u16 value to store +the quality internally.

+

RFC 7231 §5.3.1 gives more information on quality values in HTTP header fields.

+

§Examples

+
use actix_http::header::{Quality, q};
+assert_eq!(q(1.0), Quality::MAX);
+
+assert_eq!(q(0.42).to_string(), "0.42");
+assert_eq!(q(1.0).to_string(), "1");
+assert_eq!(Quality::MIN.to_string(), "0.001");
+assert_eq!(Quality::ZERO.to_string(), "0");
+

Implementations§

source§

impl Quality

source

pub const MAX: Quality = _

The maximum quality value, equivalent to q=1.0.

+
source

pub const MIN: Quality = _

The minimum, non-zero quality value, equivalent to q=0.001.

+
source

pub const ZERO: Quality = _

The zero quality value, equivalent to q=0.0.

+

Trait Implementations§

source§

impl Clone for Quality

source§

fn clone(&self) -> Quality

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Quality

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Quality

The default value is Quality::MAX.

+
source§

fn default() -> Quality

Returns the “default value” for a type. Read more
source§

impl Display for Quality

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Ord for Quality

source§

fn cmp(&self, other: &Quality) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq for Quality

source§

fn eq(&self, other: &Quality) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for Quality

source§

fn partial_cmp(&self, other: &Quality) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl TryFrom<f32> for Quality

§

type Error = QualityOutOfBounds

The type returned in the event of a conversion error.
source§

fn try_from(value: f32) -> Result<Self, Self::Error>

Performs the conversion.
source§

impl Copy for Quality

source§

impl Eq for Quality

source§

impl StructuralPartialEq for Quality

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/struct.QualityItem.html b/actix_http/header/struct.QualityItem.html new file mode 100644 index 000000000..bb6fbae4f --- /dev/null +++ b/actix_http/header/struct.QualityItem.html @@ -0,0 +1,64 @@ +QualityItem in actix_http::header - Rust

Struct actix_http::header::QualityItem

source ·
pub struct QualityItem<T> {
+    pub item: T,
+    pub quality: Quality,
+}
Expand description

Represents an item with a quality value as defined +in RFC 7231 §5.3.1.

+

§Parsing and Formatting

+

This wrapper be used to parse header value items that have a q-factor annotation as well as +serialize items with a their q-factor.

+

§Ordering

+

Since this context of use for this type is header value items, ordering is defined for +QualityItems but only considers the item’s quality. Order of appearance should be used as +the secondary sorting parameter; i.e., a stable sort over the quality values will produce a +correctly sorted sequence.

+

§Examples

+
let q_item: QualityItem<String> = "hello;q=0.3".parse().unwrap();
+assert_eq!(&q_item.item, "hello");
+assert_eq!(q_item.quality, q(0.3));
+
+// note that format is normalized compared to parsed item
+assert_eq!(q_item.to_string(), "hello; q=0.3");
+
+// item with q=0.3 is greater than item with q=0.1
+let q_item_fallback: QualityItem<String> = "abc;q=0.1".parse().unwrap();
+assert!(q_item > q_item_fallback);
+

Fields§

§item: T

The wrapped contents of the field.

+
§quality: Quality

The quality (client or server preference) for the value.

+

Implementations§

source§

impl<T> QualityItem<T>

source

pub fn new(item: T, quality: Quality) -> Self

Constructs a new QualityItem from an item and a quality value.

+

The item can be of any type. The quality should be a value in the range [0, 1].

+
source

pub fn max(item: T) -> Self

Constructs a new QualityItem from an item, using the maximum q-value.

+
source

pub fn min(item: T) -> Self

Constructs a new QualityItem from an item, using the minimum, non-zero q-value.

+
source

pub fn zero(item: T) -> Self

Constructs a new QualityItem from an item, using zero q-value of zero.

+

Trait Implementations§

source§

impl<T: Clone> Clone for QualityItem<T>

source§

fn clone(&self) -> QualityItem<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for QualityItem<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: Display> Display for QualityItem<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: FromStr> FromStr for QualityItem<T>

§

type Err = ParseError

The associated error which can be returned from parsing.
source§

fn from_str(q_item_str: &str) -> Result<Self, Self::Err>

Parses a string s to return a value of this type. Read more
source§

impl<T: PartialEq> PartialEq for QualityItem<T>

source§

fn eq(&self, other: &QualityItem<T>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<T: PartialEq> PartialOrd for QualityItem<T>

source§

fn partial_cmp(&self, other: &QualityItem<T>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<T: Copy> Copy for QualityItem<T>

source§

impl<T: Eq> Eq for QualityItem<T>

source§

impl<T> StructuralPartialEq for QualityItem<T>

Auto Trait Implementations§

§

impl<T> Freeze for QualityItem<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for QualityItem<T>
where + T: RefUnwindSafe,

§

impl<T> Send for QualityItem<T>
where + T: Send,

§

impl<T> Sync for QualityItem<T>
where + T: Sync,

§

impl<T> Unpin for QualityItem<T>
where + T: Unpin,

§

impl<T> UnwindSafe for QualityItem<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/struct.ToStrError.html b/actix_http/header/struct.ToStrError.html new file mode 100644 index 000000000..b6885cc54 --- /dev/null +++ b/actix_http/header/struct.ToStrError.html @@ -0,0 +1,21 @@ +ToStrError in actix_http::header - Rust

Struct actix_http::header::ToStrError

source ·
pub struct ToStrError { /* private fields */ }
Expand description

A possible error when converting a HeaderValue to a string representation.

+

Header field values may contain opaque bytes, in which case it is not +possible to represent the value as a string.

+

Trait Implementations§

source§

impl Debug for ToStrError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for ToStrError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for ToStrError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/header/trait.AsHeaderName.html b/actix_http/header/trait.AsHeaderName.html new file mode 100644 index 000000000..a813671cd --- /dev/null +++ b/actix_http/header/trait.AsHeaderName.html @@ -0,0 +1,2 @@ +AsHeaderName in actix_http::header - Rust

Trait actix_http::header::AsHeaderName

source ·
pub trait AsHeaderName: Sealed { }
Expand description

Sealed trait implemented for types that can be effectively borrowed as a HeaderValue.

+

Implementations on Foreign Types§

source§

impl AsHeaderName for &str

source§

impl AsHeaderName for &String

source§

impl AsHeaderName for String

Implementors§

\ No newline at end of file diff --git a/actix_http/header/trait.Header.html b/actix_http/header/trait.Header.html new file mode 100644 index 000000000..eb267898b --- /dev/null +++ b/actix_http/header/trait.Header.html @@ -0,0 +1,8 @@ +Header in actix_http::header - Rust

Trait actix_http::header::Header

source ·
pub trait Header: TryIntoHeaderValue {
+    // Required methods
+    fn name() -> HeaderName;
+    fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>;
+}
Expand description

An interface for types that already represent a valid header.

+

Required Methods§

source

fn name() -> HeaderName

Returns the name of the header field.

+
source

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.

+

Object Safety§

This trait is not object safe.

Implementors§

\ No newline at end of file diff --git a/actix_http/header/trait.TryIntoHeaderPair.html b/actix_http/header/trait.TryIntoHeaderPair.html new file mode 100644 index 000000000..16e66cc07 --- /dev/null +++ b/actix_http/header/trait.TryIntoHeaderPair.html @@ -0,0 +1,18 @@ +TryIntoHeaderPair in actix_http::header - Rust

Trait actix_http::header::TryIntoHeaderPair

source ·
pub trait TryIntoHeaderPair: Sized {
+    type Error: Into<HttpError>;
+
+    // Required method
+    fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error>;
+}
Expand description

An interface for types that can be converted into a HeaderName + HeaderValue pair for +insertion into a HeaderMap.

+

Required Associated Types§

Required Methods§

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<V> TryIntoHeaderPair for (&str, V)

§

type Error = InvalidHeaderPart

source§

fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error>

source§

impl<V> TryIntoHeaderPair for (&HeaderName, V)

§

type Error = InvalidHeaderPart

source§

fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error>

source§

impl<V> TryIntoHeaderPair for (&[u8], V)

§

type Error = InvalidHeaderPart

source§

fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error>

source§

impl<V> TryIntoHeaderPair for (String, V)

§

type Error = InvalidHeaderPart

source§

fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error>

source§

impl<V> TryIntoHeaderPair for (HeaderName, V)

§

type Error = InvalidHeaderPart

source§

fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error>

Implementors§

\ No newline at end of file diff --git a/actix_http/header/trait.TryIntoHeaderValue.html b/actix_http/header/trait.TryIntoHeaderValue.html new file mode 100644 index 000000000..49ea02210 --- /dev/null +++ b/actix_http/header/trait.TryIntoHeaderValue.html @@ -0,0 +1,9 @@ +TryIntoHeaderValue in actix_http::header - Rust

Trait actix_http::header::TryIntoHeaderValue

source ·
pub trait TryIntoHeaderValue: Sized {
+    type Error: Into<HttpError>;
+
+    // Required method
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error>;
+}
Expand description

An interface for types that can be converted into a HeaderValue.

+

Required Associated Types§

source

type Error: Into<HttpError>

The type returned in the event of a conversion error.

+

Required Methods§

source

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.

+

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl TryIntoHeaderValue for &str

source§

impl TryIntoHeaderValue for &[u8]

source§

impl TryIntoHeaderValue for i32

source§

impl TryIntoHeaderValue for i64

source§

impl TryIntoHeaderValue for u32

source§

impl TryIntoHeaderValue for u64

source§

impl TryIntoHeaderValue for usize

source§

impl TryIntoHeaderValue for String

source§

impl TryIntoHeaderValue for Vec<u8>

source§

impl TryIntoHeaderValue for Mime

source§

impl TryIntoHeaderValue for Bytes

Implementors§

\ No newline at end of file diff --git a/actix_http/header/utils/fn.fmt_comma_delimited.html b/actix_http/header/utils/fn.fmt_comma_delimited.html new file mode 100644 index 000000000..de62b8b17 --- /dev/null +++ b/actix_http/header/utils/fn.fmt_comma_delimited.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/header/fn.fmt_comma_delimited.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/utils/fn.from_comma_delimited.html b/actix_http/header/utils/fn.from_comma_delimited.html new file mode 100644 index 000000000..1d460a04e --- /dev/null +++ b/actix_http/header/utils/fn.from_comma_delimited.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/header/fn.from_comma_delimited.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/utils/fn.from_one_raw_str.html b/actix_http/header/utils/fn.from_one_raw_str.html new file mode 100644 index 000000000..cd59d635c --- /dev/null +++ b/actix_http/header/utils/fn.from_one_raw_str.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/header/fn.from_one_raw_str.html...

+ + + \ No newline at end of file diff --git a/actix_http/header/utils/fn.http_percent_encode.html b/actix_http/header/utils/fn.http_percent_encode.html new file mode 100644 index 000000000..06ab773c0 --- /dev/null +++ b/actix_http/header/utils/fn.http_percent_encode.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/header/fn.http_percent_encode.html...

+ + + \ No newline at end of file diff --git a/actix_http/http_message/trait.HttpMessage.html b/actix_http/http_message/trait.HttpMessage.html new file mode 100644 index 000000000..827e26d32 --- /dev/null +++ b/actix_http/http_message/trait.HttpMessage.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_http/trait.HttpMessage.html...

+ + + \ No newline at end of file diff --git a/actix_http/index.html b/actix_http/index.html new file mode 100644 index 000000000..431eafab3 --- /dev/null +++ b/actix_http/index.html @@ -0,0 +1,14 @@ +actix_http - Rust

Crate actix_http

source ·
Expand description

HTTP types and services for the Actix ecosystem.

+

§Crate Features

+ + + + + + + + + + +
FeatureFunctionality
http2HTTP/2 support via h2.
opensslTLS support via OpenSSL.
rustlsTLS support via rustls 0.20.
rustls-0_21TLS support via rustls 0.21.
rustls-0_22TLS support via rustls 0.22.
rustls-0_23TLS support via rustls 0.23.
compress-brotliPayload compression support: Brotli.
compress-gzipPayload compression support: Deflate, Gzip.
compress-zstdPayload compression support: Zstd.
trust-dnsUse trust-dns as the client DNS resolver.
+

Re-exports§

  • pub use self::payload::PayloadStream;
    Deprecated
  • pub use self::error::Error;
  • pub use self::header::ContentEncoding;

Modules§

  • Traits and structures to aid consuming and writing HTTP payloads.
  • encoding__compress
    Content-Encoding support.
  • Error and Result module
  • HTTP/1 protocol implementation.
  • h2http2
    HTTP/2 protocol.
  • Pre-defined HeaderNames, traits for parsing and conversion, and other header utility methods.
  • Various testing helpers for use in internal and app tests.
  • URI component of request and response lines
  • wsws
    WebSocket protocol implementation.

Structs§

Enums§

Traits§

  • Trait that implements general purpose operations on HTTP messages.

Type Aliases§

\ No newline at end of file diff --git a/actix_http/keep_alive/enum.KeepAlive.html b/actix_http/keep_alive/enum.KeepAlive.html new file mode 100644 index 000000000..e57e6517a --- /dev/null +++ b/actix_http/keep_alive/enum.KeepAlive.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_http/enum.KeepAlive.html...

+ + + \ No newline at end of file diff --git a/actix_http/message/enum.ConnectionType.html b/actix_http/message/enum.ConnectionType.html new file mode 100644 index 000000000..0db9eea94 --- /dev/null +++ b/actix_http/message/enum.ConnectionType.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_http/enum.ConnectionType.html...

+ + + \ No newline at end of file diff --git a/actix_http/message/struct.Message.html b/actix_http/message/struct.Message.html new file mode 100644 index 000000000..cea0a296f --- /dev/null +++ b/actix_http/message/struct.Message.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_http/struct.Message.html...

+ + + \ No newline at end of file diff --git a/actix_http/payload/enum.Payload.html b/actix_http/payload/enum.Payload.html new file mode 100644 index 000000000..961ee12d2 --- /dev/null +++ b/actix_http/payload/enum.Payload.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_http/enum.Payload.html...

+ + + \ No newline at end of file diff --git a/actix_http/payload/type.BoxedPayloadStream.html b/actix_http/payload/type.BoxedPayloadStream.html new file mode 100644 index 000000000..dc7219430 --- /dev/null +++ b/actix_http/payload/type.BoxedPayloadStream.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_http/type.BoxedPayloadStream.html...

+ + + \ No newline at end of file diff --git a/actix_http/requests/head/enum.RequestHeadType.html b/actix_http/requests/head/enum.RequestHeadType.html new file mode 100644 index 000000000..47cb7f3f7 --- /dev/null +++ b/actix_http/requests/head/enum.RequestHeadType.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/enum.RequestHeadType.html...

+ + + \ No newline at end of file diff --git a/actix_http/requests/head/struct.RequestHead.html b/actix_http/requests/head/struct.RequestHead.html new file mode 100644 index 000000000..3cfdc8830 --- /dev/null +++ b/actix_http/requests/head/struct.RequestHead.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/struct.RequestHead.html...

+ + + \ No newline at end of file diff --git a/actix_http/requests/request/struct.Request.html b/actix_http/requests/request/struct.Request.html new file mode 100644 index 000000000..4677b14ce --- /dev/null +++ b/actix_http/requests/request/struct.Request.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/struct.Request.html...

+ + + \ No newline at end of file diff --git a/actix_http/responses/builder/struct.ResponseBuilder.html b/actix_http/responses/builder/struct.ResponseBuilder.html new file mode 100644 index 000000000..a558b18a0 --- /dev/null +++ b/actix_http/responses/builder/struct.ResponseBuilder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/struct.ResponseBuilder.html...

+ + + \ No newline at end of file diff --git a/actix_http/responses/head/struct.ResponseHead.html b/actix_http/responses/head/struct.ResponseHead.html new file mode 100644 index 000000000..60ae31046 --- /dev/null +++ b/actix_http/responses/head/struct.ResponseHead.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/struct.ResponseHead.html...

+ + + \ No newline at end of file diff --git a/actix_http/responses/response/struct.Response.html b/actix_http/responses/response/struct.Response.html new file mode 100644 index 000000000..3593790f4 --- /dev/null +++ b/actix_http/responses/response/struct.Response.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/struct.Response.html...

+ + + \ No newline at end of file diff --git a/actix_http/service/struct.HttpService.html b/actix_http/service/struct.HttpService.html new file mode 100644 index 000000000..ee1bc3198 --- /dev/null +++ b/actix_http/service/struct.HttpService.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_http/struct.HttpService.html...

+ + + \ No newline at end of file diff --git a/actix_http/service/struct.TlsAcceptorConfig.html b/actix_http/service/struct.TlsAcceptorConfig.html new file mode 100644 index 000000000..392747c3f --- /dev/null +++ b/actix_http/service/struct.TlsAcceptorConfig.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_http/struct.TlsAcceptorConfig.html...

+ + + \ No newline at end of file diff --git a/actix_http/sidebar-items.js b/actix_http/sidebar-items.js new file mode 100644 index 000000000..db0b7ccae --- /dev/null +++ b/actix_http/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["ConnectionType","KeepAlive","Payload","Protocol","RequestHeadType"],"mod":["body","encoding","error","h1","h2","header","test","uri","ws"],"struct":["Extensions","HttpService","HttpServiceBuilder","Message","Method","Request","RequestHead","Response","ResponseBuilder","ResponseHead","ServiceConfig","StatusCode","TlsAcceptorConfig","Uri","Version"],"trait":["HttpMessage"],"type":["BoxedPayloadStream"]}; \ No newline at end of file diff --git a/actix_http/struct.Extensions.html b/actix_http/struct.Extensions.html new file mode 100644 index 000000000..4a4bed33e --- /dev/null +++ b/actix_http/struct.Extensions.html @@ -0,0 +1,65 @@ +Extensions in actix_http - Rust

Struct actix_http::Extensions

source ·
pub struct Extensions { /* private fields */ }
Expand description

A type map for request extensions.

+

All entries into this map must be owned types (or static references).

+

Implementations§

source§

impl Extensions

source

pub fn new() -> Extensions

Creates an empty Extensions.

+
source

pub fn insert<T: 'static>(&mut self, val: T) -> Option<T>

Insert an item into the map.

+

If an item of this type was already stored, it will be replaced and returned.

+ +
let mut map = Extensions::new();
+assert_eq!(map.insert(""), None);
+assert_eq!(map.insert(1u32), None);
+assert_eq!(map.insert(2u32), Some(1u32));
+assert_eq!(*map.get::<u32>().unwrap(), 2u32);
+
source

pub fn contains<T: 'static>(&self) -> bool

Check if map contains an item of a given type.

+ +
let mut map = Extensions::new();
+assert!(!map.contains::<u32>());
+
+assert_eq!(map.insert(1u32), None);
+assert!(map.contains::<u32>());
+
source

pub fn get<T: 'static>(&self) -> Option<&T>

Get a reference to an item of a given type.

+ +
let mut map = Extensions::new();
+map.insert(1u32);
+assert_eq!(map.get::<u32>(), Some(&1u32));
+
source

pub fn get_mut<T: 'static>(&mut self) -> Option<&mut T>

Get a mutable reference to an item of a given type.

+ +
let mut map = Extensions::new();
+map.insert(1u32);
+assert_eq!(map.get_mut::<u32>(), Some(&mut 1u32));
+
source

pub fn remove<T: 'static>(&mut self) -> Option<T>

Remove an item from the map of a given type.

+

If an item of this type was already stored, it will be returned.

+ +
let mut map = Extensions::new();
+
+map.insert(1u32);
+assert_eq!(map.get::<u32>(), Some(&1u32));
+
+assert_eq!(map.remove::<u32>(), Some(1u32));
+assert!(!map.contains::<u32>());
+
source

pub fn clear(&mut self)

Clear the Extensions of all inserted extensions.

+ +
let mut map = Extensions::new();
+
+map.insert(1u32);
+assert!(map.contains::<u32>());
+
+map.clear();
+assert!(!map.contains::<u32>());
+
source

pub fn extend(&mut self, other: Extensions)

Extends self with the items from another Extensions.

+

Trait Implementations§

source§

impl Debug for Extensions

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Extensions

source§

fn default() -> Extensions

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/struct.HttpService.html b/actix_http/struct.HttpService.html new file mode 100644 index 000000000..28f0c40a1 --- /dev/null +++ b/actix_http/struct.HttpService.html @@ -0,0 +1,255 @@ +HttpService in actix_http - Rust

Struct actix_http::HttpService

source ·
pub struct HttpService<T, S, B, X = ExpectHandler, U = UpgradeHandler> { /* private fields */ }
Expand description

A [ServiceFactory] for HTTP/1.1 and HTTP/2 connections.

+

Use build to begin constructing service. Also see HttpServiceBuilder.

+

§Automatic HTTP Version Selection

+

There are two ways to select the HTTP version of an incoming connection:

+
    +
  • One is to rely on the ALPN information that is provided when using TLS (HTTPS); both versions +are supported automatically when using either of the .rustls() or .openssl() finalizing +methods.
  • +
  • The other is to read the first few bytes of the TCP stream. This is the only viable approach +for supporting H2C, which allows the HTTP/2 protocol to work over plaintext connections. Use +the .tcp_auto_h2c() finalizing method to enable this behavior.
  • +
+

§Examples

+
use actix_http::{HttpService, Request, Response, StatusCode};
+
+// this service would constructed in an actix_server::Server
+
+HttpService::build()
+    // the builder finalizing method, other finalizers would not return an `HttpService`
+    .finish(|_req: Request| async move {
+        Ok::<_, Infallible>(
+            Response::build(StatusCode::OK).body("Hello!")
+        )
+    })
+    // the service finalizing method method
+    // you can use `.tcp_auto_h2c()`, `.rustls()`, or `.openssl()` instead of `.tcp()`
+    .tcp();
+

Implementations§

source§

impl<S, B, X, U> HttpService<TlsStream<TcpStream>, S, B, X, U>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>> + 'static, + S::InitError: Debug, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static, + X: ServiceFactory<Request, Config = (), Response = Request>, + X::Future: 'static, + X::Error: Into<Response<BoxBody>>, + X::InitError: Debug, + U: ServiceFactory<(Request, Framed<TlsStream<TcpStream>, Codec>), Config = (), Response = ()>, + U::Future: 'static, + U::Error: Display + Into<Response<BoxBody>>, + U::InitError: Debug,

source

pub fn openssl( + self, + acceptor: SslAcceptor +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<SslError, DispatchError>, InitError = ()>

Available on crate feature openssl only.

Create OpenSSL based service.

+
source

pub fn openssl_with_config( + self, + acceptor: SslAcceptor, + tls_acceptor_config: TlsAcceptorConfig +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<SslError, DispatchError>, InitError = ()>

Available on crate feature openssl only.

Create OpenSSL based service with custom TLS acceptor configuration.

+
source§

impl<S, B, X, U> HttpService<TlsStream<TcpStream>, S, B, X, U>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>> + 'static, + S::InitError: Debug, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static, + X: ServiceFactory<Request, Config = (), Response = Request>, + X::Future: 'static, + X::Error: Into<Response<BoxBody>>, + X::InitError: Debug, + U: ServiceFactory<(Request, Framed<TlsStream<TcpStream>, Codec>), Config = (), Response = ()>, + U::Future: 'static, + U::Error: Display + Into<Response<BoxBody>>, + U::InitError: Debug,

source

pub fn rustls( + self, + config: ServerConfig +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<Error, DispatchError>, InitError = ()>

Available on crate feature rustls-0_20 only.

Create Rustls v0.20 based service.

+
source

pub fn rustls_with_config( + self, + config: ServerConfig, + tls_acceptor_config: TlsAcceptorConfig +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<Error, DispatchError>, InitError = ()>

Available on crate feature rustls-0_20 only.

Create Rustls v0.20 based service with custom TLS acceptor configuration.

+
source§

impl<S, B, X, U> HttpService<TlsStream<TcpStream>, S, B, X, U>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>> + 'static, + S::InitError: Debug, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static, + X: ServiceFactory<Request, Config = (), Response = Request>, + X::Future: 'static, + X::Error: Into<Response<BoxBody>>, + X::InitError: Debug, + U: ServiceFactory<(Request, Framed<TlsStream<TcpStream>, Codec>), Config = (), Response = ()>, + U::Future: 'static, + U::Error: Display + Into<Response<BoxBody>>, + U::InitError: Debug,

source

pub fn rustls_021( + self, + config: ServerConfig +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<Error, DispatchError>, InitError = ()>

Available on crate feature rustls-0_21 only.

Create Rustls v0.21 based service.

+
source

pub fn rustls_021_with_config( + self, + config: ServerConfig, + tls_acceptor_config: TlsAcceptorConfig +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<Error, DispatchError>, InitError = ()>

Available on crate feature rustls-0_21 only.

Create Rustls v0.21 based service with custom TLS acceptor configuration.

+
source§

impl<S, B, X, U> HttpService<TlsStream<TcpStream>, S, B, X, U>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>> + 'static, + S::InitError: Debug, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static, + X: ServiceFactory<Request, Config = (), Response = Request>, + X::Future: 'static, + X::Error: Into<Response<BoxBody>>, + X::InitError: Debug, + U: ServiceFactory<(Request, Framed<TlsStream<TcpStream>, Codec>), Config = (), Response = ()>, + U::Future: 'static, + U::Error: Display + Into<Response<BoxBody>>, + U::InitError: Debug,

source

pub fn rustls_0_22( + self, + config: ServerConfig +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<Error, DispatchError>, InitError = ()>

Available on crate feature rustls-0_22 only.

Create Rustls v0.22 based service.

+
source

pub fn rustls_0_22_with_config( + self, + config: ServerConfig, + tls_acceptor_config: TlsAcceptorConfig +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<Error, DispatchError>, InitError = ()>

Available on crate feature rustls-0_22 only.

Create Rustls v0.22 based service with custom TLS acceptor configuration.

+
source§

impl<S, B, X, U> HttpService<TlsStream<TcpStream>, S, B, X, U>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>> + 'static, + S::InitError: Debug, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static, + X: ServiceFactory<Request, Config = (), Response = Request>, + X::Future: 'static, + X::Error: Into<Response<BoxBody>>, + X::InitError: Debug, + U: ServiceFactory<(Request, Framed<TlsStream<TcpStream>, Codec>), Config = (), Response = ()>, + U::Future: 'static, + U::Error: Display + Into<Response<BoxBody>>, + U::InitError: Debug,

source

pub fn rustls_0_23( + self, + config: ServerConfig +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<Error, DispatchError>, InitError = ()>

Available on crate feature rustls-0_23 only.

Create Rustls v0.23 based service.

+
source

pub fn rustls_0_23_with_config( + self, + config: ServerConfig, + tls_acceptor_config: TlsAcceptorConfig +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = TlsError<Error, DispatchError>, InitError = ()>

Available on crate feature rustls-0_23 only.

Create Rustls v0.23 based service with custom TLS acceptor configuration.

+
source§

impl<T, S, B> HttpService<T, S, B>
where + S: ServiceFactory<Request, Config = ()>, + S::Error: Into<Response<BoxBody>> + 'static, + S::InitError: Debug, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static,

source

pub fn build() -> HttpServiceBuilder<T, S>

Constructs builder for HttpService instance.

+
source§

impl<T, S, B> HttpService<T, S, B>
where + S: ServiceFactory<Request, Config = ()>, + S::Error: Into<Response<BoxBody>> + 'static, + S::InitError: Debug, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static,

source

pub fn new<F: IntoServiceFactory<S, Request>>(service: F) -> Self

Constructs new HttpService instance from service with default config.

+
source§

impl<T, S, B, X, U> HttpService<T, S, B, X, U>
where + S: ServiceFactory<Request, Config = ()>, + S::Error: Into<Response<BoxBody>> + 'static, + S::InitError: Debug, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody,

source

pub fn expect<X1>(self, expect: X1) -> HttpService<T, S, B, X1, U>
where + X1: ServiceFactory<Request, Config = (), Response = Request>, + X1::Error: Into<Response<BoxBody>>, + X1::InitError: Debug,

Sets service for Expect: 100-Continue handling.

+

An expect service is called with requests that contain an Expect header. A successful +response type is also a request which will be forwarded to the main service.

+
source

pub fn upgrade<U1>(self, upgrade: Option<U1>) -> HttpService<T, S, B, X, U1>
where + U1: ServiceFactory<(Request, Framed<T, Codec>), Config = (), Response = ()>, + U1::Error: Display, + U1::InitError: Debug,

Sets service for custom Connection: Upgrade handling.

+

If service is provided then normal requests handling get halted and this service get called +with original request and framed object.

+
source§

impl<S, B, X, U> HttpService<TcpStream, S, B, X, U>
where + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>> + 'static, + S::InitError: Debug, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static, + X: ServiceFactory<Request, Config = (), Response = Request>, + X::Future: 'static, + X::Error: Into<Response<BoxBody>>, + X::InitError: Debug, + U: ServiceFactory<(Request, Framed<TcpStream, Codec>), Config = (), Response = ()>, + U::Future: 'static, + U::Error: Display + Into<Response<BoxBody>>, + U::InitError: Debug,

source

pub fn tcp( + self +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = DispatchError, InitError = ()>

Creates TCP stream service from HTTP service.

+

The resulting service only supports HTTP/1.x.

+
source

pub fn tcp_auto_h2c( + self +) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = DispatchError, InitError = ()>

Available on crate feature http2 only.

Creates TCP stream service from HTTP service that automatically selects HTTP/1.x or HTTP/2 +on plaintext connections.

+

Trait Implementations§

source§

impl<T, S, B, X, U> ServiceFactory<(T, Protocol, Option<SocketAddr>)> for HttpService<T, S, B, X, U>
where + T: AsyncRead + AsyncWrite + Unpin + 'static, + S: ServiceFactory<Request, Config = ()>, + S::Future: 'static, + S::Error: Into<Response<BoxBody>> + 'static, + S::InitError: Debug, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static, + X: ServiceFactory<Request, Config = (), Response = Request>, + X::Future: 'static, + X::Error: Into<Response<BoxBody>>, + X::InitError: Debug, + U: ServiceFactory<(Request, Framed<T, Codec>), Config = (), Response = ()>, + U::Future: 'static, + U::Error: Display + Into<Response<BoxBody>>, + U::InitError: Debug,

§

type Response = ()

Responses given by the created services.
§

type Error = DispatchError

Errors produced by the created services.
§

type Config = ()

Service factory configuration.
§

type Service = HttpServiceHandler<T, <S as ServiceFactory<Request>>::Service, B, <X as ServiceFactory<Request>>::Service, <U as ServiceFactory<(Request, Framed<T, Codec>)>>::Service>

The kind of Service created by this factory.
§

type InitError = ()

Errors potentially raised while building a service.
§

type Future = Pin<Box<dyn Future<Output = Result<<HttpService<T, S, B, X, U> as ServiceFactory<(T, Protocol, Option<SocketAddr>)>>::Service, <HttpService<T, S, B, X, U> as ServiceFactory<(T, Protocol, Option<SocketAddr>)>>::InitError>>>>

The future of the Service instance.g
source§

fn new_service(&self, _: ()) -> Self::Future

Create and return a new service asynchronously.

Auto Trait Implementations§

§

impl<T, S, B, X, U> Freeze for HttpService<T, S, B, X, U>
where + S: Freeze, + X: Freeze, + U: Freeze,

§

impl<T, S, B, X = ExpectHandler, U = UpgradeHandler> !RefUnwindSafe for HttpService<T, S, B, X, U>

§

impl<T, S, B, X = ExpectHandler, U = UpgradeHandler> !Send for HttpService<T, S, B, X, U>

§

impl<T, S, B, X = ExpectHandler, U = UpgradeHandler> !Sync for HttpService<T, S, B, X, U>

§

impl<T, S, B, X, U> Unpin for HttpService<T, S, B, X, U>
where + S: Unpin, + X: Unpin, + U: Unpin, + B: Unpin,

§

impl<T, S, B, X = ExpectHandler, U = UpgradeHandler> !UnwindSafe for HttpService<T, S, B, X, U>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
§

impl<SF, Req> IntoServiceFactory<SF, Req> for SF
where + SF: ServiceFactory<Req>,

§

fn into_factory(self) -> SF

Convert Self to a ServiceFactory
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<SF, Req> ServiceFactoryExt<Req> for SF
where + SF: ServiceFactory<Req>,

§

fn map<F, R>(self, f: F) -> MapServiceFactory<Self, F, Req, R>
where + Self: Sized, + F: FnMut(Self::Response) -> R + Clone,

Map this service’s output to a different type, returning a new service +of the resulting type.
§

fn map_err<F, E>(self, f: F) -> MapErrServiceFactory<Self, Req, F, E>
where + Self: Sized, + F: Fn(Self::Error) -> E + Clone,

Map this service’s error to a different error, returning a new service.
§

fn map_init_err<F, E>(self, f: F) -> MapInitErr<Self, F, Req, E>
where + Self: Sized, + F: Fn(Self::InitError) -> E + Clone,

Map this factory’s init error to a different error, returning a new service.
§

fn and_then<I, SF1>(self, factory: I) -> AndThenServiceFactory<Self, SF1, Req>
where + Self: Sized, + Self::Config: Clone, + I: IntoServiceFactory<SF1, Self::Response>, + SF1: ServiceFactory<Self::Response, Config = Self::Config, Error = Self::Error, InitError = Self::InitError>,

Call another service after call to this one has resolved successfully.
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/struct.HttpServiceBuilder.html b/actix_http/struct.HttpServiceBuilder.html new file mode 100644 index 000000000..b23d534a9 --- /dev/null +++ b/actix_http/struct.HttpServiceBuilder.html @@ -0,0 +1,92 @@ +HttpServiceBuilder in actix_http - Rust

Struct actix_http::HttpServiceBuilder

source ·
pub struct HttpServiceBuilder<T, S, X = ExpectHandler, U = UpgradeHandler> { /* private fields */ }
Expand description

An HTTP service builder.

+

This type can construct an instance of HttpService through a builder-like pattern.

+

Implementations§

source§

impl<T, S, X, U> HttpServiceBuilder<T, S, X, U>
where + S: ServiceFactory<Request, Config = ()>, + S::Error: Into<Response<BoxBody>> + 'static, + S::InitError: Debug, + <S::Service as Service<Request>>::Future: 'static, + X: ServiceFactory<Request, Config = (), Response = Request>, + X::Error: Into<Response<BoxBody>>, + X::InitError: Debug, + U: ServiceFactory<(Request, Framed<T, Codec>), Config = (), Response = ()>, + U::Error: Display, + U::InitError: Debug,

source

pub fn keep_alive<W: Into<KeepAlive>>(self, val: W) -> Self

Set connection keep-alive setting.

+

Applies to HTTP/1.1 keep-alive and HTTP/2 ping-pong.

+

By default keep-alive is 5 seconds.

+
source

pub fn secure(self) -> Self

Set connection secure state

+
source

pub fn local_addr(self, addr: SocketAddr) -> Self

Set the local address that this service is bound to.

+
source

pub fn client_request_timeout(self, dur: Duration) -> Self

Set client request timeout (for first request).

+

Defines a timeout for reading client request header. If the client does not transmit the +request head within this duration, the connection is terminated with a 408 Request Timeout +response error.

+

A duration of zero disables the timeout.

+

By default, the client timeout is 5 seconds.

+
source

pub fn client_disconnect_timeout(self, dur: Duration) -> Self

Set client connection disconnect timeout.

+

Defines a timeout for disconnect connection. If a disconnect procedure does not complete +within this time, the request get dropped. This timeout affects secure connections.

+

A duration of zero disables the timeout.

+

By default, the disconnect timeout is disabled.

+
source

pub fn expect<F, X1>(self, expect: F) -> HttpServiceBuilder<T, S, X1, U>
where + F: IntoServiceFactory<X1, Request>, + X1: ServiceFactory<Request, Config = (), Response = Request>, + X1::Error: Into<Response<BoxBody>>, + X1::InitError: Debug,

Provide service for EXPECT: 100-Continue support.

+

Service get called with request that contains EXPECT header. +Service must return request in case of success, in that case +request will be forwarded to main service.

+
source

pub fn upgrade<F, U1>(self, upgrade: F) -> HttpServiceBuilder<T, S, X, U1>
where + F: IntoServiceFactory<U1, (Request, Framed<T, Codec>)>, + U1: ServiceFactory<(Request, Framed<T, Codec>), Config = (), Response = ()>, + U1::Error: Display, + U1::InitError: Debug,

Provide service for custom Connection: UPGRADE support.

+

If service is provided then normal requests handling get halted +and this service get called with original request and framed object.

+
source

pub fn on_connect_ext<F>(self, f: F) -> Self
where + F: Fn(&T, &mut Extensions) + 'static,

Sets the callback to be run on connection establishment.

+

Has mutable access to a data container that will be merged into request extensions. +This enables transport layer data (like client certificates) to be accessed in middleware +and handlers.

+
source

pub fn h1<F, B>(self, service: F) -> H1Service<T, S, B, X, U>
where + B: MessageBody, + F: IntoServiceFactory<S, Request>, + S::Error: Into<Response<BoxBody>>, + S::InitError: Debug, + S::Response: Into<Response<B>>,

Finish service configuration and create a service for the HTTP/1 protocol.

+
source

pub fn h2<F, B>(self, service: F) -> H2Service<T, S, B>
where + F: IntoServiceFactory<S, Request>, + S::Error: Into<Response<BoxBody>> + 'static, + S::InitError: Debug, + S::Response: Into<Response<B>> + 'static, + B: MessageBody + 'static,

Available on crate feature http2 only.

Finish service configuration and create a service for the HTTP/2 protocol.

+
source

pub fn finish<F, B>(self, service: F) -> HttpService<T, S, B, X, U>
where + F: IntoServiceFactory<S, Request>, + S::Error: Into<Response<BoxBody>> + 'static, + S::InitError: Debug, + S::Response: Into<Response<B>> + 'static, + B: MessageBody + 'static,

Finish service configuration and create HttpService instance.

+

Trait Implementations§

source§

impl<T, S> Default for HttpServiceBuilder<T, S, ExpectHandler, UpgradeHandler>
where + S: ServiceFactory<Request, Config = ()>, + S::Error: Into<Response<BoxBody>> + 'static, + S::InitError: Debug, + <S::Service as Service<Request>>::Future: 'static,

source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<T, S, X, U> Freeze for HttpServiceBuilder<T, S, X, U>
where + X: Freeze, + U: Freeze,

§

impl<T, S, X = ExpectHandler, U = UpgradeHandler> !RefUnwindSafe for HttpServiceBuilder<T, S, X, U>

§

impl<T, S, X = ExpectHandler, U = UpgradeHandler> !Send for HttpServiceBuilder<T, S, X, U>

§

impl<T, S, X = ExpectHandler, U = UpgradeHandler> !Sync for HttpServiceBuilder<T, S, X, U>

§

impl<T, S, X, U> Unpin for HttpServiceBuilder<T, S, X, U>
where + X: Unpin, + U: Unpin, + S: Unpin,

§

impl<T, S, X = ExpectHandler, U = UpgradeHandler> !UnwindSafe for HttpServiceBuilder<T, S, X, U>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/struct.Message.html b/actix_http/struct.Message.html new file mode 100644 index 000000000..ff75fc0d2 --- /dev/null +++ b/actix_http/struct.Message.html @@ -0,0 +1,20 @@ +Message in actix_http - Rust

Struct actix_http::Message

source ·
pub struct Message<T: Head> { /* private fields */ }

Implementations§

source§

impl<T: Head> Message<T>

source

pub fn new() -> Self

Get new message from the pool of objects

+

Trait Implementations§

source§

impl<T: Head> Deref for Message<T>

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl<T: Head> DerefMut for Message<T>

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl<T: Head> Drop for Message<T>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl From<Message<RequestHead>> for Request<BoxedPayloadStream>

source§

fn from(head: Message<RequestHead>) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl<T> Freeze for Message<T>

§

impl<T> RefUnwindSafe for Message<T>
where + T: RefUnwindSafe,

§

impl<T> !Send for Message<T>

§

impl<T> !Sync for Message<T>

§

impl<T> Unpin for Message<T>

§

impl<T> UnwindSafe for Message<T>
where + T: RefUnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/struct.Method.html b/actix_http/struct.Method.html new file mode 100644 index 000000000..d69aa55df --- /dev/null +++ b/actix_http/struct.Method.html @@ -0,0 +1,71 @@ +Method in actix_http - Rust

Struct actix_http::Method

source ·
pub struct Method(/* private fields */);
Expand description

The Request Method (VERB)

+

This type also contains constants for a number of common HTTP methods such +as GET, POST, etc.

+

Currently includes 8 variants representing the 8 methods defined in +RFC 7230, plus PATCH, +and an Extension variant for all extensions.

+

§Examples

+
use http::Method;
+
+assert_eq!(Method::GET, Method::from_bytes(b"GET").unwrap());
+assert!(Method::GET.is_idempotent());
+assert_eq!(Method::POST.as_str(), "POST");
+

Implementations§

source§

impl Method

source

pub const GET: Method = _

GET

+
source

pub const POST: Method = _

POST

+
source

pub const PUT: Method = _

PUT

+
source

pub const DELETE: Method = _

DELETE

+
source

pub const HEAD: Method = _

HEAD

+
source

pub const OPTIONS: Method = _

OPTIONS

+
source

pub const CONNECT: Method = _

CONNECT

+
source

pub const PATCH: Method = _

PATCH

+
source

pub const TRACE: Method = _

TRACE

+
source

pub fn from_bytes(src: &[u8]) -> Result<Method, InvalidMethod>

Converts a slice of bytes to an HTTP method.

+
source

pub fn is_safe(&self) -> bool

Whether a method is considered “safe”, meaning the request is +essentially read-only.

+

See the spec +for more words.

+
source

pub fn is_idempotent(&self) -> bool

Whether a method is considered “idempotent”, meaning the request has +the same result if executed multiple times.

+

See the spec for +more words.

+
source

pub fn as_str(&self) -> &str

Return a &str representation of the HTTP method

+

Trait Implementations§

source§

impl AsRef<str> for Method

source§

fn as_ref(&self) -> &str

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for Method

source§

fn clone(&self) -> Method

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Method

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Method

source§

fn default() -> Method

Returns the “default value” for a type. Read more
source§

impl Display for Method

source§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a Method> for Method

source§

fn from(t: &'a Method) -> Method

Converts to this type from the input type.
source§

impl FromStr for Method

§

type Err = InvalidMethod

The associated error which can be returned from parsing.
source§

fn from_str(t: &str) -> Result<Method, <Method as FromStr>::Err>

Parses a string s to return a value of this type. Read more
source§

impl Hash for Method

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<'a> PartialEq<&'a Method> for Method

source§

fn eq(&self, other: &&'a Method) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<&'a str> for Method

source§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<Method> for &'a Method

source§

fn eq(&self, other: &Method) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<Method> for &'a str

source§

fn eq(&self, other: &Method) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Method> for str

source§

fn eq(&self, other: &Method) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for Method

source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Method

source§

fn eq(&self, other: &Method) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> TryFrom<&'a [u8]> for Method

§

type Error = InvalidMethod

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a [u8]) -> Result<Method, <Method as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for Method

§

type Error = InvalidMethod

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a str) -> Result<Method, <Method as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl Eq for Method

source§

impl StructuralPartialEq for Method

Auto Trait Implementations§

§

impl Freeze for Method

§

impl RefUnwindSafe for Method

§

impl Send for Method

§

impl Sync for Method

§

impl Unpin for Method

§

impl UnwindSafe for Method

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/struct.Request.html b/actix_http/struct.Request.html new file mode 100644 index 000000000..55740fb42 --- /dev/null +++ b/actix_http/struct.Request.html @@ -0,0 +1,47 @@ +Request in actix_http - Rust

Struct actix_http::Request

source ·
pub struct Request<P = BoxedPayloadStream> { /* private fields */ }
Expand description

An HTTP request.

+

Implementations§

source§

impl Request<BoxedPayloadStream>

source

pub fn new() -> Request<BoxedPayloadStream>

Create new Request instance

+
source§

impl<P> Request<P>

source

pub fn with_payload(payload: Payload<P>) -> Request<P>

Create new Request instance

+
source

pub fn replace_payload<P1>( + self, + payload: Payload<P1> +) -> (Request<P1>, Payload<P>)

Create new Request instance

+
source

pub fn payload(&mut self) -> &mut Payload<P>

Get request’s payload

+
source

pub fn take_payload(&mut self) -> Payload<P>

Get request’s payload

+
source

pub fn into_parts(self) -> (Message<RequestHead>, Payload<P>)

Split request into request head and payload

+
source

pub fn head(&self) -> &RequestHead

Http message part of the request

+
source

pub fn headers_mut(&mut self) -> &mut HeaderMap

Mutable reference to the message’s headers.

+
source

pub fn uri(&self) -> &Uri

Request’s uri.

+
source

pub fn uri_mut(&mut self) -> &mut Uri

Mutable reference to the request’s uri.

+
source

pub fn method(&self) -> &Method

Read the Request method.

+
source

pub fn version(&self) -> Version

Read the Request Version.

+
source

pub fn path(&self) -> &str

The target path of this Request.

+
source

pub fn upgrade(&self) -> bool

Check if request requires connection upgrade

+
source

pub fn peer_addr(&self) -> Option<SocketAddr>

Peer socket address.

+

Peer address is the directly connected peer’s socket address. If a proxy is used in front of +the Actix Web server, then it would be address of this proxy.

+

Will only return None when called in unit tests unless set manually.

+
source

pub fn conn_data<T: 'static>(&self) -> Option<&T>

Returns a reference a piece of connection data set in an on-connect callback.

+ +
let opt_t = req.conn_data::<PeerCertificate>();
+
source

pub fn take_conn_data(&mut self) -> Option<Rc<Extensions>>

Returns the connection-level data/extensions container if an on-connect callback was +registered, leaving an empty one in its place.

+
source

pub fn take_req_data(&mut self) -> Extensions

Returns the request-local data/extensions container, leaving an empty one in its place.

+

Trait Implementations§

source§

impl<P> Debug for Request<P>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl From<Message<RequestHead>> for Request<BoxedPayloadStream>

source§

fn from(head: Message<RequestHead>) -> Self

Converts to this type from the input type.
source§

impl<P> HttpMessage for Request<P>

§

type Stream = P

Type of message payload stream
source§

fn headers(&self) -> &HeaderMap

Read the message headers.
source§

fn take_payload(&mut self) -> Payload<P>

Message payload stream
source§

fn extensions(&self) -> Ref<'_, Extensions>

Returns a reference to the request-local data/extensions container.
source§

fn extensions_mut(&self) -> RefMut<'_, Extensions>

Returns a mutable reference to the request-local data/extensions container.
source§

fn content_type(&self) -> &str

Read the request content type. If request did not contain a Content-Type header, an empty +string is returned.
source§

fn encoding(&self) -> Result<&'static Encoding, ContentTypeError>

Get content type encoding. Read more
source§

fn mime_type(&self) -> Result<Option<Mime>, ContentTypeError>

Convert the request content type to a known mime type.
source§

fn chunked(&self) -> Result<bool, ParseError>

Check if request has chunked transfer encoding.
source§

impl Service<Request> for ExpectHandler

§

type Response = Request

Responses given by the service.
§

type Error = Error

Errors produced by the service when polling readiness or executing call.
§

type Future = Ready<Result<<ExpectHandler as Service<Request>>::Response, <ExpectHandler as Service<Request>>::Error>>

The future response value.
source§

fn poll_ready(&self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>>

Returns Ready when the service is able to process requests. Read more
source§

fn call(&self, req: Request) -> Self::Future

Process the request and return the response asynchronously. Read more
source§

impl ServiceFactory<Request> for ExpectHandler

§

type Response = Request

Responses given by the created services.
§

type Error = Error

Errors produced by the created services.
§

type Config = ()

Service factory configuration.
§

type Service = ExpectHandler

The kind of Service created by this factory.
§

type InitError = Error

Errors potentially raised while building a service.
§

type Future = Ready<Result<<ExpectHandler as ServiceFactory<Request>>::Service, <ExpectHandler as ServiceFactory<Request>>::InitError>>

The future of the Service instance.g
source§

fn new_service(&self, _: Self::Config) -> Self::Future

Create and return a new service asynchronously.

Auto Trait Implementations§

§

impl<P = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Freeze for Request<P>

§

impl<P = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !RefUnwindSafe for Request<P>

§

impl<P = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Send for Request<P>

§

impl<P = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Sync for Request<P>

§

impl<P> Unpin for Request<P>
where + P: Unpin,

§

impl<P = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !UnwindSafe for Request<P>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/struct.RequestHead.html b/actix_http/struct.RequestHead.html new file mode 100644 index 000000000..f4e71c70a --- /dev/null +++ b/actix_http/struct.RequestHead.html @@ -0,0 +1,36 @@ +RequestHead in actix_http - Rust

Struct actix_http::RequestHead

source ·
pub struct RequestHead {
+    pub method: Method,
+    pub uri: Uri,
+    pub version: Version,
+    pub headers: HeaderMap,
+    pub peer_addr: Option<SocketAddr>,
+    /* private fields */
+}

Fields§

§method: Method§uri: Uri§version: Version§headers: HeaderMap§peer_addr: Option<SocketAddr>

Will only be None when called in unit tests unless set manually.

+

Implementations§

source§

impl RequestHead

source

pub fn headers(&self) -> &HeaderMap

Read the message headers.

+
source

pub fn headers_mut(&mut self) -> &mut HeaderMap

Mutable reference to the message headers.

+
source

pub fn camel_case_headers(&self) -> bool

Is to uppercase headers with Camel-Case. +Default is false

+
source

pub fn set_camel_case_headers(&mut self, val: bool)

Set true to send headers which are formatted as Camel-Case.

+
source

pub fn set_connection_type(&mut self, ctype: ConnectionType)

Set connection type of the message

+
source

pub fn connection_type(&self) -> ConnectionType

Connection type

+
source

pub fn upgrade(&self) -> bool

Connection upgrade status

+
source

pub fn chunked(&self) -> bool

Get response body chunking state

+
source

pub fn no_chunking(&mut self, val: bool)

source

pub fn expect(&self) -> bool

Request contains EXPECT header.

+

Trait Implementations§

source§

impl AsRef<RequestHead> for RequestHeadType

source§

fn as_ref(&self) -> &RequestHead

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for RequestHead

source§

fn clone(&self) -> RequestHead

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for RequestHead

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for RequestHead

source§

fn default() -> RequestHead

Returns the “default value” for a type. Read more
source§

impl From<RequestHead> for RequestHeadType

source§

fn from(head: RequestHead) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/struct.Response.html b/actix_http/struct.Response.html new file mode 100644 index 000000000..a569ea816 --- /dev/null +++ b/actix_http/struct.Response.html @@ -0,0 +1,51 @@ +Response in actix_http - Rust

Struct actix_http::Response

source ·
pub struct Response<B> { /* private fields */ }
Expand description

An HTTP response.

+

Implementations§

source§

impl Response<BoxBody>

source

pub fn new(status: StatusCode) -> Self

Constructs a new response with default body.

+
source

pub fn build(status: StatusCode) -> ResponseBuilder

Constructs a new response builder.

+
source

pub fn ok() -> Self

Constructs a new response with status 200 OK.

+
source

pub fn bad_request() -> Self

Constructs a new response with status 400 Bad Request.

+
source

pub fn not_found() -> Self

Constructs a new response with status 404 Not Found.

+
source

pub fn internal_server_error() -> Self

Constructs a new response with status 500 Internal Server Error.

+
source§

impl<B> Response<B>

source

pub fn with_body(status: StatusCode, body: B) -> Response<B>

Constructs a new response with given body.

+
source

pub fn head(&self) -> &ResponseHead

Returns a reference to the head of this response.

+
source

pub fn head_mut(&mut self) -> &mut ResponseHead

Returns a mutable reference to the head of this response.

+
source

pub fn status(&self) -> StatusCode

Returns the status code of this response.

+
source

pub fn status_mut(&mut self) -> &mut StatusCode

Returns a mutable reference the status code of this response.

+
source

pub fn headers(&self) -> &HeaderMap

Returns a reference to response headers.

+
source

pub fn headers_mut(&mut self) -> &mut HeaderMap

Returns a mutable reference to response headers.

+
source

pub fn upgrade(&self) -> bool

Returns true if connection upgrade is enabled.

+
source

pub fn keep_alive(&self) -> bool

Returns true if keep-alive is enabled.

+
source

pub fn extensions(&self) -> Ref<'_, Extensions>

Returns a reference to the request-local data/extensions container.

+
source

pub fn extensions_mut(&mut self) -> RefMut<'_, Extensions>

Returns a mutable reference to the request-local data/extensions container.

+
source

pub fn body(&self) -> &B

Returns a reference to the body of this response.

+
source

pub fn set_body<B2>(self, body: B2) -> Response<B2>

Sets new body.

+
source

pub fn drop_body(self) -> Response<()>

Drops body and returns new response.

+
source

pub fn into_parts(self) -> (Response<()>, B)

Returns split head and body.

+
§Implementation Notes
+

Due to internal performance optimizations, the first element of the returned tuple is a +Response as well but only contains the head of the response this was called on.

+
source

pub fn map_body<F, B2>(self, f: F) -> Response<B2>
where + F: FnOnce(&mut ResponseHead, B) -> B2,

Map the current body type to another using a closure, returning a new response.

+

Closure receives the response head and the current body type.

+
source

pub fn map_into_boxed_body(self) -> Response<BoxBody>
where + B: MessageBody + 'static,

Map the current body to a type-erased BoxBody.

+
source

pub fn into_body(self) -> B

Returns the response body, dropping all other parts.

+

Trait Implementations§

source§

impl<B> Debug for Response<B>
where + B: MessageBody,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<B: Default> Default for Response<B>

source§

fn default() -> Response<B>

Returns the “default value” for a type. Read more
source§

impl From<&'static [u8]> for Response<&'static [u8]>

source§

fn from(val: &'static [u8]) -> Self

Converts to this type from the input type.
source§

impl From<&HandshakeError> for Response<BoxBody>

Available on crate feature ws only.
source§

fn from(err: &HandshakeError) -> Self

Converts to this type from the input type.
source§

impl From<&String> for Response<String>

source§

fn from(val: &String) -> Self

Converts to this type from the input type.
source§

impl From<&Vec<u8>> for Response<Vec<u8>>

source§

fn from(val: &Vec<u8>) -> Self

Converts to this type from the input type.
source§

impl From<&'static str> for Response<&'static str>

source§

fn from(val: &'static str) -> Self

Converts to this type from the input type.
source§

impl From<ByteString> for Response<ByteString>

source§

fn from(val: ByteString) -> Self

Converts to this type from the input type.
source§

impl From<Bytes> for Response<Bytes>

source§

fn from(val: Bytes) -> Self

Converts to this type from the input type.
source§

impl From<BytesMut> for Response<BytesMut>

source§

fn from(val: BytesMut) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Response<BoxBody>

source§

fn from(err: Error) -> Self

Converts to this type from the input type.
source§

impl From<HandshakeError> for Response<BoxBody>

Available on crate feature ws only.
source§

fn from(err: HandshakeError) -> Self

Converts to this type from the input type.
source§

impl From<Infallible> for Response<BoxBody>

source§

fn from(val: Infallible) -> Self

Converts to this type from the input type.
source§

impl From<ParseError> for Response<BoxBody>

source§

fn from(err: ParseError) -> Self

Converts to this type from the input type.
source§

impl<B> From<Response<B>> for ResponseBuilder

Convert Response to a ResponseBuilder. Body get dropped.

+
source§

fn from(res: Response<B>) -> ResponseBuilder

Converts to this type from the input type.
source§

impl From<Response<BoxBody>> for DispatchError

source§

fn from(original: Response<BoxBody>) -> DispatchError

Converts to this type from the input type.
source§

impl From<ResponseBuilder> for Response<EitherBody<()>>

source§

fn from(builder: ResponseBuilder) -> Self

Converts to this type from the input type.
source§

impl<I: Into<Response<BoxBody>>, E: Into<Error>> From<Result<I, E>> for Response<BoxBody>

source§

fn from(res: Result<I, E>) -> Self

Converts to this type from the input type.
source§

impl From<String> for Response<String>

source§

fn from(val: String) -> Self

Converts to this type from the input type.
source§

impl From<Vec<u8>> for Response<Vec<u8>>

source§

fn from(val: Vec<u8>) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl<B> !Freeze for Response<B>

§

impl<B> !RefUnwindSafe for Response<B>

§

impl<B> !Send for Response<B>

§

impl<B> !Sync for Response<B>

§

impl<B> Unpin for Response<B>
where + B: Unpin,

§

impl<B> !UnwindSafe for Response<B>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/struct.ResponseBuilder.html b/actix_http/struct.ResponseBuilder.html new file mode 100644 index 000000000..aa712d43f --- /dev/null +++ b/actix_http/struct.ResponseBuilder.html @@ -0,0 +1,87 @@ +ResponseBuilder in actix_http - Rust

Struct actix_http::ResponseBuilder

source ·
pub struct ResponseBuilder { /* private fields */ }
Expand description

An HTTP response builder.

+

Used to construct an instance of Response using a builder pattern. Response builders are often +created using Response::build.

+

§Examples

+
use actix_http::{Response, ResponseBuilder, StatusCode, body, header};
+
+let mut res: Response<_> = Response::build(StatusCode::OK)
+    .content_type(mime::APPLICATION_JSON)
+    .insert_header((header::SERVER, "my-app/1.0"))
+    .append_header((header::SET_COOKIE, "a=1"))
+    .append_header((header::SET_COOKIE, "b=2"))
+    .body("1234");
+
+assert_eq!(res.status(), StatusCode::OK);
+
+assert!(res.headers().contains_key("server"));
+assert_eq!(res.headers().get_all("set-cookie").count(), 2);
+
+assert_eq!(body::to_bytes(res.into_body()).await.unwrap(), &b"1234"[..]);
+

Implementations§

source§

impl ResponseBuilder

source

pub fn new(status: StatusCode) -> Self

Create response builder

+
§Examples
+
use actix_http::{Response, ResponseBuilder, StatusCode};
+let res: Response<_> = ResponseBuilder::default().finish();
+assert_eq!(res.status(), StatusCode::OK);
+
source

pub fn status(&mut self, status: StatusCode) -> &mut Self

Set HTTP status code of this response.

+
§Examples
+
use actix_http::{ResponseBuilder, StatusCode};
+let res = ResponseBuilder::default().status(StatusCode::NOT_FOUND).finish();
+assert_eq!(res.status(), StatusCode::NOT_FOUND);
+
source

pub fn insert_header(&mut self, header: impl TryIntoHeaderPair) -> &mut Self

Insert a header, replacing any that were set with an equivalent field name.

+
§Examples
+
use actix_http::{ResponseBuilder, header};
+
+let res = ResponseBuilder::default()
+    .insert_header((header::CONTENT_TYPE, mime::APPLICATION_JSON))
+    .insert_header(("X-TEST", "value"))
+    .finish();
+
+assert!(res.headers().contains_key("content-type"));
+assert!(res.headers().contains_key("x-test"));
+
source

pub fn append_header(&mut self, header: impl TryIntoHeaderPair) -> &mut Self

Append a header, keeping any that were set with an equivalent field name.

+
§Examples
+
use actix_http::{ResponseBuilder, header};
+
+let res = ResponseBuilder::default()
+    .append_header((header::CONTENT_TYPE, mime::APPLICATION_JSON))
+    .append_header(("X-TEST", "value1"))
+    .append_header(("X-TEST", "value2"))
+    .finish();
+
+assert_eq!(res.headers().get_all("content-type").count(), 1);
+assert_eq!(res.headers().get_all("x-test").count(), 2);
+
source

pub fn reason(&mut self, reason: &'static str) -> &mut Self

Set the custom reason for the response.

+
source

pub fn keep_alive(&mut self) -> &mut Self

Set connection type to KeepAlive

+
source

pub fn upgrade<V>(&mut self, value: V) -> &mut Self
where + V: TryIntoHeaderValue,

Set connection type to Upgrade.

+
source

pub fn force_close(&mut self) -> &mut Self

Force-close connection, even if it is marked as keep-alive.

+
source

pub fn no_chunking(&mut self, len: u64) -> &mut Self

Disable chunked transfer encoding for HTTP/1.1 streaming responses.

+
source

pub fn content_type<V>(&mut self, value: V) -> &mut Self
where + V: TryIntoHeaderValue,

Set response content type.

+
source

pub fn body<B>(&mut self, body: B) -> Response<EitherBody<B>>
where + B: MessageBody + 'static,

Generate response with a wrapped body.

+

This ResponseBuilder will be left in a useless state.

+
source

pub fn message_body<B>(&mut self, body: B) -> Result<Response<B>, Error>

Generate response with a body.

+

This ResponseBuilder will be left in a useless state.

+
source

pub fn finish(&mut self) -> Response<EitherBody<()>>

Generate response with an empty body.

+

This ResponseBuilder will be left in a useless state.

+
source

pub fn take(&mut self) -> ResponseBuilder

Create an owned ResponseBuilder, leaving the original in a useless state.

+

Trait Implementations§

source§

impl Debug for ResponseBuilder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for ResponseBuilder

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<'a> From<&'a ResponseHead> for ResponseBuilder

Convert ResponseHead to a ResponseBuilder

+
source§

fn from(head: &'a ResponseHead) -> ResponseBuilder

Converts to this type from the input type.
source§

impl<B> From<Response<B>> for ResponseBuilder

Convert Response to a ResponseBuilder. Body get dropped.

+
source§

fn from(res: Response<B>) -> ResponseBuilder

Converts to this type from the input type.
source§

impl From<ResponseBuilder> for Response<EitherBody<()>>

source§

fn from(builder: ResponseBuilder) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/struct.ResponseHead.html b/actix_http/struct.ResponseHead.html new file mode 100644 index 000000000..bb5abe50d --- /dev/null +++ b/actix_http/struct.ResponseHead.html @@ -0,0 +1,36 @@ +ResponseHead in actix_http - Rust

Struct actix_http::ResponseHead

source ·
pub struct ResponseHead {
+    pub version: Version,
+    pub status: StatusCode,
+    pub headers: HeaderMap,
+    pub reason: Option<&'static str>,
+    /* private fields */
+}

Fields§

§version: Version§status: StatusCode§headers: HeaderMap§reason: Option<&'static str>

Implementations§

source§

impl ResponseHead

source

pub fn new(status: StatusCode) -> ResponseHead

Create new instance of ResponseHead type

+
source

pub fn headers(&self) -> &HeaderMap

Read the message headers.

+
source

pub fn headers_mut(&mut self) -> &mut HeaderMap

Mutable reference to the message headers.

+
source

pub fn set_camel_case_headers(&mut self, camel_case: bool)

Sets the flag that controls whether to send headers formatted as Camel-Case.

+

Only applicable to HTTP/1.x responses; HTTP/2 header names are always lowercase.

+
source

pub fn set_connection_type(&mut self, ctype: ConnectionType)

Set connection type of the message

+
source

pub fn connection_type(&self) -> ConnectionType

source

pub fn keep_alive(&self) -> bool

Check if keep-alive is enabled

+
source

pub fn upgrade(&self) -> bool

Check upgrade status of this message

+
source

pub fn reason(&self) -> &str

Get custom reason for the response

+
source

pub fn chunked(&self) -> bool

Get response body chunking state

+
source

pub fn no_chunking(&mut self, val: bool)

Set no chunking for payload

+

Trait Implementations§

source§

impl Clone for ResponseHead

source§

fn clone(&self) -> ResponseHead

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ResponseHead

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a ResponseHead> for ResponseBuilder

Convert ResponseHead to a ResponseBuilder

+
source§

fn from(head: &'a ResponseHead) -> ResponseBuilder

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/struct.ServiceConfig.html b/actix_http/struct.ServiceConfig.html new file mode 100644 index 000000000..1226ba284 --- /dev/null +++ b/actix_http/struct.ServiceConfig.html @@ -0,0 +1,37 @@ +ServiceConfig in actix_http - Rust

Struct actix_http::ServiceConfig

source ·
pub struct ServiceConfig(/* private fields */);
Expand description

HTTP service configuration.

+

Implementations§

source§

impl ServiceConfig

source

pub fn new( + keep_alive: KeepAlive, + client_request_timeout: Duration, + client_disconnect_timeout: Duration, + secure: bool, + local_addr: Option<SocketAddr> +) -> ServiceConfig

Create instance of ServiceConfig.

+
source

pub fn secure(&self) -> bool

Returns true if connection is secure (i.e., using TLS / HTTPS).

+
source

pub fn local_addr(&self) -> Option<SocketAddr>

Returns the local address that this server is bound to.

+

Returns None for connections via UDS (Unix Domain Socket).

+
source

pub fn keep_alive(&self) -> KeepAlive

Connection keep-alive setting.

+
source

pub fn keep_alive_deadline(&self) -> Option<Instant>

Creates a time object representing the deadline for this connection’s keep-alive period, if +enabled.

+

When KeepAlive::Os or KeepAlive::Disabled is set, this will return None.

+
source

pub fn client_request_deadline(&self) -> Option<Instant>

Creates a time object representing the deadline for the client to finish sending the head of +its first request.

+

Returns None if this ServiceConfig was constructed with client_request_timeout: 0.

+
source

pub fn client_disconnect_deadline(&self) -> Option<Instant>

Creates a time object representing the deadline for the client to disconnect.

+

Trait Implementations§

source§

impl Clone for ServiceConfig

source§

fn clone(&self) -> ServiceConfig

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ServiceConfig

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for ServiceConfig

source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/struct.StatusCode.html b/actix_http/struct.StatusCode.html new file mode 100644 index 000000000..441825d09 --- /dev/null +++ b/actix_http/struct.StatusCode.html @@ -0,0 +1,221 @@ +StatusCode in actix_http - Rust

Struct actix_http::StatusCode

source ·
pub struct StatusCode(/* private fields */);
Expand description

An HTTP status code (status-code in RFC 7230 et al.).

+

Constants are provided for known status codes, including those in the IANA +HTTP Status Code Registry.

+

Status code values in the range 100-999 (inclusive) are supported by this +type. Values in the range 100-599 are semantically classified by the most +significant digit. See StatusCode::is_success, etc. Values above 599 +are unclassified but allowed for legacy compatibility, though their use is +discouraged. Applications may interpret such values as protocol errors.

+

§Examples

+
use http::StatusCode;
+
+assert_eq!(StatusCode::from_u16(200).unwrap(), StatusCode::OK);
+assert_eq!(StatusCode::NOT_FOUND.as_u16(), 404);
+assert!(StatusCode::OK.is_success());
+

Implementations§

source§

impl StatusCode

source

pub fn from_u16(src: u16) -> Result<StatusCode, InvalidStatusCode>

Converts a u16 to a status code.

+

The function validates the correctness of the supplied u16. It must be +greater or equal to 100 and less than 1000.

+
§Example
+
use http::StatusCode;
+
+let ok = StatusCode::from_u16(200).unwrap();
+assert_eq!(ok, StatusCode::OK);
+
+let err = StatusCode::from_u16(99);
+assert!(err.is_err());
+
source

pub fn from_bytes(src: &[u8]) -> Result<StatusCode, InvalidStatusCode>

Converts a &u8 to a status code

+
source

pub fn as_u16(&self) -> u16

Returns the u16 corresponding to this StatusCode.

+
§Note
+

This is the same as the From<StatusCode> implementation, but +included as an inherent method because that implementation doesn’t +appear in rustdocs, as well as a way to force the type instead of +relying on inference.

+
§Example
+
let status = http::StatusCode::OK;
+assert_eq!(status.as_u16(), 200);
+
source

pub fn as_str(&self) -> &str

Returns a &str representation of the StatusCode

+

The return value only includes a numerical representation of the +status code. The canonical reason is not included.

+
§Example
+
let status = http::StatusCode::OK;
+assert_eq!(status.as_str(), "200");
+
source

pub fn canonical_reason(&self) -> Option<&'static str>

Get the standardised reason-phrase for this status code.

+

This is mostly here for servers writing responses, but could potentially have application +at other times.

+

The reason phrase is defined as being exclusively for human readers. You should avoid +deriving any meaning from it at all costs.

+

Bear in mind also that in HTTP/2.0 and HTTP/3.0 the reason phrase is abolished from +transmission, and so this canonical reason phrase really is the only reason phrase you’ll +find.

+
§Example
+
let status = http::StatusCode::OK;
+assert_eq!(status.canonical_reason(), Some("OK"));
+
source

pub fn is_informational(&self) -> bool

Check if status is within 100-199.

+
source

pub fn is_success(&self) -> bool

Check if status is within 200-299.

+
source

pub fn is_redirection(&self) -> bool

Check if status is within 300-399.

+
source

pub fn is_client_error(&self) -> bool

Check if status is within 400-499.

+
source

pub fn is_server_error(&self) -> bool

Check if status is within 500-599.

+
source§

impl StatusCode

source

pub const CONTINUE: StatusCode = _

100 Continue +[RFC7231, Section 6.2.1]

+
source

pub const SWITCHING_PROTOCOLS: StatusCode = _

101 Switching Protocols +[RFC7231, Section 6.2.2]

+
source

pub const PROCESSING: StatusCode = _

102 Processing +[RFC2518]

+
source

pub const OK: StatusCode = _

source

pub const CREATED: StatusCode = _

201 Created +[RFC7231, Section 6.3.2]

+
source

pub const ACCEPTED: StatusCode = _

202 Accepted +[RFC7231, Section 6.3.3]

+
source

pub const NON_AUTHORITATIVE_INFORMATION: StatusCode = _

203 Non-Authoritative Information +[RFC7231, Section 6.3.4]

+
source

pub const NO_CONTENT: StatusCode = _

204 No Content +[RFC7231, Section 6.3.5]

+
source

pub const RESET_CONTENT: StatusCode = _

205 Reset Content +[RFC7231, Section 6.3.6]

+
source

pub const PARTIAL_CONTENT: StatusCode = _

206 Partial Content +[RFC7233, Section 4.1]

+
source

pub const MULTI_STATUS: StatusCode = _

207 Multi-Status +[RFC4918]

+
source

pub const ALREADY_REPORTED: StatusCode = _

208 Already Reported +[RFC5842]

+
source

pub const IM_USED: StatusCode = _

226 IM Used +[RFC3229]

+
source

pub const MULTIPLE_CHOICES: StatusCode = _

300 Multiple Choices +[RFC7231, Section 6.4.1]

+
source

pub const MOVED_PERMANENTLY: StatusCode = _

301 Moved Permanently +[RFC7231, Section 6.4.2]

+
source

pub const FOUND: StatusCode = _

302 Found +[RFC7231, Section 6.4.3]

+
source

pub const SEE_OTHER: StatusCode = _

303 See Other +[RFC7231, Section 6.4.4]

+
source

pub const NOT_MODIFIED: StatusCode = _

304 Not Modified +[RFC7232, Section 4.1]

+
source

pub const USE_PROXY: StatusCode = _

305 Use Proxy +[RFC7231, Section 6.4.5]

+
source

pub const TEMPORARY_REDIRECT: StatusCode = _

307 Temporary Redirect +[RFC7231, Section 6.4.7]

+
source

pub const PERMANENT_REDIRECT: StatusCode = _

308 Permanent Redirect +[RFC7238]

+
source

pub const BAD_REQUEST: StatusCode = _

400 Bad Request +[RFC7231, Section 6.5.1]

+
source

pub const UNAUTHORIZED: StatusCode = _

401 Unauthorized +[RFC7235, Section 3.1]

+
source

pub const PAYMENT_REQUIRED: StatusCode = _

402 Payment Required +[RFC7231, Section 6.5.2]

+
source

pub const FORBIDDEN: StatusCode = _

403 Forbidden +[RFC7231, Section 6.5.3]

+
source

pub const NOT_FOUND: StatusCode = _

404 Not Found +[RFC7231, Section 6.5.4]

+
source

pub const METHOD_NOT_ALLOWED: StatusCode = _

405 Method Not Allowed +[RFC7231, Section 6.5.5]

+
source

pub const NOT_ACCEPTABLE: StatusCode = _

406 Not Acceptable +[RFC7231, Section 6.5.6]

+
source

pub const PROXY_AUTHENTICATION_REQUIRED: StatusCode = _

407 Proxy Authentication Required +[RFC7235, Section 3.2]

+
source

pub const REQUEST_TIMEOUT: StatusCode = _

408 Request Timeout +[RFC7231, Section 6.5.7]

+
source

pub const CONFLICT: StatusCode = _

409 Conflict +[RFC7231, Section 6.5.8]

+
source

pub const GONE: StatusCode = _

source

pub const LENGTH_REQUIRED: StatusCode = _

411 Length Required +[RFC7231, Section 6.5.10]

+
source

pub const PRECONDITION_FAILED: StatusCode = _

412 Precondition Failed +[RFC7232, Section 4.2]

+
source

pub const PAYLOAD_TOO_LARGE: StatusCode = _

413 Payload Too Large +[RFC7231, Section 6.5.11]

+
source

pub const URI_TOO_LONG: StatusCode = _

414 URI Too Long +[RFC7231, Section 6.5.12]

+
source

pub const UNSUPPORTED_MEDIA_TYPE: StatusCode = _

415 Unsupported Media Type +[RFC7231, Section 6.5.13]

+
source

pub const RANGE_NOT_SATISFIABLE: StatusCode = _

416 Range Not Satisfiable +[RFC7233, Section 4.4]

+
source

pub const EXPECTATION_FAILED: StatusCode = _

417 Expectation Failed +[RFC7231, Section 6.5.14]

+
source

pub const IM_A_TEAPOT: StatusCode = _

418 I’m a teapot +[curiously not registered by IANA but RFC2324]

+
source

pub const MISDIRECTED_REQUEST: StatusCode = _

421 Misdirected Request +RFC7540, Section 9.1.2

+
source

pub const UNPROCESSABLE_ENTITY: StatusCode = _

422 Unprocessable Entity +[RFC4918]

+
source

pub const LOCKED: StatusCode = _

423 Locked +[RFC4918]

+
source

pub const FAILED_DEPENDENCY: StatusCode = _

424 Failed Dependency +[RFC4918]

+
source

pub const UPGRADE_REQUIRED: StatusCode = _

426 Upgrade Required +[RFC7231, Section 6.5.15]

+
source

pub const PRECONDITION_REQUIRED: StatusCode = _

428 Precondition Required +[RFC6585]

+
source

pub const TOO_MANY_REQUESTS: StatusCode = _

429 Too Many Requests +[RFC6585]

+
source

pub const REQUEST_HEADER_FIELDS_TOO_LARGE: StatusCode = _

431 Request Header Fields Too Large +[RFC6585]

+

451 Unavailable For Legal Reasons +[RFC7725]

+
source

pub const INTERNAL_SERVER_ERROR: StatusCode = _

500 Internal Server Error +[RFC7231, Section 6.6.1]

+
source

pub const NOT_IMPLEMENTED: StatusCode = _

501 Not Implemented +[RFC7231, Section 6.6.2]

+
source

pub const BAD_GATEWAY: StatusCode = _

502 Bad Gateway +[RFC7231, Section 6.6.3]

+
source

pub const SERVICE_UNAVAILABLE: StatusCode = _

503 Service Unavailable +[RFC7231, Section 6.6.4]

+
source

pub const GATEWAY_TIMEOUT: StatusCode = _

504 Gateway Timeout +[RFC7231, Section 6.6.5]

+
source

pub const HTTP_VERSION_NOT_SUPPORTED: StatusCode = _

505 HTTP Version Not Supported +[RFC7231, Section 6.6.6]

+
source

pub const VARIANT_ALSO_NEGOTIATES: StatusCode = _

506 Variant Also Negotiates +[RFC2295]

+
source

pub const INSUFFICIENT_STORAGE: StatusCode = _

507 Insufficient Storage +[RFC4918]

+
source

pub const LOOP_DETECTED: StatusCode = _

508 Loop Detected +[RFC5842]

+
source

pub const NOT_EXTENDED: StatusCode = _

510 Not Extended +[RFC2774]

+
source

pub const NETWORK_AUTHENTICATION_REQUIRED: StatusCode = _

511 Network Authentication Required +[RFC6585]

+

Trait Implementations§

source§

impl Clone for StatusCode

source§

fn clone(&self) -> StatusCode

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for StatusCode

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for StatusCode

source§

fn default() -> StatusCode

Returns the “default value” for a type. Read more
source§

impl Display for StatusCode

Formats the status code, including the canonical reason.

+

§Example

+
assert_eq!(format!("{}", StatusCode::OK), "200 OK");
+
source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a StatusCode> for StatusCode

source§

fn from(t: &'a StatusCode) -> StatusCode

Converts to this type from the input type.
source§

impl FromStr for StatusCode

§

type Err = InvalidStatusCode

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<StatusCode, InvalidStatusCode>

Parses a string s to return a value of this type. Read more
source§

impl Hash for StatusCode

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for StatusCode

source§

fn cmp(&self, other: &StatusCode) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq<u16> for StatusCode

source§

fn eq(&self, other: &u16) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for StatusCode

source§

fn eq(&self, other: &StatusCode) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for StatusCode

source§

fn partial_cmp(&self, other: &StatusCode) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> TryFrom<&'a [u8]> for StatusCode

§

type Error = InvalidStatusCode

The type returned in the event of a conversion error.
source§

fn try_from( + t: &'a [u8] +) -> Result<StatusCode, <StatusCode as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for StatusCode

§

type Error = InvalidStatusCode

The type returned in the event of a conversion error.
source§

fn try_from( + t: &'a str +) -> Result<StatusCode, <StatusCode as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<u16> for StatusCode

§

type Error = InvalidStatusCode

The type returned in the event of a conversion error.
source§

fn try_from(t: u16) -> Result<StatusCode, <StatusCode as TryFrom<u16>>::Error>

Performs the conversion.
source§

impl Copy for StatusCode

source§

impl Eq for StatusCode

source§

impl StructuralPartialEq for StatusCode

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/struct.TlsAcceptorConfig.html b/actix_http/struct.TlsAcceptorConfig.html new file mode 100644 index 000000000..07cb9df59 --- /dev/null +++ b/actix_http/struct.TlsAcceptorConfig.html @@ -0,0 +1,19 @@ +TlsAcceptorConfig in actix_http - Rust

Struct actix_http::TlsAcceptorConfig

source ·
pub struct TlsAcceptorConfig { /* private fields */ }
Available on crate features openssl or rustls-0_20 or rustls-0_21 or rustls-0_22 or rustls-0_23 only.
Expand description

Configuration options used when accepting TLS connection.

+

Implementations§

source§

impl TlsAcceptorConfig

source

pub fn handshake_timeout(self, dur: Duration) -> Self

Set TLS handshake timeout duration.

+

Trait Implementations§

source§

impl Debug for TlsAcceptorConfig

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for TlsAcceptorConfig

source§

fn default() -> TlsAcceptorConfig

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/struct.Uri.html b/actix_http/struct.Uri.html new file mode 100644 index 000000000..1a630bfb1 --- /dev/null +++ b/actix_http/struct.Uri.html @@ -0,0 +1,284 @@ +Uri in actix_http - Rust

Struct actix_http::Uri

source ·
pub struct Uri { /* private fields */ }
Expand description

The URI component of a request.

+

For HTTP 1, this is included as part of the request line. From Section 5.3, +Request Target:

+
+

Once an inbound connection is obtained, the client sends an HTTP +request message (Section 3) with a request-target derived from the +target URI. There are four distinct formats for the request-target, +depending on both the method being requested and whether the request +is to a proxy.

+
request-target = origin-form
+               / absolute-form
+               / authority-form
+               / asterisk-form
+
+

The URI is structured as follows:

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+|-|   |-------------------------------||--------| |-------------------| |-----|
+ |                  |                       |               |              |
+scheme          authority                 path            query         fragment
+
+

For HTTP 2.0, the URI is encoded using pseudoheaders.

+

§Examples

+
use http::Uri;
+
+let uri = "/foo/bar?baz".parse::<Uri>().unwrap();
+assert_eq!(uri.path(), "/foo/bar");
+assert_eq!(uri.query(), Some("baz"));
+assert_eq!(uri.host(), None);
+
+let uri = "https://www.rust-lang.org/install.html".parse::<Uri>().unwrap();
+assert_eq!(uri.scheme_str(), Some("https"));
+assert_eq!(uri.host(), Some("www.rust-lang.org"));
+assert_eq!(uri.path(), "/install.html");
+

Implementations§

source§

impl Uri

source

pub fn builder() -> Builder

Creates a new builder-style object to manufacture a Uri.

+

This method returns an instance of Builder which can be usd to +create a Uri.

+
§Examples
+
use http::Uri;
+
+let uri = Uri::builder()
+    .scheme("https")
+    .authority("hyper.rs")
+    .path_and_query("/")
+    .build()
+    .unwrap();
+
source

pub fn from_parts(src: Parts) -> Result<Uri, InvalidUriParts>

Attempt to convert a Parts into a Uri.

+
§Examples
+

Relative URI

+ +
let mut parts = Parts::default();
+parts.path_and_query = Some("/foo".parse().unwrap());
+
+let uri = Uri::from_parts(parts).unwrap();
+
+assert_eq!(uri.path(), "/foo");
+
+assert!(uri.scheme().is_none());
+assert!(uri.authority().is_none());
+

Absolute URI

+ +
let mut parts = Parts::default();
+parts.scheme = Some("http".parse().unwrap());
+parts.authority = Some("foo.com".parse().unwrap());
+parts.path_and_query = Some("/foo".parse().unwrap());
+
+let uri = Uri::from_parts(parts).unwrap();
+
+assert_eq!(uri.scheme().unwrap().as_str(), "http");
+assert_eq!(uri.authority().unwrap(), "foo.com");
+assert_eq!(uri.path(), "/foo");
+
source

pub fn from_maybe_shared<T>(src: T) -> Result<Uri, InvalidUri>
where + T: AsRef<[u8]> + 'static,

Attempt to convert a Bytes buffer to a Uri.

+

This will try to prevent a copy if the type passed is the type used +internally, and will copy the data if it is not.

+
source

pub fn from_static(src: &'static str) -> Uri

Convert a Uri from a static string.

+

This function will not perform any copying, however the string is +checked to ensure that it is valid.

+
§Panics
+

This function panics if the argument is an invalid URI.

+
§Examples
+
let uri = Uri::from_static("http://example.com/foo");
+
+assert_eq!(uri.host().unwrap(), "example.com");
+assert_eq!(uri.path(), "/foo");
+
source

pub fn into_parts(self) -> Parts

Convert a Uri into Parts.

+
§Note
+

This is just an inherent method providing the same functionality as +let parts: Parts = uri.into()

+
§Examples
+
let uri: Uri = "/foo".parse().unwrap();
+
+let parts = uri.into_parts();
+
+assert_eq!(parts.path_and_query.unwrap(), "/foo");
+
+assert!(parts.scheme.is_none());
+assert!(parts.authority.is_none());
+
source

pub fn path_and_query(&self) -> Option<&PathAndQuery>

Returns the path & query components of the Uri

+
source

pub fn path(&self) -> &str

Get the path of this Uri.

+

Both relative and absolute URIs contain a path component, though it +might be the empty string. The path component is case sensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                       |--------|
+                                            |
+                                          path
+
+

If the URI is * then the path component is equal to *.

+
§Examples
+

A relative URI

+ +

+let uri: Uri = "/hello/world".parse().unwrap();
+
+assert_eq!(uri.path(), "/hello/world");
+

An absolute URI

+ +
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.path(), "/hello/world");
+
source

pub fn scheme(&self) -> Option<&Scheme>

Get the scheme of this Uri.

+

The URI scheme refers to a specification for assigning identifiers +within that scheme. Only absolute URIs contain a scheme component, but +not all absolute URIs will contain a scheme component. Although scheme +names are case-insensitive, the canonical form is lowercase.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+|-|
+ |
+scheme
+
§Examples
+

Absolute URI

+ +
use http::uri::{Scheme, Uri};
+
+let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.scheme(), Some(&Scheme::HTTP));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.scheme().is_none());
+
source

pub fn scheme_str(&self) -> Option<&str>

Get the scheme of this Uri as a &str.

+
§Example
+
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.scheme_str(), Some("http"));
+
source

pub fn authority(&self) -> Option<&Authority>

Get the authority of this Uri.

+

The authority is a hierarchical element for naming authority such that +the remainder of the URI is delegated to that authority. For HTTP, the +authority consists of the host and port. The host portion of the +authority is case-insensitive.

+

The authority also includes a username:password component, however +the use of this is deprecated and should be avoided.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+      |-------------------------------|
+                    |
+                authority
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.authority().map(|a| a.as_str()), Some("example.org:80"));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.authority().is_none());
+
source

pub fn host(&self) -> Option<&str>

Get the host of this Uri.

+

The host subcomponent of authority is identified by an IP literal +encapsulated within square brackets, an IPv4 address in dotted- decimal +form, or a registered name. The host subcomponent is case-insensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                        |---------|
+                             |
+                            host
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.host(), Some("example.org"));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.host().is_none());
+
source

pub fn port(&self) -> Option<Port<&str>>

Get the port part of this Uri.

+

The port subcomponent of authority is designated by an optional port +number following the host and delimited from it by a single colon (“:”) +character. It can be turned into a decimal port number with the as_u16 +method or as a str with the as_str method.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                    |-|
+                                     |
+                                    port
+
§Examples
+

Absolute URI with port

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+let port = uri.port().unwrap();
+assert_eq!(port.as_u16(), 80);
+

Absolute URI without port

+ +
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert!(uri.port().is_none());
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.port().is_none());
+
source

pub fn port_u16(&self) -> Option<u16>

Get the port of this Uri as a u16.

+
§Example
+
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.port_u16(), Some(80));
+
source

pub fn query(&self) -> Option<&str>

Get the query string of this Uri, starting after the ?.

+

The query component contains non-hierarchical data that, along with data +in the path component, serves to identify a resource within the scope of +the URI’s scheme and naming authority (if any). The query component is +indicated by the first question mark (“?”) character and terminated by a +number sign (“#”) character or by the end of the URI.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                                  |-------------------|
+                                                            |
+                                                          query
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org/hello/world?key=value".parse().unwrap();
+
+assert_eq!(uri.query(), Some("key=value"));
+

Relative URI with a query string component

+ +
let uri: Uri = "/hello/world?key=value&foo=bar".parse().unwrap();
+
+assert_eq!(uri.query(), Some("key=value&foo=bar"));
+

Relative URI without a query string component

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.query().is_none());
+

Trait Implementations§

source§

impl Clone for Uri

source§

fn clone(&self) -> Uri

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Uri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Uri

Returns a Uri representing /

+
source§

fn default() -> Uri

Returns the “default value” for a type. Read more
source§

impl Display for Uri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl From<Authority> for Uri

Convert an Authority into a Uri.

+
source§

fn from(authority: Authority) -> Uri

Converts to this type from the input type.
source§

impl From<PathAndQuery> for Uri

Convert a PathAndQuery into a Uri.

+
source§

fn from(path_and_query: PathAndQuery) -> Uri

Converts to this type from the input type.
source§

impl From<Uri> for Parts

Convert a Uri into Parts

+
source§

fn from(src: Uri) -> Parts

Converts to this type from the input type.
source§

impl FromStr for Uri

§

type Err = InvalidUri

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Uri, InvalidUri>

Parses a string s to return a value of this type. Read more
source§

impl Hash for Uri

source§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl Host for Uri

§

fn hostname(&self) -> &str

Extract hostname.
§

fn port(&self) -> Option<u16>

Extract optional port.
source§

impl<'a> PartialEq<&'a str> for Uri

source§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<Uri> for &'a str

source§

fn eq(&self, uri: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Uri> for str

source§

fn eq(&self, uri: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for Uri

source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Uri

source§

fn eq(&self, other: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> TryFrom<&'a [u8]> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a [u8]) -> Result<Uri, <Uri as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a String> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a String) -> Result<Uri, <Uri as TryFrom<&'a String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a Uri> for Uri

§

type Error = Error

The type returned in the event of a conversion error.
source§

fn try_from(src: &'a Uri) -> Result<Uri, <Uri as TryFrom<&'a Uri>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a str) -> Result<Uri, <Uri as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<Parts> for Uri

§

type Error = InvalidUriParts

The type returned in the event of a conversion error.
source§

fn try_from(src: Parts) -> Result<Uri, <Uri as TryFrom<Parts>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: String) -> Result<Uri, <Uri as TryFrom<String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<Vec<u8>> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(vec: Vec<u8>) -> Result<Uri, <Uri as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
source§

impl Eq for Uri

Auto Trait Implementations§

§

impl !Freeze for Uri

§

impl RefUnwindSafe for Uri

§

impl Send for Uri

§

impl Sync for Uri

§

impl Unpin for Uri

§

impl UnwindSafe for Uri

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/struct.Version.html b/actix_http/struct.Version.html new file mode 100644 index 000000000..4d2f24ed5 --- /dev/null +++ b/actix_http/struct.Version.html @@ -0,0 +1,40 @@ +Version in actix_http - Rust

Struct actix_http::Version

source ·
pub struct Version(/* private fields */);
Expand description

Represents a version of the HTTP spec.

+

Implementations§

source§

impl Version

source

pub const HTTP_09: Version = _

HTTP/0.9

+
source

pub const HTTP_10: Version = _

HTTP/1.0

+
source

pub const HTTP_11: Version = _

HTTP/1.1

+
source

pub const HTTP_2: Version = _

HTTP/2.0

+
source

pub const HTTP_3: Version = _

HTTP/3.0

+

Trait Implementations§

source§

impl Clone for Version

source§

fn clone(&self) -> Version

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Version

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Version

source§

fn default() -> Version

Returns the “default value” for a type. Read more
source§

impl Hash for Version

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for Version

source§

fn cmp(&self, other: &Version) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq for Version

source§

fn eq(&self, other: &Version) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for Version

source§

fn partial_cmp(&self, other: &Version) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl Copy for Version

source§

impl Eq for Version

source§

impl StructuralPartialEq for Version

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/test/index.html b/actix_http/test/index.html new file mode 100644 index 000000000..60d800b24 --- /dev/null +++ b/actix_http/test/index.html @@ -0,0 +1,2 @@ +actix_http::test - Rust

Module actix_http::test

source ·
Expand description

Various testing helpers for use in internal and app tests.

+

Structs§

\ No newline at end of file diff --git a/actix_http/test/sidebar-items.js b/actix_http/test/sidebar-items.js new file mode 100644 index 000000000..7ac796fec --- /dev/null +++ b/actix_http/test/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["TestBuffer","TestRequest","TestSeqBuffer","TestSeqInner"]}; \ No newline at end of file diff --git a/actix_http/test/struct.TestBuffer.html b/actix_http/test/struct.TestBuffer.html new file mode 100644 index 000000000..1c8b31f58 --- /dev/null +++ b/actix_http/test/struct.TestBuffer.html @@ -0,0 +1,172 @@ +TestBuffer in actix_http::test - Rust

Struct actix_http::test::TestBuffer

source ·
pub struct TestBuffer {
+    pub read_buf: Rc<RefCell<BytesMut>>,
+    pub write_buf: Rc<RefCell<BytesMut>>,
+    pub err: Option<Rc<Error>>,
+}
Expand description

Async I/O test buffer.

+

Fields§

§read_buf: Rc<RefCell<BytesMut>>§write_buf: Rc<RefCell<BytesMut>>§err: Option<Rc<Error>>

Implementations§

source§

impl TestBuffer

source

pub fn new<T>(data: T) -> Self
where + T: Into<BytesMut>,

Create new TestBuffer instance with initial read buffer.

+
source

pub fn empty() -> Self

Create new empty TestBuffer instance.

+
source

pub fn extend_read_buf<T: AsRef<[u8]>>(&mut self, data: T)

Add data to read buffer.

+

Trait Implementations§

source§

impl AsyncRead for TestBuffer

source§

fn poll_read( + self: Pin<&mut Self>, + _: &mut Context<'_>, + buf: &mut ReadBuf<'_> +) -> Poll<Result<()>>

Attempts to read from the AsyncRead into buf. Read more
source§

impl AsyncWrite for TestBuffer

source§

fn poll_write( + self: Pin<&mut Self>, + _: &mut Context<'_>, + buf: &[u8] +) -> Poll<Result<usize>>

Attempt to write bytes from buf into the object. Read more
source§

fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<()>>

Attempts to flush the object, ensuring that any buffered data reach +their destination. Read more
source§

fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<()>>

Initiates or attempts to shut down this writer, returning success when +the I/O connection has completely shut down. Read more
§

fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[IoSlice<'_>] +) -> Poll<Result<usize, Error>>

Like poll_write, except that it writes from a slice of buffers. Read more
§

fn is_write_vectored(&self) -> bool

Determines if this writer has an efficient poll_write_vectored +implementation. Read more
source§

impl Debug for TestBuffer

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Read for TestBuffer

source§

fn read(&mut self, dst: &mut [u8]) -> Result<usize, Error>

Pull some bytes from this source into the specified buffer, returning +how many bytes were read. Read more
1.36.0 · source§

fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize, Error>

Like read, except that it reads into a slice of buffers. Read more
source§

fn is_read_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Reader has an efficient read_vectored +implementation. Read more
1.0.0 · source§

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, Error>

Read all bytes until EOF in this source, placing them into buf. Read more
1.0.0 · source§

fn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>

Read all bytes until EOF in this source, appending them to buf. Read more
1.6.0 · source§

fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>

Read the exact number of bytes required to fill buf. Read more
source§

fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<(), Error>

🔬This is a nightly-only experimental API. (read_buf)
Pull some bytes from this source into the specified buffer. Read more
source§

fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<(), Error>

🔬This is a nightly-only experimental API. (read_buf)
Read the exact number of bytes required to fill cursor. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Creates a “by reference” adaptor for this instance of Read. Read more
1.0.0 · source§

fn bytes(self) -> Bytes<Self>
where + Self: Sized,

Transforms this Read instance to an Iterator over its bytes. Read more
1.0.0 · source§

fn chain<R>(self, next: R) -> Chain<Self, R>
where + R: Read, + Self: Sized,

Creates an adapter which will chain this stream with another. Read more
1.0.0 · source§

fn take(self, limit: u64) -> Take<Self>
where + Self: Sized,

Creates an adapter which will read at most limit bytes from it. Read more
source§

impl Write for TestBuffer

source§

fn write(&mut self, buf: &[u8]) -> Result<usize>

Write a buffer into this writer, returning how many bytes were written. Read more
source§

fn flush(&mut self) -> Result<()>

Flush this output stream, ensuring that all intermediately buffered +contents reach their destination. Read more
1.36.0 · source§

fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize, Error>

Like write, except that it writes from a slice of buffers. Read more
source§

fn is_write_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Writer has an efficient write_vectored +implementation. Read more
1.0.0 · source§

fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>

Attempts to write an entire buffer into this writer. Read more
source§

fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>

🔬This is a nightly-only experimental API. (write_all_vectored)
Attempts to write multiple buffers into this writer. Read more
1.0.0 · source§

fn write_fmt(&mut self, fmt: Arguments<'_>) -> Result<(), Error>

Writes a formatted string into this writer, returning any error +encountered. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Creates a “by reference” adapter for this instance of Write. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<R> AsyncReadExt for R
where + R: AsyncRead + ?Sized,

§

fn chain<R>(self, next: R) -> Chain<Self, R>
where + Self: Sized, + R: AsyncRead,

Creates a new AsyncRead instance that chains this stream with +next. Read more
§

fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>
where + Self: Unpin,

Pulls some bytes from this source into the specified buffer, +returning how many bytes were read. Read more
§

fn read_buf<'a, B>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B>
where + Self: Unpin, + B: BufMut + ?Sized,

Pulls some bytes from this source into the specified buffer, +advancing the buffer’s internal cursor. Read more
§

fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self>
where + Self: Unpin,

Reads the exact number of bytes required to fill buf. Read more
§

fn read_u8(&mut self) -> ReadU8<&mut Self>
where + Self: Unpin,

Reads an unsigned 8 bit integer from the underlying reader. Read more
§

fn read_i8(&mut self) -> ReadI8<&mut Self>
where + Self: Unpin,

Reads a signed 8 bit integer from the underlying reader. Read more
§

fn read_u16(&mut self) -> ReadU16<&mut Self>
where + Self: Unpin,

Reads an unsigned 16-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i16(&mut self) -> ReadI16<&mut Self>
where + Self: Unpin,

Reads a signed 16-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u32(&mut self) -> ReadU32<&mut Self>
where + Self: Unpin,

Reads an unsigned 32-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i32(&mut self) -> ReadI32<&mut Self>
where + Self: Unpin,

Reads a signed 32-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u64(&mut self) -> ReadU64<&mut Self>
where + Self: Unpin,

Reads an unsigned 64-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i64(&mut self) -> ReadI64<&mut Self>
where + Self: Unpin,

Reads an signed 64-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u128(&mut self) -> ReadU128<&mut Self>
where + Self: Unpin,

Reads an unsigned 128-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i128(&mut self) -> ReadI128<&mut Self>
where + Self: Unpin,

Reads an signed 128-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_f32(&mut self) -> ReadF32<&mut Self>
where + Self: Unpin,

Reads an 32-bit floating point type in big-endian order from the +underlying reader. Read more
§

fn read_f64(&mut self) -> ReadF64<&mut Self>
where + Self: Unpin,

Reads an 64-bit floating point type in big-endian order from the +underlying reader. Read more
§

fn read_u16_le(&mut self) -> ReadU16Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 16-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i16_le(&mut self) -> ReadI16Le<&mut Self>
where + Self: Unpin,

Reads a signed 16-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u32_le(&mut self) -> ReadU32Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 32-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i32_le(&mut self) -> ReadI32Le<&mut Self>
where + Self: Unpin,

Reads a signed 32-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u64_le(&mut self) -> ReadU64Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 64-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i64_le(&mut self) -> ReadI64Le<&mut Self>
where + Self: Unpin,

Reads an signed 64-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u128_le(&mut self) -> ReadU128Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 128-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i128_le(&mut self) -> ReadI128Le<&mut Self>
where + Self: Unpin,

Reads an signed 128-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_f32_le(&mut self) -> ReadF32Le<&mut Self>
where + Self: Unpin,

Reads an 32-bit floating point type in little-endian order from the +underlying reader. Read more
§

fn read_f64_le(&mut self) -> ReadF64Le<&mut Self>
where + Self: Unpin,

Reads an 64-bit floating point type in little-endian order from the +underlying reader. Read more
§

fn read_to_end<'a>(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEnd<'a, Self>
where + Self: Unpin,

Reads all bytes until EOF in this source, placing them into buf. Read more
§

fn read_to_string<'a>( + &'a mut self, + dst: &'a mut String +) -> ReadToString<'a, Self>
where + Self: Unpin,

Reads all bytes until EOF in this source, appending them to buf. Read more
§

fn take(self, limit: u64) -> Take<Self>
where + Self: Sized,

Creates an adaptor which reads at most limit bytes from it. Read more
§

impl<W> AsyncWriteExt for W
where + W: AsyncWrite + ?Sized,

§

fn write<'a>(&'a mut self, src: &'a [u8]) -> Write<'a, Self>
where + Self: Unpin,

Writes a buffer into this writer, returning how many bytes were +written. Read more
§

fn write_vectored<'a, 'b>( + &'a mut self, + bufs: &'a [IoSlice<'b>] +) -> WriteVectored<'a, 'b, Self>
where + Self: Unpin,

Like write, except that it writes from a slice of buffers. Read more
§

fn write_buf<'a, B>(&'a mut self, src: &'a mut B) -> WriteBuf<'a, Self, B>
where + Self: Sized + Unpin, + B: Buf,

Writes a buffer into this writer, advancing the buffer’s internal +cursor. Read more
§

fn write_all_buf<'a, B>( + &'a mut self, + src: &'a mut B +) -> WriteAllBuf<'a, Self, B>
where + Self: Sized + Unpin, + B: Buf,

Attempts to write an entire buffer into this writer. Read more
§

fn write_all<'a>(&'a mut self, src: &'a [u8]) -> WriteAll<'a, Self>
where + Self: Unpin,

Attempts to write an entire buffer into this writer. Read more
§

fn write_u8(&mut self, n: u8) -> WriteU8<&mut Self>
where + Self: Unpin,

Writes an unsigned 8-bit integer to the underlying writer. Read more
§

fn write_i8(&mut self, n: i8) -> WriteI8<&mut Self>
where + Self: Unpin,

Writes a signed 8-bit integer to the underlying writer. Read more
§

fn write_u16(&mut self, n: u16) -> WriteU16<&mut Self>
where + Self: Unpin,

Writes an unsigned 16-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i16(&mut self, n: i16) -> WriteI16<&mut Self>
where + Self: Unpin,

Writes a signed 16-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u32(&mut self, n: u32) -> WriteU32<&mut Self>
where + Self: Unpin,

Writes an unsigned 32-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i32(&mut self, n: i32) -> WriteI32<&mut Self>
where + Self: Unpin,

Writes a signed 32-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u64(&mut self, n: u64) -> WriteU64<&mut Self>
where + Self: Unpin,

Writes an unsigned 64-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i64(&mut self, n: i64) -> WriteI64<&mut Self>
where + Self: Unpin,

Writes an signed 64-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u128(&mut self, n: u128) -> WriteU128<&mut Self>
where + Self: Unpin,

Writes an unsigned 128-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i128(&mut self, n: i128) -> WriteI128<&mut Self>
where + Self: Unpin,

Writes an signed 128-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_f32(&mut self, n: f32) -> WriteF32<&mut Self>
where + Self: Unpin,

Writes an 32-bit floating point type in big-endian order to the +underlying writer. Read more
§

fn write_f64(&mut self, n: f64) -> WriteF64<&mut Self>
where + Self: Unpin,

Writes an 64-bit floating point type in big-endian order to the +underlying writer. Read more
§

fn write_u16_le(&mut self, n: u16) -> WriteU16Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 16-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i16_le(&mut self, n: i16) -> WriteI16Le<&mut Self>
where + Self: Unpin,

Writes a signed 16-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u32_le(&mut self, n: u32) -> WriteU32Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 32-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i32_le(&mut self, n: i32) -> WriteI32Le<&mut Self>
where + Self: Unpin,

Writes a signed 32-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u64_le(&mut self, n: u64) -> WriteU64Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 64-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i64_le(&mut self, n: i64) -> WriteI64Le<&mut Self>
where + Self: Unpin,

Writes an signed 64-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u128_le(&mut self, n: u128) -> WriteU128Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 128-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i128_le(&mut self, n: i128) -> WriteI128Le<&mut Self>
where + Self: Unpin,

Writes an signed 128-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_f32_le(&mut self, n: f32) -> WriteF32Le<&mut Self>
where + Self: Unpin,

Writes an 32-bit floating point type in little-endian order to the +underlying writer. Read more
§

fn write_f64_le(&mut self, n: f64) -> WriteF64Le<&mut Self>
where + Self: Unpin,

Writes an 64-bit floating point type in little-endian order to the +underlying writer. Read more
§

fn flush(&mut self) -> Flush<'_, Self>
where + Self: Unpin,

Flushes this output stream, ensuring that all intermediately buffered +contents reach their destination. Read more
§

fn shutdown(&mut self) -> Shutdown<'_, Self>
where + Self: Unpin,

Shuts down the output stream, ensuring that the value can be dropped +cleanly. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/test/struct.TestRequest.html b/actix_http/test/struct.TestRequest.html new file mode 100644 index 000000000..73e5b18df --- /dev/null +++ b/actix_http/test/struct.TestRequest.html @@ -0,0 +1,28 @@ +TestRequest in actix_http::test - Rust

Struct actix_http::test::TestRequest

source ·
pub struct TestRequest(/* private fields */);
Expand description

Test Request builder.

+

Implementations§

source§

impl TestRequest

source

pub fn with_uri(path: &str) -> TestRequest

Create a default TestRequest and then set its URI.

+
source

pub fn version(&mut self, ver: Version) -> &mut Self

Set HTTP version of this request.

+
source

pub fn method(&mut self, meth: Method) -> &mut Self

Set HTTP method of this request.

+
source

pub fn uri(&mut self, path: &str) -> &mut Self

Set URI of this request.

+
§Panics
+

If provided URI is invalid.

+
source

pub fn insert_header(&mut self, header: impl TryIntoHeaderPair) -> &mut Self

Insert a header, replacing any that were set with an equivalent field name.

+
source

pub fn append_header(&mut self, header: impl TryIntoHeaderPair) -> &mut Self

Append a header, keeping any that were set with an equivalent field name.

+
source

pub fn set_payload(&mut self, data: impl Into<Bytes>) -> &mut Self

Set request payload.

+
source

pub fn take(&mut self) -> TestRequest

source

pub fn finish(&mut self) -> Request

Complete request creation and generate Request instance.

+

Trait Implementations§

source§

impl Default for TestRequest

source§

fn default() -> TestRequest

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/test/struct.TestSeqBuffer.html b/actix_http/test/struct.TestSeqBuffer.html new file mode 100644 index 000000000..35c4cc725 --- /dev/null +++ b/actix_http/test/struct.TestSeqBuffer.html @@ -0,0 +1,169 @@ +TestSeqBuffer in actix_http::test - Rust

Struct actix_http::test::TestSeqBuffer

source ·
pub struct TestSeqBuffer(/* private fields */);
Expand description

Async I/O test buffer with ability to incrementally add to the read buffer.

+

Implementations§

source§

impl TestSeqBuffer

source

pub fn new<T>(data: T) -> Self
where + T: Into<BytesMut>,

Create new TestBuffer instance with initial read buffer.

+
source

pub fn empty() -> Self

Create new empty TestBuffer instance.

+
source

pub fn read_buf(&self) -> Ref<'_, BytesMut>

source

pub fn write_buf(&self) -> Ref<'_, BytesMut>

source

pub fn err(&self) -> Ref<'_, Option<Error>>

source

pub fn extend_read_buf<T: AsRef<[u8]>>(&mut self, data: T)

Add data to read buffer.

+

Trait Implementations§

source§

impl AsyncRead for TestSeqBuffer

source§

fn poll_read( + self: Pin<&mut Self>, + _: &mut Context<'_>, + buf: &mut ReadBuf<'_> +) -> Poll<Result<()>>

Attempts to read from the AsyncRead into buf. Read more
source§

impl AsyncWrite for TestSeqBuffer

source§

fn poll_write( + self: Pin<&mut Self>, + _: &mut Context<'_>, + buf: &[u8] +) -> Poll<Result<usize>>

Attempt to write bytes from buf into the object. Read more
source§

fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<()>>

Attempts to flush the object, ensuring that any buffered data reach +their destination. Read more
source§

fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<()>>

Initiates or attempts to shut down this writer, returning success when +the I/O connection has completely shut down. Read more
§

fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[IoSlice<'_>] +) -> Poll<Result<usize, Error>>

Like poll_write, except that it writes from a slice of buffers. Read more
§

fn is_write_vectored(&self) -> bool

Determines if this writer has an efficient poll_write_vectored +implementation. Read more
source§

impl Clone for TestSeqBuffer

source§

fn clone(&self) -> TestSeqBuffer

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Read for TestSeqBuffer

source§

fn read(&mut self, dst: &mut [u8]) -> Result<usize, Error>

Pull some bytes from this source into the specified buffer, returning +how many bytes were read. Read more
1.36.0 · source§

fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize, Error>

Like read, except that it reads into a slice of buffers. Read more
source§

fn is_read_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Reader has an efficient read_vectored +implementation. Read more
1.0.0 · source§

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, Error>

Read all bytes until EOF in this source, placing them into buf. Read more
1.0.0 · source§

fn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>

Read all bytes until EOF in this source, appending them to buf. Read more
1.6.0 · source§

fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>

Read the exact number of bytes required to fill buf. Read more
source§

fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<(), Error>

🔬This is a nightly-only experimental API. (read_buf)
Pull some bytes from this source into the specified buffer. Read more
source§

fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<(), Error>

🔬This is a nightly-only experimental API. (read_buf)
Read the exact number of bytes required to fill cursor. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Creates a “by reference” adaptor for this instance of Read. Read more
1.0.0 · source§

fn bytes(self) -> Bytes<Self>
where + Self: Sized,

Transforms this Read instance to an Iterator over its bytes. Read more
1.0.0 · source§

fn chain<R>(self, next: R) -> Chain<Self, R>
where + R: Read, + Self: Sized,

Creates an adapter which will chain this stream with another. Read more
1.0.0 · source§

fn take(self, limit: u64) -> Take<Self>
where + Self: Sized,

Creates an adapter which will read at most limit bytes from it. Read more
source§

impl Write for TestSeqBuffer

source§

fn write(&mut self, buf: &[u8]) -> Result<usize>

Write a buffer into this writer, returning how many bytes were written. Read more
source§

fn flush(&mut self) -> Result<()>

Flush this output stream, ensuring that all intermediately buffered +contents reach their destination. Read more
1.36.0 · source§

fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize, Error>

Like write, except that it writes from a slice of buffers. Read more
source§

fn is_write_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Writer has an efficient write_vectored +implementation. Read more
1.0.0 · source§

fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>

Attempts to write an entire buffer into this writer. Read more
source§

fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>

🔬This is a nightly-only experimental API. (write_all_vectored)
Attempts to write multiple buffers into this writer. Read more
1.0.0 · source§

fn write_fmt(&mut self, fmt: Arguments<'_>) -> Result<(), Error>

Writes a formatted string into this writer, returning any error +encountered. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Creates a “by reference” adapter for this instance of Write. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<R> AsyncReadExt for R
where + R: AsyncRead + ?Sized,

§

fn chain<R>(self, next: R) -> Chain<Self, R>
where + Self: Sized, + R: AsyncRead,

Creates a new AsyncRead instance that chains this stream with +next. Read more
§

fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>
where + Self: Unpin,

Pulls some bytes from this source into the specified buffer, +returning how many bytes were read. Read more
§

fn read_buf<'a, B>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B>
where + Self: Unpin, + B: BufMut + ?Sized,

Pulls some bytes from this source into the specified buffer, +advancing the buffer’s internal cursor. Read more
§

fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self>
where + Self: Unpin,

Reads the exact number of bytes required to fill buf. Read more
§

fn read_u8(&mut self) -> ReadU8<&mut Self>
where + Self: Unpin,

Reads an unsigned 8 bit integer from the underlying reader. Read more
§

fn read_i8(&mut self) -> ReadI8<&mut Self>
where + Self: Unpin,

Reads a signed 8 bit integer from the underlying reader. Read more
§

fn read_u16(&mut self) -> ReadU16<&mut Self>
where + Self: Unpin,

Reads an unsigned 16-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i16(&mut self) -> ReadI16<&mut Self>
where + Self: Unpin,

Reads a signed 16-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u32(&mut self) -> ReadU32<&mut Self>
where + Self: Unpin,

Reads an unsigned 32-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i32(&mut self) -> ReadI32<&mut Self>
where + Self: Unpin,

Reads a signed 32-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u64(&mut self) -> ReadU64<&mut Self>
where + Self: Unpin,

Reads an unsigned 64-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i64(&mut self) -> ReadI64<&mut Self>
where + Self: Unpin,

Reads an signed 64-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u128(&mut self) -> ReadU128<&mut Self>
where + Self: Unpin,

Reads an unsigned 128-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i128(&mut self) -> ReadI128<&mut Self>
where + Self: Unpin,

Reads an signed 128-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_f32(&mut self) -> ReadF32<&mut Self>
where + Self: Unpin,

Reads an 32-bit floating point type in big-endian order from the +underlying reader. Read more
§

fn read_f64(&mut self) -> ReadF64<&mut Self>
where + Self: Unpin,

Reads an 64-bit floating point type in big-endian order from the +underlying reader. Read more
§

fn read_u16_le(&mut self) -> ReadU16Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 16-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i16_le(&mut self) -> ReadI16Le<&mut Self>
where + Self: Unpin,

Reads a signed 16-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u32_le(&mut self) -> ReadU32Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 32-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i32_le(&mut self) -> ReadI32Le<&mut Self>
where + Self: Unpin,

Reads a signed 32-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u64_le(&mut self) -> ReadU64Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 64-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i64_le(&mut self) -> ReadI64Le<&mut Self>
where + Self: Unpin,

Reads an signed 64-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u128_le(&mut self) -> ReadU128Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 128-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i128_le(&mut self) -> ReadI128Le<&mut Self>
where + Self: Unpin,

Reads an signed 128-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_f32_le(&mut self) -> ReadF32Le<&mut Self>
where + Self: Unpin,

Reads an 32-bit floating point type in little-endian order from the +underlying reader. Read more
§

fn read_f64_le(&mut self) -> ReadF64Le<&mut Self>
where + Self: Unpin,

Reads an 64-bit floating point type in little-endian order from the +underlying reader. Read more
§

fn read_to_end<'a>(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEnd<'a, Self>
where + Self: Unpin,

Reads all bytes until EOF in this source, placing them into buf. Read more
§

fn read_to_string<'a>( + &'a mut self, + dst: &'a mut String +) -> ReadToString<'a, Self>
where + Self: Unpin,

Reads all bytes until EOF in this source, appending them to buf. Read more
§

fn take(self, limit: u64) -> Take<Self>
where + Self: Sized,

Creates an adaptor which reads at most limit bytes from it. Read more
§

impl<W> AsyncWriteExt for W
where + W: AsyncWrite + ?Sized,

§

fn write<'a>(&'a mut self, src: &'a [u8]) -> Write<'a, Self>
where + Self: Unpin,

Writes a buffer into this writer, returning how many bytes were +written. Read more
§

fn write_vectored<'a, 'b>( + &'a mut self, + bufs: &'a [IoSlice<'b>] +) -> WriteVectored<'a, 'b, Self>
where + Self: Unpin,

Like write, except that it writes from a slice of buffers. Read more
§

fn write_buf<'a, B>(&'a mut self, src: &'a mut B) -> WriteBuf<'a, Self, B>
where + Self: Sized + Unpin, + B: Buf,

Writes a buffer into this writer, advancing the buffer’s internal +cursor. Read more
§

fn write_all_buf<'a, B>( + &'a mut self, + src: &'a mut B +) -> WriteAllBuf<'a, Self, B>
where + Self: Sized + Unpin, + B: Buf,

Attempts to write an entire buffer into this writer. Read more
§

fn write_all<'a>(&'a mut self, src: &'a [u8]) -> WriteAll<'a, Self>
where + Self: Unpin,

Attempts to write an entire buffer into this writer. Read more
§

fn write_u8(&mut self, n: u8) -> WriteU8<&mut Self>
where + Self: Unpin,

Writes an unsigned 8-bit integer to the underlying writer. Read more
§

fn write_i8(&mut self, n: i8) -> WriteI8<&mut Self>
where + Self: Unpin,

Writes a signed 8-bit integer to the underlying writer. Read more
§

fn write_u16(&mut self, n: u16) -> WriteU16<&mut Self>
where + Self: Unpin,

Writes an unsigned 16-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i16(&mut self, n: i16) -> WriteI16<&mut Self>
where + Self: Unpin,

Writes a signed 16-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u32(&mut self, n: u32) -> WriteU32<&mut Self>
where + Self: Unpin,

Writes an unsigned 32-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i32(&mut self, n: i32) -> WriteI32<&mut Self>
where + Self: Unpin,

Writes a signed 32-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u64(&mut self, n: u64) -> WriteU64<&mut Self>
where + Self: Unpin,

Writes an unsigned 64-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i64(&mut self, n: i64) -> WriteI64<&mut Self>
where + Self: Unpin,

Writes an signed 64-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u128(&mut self, n: u128) -> WriteU128<&mut Self>
where + Self: Unpin,

Writes an unsigned 128-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i128(&mut self, n: i128) -> WriteI128<&mut Self>
where + Self: Unpin,

Writes an signed 128-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_f32(&mut self, n: f32) -> WriteF32<&mut Self>
where + Self: Unpin,

Writes an 32-bit floating point type in big-endian order to the +underlying writer. Read more
§

fn write_f64(&mut self, n: f64) -> WriteF64<&mut Self>
where + Self: Unpin,

Writes an 64-bit floating point type in big-endian order to the +underlying writer. Read more
§

fn write_u16_le(&mut self, n: u16) -> WriteU16Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 16-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i16_le(&mut self, n: i16) -> WriteI16Le<&mut Self>
where + Self: Unpin,

Writes a signed 16-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u32_le(&mut self, n: u32) -> WriteU32Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 32-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i32_le(&mut self, n: i32) -> WriteI32Le<&mut Self>
where + Self: Unpin,

Writes a signed 32-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u64_le(&mut self, n: u64) -> WriteU64Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 64-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i64_le(&mut self, n: i64) -> WriteI64Le<&mut Self>
where + Self: Unpin,

Writes an signed 64-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u128_le(&mut self, n: u128) -> WriteU128Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 128-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i128_le(&mut self, n: i128) -> WriteI128Le<&mut Self>
where + Self: Unpin,

Writes an signed 128-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_f32_le(&mut self, n: f32) -> WriteF32Le<&mut Self>
where + Self: Unpin,

Writes an 32-bit floating point type in little-endian order to the +underlying writer. Read more
§

fn write_f64_le(&mut self, n: f64) -> WriteF64Le<&mut Self>
where + Self: Unpin,

Writes an 64-bit floating point type in little-endian order to the +underlying writer. Read more
§

fn flush(&mut self) -> Flush<'_, Self>
where + Self: Unpin,

Flushes this output stream, ensuring that all intermediately buffered +contents reach their destination. Read more
§

fn shutdown(&mut self) -> Shutdown<'_, Self>
where + Self: Unpin,

Shuts down the output stream, ensuring that the value can be dropped +cleanly. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/test/struct.TestSeqInner.html b/actix_http/test/struct.TestSeqInner.html new file mode 100644 index 000000000..735603603 --- /dev/null +++ b/actix_http/test/struct.TestSeqInner.html @@ -0,0 +1,17 @@ +TestSeqInner in actix_http::test - Rust

Struct actix_http::test::TestSeqInner

source ·
pub struct TestSeqInner { /* private fields */ }

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/trait.HttpMessage.html b/actix_http/trait.HttpMessage.html new file mode 100644 index 000000000..00feaa1d3 --- /dev/null +++ b/actix_http/trait.HttpMessage.html @@ -0,0 +1,31 @@ +HttpMessage in actix_http - Rust

Trait actix_http::HttpMessage

source ·
pub trait HttpMessage: Sized {
+    type Stream;
+
+    // Required methods
+    fn headers(&self) -> &HeaderMap;
+    fn take_payload(&mut self) -> Payload<Self::Stream>;
+    fn extensions(&self) -> Ref<'_, Extensions>;
+    fn extensions_mut(&self) -> RefMut<'_, Extensions>;
+
+    // Provided methods
+    fn content_type(&self) -> &str { ... }
+    fn encoding(&self) -> Result<&'static Encoding, ContentTypeError> { ... }
+    fn mime_type(&self) -> Result<Option<Mime>, ContentTypeError> { ... }
+    fn chunked(&self) -> Result<bool, ParseError> { ... }
+}
Expand description

Trait that implements general purpose operations on HTTP messages.

+

Required Associated Types§

source

type Stream

Type of message payload stream

+

Required Methods§

source

fn headers(&self) -> &HeaderMap

Read the message headers.

+
source

fn take_payload(&mut self) -> Payload<Self::Stream>

Message payload stream

+
source

fn extensions(&self) -> Ref<'_, Extensions>

Returns a reference to the request-local data/extensions container.

+
source

fn extensions_mut(&self) -> RefMut<'_, Extensions>

Returns a mutable reference to the request-local data/extensions container.

+

Provided Methods§

source

fn content_type(&self) -> &str

Read the request content type. If request did not contain a Content-Type header, an empty +string is returned.

+
source

fn encoding(&self) -> Result<&'static Encoding, ContentTypeError>

Get content type encoding.

+

UTF-8 is used by default, If request charset is not set.

+
source

fn mime_type(&self) -> Result<Option<Mime>, ContentTypeError>

Convert the request content type to a known mime type.

+
source

fn chunked(&self) -> Result<bool, ParseError>

Check if request has chunked transfer encoding.

+

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<'a, T> HttpMessage for &'a mut T
where + T: HttpMessage,

source§

fn take_payload(&mut self) -> Payload<Self::Stream>

Message payload stream

+
source§

fn extensions(&self) -> Ref<'_, Extensions>

Request’s extensions container

+
source§

fn extensions_mut(&self) -> RefMut<'_, Extensions>

Mutable reference to a the request’s extensions container

+
§

type Stream = <T as HttpMessage>::Stream

source§

fn headers(&self) -> &HeaderMap

Implementors§

source§

impl<P> HttpMessage for Request<P>

§

type Stream = P

\ No newline at end of file diff --git a/actix_http/type.BoxedPayloadStream.html b/actix_http/type.BoxedPayloadStream.html new file mode 100644 index 000000000..d24153aba --- /dev/null +++ b/actix_http/type.BoxedPayloadStream.html @@ -0,0 +1,2 @@ +BoxedPayloadStream in actix_http - Rust

Type Alias actix_http::BoxedPayloadStream

source ·
pub type BoxedPayloadStream = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>;
Expand description

A boxed payload stream.

+

Aliased Type§

struct BoxedPayloadStream {}
\ No newline at end of file diff --git a/actix_http/uri/index.html b/actix_http/uri/index.html new file mode 100644 index 000000000..29982b111 --- /dev/null +++ b/actix_http/uri/index.html @@ -0,0 +1,19 @@ +actix_http::uri - Rust

Module actix_http::uri

source ·
Expand description

URI component of request and response lines

+

This module primarily contains the Uri type which is a component of all +HTTP requests and also reexports this type at the root of the crate. A URI +is not always a “full URL” in the sense of something you’d type into a web +browser, but HTTP requests may only have paths on servers but may have full +schemes and hostnames on clients.

+

§Examples

+
use http::Uri;
+
+let uri = "/foo/bar?baz".parse::<Uri>().unwrap();
+assert_eq!(uri.path(), "/foo/bar");
+assert_eq!(uri.query(), Some("baz"));
+assert_eq!(uri.host(), None);
+
+let uri = "https://www.rust-lang.org/install.html".parse::<Uri>().unwrap();
+assert_eq!(uri.scheme_str(), Some("https"));
+assert_eq!(uri.host(), Some("www.rust-lang.org"));
+assert_eq!(uri.path(), "/install.html");
+

Structs§

  • Represents the authority component of a URI.
  • A builder for Uris.
  • An error resulting from a failed attempt to construct a URI.
  • An error resulting from a failed attempt to construct a URI.
  • The various parts of a URI.
  • Represents the path component of a URI
  • The port component of a URI.
  • Represents the scheme component of a URI
  • The URI component of a request.
\ No newline at end of file diff --git a/actix_http/uri/sidebar-items.js b/actix_http/uri/sidebar-items.js new file mode 100644 index 000000000..0b4e597bc --- /dev/null +++ b/actix_http/uri/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Authority","Builder","InvalidUri","InvalidUriParts","Parts","PathAndQuery","Port","Scheme","Uri"]}; \ No newline at end of file diff --git a/actix_http/uri/struct.Authority.html b/actix_http/uri/struct.Authority.html new file mode 100644 index 000000000..d0a4a94e9 --- /dev/null +++ b/actix_http/uri/struct.Authority.html @@ -0,0 +1,138 @@ +Authority in actix_http::uri - Rust

Struct actix_http::uri::Authority

source ·
pub struct Authority { /* private fields */ }
Expand description

Represents the authority component of a URI.

+

Implementations§

source§

impl Authority

source

pub fn from_static(src: &'static str) -> Authority

Attempt to convert an Authority from a static string.

+

This function will not perform any copying, and the string will be +checked if it is empty or contains an invalid character.

+
§Panics
+

This function panics if the argument contains invalid characters or +is empty.

+
§Examples
+
let authority = Authority::from_static("example.com");
+assert_eq!(authority.host(), "example.com");
+
source

pub fn from_maybe_shared<T>(src: T) -> Result<Authority, InvalidUri>
where + T: AsRef<[u8]> + 'static,

Attempt to convert a Bytes buffer to a Authority.

+

This will try to prevent a copy if the type passed is the type used +internally, and will copy the data if it is not.

+
source

pub fn host(&self) -> &str

Get the host of this Authority.

+

The host subcomponent of authority is identified by an IP literal +encapsulated within square brackets, an IPv4 address in dotted- decimal +form, or a registered name. The host subcomponent is case-insensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                        |---------|
+                             |
+                            host
+
§Examples
+
let authority: Authority = "example.org:80".parse().unwrap();
+
+assert_eq!(authority.host(), "example.org");
+
source

pub fn port(&self) -> Option<Port<&str>>

Get the port part of this Authority.

+

The port subcomponent of authority is designated by an optional port +number following the host and delimited from it by a single colon (“:”) +character. It can be turned into a decimal port number with the as_u16 +method or as a str with the as_str method.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                    |-|
+                                     |
+                                    port
+
§Examples
+

Authority with port

+ +
let authority: Authority = "example.org:80".parse().unwrap();
+
+let port = authority.port().unwrap();
+assert_eq!(port.as_u16(), 80);
+assert_eq!(port.as_str(), "80");
+

Authority without port

+ +
let authority: Authority = "example.org".parse().unwrap();
+
+assert!(authority.port().is_none());
+
source

pub fn port_u16(&self) -> Option<u16>

Get the port of this Authority as a u16.

+
§Example
+
let authority: Authority = "example.org:80".parse().unwrap();
+
+assert_eq!(authority.port_u16(), Some(80));
+
source

pub fn as_str(&self) -> &str

Return a str representation of the authority

+

Trait Implementations§

source§

impl AsRef<str> for Authority

source§

fn as_ref(&self) -> &str

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for Authority

source§

fn clone(&self) -> Authority

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Authority

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for Authority

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl From<Authority> for Uri

Convert an Authority into a Uri.

+
source§

fn from(authority: Authority) -> Uri

Converts to this type from the input type.
source§

impl FromStr for Authority

§

type Err = InvalidUri

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Authority, InvalidUri>

Parses a string s to return a value of this type. Read more
source§

impl Hash for Authority

Case-insensitive hashing

+

§Examples

+

+let a: Authority = "HELLO.com".parse().unwrap();
+let b: Authority = "hello.coM".parse().unwrap();
+
+let mut s = DefaultHasher::new();
+a.hash(&mut s);
+let a = s.finish();
+
+let mut s = DefaultHasher::new();
+b.hash(&mut s);
+let b = s.finish();
+
+assert_eq!(a, b);
+
source§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<'a> PartialEq<&'a str> for Authority

source§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<Authority> for &'a str

source§

fn eq(&self, other: &Authority) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Authority> for str

source§

fn eq(&self, other: &Authority) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<String> for Authority

source§

fn eq(&self, other: &String) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for Authority

Case-insensitive equality

+

§Examples

+
let authority: Authority = "HELLO.com".parse().unwrap();
+assert_eq!(authority, "hello.coM");
+assert_eq!("hello.com", authority);
+
source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Authority

source§

fn eq(&self, other: &Authority) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialOrd<&'a str> for Authority

source§

fn partial_cmp(&self, other: &&'a str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> PartialOrd<Authority> for &'a str

source§

fn partial_cmp(&self, other: &Authority) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<Authority> for str

source§

fn partial_cmp(&self, other: &Authority) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<String> for Authority

source§

fn partial_cmp(&self, other: &String) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<str> for Authority

source§

fn partial_cmp(&self, other: &str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for Authority

Case-insensitive ordering

+

§Examples

+
let authority: Authority = "DEF.com".parse().unwrap();
+assert!(authority < "ghi.com");
+assert!(authority > "abc.com");
+
source§

fn partial_cmp(&self, other: &Authority) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> TryFrom<&'a [u8]> for Authority

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a [u8] +) -> Result<Authority, <Authority as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for Authority

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a str +) -> Result<Authority, <Authority as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for Authority

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + t: String +) -> Result<Authority, <Authority as TryFrom<String>>::Error>

Performs the conversion.
source§

impl TryFrom<Vec<u8>> for Authority

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + vec: Vec<u8> +) -> Result<Authority, <Authority as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
source§

impl Eq for Authority

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/uri/struct.Builder.html b/actix_http/uri/struct.Builder.html new file mode 100644 index 000000000..dfbfd6305 --- /dev/null +++ b/actix_http/uri/struct.Builder.html @@ -0,0 +1,70 @@ +Builder in actix_http::uri - Rust

Struct actix_http::uri::Builder

source ·
pub struct Builder { /* private fields */ }
Expand description

A builder for Uris.

+

This type can be used to construct an instance of Uri +through a builder pattern.

+

Implementations§

source§

impl Builder

source

pub fn new() -> Builder

Creates a new default instance of Builder to construct a Uri.

+
§Examples
+

+let uri = uri::Builder::new()
+    .scheme("https")
+    .authority("hyper.rs")
+    .path_and_query("/")
+    .build()
+    .unwrap();
+
source

pub fn scheme<T>(self, scheme: T) -> Builder
where + Scheme: TryFrom<T>, + <Scheme as TryFrom<T>>::Error: Into<Error>,

Set the Scheme for this URI.

+
§Examples
+

+let mut builder = uri::Builder::new();
+builder.scheme("https");
+
source

pub fn authority<T>(self, auth: T) -> Builder
where + Authority: TryFrom<T>, + <Authority as TryFrom<T>>::Error: Into<Error>,

Set the Authority for this URI.

+
§Examples
+

+let uri = uri::Builder::new()
+    .authority("tokio.rs")
+    .build()
+    .unwrap();
+
source

pub fn path_and_query<T>(self, p_and_q: T) -> Builder

Set the PathAndQuery for this URI.

+
§Examples
+

+let uri = uri::Builder::new()
+    .path_and_query("/hello?foo=bar")
+    .build()
+    .unwrap();
+
source

pub fn build(self) -> Result<Uri, Error>

Consumes this builder, and tries to construct a valid Uri from +the configured pieces.

+
§Errors
+

This function may return an error if any previously configured argument +failed to parse or get converted to the internal representation. For +example if an invalid scheme was specified via scheme("!@#%/^") +the error will be returned when this function is called rather than +when scheme was called.

+

Additionally, the various forms of URI require certain combinations of +parts to be set to be valid. If the parts don’t fit into any of the +valid forms of URI, a new error is returned.

+
§Examples
+

+let uri = Uri::builder()
+    .build()
+    .unwrap();
+

Trait Implementations§

source§

impl Debug for Builder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Builder

source§

fn default() -> Builder

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/uri/struct.InvalidUri.html b/actix_http/uri/struct.InvalidUri.html new file mode 100644 index 000000000..73acfdd22 --- /dev/null +++ b/actix_http/uri/struct.InvalidUri.html @@ -0,0 +1,19 @@ +InvalidUri in actix_http::uri - Rust

Struct actix_http::uri::InvalidUri

source ·
pub struct InvalidUri(/* private fields */);
Expand description

An error resulting from a failed attempt to construct a URI.

+

Trait Implementations§

source§

impl Debug for InvalidUri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for InvalidUri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for InvalidUri

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<ErrorKind> for InvalidUri

source§

fn from(src: ErrorKind) -> InvalidUri

Converts to this type from the input type.
source§

impl From<InvalidUri> for Error

source§

fn from(err: InvalidUri) -> Error

Converts to this type from the input type.
source§

impl From<InvalidUri> for ParseError

source§

fn from(err: InvalidUri) -> ParseError

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/uri/struct.InvalidUriParts.html b/actix_http/uri/struct.InvalidUriParts.html new file mode 100644 index 000000000..9bb15f6fa --- /dev/null +++ b/actix_http/uri/struct.InvalidUriParts.html @@ -0,0 +1,19 @@ +InvalidUriParts in actix_http::uri - Rust

Struct actix_http::uri::InvalidUriParts

source ·
pub struct InvalidUriParts(/* private fields */);
Expand description

An error resulting from a failed attempt to construct a URI.

+

Trait Implementations§

source§

impl Debug for InvalidUriParts

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for InvalidUriParts

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for InvalidUriParts

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<ErrorKind> for InvalidUriParts

source§

fn from(src: ErrorKind) -> InvalidUriParts

Converts to this type from the input type.
source§

impl From<InvalidUriParts> for Error

source§

fn from(err: InvalidUriParts) -> Error

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/uri/struct.Parts.html b/actix_http/uri/struct.Parts.html new file mode 100644 index 000000000..20217f5fe --- /dev/null +++ b/actix_http/uri/struct.Parts.html @@ -0,0 +1,28 @@ +Parts in actix_http::uri - Rust

Struct actix_http::uri::Parts

source ·
pub struct Parts {
+    pub scheme: Option<Scheme>,
+    pub authority: Option<Authority>,
+    pub path_and_query: Option<PathAndQuery>,
+    /* private fields */
+}
Expand description

The various parts of a URI.

+

This struct is used to provide to and retrieve from a URI.

+

Fields§

§scheme: Option<Scheme>

The scheme component of a URI

+
§authority: Option<Authority>

The authority component of a URI

+
§path_and_query: Option<PathAndQuery>

The origin-form component of a URI

+

Trait Implementations§

source§

impl Debug for Parts

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Parts

source§

fn default() -> Parts

Returns the “default value” for a type. Read more
source§

impl From<Uri> for Parts

Convert a Uri into Parts

+
source§

fn from(src: Uri) -> Parts

Converts to this type from the input type.
source§

impl TryFrom<Parts> for Uri

§

type Error = InvalidUriParts

The type returned in the event of a conversion error.
source§

fn try_from(src: Parts) -> Result<Uri, <Uri as TryFrom<Parts>>::Error>

Performs the conversion.

Auto Trait Implementations§

§

impl !Freeze for Parts

§

impl RefUnwindSafe for Parts

§

impl Send for Parts

§

impl Sync for Parts

§

impl Unpin for Parts

§

impl UnwindSafe for Parts

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/uri/struct.PathAndQuery.html b/actix_http/uri/struct.PathAndQuery.html new file mode 100644 index 000000000..adf727099 --- /dev/null +++ b/actix_http/uri/struct.PathAndQuery.html @@ -0,0 +1,122 @@ +PathAndQuery in actix_http::uri - Rust

Struct actix_http::uri::PathAndQuery

source ·
pub struct PathAndQuery { /* private fields */ }
Expand description

Represents the path component of a URI

+

Implementations§

source§

impl PathAndQuery

source

pub fn from_static(src: &'static str) -> PathAndQuery

Convert a PathAndQuery from a static string.

+

This function will not perform any copying, however the string is +checked to ensure that it is valid.

+
§Panics
+

This function panics if the argument is an invalid path and query.

+
§Examples
+
let v = PathAndQuery::from_static("/hello?world");
+
+assert_eq!(v.path(), "/hello");
+assert_eq!(v.query(), Some("world"));
+
source

pub fn from_maybe_shared<T>(src: T) -> Result<PathAndQuery, InvalidUri>
where + T: AsRef<[u8]> + 'static,

Attempt to convert a Bytes buffer to a PathAndQuery.

+

This will try to prevent a copy if the type passed is the type used +internally, and will copy the data if it is not.

+
source

pub fn path(&self) -> &str

Returns the path component

+

The path component is case sensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                       |--------|
+                                            |
+                                          path
+
+

If the URI is * then the path component is equal to *.

+
§Examples
+

+let path_and_query: PathAndQuery = "/hello/world".parse().unwrap();
+
+assert_eq!(path_and_query.path(), "/hello/world");
+
source

pub fn query(&self) -> Option<&str>

Returns the query string component

+

The query component contains non-hierarchical data that, along with data +in the path component, serves to identify a resource within the scope of +the URI’s scheme and naming authority (if any). The query component is +indicated by the first question mark (“?”) character and terminated by a +number sign (“#”) character or by the end of the URI.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                                  |-------------------|
+                                                            |
+                                                          query
+
§Examples
+

With a query string component

+ +
let path_and_query: PathAndQuery = "/hello/world?key=value&foo=bar".parse().unwrap();
+
+assert_eq!(path_and_query.query(), Some("key=value&foo=bar"));
+

Without a query string component

+ +
let path_and_query: PathAndQuery = "/hello/world".parse().unwrap();
+
+assert!(path_and_query.query().is_none());
+
source

pub fn as_str(&self) -> &str

Returns the path and query as a string component.

+
§Examples
+

With a query string component

+ +
let path_and_query: PathAndQuery = "/hello/world?key=value&foo=bar".parse().unwrap();
+
+assert_eq!(path_and_query.as_str(), "/hello/world?key=value&foo=bar");
+

Without a query string component

+ +
let path_and_query: PathAndQuery = "/hello/world".parse().unwrap();
+
+assert_eq!(path_and_query.as_str(), "/hello/world");
+

Trait Implementations§

source§

impl Clone for PathAndQuery

source§

fn clone(&self) -> PathAndQuery

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for PathAndQuery

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for PathAndQuery

source§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl From<PathAndQuery> for Uri

Convert a PathAndQuery into a Uri.

+
source§

fn from(path_and_query: PathAndQuery) -> Uri

Converts to this type from the input type.
source§

impl FromStr for PathAndQuery

§

type Err = InvalidUri

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<PathAndQuery, InvalidUri>

Parses a string s to return a value of this type. Read more
source§

impl Hash for PathAndQuery

source§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<'a> PartialEq<&'a str> for PathAndQuery

source§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<PathAndQuery> for &'a str

source§

fn eq(&self, other: &PathAndQuery) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<PathAndQuery> for str

source§

fn eq(&self, other: &PathAndQuery) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<String> for PathAndQuery

source§

fn eq(&self, other: &String) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for PathAndQuery

source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for PathAndQuery

source§

fn eq(&self, other: &PathAndQuery) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialOrd<&'a str> for PathAndQuery

source§

fn partial_cmp(&self, other: &&'a str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> PartialOrd<PathAndQuery> for &'a str

source§

fn partial_cmp(&self, other: &PathAndQuery) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<PathAndQuery> for str

source§

fn partial_cmp(&self, other: &PathAndQuery) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<String> for PathAndQuery

source§

fn partial_cmp(&self, other: &String) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<str> for PathAndQuery

source§

fn partial_cmp(&self, other: &str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for PathAndQuery

source§

fn partial_cmp(&self, other: &PathAndQuery) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> TryFrom<&'a [u8]> for PathAndQuery

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a [u8] +) -> Result<PathAndQuery, <PathAndQuery as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl TryFrom<&String> for PathAndQuery

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: &String +) -> Result<PathAndQuery, <PathAndQuery as TryFrom<&String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for PathAndQuery

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a str +) -> Result<PathAndQuery, <PathAndQuery as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for PathAndQuery

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: String +) -> Result<PathAndQuery, <PathAndQuery as TryFrom<String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<Vec<u8>> for PathAndQuery

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + vec: Vec<u8> +) -> Result<PathAndQuery, <PathAndQuery as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
source§

impl Eq for PathAndQuery

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/uri/struct.Port.html b/actix_http/uri/struct.Port.html new file mode 100644 index 000000000..b14e906fb --- /dev/null +++ b/actix_http/uri/struct.Port.html @@ -0,0 +1,48 @@ +Port in actix_http::uri - Rust

Struct actix_http::uri::Port

source ·
pub struct Port<T> { /* private fields */ }
Expand description

The port component of a URI.

+

Implementations§

source§

impl<T> Port<T>

source

pub fn as_u16(&self) -> u16

Returns the port number as a u16.

+
§Examples
+

Port as u16.

+ +
let authority: Authority = "example.org:80".parse().unwrap();
+
+let port = authority.port().unwrap();
+assert_eq!(port.as_u16(), 80);
+
source§

impl<T> Port<T>
where + T: AsRef<str>,

source

pub fn as_str(&self) -> &str

Returns the port number as a str.

+
§Examples
+

Port as str.

+ +
let authority: Authority = "example.org:80".parse().unwrap();
+
+let port = authority.port().unwrap();
+assert_eq!(port.as_str(), "80");
+

Trait Implementations§

source§

impl<T> AsRef<str> for Port<T>
where + T: AsRef<str>,

source§

fn as_ref(&self) -> &str

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl<T> Debug for Port<T>
where + T: Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<T> Display for Port<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<T, U> PartialEq<Port<U>> for Port<T>

source§

fn eq(&self, other: &Port<U>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<T> PartialEq<u16> for Port<T>

source§

fn eq(&self, other: &u16) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

§

impl<T> Freeze for Port<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for Port<T>
where + T: RefUnwindSafe,

§

impl<T> Send for Port<T>
where + T: Send,

§

impl<T> Sync for Port<T>
where + T: Sync,

§

impl<T> Unpin for Port<T>
where + T: Unpin,

§

impl<T> UnwindSafe for Port<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/uri/struct.Scheme.html b/actix_http/uri/struct.Scheme.html new file mode 100644 index 000000000..189498d4f --- /dev/null +++ b/actix_http/uri/struct.Scheme.html @@ -0,0 +1,45 @@ +Scheme in actix_http::uri - Rust

Struct actix_http::uri::Scheme

source ·
pub struct Scheme { /* private fields */ }
Expand description

Represents the scheme component of a URI

+

Implementations§

source§

impl Scheme

source

pub const HTTP: Scheme = _

HTTP protocol scheme

+
source

pub const HTTPS: Scheme = _

HTTP protocol over TLS.

+
source

pub fn as_str(&self) -> &str

Return a str representation of the scheme

+
§Examples
+
let scheme: Scheme = "http".parse().unwrap();
+assert_eq!(scheme.as_str(), "http");
+

Trait Implementations§

source§

impl AsRef<str> for Scheme

source§

fn as_ref(&self) -> &str

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for Scheme

source§

fn clone(&self) -> Scheme

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Scheme

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for Scheme

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl FromStr for Scheme

§

type Err = InvalidUri

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Scheme, <Scheme as FromStr>::Err>

Parses a string s to return a value of this type. Read more
source§

impl Hash for Scheme

Case-insensitive hashing

+
source§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq<Scheme> for str

Case-insensitive equality

+
source§

fn eq(&self, other: &Scheme) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for Scheme

Case-insensitive equality

+

§Examples

+
let scheme: Scheme = "HTTP".parse().unwrap();
+assert_eq!(scheme, *"http");
+
source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Scheme

source§

fn eq(&self, other: &Scheme) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> TryFrom<&'a [u8]> for Scheme

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(s: &'a [u8]) -> Result<Scheme, <Scheme as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for Scheme

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(s: &'a str) -> Result<Scheme, <Scheme as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl Eq for Scheme

Auto Trait Implementations§

§

impl Freeze for Scheme

§

impl RefUnwindSafe for Scheme

§

impl Send for Scheme

§

impl Sync for Scheme

§

impl Unpin for Scheme

§

impl UnwindSafe for Scheme

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/uri/struct.Uri.html b/actix_http/uri/struct.Uri.html new file mode 100644 index 000000000..a547a29ee --- /dev/null +++ b/actix_http/uri/struct.Uri.html @@ -0,0 +1,284 @@ +Uri in actix_http::uri - Rust

Struct actix_http::uri::Uri

source ·
pub struct Uri { /* private fields */ }
Expand description

The URI component of a request.

+

For HTTP 1, this is included as part of the request line. From Section 5.3, +Request Target:

+
+

Once an inbound connection is obtained, the client sends an HTTP +request message (Section 3) with a request-target derived from the +target URI. There are four distinct formats for the request-target, +depending on both the method being requested and whether the request +is to a proxy.

+
request-target = origin-form
+               / absolute-form
+               / authority-form
+               / asterisk-form
+
+

The URI is structured as follows:

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+|-|   |-------------------------------||--------| |-------------------| |-----|
+ |                  |                       |               |              |
+scheme          authority                 path            query         fragment
+
+

For HTTP 2.0, the URI is encoded using pseudoheaders.

+

§Examples

+
use http::Uri;
+
+let uri = "/foo/bar?baz".parse::<Uri>().unwrap();
+assert_eq!(uri.path(), "/foo/bar");
+assert_eq!(uri.query(), Some("baz"));
+assert_eq!(uri.host(), None);
+
+let uri = "https://www.rust-lang.org/install.html".parse::<Uri>().unwrap();
+assert_eq!(uri.scheme_str(), Some("https"));
+assert_eq!(uri.host(), Some("www.rust-lang.org"));
+assert_eq!(uri.path(), "/install.html");
+

Implementations§

source§

impl Uri

source

pub fn builder() -> Builder

Creates a new builder-style object to manufacture a Uri.

+

This method returns an instance of Builder which can be usd to +create a Uri.

+
§Examples
+
use http::Uri;
+
+let uri = Uri::builder()
+    .scheme("https")
+    .authority("hyper.rs")
+    .path_and_query("/")
+    .build()
+    .unwrap();
+
source

pub fn from_parts(src: Parts) -> Result<Uri, InvalidUriParts>

Attempt to convert a Parts into a Uri.

+
§Examples
+

Relative URI

+ +
let mut parts = Parts::default();
+parts.path_and_query = Some("/foo".parse().unwrap());
+
+let uri = Uri::from_parts(parts).unwrap();
+
+assert_eq!(uri.path(), "/foo");
+
+assert!(uri.scheme().is_none());
+assert!(uri.authority().is_none());
+

Absolute URI

+ +
let mut parts = Parts::default();
+parts.scheme = Some("http".parse().unwrap());
+parts.authority = Some("foo.com".parse().unwrap());
+parts.path_and_query = Some("/foo".parse().unwrap());
+
+let uri = Uri::from_parts(parts).unwrap();
+
+assert_eq!(uri.scheme().unwrap().as_str(), "http");
+assert_eq!(uri.authority().unwrap(), "foo.com");
+assert_eq!(uri.path(), "/foo");
+
source

pub fn from_maybe_shared<T>(src: T) -> Result<Uri, InvalidUri>
where + T: AsRef<[u8]> + 'static,

Attempt to convert a Bytes buffer to a Uri.

+

This will try to prevent a copy if the type passed is the type used +internally, and will copy the data if it is not.

+
source

pub fn from_static(src: &'static str) -> Uri

Convert a Uri from a static string.

+

This function will not perform any copying, however the string is +checked to ensure that it is valid.

+
§Panics
+

This function panics if the argument is an invalid URI.

+
§Examples
+
let uri = Uri::from_static("http://example.com/foo");
+
+assert_eq!(uri.host().unwrap(), "example.com");
+assert_eq!(uri.path(), "/foo");
+
source

pub fn into_parts(self) -> Parts

Convert a Uri into Parts.

+
§Note
+

This is just an inherent method providing the same functionality as +let parts: Parts = uri.into()

+
§Examples
+
let uri: Uri = "/foo".parse().unwrap();
+
+let parts = uri.into_parts();
+
+assert_eq!(parts.path_and_query.unwrap(), "/foo");
+
+assert!(parts.scheme.is_none());
+assert!(parts.authority.is_none());
+
source

pub fn path_and_query(&self) -> Option<&PathAndQuery>

Returns the path & query components of the Uri

+
source

pub fn path(&self) -> &str

Get the path of this Uri.

+

Both relative and absolute URIs contain a path component, though it +might be the empty string. The path component is case sensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                       |--------|
+                                            |
+                                          path
+
+

If the URI is * then the path component is equal to *.

+
§Examples
+

A relative URI

+ +

+let uri: Uri = "/hello/world".parse().unwrap();
+
+assert_eq!(uri.path(), "/hello/world");
+

An absolute URI

+ +
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.path(), "/hello/world");
+
source

pub fn scheme(&self) -> Option<&Scheme>

Get the scheme of this Uri.

+

The URI scheme refers to a specification for assigning identifiers +within that scheme. Only absolute URIs contain a scheme component, but +not all absolute URIs will contain a scheme component. Although scheme +names are case-insensitive, the canonical form is lowercase.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+|-|
+ |
+scheme
+
§Examples
+

Absolute URI

+ +
use http::uri::{Scheme, Uri};
+
+let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.scheme(), Some(&Scheme::HTTP));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.scheme().is_none());
+
source

pub fn scheme_str(&self) -> Option<&str>

Get the scheme of this Uri as a &str.

+
§Example
+
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.scheme_str(), Some("http"));
+
source

pub fn authority(&self) -> Option<&Authority>

Get the authority of this Uri.

+

The authority is a hierarchical element for naming authority such that +the remainder of the URI is delegated to that authority. For HTTP, the +authority consists of the host and port. The host portion of the +authority is case-insensitive.

+

The authority also includes a username:password component, however +the use of this is deprecated and should be avoided.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+      |-------------------------------|
+                    |
+                authority
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.authority().map(|a| a.as_str()), Some("example.org:80"));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.authority().is_none());
+
source

pub fn host(&self) -> Option<&str>

Get the host of this Uri.

+

The host subcomponent of authority is identified by an IP literal +encapsulated within square brackets, an IPv4 address in dotted- decimal +form, or a registered name. The host subcomponent is case-insensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                        |---------|
+                             |
+                            host
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.host(), Some("example.org"));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.host().is_none());
+
source

pub fn port(&self) -> Option<Port<&str>>

Get the port part of this Uri.

+

The port subcomponent of authority is designated by an optional port +number following the host and delimited from it by a single colon (“:”) +character. It can be turned into a decimal port number with the as_u16 +method or as a str with the as_str method.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                    |-|
+                                     |
+                                    port
+
§Examples
+

Absolute URI with port

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+let port = uri.port().unwrap();
+assert_eq!(port.as_u16(), 80);
+

Absolute URI without port

+ +
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert!(uri.port().is_none());
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.port().is_none());
+
source

pub fn port_u16(&self) -> Option<u16>

Get the port of this Uri as a u16.

+
§Example
+
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.port_u16(), Some(80));
+
source

pub fn query(&self) -> Option<&str>

Get the query string of this Uri, starting after the ?.

+

The query component contains non-hierarchical data that, along with data +in the path component, serves to identify a resource within the scope of +the URI’s scheme and naming authority (if any). The query component is +indicated by the first question mark (“?”) character and terminated by a +number sign (“#”) character or by the end of the URI.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                                  |-------------------|
+                                                            |
+                                                          query
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org/hello/world?key=value".parse().unwrap();
+
+assert_eq!(uri.query(), Some("key=value"));
+

Relative URI with a query string component

+ +
let uri: Uri = "/hello/world?key=value&foo=bar".parse().unwrap();
+
+assert_eq!(uri.query(), Some("key=value&foo=bar"));
+

Relative URI without a query string component

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.query().is_none());
+

Trait Implementations§

source§

impl Clone for Uri

source§

fn clone(&self) -> Uri

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Uri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Uri

Returns a Uri representing /

+
source§

fn default() -> Uri

Returns the “default value” for a type. Read more
source§

impl Display for Uri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl From<Authority> for Uri

Convert an Authority into a Uri.

+
source§

fn from(authority: Authority) -> Uri

Converts to this type from the input type.
source§

impl From<PathAndQuery> for Uri

Convert a PathAndQuery into a Uri.

+
source§

fn from(path_and_query: PathAndQuery) -> Uri

Converts to this type from the input type.
source§

impl From<Uri> for Parts

Convert a Uri into Parts

+
source§

fn from(src: Uri) -> Parts

Converts to this type from the input type.
source§

impl FromStr for Uri

§

type Err = InvalidUri

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Uri, InvalidUri>

Parses a string s to return a value of this type. Read more
source§

impl Hash for Uri

source§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl Host for Uri

§

fn hostname(&self) -> &str

Extract hostname.
§

fn port(&self) -> Option<u16>

Extract optional port.
source§

impl<'a> PartialEq<&'a str> for Uri

source§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<Uri> for &'a str

source§

fn eq(&self, uri: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Uri> for str

source§

fn eq(&self, uri: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for Uri

source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Uri

source§

fn eq(&self, other: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> TryFrom<&'a [u8]> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a [u8]) -> Result<Uri, <Uri as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a String> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a String) -> Result<Uri, <Uri as TryFrom<&'a String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a Uri> for Uri

§

type Error = Error

The type returned in the event of a conversion error.
source§

fn try_from(src: &'a Uri) -> Result<Uri, <Uri as TryFrom<&'a Uri>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a str) -> Result<Uri, <Uri as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<Parts> for Uri

§

type Error = InvalidUriParts

The type returned in the event of a conversion error.
source§

fn try_from(src: Parts) -> Result<Uri, <Uri as TryFrom<Parts>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: String) -> Result<Uri, <Uri as TryFrom<String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<Vec<u8>> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(vec: Vec<u8>) -> Result<Uri, <Uri as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
source§

impl Eq for Uri

Auto Trait Implementations§

§

impl !Freeze for Uri

§

impl RefUnwindSafe for Uri

§

impl Send for Uri

§

impl Sync for Uri

§

impl Unpin for Uri

§

impl UnwindSafe for Uri

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/ws/codec/enum.Frame.html b/actix_http/ws/codec/enum.Frame.html new file mode 100644 index 000000000..33a83daae --- /dev/null +++ b/actix_http/ws/codec/enum.Frame.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/ws/enum.Frame.html...

+ + + \ No newline at end of file diff --git a/actix_http/ws/codec/enum.Item.html b/actix_http/ws/codec/enum.Item.html new file mode 100644 index 000000000..a2fdc768b --- /dev/null +++ b/actix_http/ws/codec/enum.Item.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/ws/enum.Item.html...

+ + + \ No newline at end of file diff --git a/actix_http/ws/codec/enum.Message.html b/actix_http/ws/codec/enum.Message.html new file mode 100644 index 000000000..7dc4571ed --- /dev/null +++ b/actix_http/ws/codec/enum.Message.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/ws/enum.Message.html...

+ + + \ No newline at end of file diff --git a/actix_http/ws/codec/struct.Codec.html b/actix_http/ws/codec/struct.Codec.html new file mode 100644 index 000000000..90481b7e5 --- /dev/null +++ b/actix_http/ws/codec/struct.Codec.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/ws/struct.Codec.html...

+ + + \ No newline at end of file diff --git a/actix_http/ws/dispatcher/struct.Dispatcher.html b/actix_http/ws/dispatcher/struct.Dispatcher.html new file mode 100644 index 000000000..06b6d1879 --- /dev/null +++ b/actix_http/ws/dispatcher/struct.Dispatcher.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/ws/struct.Dispatcher.html...

+ + + \ No newline at end of file diff --git a/actix_http/ws/enum.CloseCode.html b/actix_http/ws/enum.CloseCode.html new file mode 100644 index 000000000..482908f3a --- /dev/null +++ b/actix_http/ws/enum.CloseCode.html @@ -0,0 +1,72 @@ +CloseCode in actix_http::ws - Rust

Enum actix_http::ws::CloseCode

source ·
pub enum CloseCode {
+    Normal,
+    Away,
+    Protocol,
+    Unsupported,
+    Abnormal,
+    Invalid,
+    Policy,
+    Size,
+    Extension,
+    Error,
+    Restart,
+    Again,
+    // some variants omitted
+}
Available on crate feature ws only.
Expand description

Status code used to indicate why an endpoint is closing the WebSocket connection.

+

Variants§

§

Normal

Indicates a normal closure, meaning that the purpose for which the connection was +established has been fulfilled.

+
§

Away

Indicates that an endpoint is “going away”, such as a server going down or a browser having +navigated away from a page.

+
§

Protocol

Indicates that an endpoint is terminating the connection due to a protocol error.

+
§

Unsupported

Indicates that an endpoint is terminating the connection because it has received a type of +data it cannot accept (e.g., an endpoint that understands only text data MAY send this if it +receives a binary message).

+
§

Abnormal

Indicates an abnormal closure. If the abnormal closure was due to an error, this close code +will not be used. Instead, the on_error method of the handler will be called with +the error. However, if the connection is simply dropped, without an error, this close code +will be sent to the handler.

+
§

Invalid

Indicates that an endpoint is terminating the connection because it has received data within +a message that was not consistent with the type of the message (e.g., non-UTF-8 [RFC 3629] +data within a text message).

+
§

Policy

Indicates that an endpoint is terminating the connection because it has received a message +that violates its policy. This is a generic status code that can be returned when there is +no other more suitable status code (e.g., Unsupported or Size) or if there is a need to hide +specific details about the policy.

+
§

Size

Indicates that an endpoint is terminating the connection because it has received a message +that is too big for it to process.

+
§

Extension

Indicates that an endpoint (client) is terminating the connection because it has expected +the server to negotiate one or more extension, but the server didn’t return them in the +response message of the WebSocket handshake. The list of extensions that are needed should +be given as the reason for closing. Note that this status code is not used by the server, +because it can fail the WebSocket handshake instead.

+
§

Error

Indicates that a server is terminating the connection because it encountered an unexpected +condition that prevented it from fulfilling the request.

+
§

Restart

Indicates that the server is restarting. A client may choose to reconnect, and if it does, +it should use a randomized delay of 5-30 seconds between attempts.

+
§

Again

Indicates that the server is overloaded and the client should either connect to a different +IP (when multiple targets exist), or reconnect to the same IP when a user has performed +an action.

+

Trait Implementations§

source§

impl Clone for CloseCode

source§

fn clone(&self) -> CloseCode

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for CloseCode

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl From<CloseCode> for CloseReason

source§

fn from(code: CloseCode) -> Self

Converts to this type from the input type.
source§

impl From<CloseCode> for u16

source§

fn from(code: CloseCode) -> u16

Converts to this type from the input type.
source§

impl From<u16> for CloseCode

source§

fn from(code: u16) -> CloseCode

Converts to this type from the input type.
source§

impl PartialEq for CloseCode

source§

fn eq(&self, other: &CloseCode) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for CloseCode

source§

impl Eq for CloseCode

source§

impl StructuralPartialEq for CloseCode

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/ws/enum.Frame.html b/actix_http/ws/enum.Frame.html new file mode 100644 index 000000000..7476a45cc --- /dev/null +++ b/actix_http/ws/enum.Frame.html @@ -0,0 +1,37 @@ +Frame in actix_http::ws - Rust

Enum actix_http::ws::Frame

source ·
pub enum Frame {
+    Text(Bytes),
+    Binary(Bytes),
+    Continuation(Item),
+    Ping(Bytes),
+    Pong(Bytes),
+    Close(Option<CloseReason>),
+}
Available on crate feature ws only.
Expand description

A WebSocket frame.

+

Variants§

§

Text(Bytes)

Text frame. Note that the codec does not validate UTF-8 encoding.

+
§

Binary(Bytes)

Binary frame.

+
§

Continuation(Item)

Continuation.

+
§

Ping(Bytes)

Ping message.

+
§

Pong(Bytes)

Pong message.

+
§

Close(Option<CloseReason>)

Close message with optional reason.

+

Trait Implementations§

source§

impl Debug for Frame

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq for Frame

source§

fn eq(&self, other: &Frame) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for Frame

source§

impl StructuralPartialEq for Frame

Auto Trait Implementations§

§

impl !Freeze for Frame

§

impl RefUnwindSafe for Frame

§

impl Send for Frame

§

impl Sync for Frame

§

impl Unpin for Frame

§

impl UnwindSafe for Frame

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/ws/enum.HandshakeError.html b/actix_http/ws/enum.HandshakeError.html new file mode 100644 index 000000000..760d237c9 --- /dev/null +++ b/actix_http/ws/enum.HandshakeError.html @@ -0,0 +1,39 @@ +HandshakeError in actix_http::ws - Rust

Enum actix_http::ws::HandshakeError

source ·
pub enum HandshakeError {
+    GetMethodRequired,
+    NoWebsocketUpgrade,
+    NoConnectionUpgrade,
+    NoVersionHeader,
+    UnsupportedVersion,
+    BadWebsocketKey,
+}
Available on crate feature ws only.
Expand description

WebSocket handshake errors

+

Variants§

§

GetMethodRequired

Only get method is allowed.

+
§

NoWebsocketUpgrade

Upgrade header if not set to WebSocket.

+
§

NoConnectionUpgrade

Connection header is not set to upgrade.

+
§

NoVersionHeader

WebSocket version header is not set.

+
§

UnsupportedVersion

Unsupported WebSocket version.

+
§

BadWebsocketKey

WebSocket key is not set or wrong.

+

Trait Implementations§

source§

impl Clone for HandshakeError

source§

fn clone(&self) -> HandshakeError

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for HandshakeError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for HandshakeError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for HandshakeError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<&HandshakeError> for Response<BoxBody>

source§

fn from(err: &HandshakeError) -> Self

Converts to this type from the input type.
source§

impl From<HandshakeError> for Error

source§

fn from(err: HandshakeError) -> Self

Converts to this type from the input type.
source§

impl From<HandshakeError> for Response<BoxBody>

source§

fn from(err: HandshakeError) -> Self

Converts to this type from the input type.
source§

impl PartialEq for HandshakeError

source§

fn eq(&self, other: &HandshakeError) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for HandshakeError

source§

impl Eq for HandshakeError

source§

impl StructuralPartialEq for HandshakeError

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/ws/enum.Item.html b/actix_http/ws/enum.Item.html new file mode 100644 index 000000000..d3a76fb86 --- /dev/null +++ b/actix_http/ws/enum.Item.html @@ -0,0 +1,29 @@ +Item in actix_http::ws - Rust

Enum actix_http::ws::Item

source ·
pub enum Item {
+    FirstText(Bytes),
+    FirstBinary(Bytes),
+    Continue(Bytes),
+    Last(Bytes),
+}
Available on crate feature ws only.
Expand description

A WebSocket continuation item.

+

Variants§

§

FirstText(Bytes)

§

FirstBinary(Bytes)

§

Continue(Bytes)

§

Last(Bytes)

Trait Implementations§

source§

impl Debug for Item

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq for Item

source§

fn eq(&self, other: &Item) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for Item

source§

impl StructuralPartialEq for Item

Auto Trait Implementations§

§

impl !Freeze for Item

§

impl RefUnwindSafe for Item

§

impl Send for Item

§

impl Sync for Item

§

impl Unpin for Item

§

impl UnwindSafe for Item

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/ws/enum.Message.html b/actix_http/ws/enum.Message.html new file mode 100644 index 000000000..5dfb6bc04 --- /dev/null +++ b/actix_http/ws/enum.Message.html @@ -0,0 +1,43 @@ +Message in actix_http::ws - Rust

Enum actix_http::ws::Message

source ·
pub enum Message {
+    Text(ByteString),
+    Binary(Bytes),
+    Continuation(Item),
+    Ping(Bytes),
+    Pong(Bytes),
+    Close(Option<CloseReason>),
+    Nop,
+}
Available on crate feature ws only.
Expand description

A WebSocket message.

+

Variants§

§

Text(ByteString)

Text message.

+
§

Binary(Bytes)

Binary message.

+
§

Continuation(Item)

Continuation.

+
§

Ping(Bytes)

Ping message.

+
§

Pong(Bytes)

Pong message.

+
§

Close(Option<CloseReason>)

Close message with optional reason.

+
§

Nop

No-op. Useful for low-level services.

+

Trait Implementations§

source§

impl Debug for Message

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Encoder<Message> for Codec

§

type Error = ProtocolError

The type of encoding errors. Read more
source§

fn encode( + &mut self, + item: Message, + dst: &mut BytesMut +) -> Result<(), Self::Error>

Encodes a frame into the buffer provided. Read more
source§

impl PartialEq for Message

source§

fn eq(&self, other: &Message) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for Message

source§

impl StructuralPartialEq for Message

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/ws/enum.OpCode.html b/actix_http/ws/enum.OpCode.html new file mode 100644 index 000000000..69e180857 --- /dev/null +++ b/actix_http/ws/enum.OpCode.html @@ -0,0 +1,41 @@ +OpCode in actix_http::ws - Rust

Enum actix_http::ws::OpCode

source ·
pub enum OpCode {
+    Continue,
+    Text,
+    Binary,
+    Close,
+    Ping,
+    Pong,
+    Bad,
+}
Available on crate feature ws only.
Expand description

Operation codes defined in [RFC 6455 §11.8].

+

Variants§

§

Continue

Indicates a continuation frame of a fragmented message.

+
§

Text

Indicates a text data frame.

+
§

Binary

Indicates a binary data frame.

+
§

Close

Indicates a close control frame.

+
§

Ping

Indicates a ping control frame.

+
§

Pong

Indicates a pong control frame.

+
§

Bad

Indicates an invalid opcode was received.

+

Trait Implementations§

source§

impl Clone for OpCode

source§

fn clone(&self) -> OpCode

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for OpCode

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for OpCode

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl From<OpCode> for ProtocolError

source§

fn from(original: OpCode) -> ProtocolError

Converts to this type from the input type.
source§

impl From<OpCode> for u8

source§

fn from(op: OpCode) -> u8

Converts to this type from the input type.
source§

impl From<u8> for OpCode

source§

fn from(byte: u8) -> OpCode

Converts to this type from the input type.
source§

impl PartialEq for OpCode

source§

fn eq(&self, other: &OpCode) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for OpCode

source§

impl Eq for OpCode

source§

impl StructuralPartialEq for OpCode

Auto Trait Implementations§

§

impl Freeze for OpCode

§

impl RefUnwindSafe for OpCode

§

impl Send for OpCode

§

impl Sync for OpCode

§

impl Unpin for OpCode

§

impl UnwindSafe for OpCode

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/ws/enum.ProtocolError.html b/actix_http/ws/enum.ProtocolError.html new file mode 100644 index 000000000..b9f9cdea4 --- /dev/null +++ b/actix_http/ws/enum.ProtocolError.html @@ -0,0 +1,40 @@ +ProtocolError in actix_http::ws - Rust

Enum actix_http::ws::ProtocolError

source ·
pub enum ProtocolError {
+    UnmaskedFrame,
+    MaskedFrame,
+    InvalidOpcode(u8),
+    InvalidLength(usize),
+    BadOpCode,
+    Overflow,
+    ContinuationNotStarted,
+    ContinuationStarted,
+    ContinuationFragment(OpCode),
+    Io(Error),
+}
Available on crate feature ws only.
Expand description

WebSocket protocol errors.

+

Variants§

§

UnmaskedFrame

Received an unmasked frame from client.

+
§

MaskedFrame

Received a masked frame from server.

+
§

InvalidOpcode(u8)

Encountered invalid opcode.

+
§

InvalidLength(usize)

Invalid control frame length

+
§

BadOpCode

Bad opcode.

+
§

Overflow

A payload reached size limit.

+
§

ContinuationNotStarted

Continuation has not started.

+
§

ContinuationStarted

Received new continuation but it is already started.

+
§

ContinuationFragment(OpCode)

Unknown continuation fragment.

+
§

Io(Error)

I/O error.

+

Trait Implementations§

source§

impl Debug for ProtocolError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for ProtocolError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for ProtocolError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<Error> for ProtocolError

source§

fn from(original: Error) -> ProtocolError

Converts to this type from the input type.
source§

impl From<OpCode> for ProtocolError

source§

fn from(original: OpCode) -> ProtocolError

Converts to this type from the input type.
source§

impl From<ProtocolError> for Error

source§

fn from(err: ProtocolError) -> Self

Converts to this type from the input type.
source§

impl From<u8> for ProtocolError

source§

fn from(original: u8) -> ProtocolError

Converts to this type from the input type.
source§

impl From<usize> for ProtocolError

source§

fn from(original: usize) -> ProtocolError

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/ws/fn.handshake.html b/actix_http/ws/fn.handshake.html new file mode 100644 index 000000000..64ce2e9d5 --- /dev/null +++ b/actix_http/ws/fn.handshake.html @@ -0,0 +1,2 @@ +handshake in actix_http::ws - Rust

Function actix_http::ws::handshake

source ·
pub fn handshake(req: &RequestHead) -> Result<ResponseBuilder, HandshakeError>
Available on crate feature ws only.
Expand description

Verify WebSocket handshake request and create handshake response.

+
\ No newline at end of file diff --git a/actix_http/ws/fn.handshake_response.html b/actix_http/ws/fn.handshake_response.html new file mode 100644 index 000000000..56272a5f0 --- /dev/null +++ b/actix_http/ws/fn.handshake_response.html @@ -0,0 +1,3 @@ +handshake_response in actix_http::ws - Rust

Function actix_http::ws::handshake_response

source ·
pub fn handshake_response(req: &RequestHead) -> ResponseBuilder
Available on crate feature ws only.
Expand description

Create WebSocket handshake response.

+

This function returns handshake Response, ready to send to peer.

+
\ No newline at end of file diff --git a/actix_http/ws/fn.hash_key.html b/actix_http/ws/fn.hash_key.html new file mode 100644 index 000000000..871e24255 --- /dev/null +++ b/actix_http/ws/fn.hash_key.html @@ -0,0 +1,3 @@ +hash_key in actix_http::ws - Rust

Function actix_http::ws::hash_key

source ·
pub fn hash_key(key: &[u8]) -> [u8; 28]
Available on crate feature ws only.
Expand description

Hashes the Sec-WebSocket-Key header according to the WebSocket spec.

+

Result is a Base64 encoded byte array. base64(sha1(input)) is always 28 bytes.

+
\ No newline at end of file diff --git a/actix_http/ws/fn.verify_handshake.html b/actix_http/ws/fn.verify_handshake.html new file mode 100644 index 000000000..2ad6f66e7 --- /dev/null +++ b/actix_http/ws/fn.verify_handshake.html @@ -0,0 +1,2 @@ +verify_handshake in actix_http::ws - Rust

Function actix_http::ws::verify_handshake

source ·
pub fn verify_handshake(req: &RequestHead) -> Result<(), HandshakeError>
Available on crate feature ws only.
Expand description

Verify WebSocket handshake request.

+
\ No newline at end of file diff --git a/actix_http/ws/frame/struct.Parser.html b/actix_http/ws/frame/struct.Parser.html new file mode 100644 index 000000000..816816357 --- /dev/null +++ b/actix_http/ws/frame/struct.Parser.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/ws/struct.Parser.html...

+ + + \ No newline at end of file diff --git a/actix_http/ws/index.html b/actix_http/ws/index.html new file mode 100644 index 000000000..a6b50dace --- /dev/null +++ b/actix_http/ws/index.html @@ -0,0 +1,4 @@ +actix_http::ws - Rust

Module actix_http::ws

source ·
Available on crate feature ws only.
Expand description

WebSocket protocol implementation.

+

To setup a WebSocket, first perform the WebSocket handshake then on success convert Payload into a +WsStream stream and then use WsWriter to communicate with the peer.

+

Structs§

Enums§

  • Status code used to indicate why an endpoint is closing the WebSocket connection.
  • A WebSocket frame.
  • WebSocket handshake errors
  • A WebSocket continuation item.
  • A WebSocket message.
  • Operation codes defined in [RFC 6455 §11.8].
  • WebSocket protocol errors.

Functions§

  • Verify WebSocket handshake request and create handshake response.
  • Create WebSocket handshake response.
  • Hashes the Sec-WebSocket-Key header according to the WebSocket spec.
  • Verify WebSocket handshake request.
\ No newline at end of file diff --git a/actix_http/ws/proto/enum.CloseCode.html b/actix_http/ws/proto/enum.CloseCode.html new file mode 100644 index 000000000..4e941f88a --- /dev/null +++ b/actix_http/ws/proto/enum.CloseCode.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/ws/enum.CloseCode.html...

+ + + \ No newline at end of file diff --git a/actix_http/ws/proto/enum.OpCode.html b/actix_http/ws/proto/enum.OpCode.html new file mode 100644 index 000000000..6c49388fd --- /dev/null +++ b/actix_http/ws/proto/enum.OpCode.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/ws/enum.OpCode.html...

+ + + \ No newline at end of file diff --git a/actix_http/ws/proto/fn.hash_key.html b/actix_http/ws/proto/fn.hash_key.html new file mode 100644 index 000000000..a52e93d72 --- /dev/null +++ b/actix_http/ws/proto/fn.hash_key.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/ws/fn.hash_key.html...

+ + + \ No newline at end of file diff --git a/actix_http/ws/proto/struct.CloseReason.html b/actix_http/ws/proto/struct.CloseReason.html new file mode 100644 index 000000000..0630a1975 --- /dev/null +++ b/actix_http/ws/proto/struct.CloseReason.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_http/ws/struct.CloseReason.html...

+ + + \ No newline at end of file diff --git a/actix_http/ws/sidebar-items.js b/actix_http/ws/sidebar-items.js new file mode 100644 index 000000000..fd82c6fa9 --- /dev/null +++ b/actix_http/ws/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["CloseCode","Frame","HandshakeError","Item","Message","OpCode","ProtocolError"],"fn":["handshake","handshake_response","hash_key","verify_handshake"],"struct":["CloseReason","Codec","Dispatcher","Parser"]}; \ No newline at end of file diff --git a/actix_http/ws/struct.CloseReason.html b/actix_http/ws/struct.CloseReason.html new file mode 100644 index 000000000..7b944ccd4 --- /dev/null +++ b/actix_http/ws/struct.CloseReason.html @@ -0,0 +1,30 @@ +CloseReason in actix_http::ws - Rust

Struct actix_http::ws::CloseReason

source ·
pub struct CloseReason {
+    pub code: CloseCode,
+    pub description: Option<String>,
+}
Available on crate feature ws only.
Expand description

Reason for closing the connection

+

Fields§

§code: CloseCode

Exit code

+
§description: Option<String>

Optional description of the exit code

+

Trait Implementations§

source§

impl Clone for CloseReason

source§

fn clone(&self) -> CloseReason

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for CloseReason

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: Into<String>> From<(CloseCode, T)> for CloseReason

source§

fn from(info: (CloseCode, T)) -> Self

Converts to this type from the input type.
source§

impl From<CloseCode> for CloseReason

source§

fn from(code: CloseCode) -> Self

Converts to this type from the input type.
source§

impl PartialEq for CloseReason

source§

fn eq(&self, other: &CloseReason) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for CloseReason

source§

impl StructuralPartialEq for CloseReason

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/ws/struct.Codec.html b/actix_http/ws/struct.Codec.html new file mode 100644 index 000000000..acb4503b4 --- /dev/null +++ b/actix_http/ws/struct.Codec.html @@ -0,0 +1,38 @@ +Codec in actix_http::ws - Rust

Struct actix_http::ws::Codec

source ·
pub struct Codec { /* private fields */ }
Available on crate feature ws only.
Expand description

WebSocket protocol codec.

+

Implementations§

source§

impl Codec

source

pub const fn new() -> Codec

Create new WebSocket frames decoder.

+
source

pub fn max_size(self, size: usize) -> Self

Set max frame size.

+

By default max size is set to 64KiB.

+
source

pub fn client_mode(self) -> Self

Set decoder to client mode.

+

By default decoder works in server mode.

+

Trait Implementations§

source§

impl Clone for Codec

source§

fn clone(&self) -> Codec

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Codec

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Decoder for Codec

§

type Item = Frame

The type of decoded frames.
§

type Error = ProtocolError

The type of unrecoverable frame decoding errors. Read more
source§

fn decode( + &mut self, + src: &mut BytesMut +) -> Result<Option<Self::Item>, Self::Error>

Attempts to decode a frame from the provided buffer of bytes. Read more
§

fn decode_eof( + &mut self, + buf: &mut BytesMut +) -> Result<Option<Self::Item>, Self::Error>

A default method available to be called when there are no more bytes +available to be read from the underlying I/O. Read more
§

fn framed<T>(self, io: T) -> Framed<T, Self>
where + T: AsyncRead + AsyncWrite, + Self: Sized,

Provides a Stream and Sink interface for reading and writing to this +Io object, using Decode and Encode to read and write the raw data. Read more
source§

impl Default for Codec

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl Encoder<Message> for Codec

§

type Error = ProtocolError

The type of encoding errors. Read more
source§

fn encode( + &mut self, + item: Message, + dst: &mut BytesMut +) -> Result<(), Self::Error>

Encodes a frame into the buffer provided. Read more

Auto Trait Implementations§

§

impl Freeze for Codec

§

impl RefUnwindSafe for Codec

§

impl Send for Codec

§

impl Sync for Codec

§

impl Unpin for Codec

§

impl UnwindSafe for Codec

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/ws/struct.Dispatcher.html b/actix_http/ws/struct.Dispatcher.html new file mode 100644 index 000000000..3d84338cf --- /dev/null +++ b/actix_http/ws/struct.Dispatcher.html @@ -0,0 +1,130 @@ +Dispatcher in actix_http::ws - Rust

Struct actix_http::ws::Dispatcher

source ·
pub struct Dispatcher<S, T>
where + S: Service<Frame, Response = Message> + 'static, + T: AsyncRead + AsyncWrite,
{ /* private fields */ }
Available on crate feature ws only.

Implementations§

source§

impl<S, T> Dispatcher<S, T>
where + T: AsyncRead + AsyncWrite, + S: Service<Frame, Response = Message>, + S::Future: 'static, + S::Error: 'static,

source

pub fn new<F: IntoService<S, Frame>>(io: T, service: F) -> Self

source

pub fn with<F: IntoService<S, Frame>>( + framed: Framed<T, Codec>, + service: F +) -> Self

Trait Implementations§

source§

impl<S, T> Future for Dispatcher<S, T>
where + T: AsyncRead + AsyncWrite, + S: Service<Frame, Response = Message>, + S::Future: 'static, + S::Error: 'static,

§

type Output = Result<(), DispatcherError<<S as Service<Frame>>::Error, Codec, Message>>

The type of value produced on completion.
source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
source§

impl<'__pin, S, T> Unpin for Dispatcher<S, T>
where + __Origin<'__pin, S, T>: Unpin, + S: Service<Frame, Response = Message> + 'static, + T: AsyncRead + AsyncWrite,

Auto Trait Implementations§

§

impl<S, T> Freeze for Dispatcher<S, T>
where + S: Freeze, + T: Freeze, + <S as Service<Frame>>::Error: Freeze,

§

impl<S, T> !RefUnwindSafe for Dispatcher<S, T>

§

impl<S, T> !Send for Dispatcher<S, T>

§

impl<S, T> !Sync for Dispatcher<S, T>

§

impl<S, T> !UnwindSafe for Dispatcher<S, T>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> FutureExt for T
where + T: Future + ?Sized,

§

fn map<U, F>(self, f: F) -> Map<Self, F>
where + F: FnOnce(Self::Output) -> U, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn map_into<U>(self) -> MapInto<Self, U>
where + Self::Output: Into<U>, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnOnce(Self::Output) -> Fut, + Fut: Future, + Self: Sized,

Chain on a computation for when a future finished, passing the result of +the future to the provided closure f. Read more
§

fn left_future<B>(self) -> Either<Self, B>
where + B: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the left-hand variant +of that Either. Read more
§

fn right_future<A>(self) -> Either<A, Self>
where + A: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the right-hand variant +of that Either. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Convert this future into a single element stream. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Output: Future, + Self: Sized,

Flatten the execution of this future when the output of this +future is itself another future. Read more
§

fn flatten_stream(self) -> FlattenStream<Self>
where + Self::Output: Stream, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a future such that poll will never again be called once it has +completed. This method can be used to turn any Future into a +FusedFuture. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnOnce(&Self::Output), + Self: Sized,

Do something with the output of a future before passing it on. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the future. Read more
§

fn shared(self) -> Shared<Self>
where + Self: Sized, + Self::Output: Clone,

Available on crate feature std only.
Create a cloneable handle to this future where all handles will resolve +to the same result. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn unit_error(self) -> UnitError<Self>
where + Self: Sized,

§

fn never_error(self) -> NeverError<Self>
where + Self: Sized,

§

fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where + Self: Unpin,

A convenience for calling Future::poll on Unpin future types.
§

fn now_or_never(self) -> Option<Self::Output>
where + Self: Sized,

Evaluates and consumes the future, returning the resulting output if +the future is ready after the first call to Future::poll. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<F> IntoFuture for F
where + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

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
§

fn try_poll( + self: Pin<&mut F>, + cx: &mut Context<'_> +) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
§

impl<Fut> TryFutureExt for Fut
where + Fut: TryFuture + ?Sized,

§

fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>
where + Self::Ok: Sink<Item, Error = Self::Error>, + Self: Sized,

Available on crate feature sink only.
Flattens the execution of this future when the successful result of this +future is a [Sink]. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + F: FnOnce(Self::Ok) -> T, + Self: Sized,

Maps this future’s success value to a different value. Read more
§

fn map_ok_or_else<T, E, F>(self, e: E, f: F) -> MapOkOrElse<Self, F, E>
where + F: FnOnce(Self::Ok) -> T, + E: FnOnce(Self::Error) -> T, + Self: Sized,

Maps this future’s success value to a different value, and permits for error handling resulting in the same type. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + F: FnOnce(Self::Error) -> E, + Self: Sized,

Maps this future’s error value to a different value. Read more
§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Maps this future’s Error to a new error type +using the Into trait. Read more
§

fn ok_into<U>(self) -> OkInto<Self, U>
where + Self: Sized, + Self::Ok: Into<U>,

Maps this future’s Ok to a new type +using the Into trait.
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnOnce(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Executes another future after this one resolves successfully. The +success value is passed to a closure to create this subsequent future. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnOnce(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Executes another future if this one resolves to an error. The +error value is passed to a closure to create this subsequent future. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnOnce(&Self::Ok), + Self: Sized,

Do something with the success value of a future before passing it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnOnce(&Self::Error), + Self: Sized,

Do something with the error value of a future before passing it on. Read more
§

fn try_flatten(self) -> TryFlatten<Self, Self::Ok>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is another future. Read more
§

fn try_flatten_stream(self) -> TryFlattenStream<Self>
where + Self::Ok: TryStream<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F>
where + Self: Sized, + F: FnOnce(Self::Error) -> Self::Ok,

Unwraps this future’s output, producing a future with this future’s +Ok type as its +Output type. Read more
§

fn into_future(self) -> IntoFuture<Self>
where + Self: Sized,

Wraps a [TryFuture] into a type that implements +Future. Read more
§

fn try_poll_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Result<Self::Ok, Self::Error>>
where + Self: Unpin,

A convenience method for calling [TryFuture::try_poll] on Unpin +future types.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http/ws/struct.Parser.html b/actix_http/ws/struct.Parser.html new file mode 100644 index 000000000..9a24336aa --- /dev/null +++ b/actix_http/ws/struct.Parser.html @@ -0,0 +1,32 @@ +Parser in actix_http::ws - Rust

Struct actix_http::ws::Parser

source ·
pub struct Parser;
Available on crate feature ws only.
Expand description

A struct representing a WebSocket frame.

+

Implementations§

source§

impl Parser

source

pub fn parse( + src: &mut BytesMut, + server: bool, + max_size: usize +) -> Result<Option<(bool, OpCode, Option<BytesMut>)>, ProtocolError>

Parse the input stream into a frame.

+
source

pub fn parse_close_payload(payload: &[u8]) -> Option<CloseReason>

Parse the payload of a close frame.

+
source

pub fn write_message<B: AsRef<[u8]>>( + dst: &mut BytesMut, + pl: B, + op: OpCode, + fin: bool, + mask: bool +)

Generate binary representation

+
source

pub fn write_close(dst: &mut BytesMut, reason: Option<CloseReason>, mask: bool)

Create a new Close control frame.

+

Trait Implementations§

source§

impl Debug for Parser

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Parser

§

impl RefUnwindSafe for Parser

§

impl Send for Parser

§

impl Sync for Parser

§

impl Unpin for Parser

§

impl UnwindSafe for Parser

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_http_test/all.html b/actix_http_test/all.html new file mode 100644 index 000000000..ef8f6dbce --- /dev/null +++ b/actix_http_test/all.html @@ -0,0 +1 @@ +List of all items in this crate
\ No newline at end of file diff --git a/actix_http_test/fn.test_server.html b/actix_http_test/fn.test_server.html new file mode 100644 index 000000000..9dd252cb8 --- /dev/null +++ b/actix_http_test/fn.test_server.html @@ -0,0 +1,28 @@ +test_server in actix_http_test - Rust

Function actix_http_test::test_server

source ·
pub async fn test_server<F: ServerServiceFactory<TcpStream>>(
+    factory: F
+) -> TestServer
Expand description

Start test server.

+

TestServer is very simple test server that simplify process of writing integration tests cases +for HTTP applications.

+

§Examples

+
use actix_http::{HttpService, Response, Error, StatusCode};
+use actix_http_test::test_server;
+use actix_service::{fn_service, map_config, ServiceFactoryExt as _};
+
+#[actix_rt::test]
+async fn test_example() {
+    let srv = test_server(|| {
+        HttpService::build()
+            .h1(fn_service(|req| async move {
+                Ok::<_, Error>(Response::ok())
+            }))
+            .tcp()
+            .map_err(|_| ())
+    })
+    .await;
+
+    let req = srv.get("/");
+    let response = req.send().await.unwrap();
+
+    assert_eq!(response.status(), StatusCode::OK);
+}
+
\ No newline at end of file diff --git a/actix_http_test/fn.test_server_with_addr.html b/actix_http_test/fn.test_server_with_addr.html new file mode 100644 index 000000000..ada55b139 --- /dev/null +++ b/actix_http_test/fn.test_server_with_addr.html @@ -0,0 +1,5 @@ +test_server_with_addr in actix_http_test - Rust

Function actix_http_test::test_server_with_addr

source ·
pub async fn test_server_with_addr<F: ServerServiceFactory<TcpStream>>(
+    tcp: TcpListener,
+    factory: F
+) -> TestServer
Expand description

Start test server on an existing address binding.

+
\ No newline at end of file diff --git a/actix_http_test/fn.unused_addr.html b/actix_http_test/fn.unused_addr.html new file mode 100644 index 000000000..652a86bbe --- /dev/null +++ b/actix_http_test/fn.unused_addr.html @@ -0,0 +1,2 @@ +unused_addr in actix_http_test - Rust

Function actix_http_test::unused_addr

source ·
pub fn unused_addr() -> SocketAddr
Expand description

Get a localhost socket address with random, unused port.

+
\ No newline at end of file diff --git a/actix_http_test/index.html b/actix_http_test/index.html new file mode 100644 index 000000000..c6071e7bc --- /dev/null +++ b/actix_http_test/index.html @@ -0,0 +1,2 @@ +actix_http_test - Rust

Crate actix_http_test

source ·
Expand description

Various helpers for Actix applications to use during testing.

+

Structs§

Functions§

\ No newline at end of file diff --git a/actix_http_test/sidebar-items.js b/actix_http_test/sidebar-items.js new file mode 100644 index 000000000..a55afe367 --- /dev/null +++ b/actix_http_test/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["test_server","test_server_with_addr","unused_addr"],"struct":["TestServer"]}; \ No newline at end of file diff --git a/actix_http_test/struct.TestServer.html b/actix_http_test/struct.TestServer.html new file mode 100644 index 000000000..b49e1bd23 --- /dev/null +++ b/actix_http_test/struct.TestServer.html @@ -0,0 +1,52 @@ +TestServer in actix_http_test - Rust

Struct actix_http_test::TestServer

source ·
pub struct TestServer { /* private fields */ }
Expand description

Test server controller

+

Implementations§

source§

impl TestServer

source

pub fn addr(&self) -> SocketAddr

Construct test server url

+
source

pub fn url(&self, uri: &str) -> String

Construct test server url

+
source

pub fn surl(&self, uri: &str) -> String

Construct test HTTPS server URL.

+
source

pub fn get<S: AsRef<str>>(&self, path: S) -> ClientRequest

Create GET request

+
source

pub fn sget<S: AsRef<str>>(&self, path: S) -> ClientRequest

Create HTTPS GET request

+
source

pub fn post<S: AsRef<str>>(&self, path: S) -> ClientRequest

Create POST request

+
source

pub fn spost<S: AsRef<str>>(&self, path: S) -> ClientRequest

Create HTTPS POST request

+
source

pub fn head<S: AsRef<str>>(&self, path: S) -> ClientRequest

Create HEAD request

+
source

pub fn shead<S: AsRef<str>>(&self, path: S) -> ClientRequest

Create HTTPS HEAD request

+
source

pub fn put<S: AsRef<str>>(&self, path: S) -> ClientRequest

Create PUT request

+
source

pub fn sput<S: AsRef<str>>(&self, path: S) -> ClientRequest

Create HTTPS PUT request

+
source

pub fn patch<S: AsRef<str>>(&self, path: S) -> ClientRequest

Create PATCH request

+
source

pub fn spatch<S: AsRef<str>>(&self, path: S) -> ClientRequest

Create HTTPS PATCH request

+
source

pub fn delete<S: AsRef<str>>(&self, path: S) -> ClientRequest

Create DELETE request

+
source

pub fn sdelete<S: AsRef<str>>(&self, path: S) -> ClientRequest

Create HTTPS DELETE request

+
source

pub fn options<S: AsRef<str>>(&self, path: S) -> ClientRequest

Create OPTIONS request

+
source

pub fn soptions<S: AsRef<str>>(&self, path: S) -> ClientRequest

Create HTTPS OPTIONS request

+
source

pub fn request<S: AsRef<str>>(&self, method: Method, path: S) -> ClientRequest

Connect to test HTTP server

+
source

pub async fn load_body<S>( + &mut self, + response: ClientResponse<S> +) -> Result<Bytes, PayloadError>
where + S: Stream<Item = Result<Bytes, PayloadError>> + Unpin + 'static,

source

pub async fn ws_at( + &mut self, + path: &str +) -> Result<Framed<impl AsyncRead + AsyncWrite, Codec>, WsClientError>

Connect to WebSocket server at a given path.

+
source

pub async fn ws( + &mut self +) -> Result<Framed<impl AsyncRead + AsyncWrite, Codec>, WsClientError>

Connect to a WebSocket server.

+
source

pub fn client_headers(&mut self) -> Option<&mut HeaderMap>

Get default HeaderMap of Client.

+

Returns Some(&mut HeaderMap) when Client object is unique +(No other clone of client exists at the same time).

+
source

pub async fn stop(&mut self)

Stop HTTP server.

+

Waits for spawned Server and System to (force) shutdown.

+

Trait Implementations§

source§

impl Drop for TestServer

source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_multipart/all.html b/actix_multipart/all.html new file mode 100644 index 000000000..0c15326c3 --- /dev/null +++ b/actix_multipart/all.html @@ -0,0 +1 @@ +List of all items in this crate
\ No newline at end of file diff --git a/actix_multipart/enum.MultipartError.html b/actix_multipart/enum.MultipartError.html new file mode 100644 index 000000000..8d10c23ce --- /dev/null +++ b/actix_multipart/enum.MultipartError.html @@ -0,0 +1,52 @@ +MultipartError in actix_multipart - Rust

Enum actix_multipart::MultipartError

source ·
#[non_exhaustive]
pub enum MultipartError { +
Show 13 variants NoContentDisposition, + NoContentType, + ParseContentType, + Boundary, + Nested, + Incomplete, + Parse(ParseError), + Payload(PayloadError), + NotConsumed, + Field { + field_name: String, + source: Error, + }, + DuplicateField(String), + MissingField(String), + UnsupportedField(String), +
}
Expand description

A set of errors that can occur during parsing multipart streams.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

NoContentDisposition

Content-Disposition header is not found or is not equal to “form-data”.

+

According to RFC 7578 §4.2 a +Content-Disposition header must always be present and equal to “form-data”.

+
§

NoContentType

Content-Type header is not found

+
§

ParseContentType

Can not parse Content-Type header

+
§

Boundary

Multipart boundary is not found

+
§

Nested

Nested multipart is not supported

+
§

Incomplete

Multipart stream is incomplete

+
§

Parse(ParseError)

Error during field parsing

+
§

Payload(PayloadError)

Payload error

+
§

NotConsumed

Not consumed

+
§

Field

An error from a field handler in a form

+

Fields

§field_name: String
§source: Error
§

DuplicateField(String)

Duplicate field

+
§

MissingField(String)

Missing field

+
§

UnsupportedField(String)

Unknown field

+

Trait Implementations§

source§

impl Debug for MultipartError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for MultipartError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for MultipartError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<(String, Error)> for MultipartError

source§

fn from(original: (String, Error)) -> MultipartError

Converts to this type from the input type.
source§

impl From<ParseError> for MultipartError

source§

fn from(original: ParseError) -> MultipartError

Converts to this type from the input type.
source§

impl From<PayloadError> for MultipartError

source§

fn from(original: PayloadError) -> MultipartError

Converts to this type from the input type.
source§

impl ResponseError for MultipartError

Return BadRequest for MultipartError

+
source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
§

fn error_response(&self) -> HttpResponse

Creates full response for error. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_multipart/error/enum.MultipartError.html b/actix_multipart/error/enum.MultipartError.html new file mode 100644 index 000000000..48776c73d --- /dev/null +++ b/actix_multipart/error/enum.MultipartError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_multipart/enum.MultipartError.html...

+ + + \ No newline at end of file diff --git a/actix_multipart/form/bytes/index.html b/actix_multipart/form/bytes/index.html new file mode 100644 index 000000000..185de3b2c --- /dev/null +++ b/actix_multipart/form/bytes/index.html @@ -0,0 +1,2 @@ +actix_multipart::form::bytes - Rust

Module actix_multipart::form::bytes

source ·
Expand description

Reads a field into memory.

+

Structs§

  • Read the field into memory.
\ No newline at end of file diff --git a/actix_multipart/form/bytes/sidebar-items.js b/actix_multipart/form/bytes/sidebar-items.js new file mode 100644 index 000000000..08885c580 --- /dev/null +++ b/actix_multipart/form/bytes/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Bytes"]}; \ No newline at end of file diff --git a/actix_multipart/form/bytes/struct.Bytes.html b/actix_multipart/form/bytes/struct.Bytes.html new file mode 100644 index 000000000..0ef462bfa --- /dev/null +++ b/actix_multipart/form/bytes/struct.Bytes.html @@ -0,0 +1,29 @@ +Bytes in actix_multipart::form::bytes - Rust

Struct actix_multipart::form::bytes::Bytes

source ·
pub struct Bytes {
+    pub data: Bytes,
+    pub content_type: Option<Mime>,
+    pub file_name: Option<String>,
+}
Expand description

Read the field into memory.

+

Fields§

§data: Bytes

The data.

+
§content_type: Option<Mime>

The value of the Content-Type header.

+
§file_name: Option<String>

The filename value in the Content-Disposition header.

+

Trait Implementations§

source§

impl Debug for Bytes

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'t> FieldReader<'t> for Bytes

§

type Future = Pin<Box<dyn Future<Output = Result<Bytes, MultipartError>> + 't>>

Future that resolves to a Self.
source§

fn read_field( + _: &'t HttpRequest, + field: Field, + limits: &'t mut Limits +) -> Self::Future

The form will call this function to handle the field.

Auto Trait Implementations§

§

impl !Freeze for Bytes

§

impl RefUnwindSafe for Bytes

§

impl Send for Bytes

§

impl Sync for Bytes

§

impl Unpin for Bytes

§

impl UnwindSafe for Bytes

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_multipart/form/derive.MultipartForm.html b/actix_multipart/form/derive.MultipartForm.html new file mode 100644 index 000000000..170560abe --- /dev/null +++ b/actix_multipart/form/derive.MultipartForm.html @@ -0,0 +1,76 @@ +MultipartForm in actix_multipart::form - Rust

Derive Macro actix_multipart::form::MultipartForm

#[derive(MultipartForm)]
+{
+    // Attributes available to this derive:
+    #[multipart]
+}
+
Available on crate feature derive only.
Expand description

Implements MultipartCollect for a struct so that it can be used with the MultipartForm +extractor.

+

§Basic Use

+

Each field type should implement the FieldReader trait:

+ +
use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
+
+#[derive(MultipartForm)]
+struct ImageUpload {
+    description: Text<String>,
+    timestamp: Text<i64>,
+    image: TempFile,
+}
+

§Optional and List Fields

+

You can also use Vec<T> and Option<T> provided that T: FieldReader.

+

A [Vec] field corresponds to an upload with multiple parts under the same field +name.

+ +
use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
+
+#[derive(MultipartForm)]
+struct Form {
+    category: Option<Text<String>>,
+    files: Vec<TempFile>,
+}
+

§Field Renaming

+

You can use the #[multipart(rename = "foo")] attribute to receive a field by a different name.

+ +
use actix_multipart::form::{tempfile::TempFile, MultipartForm};
+
+#[derive(MultipartForm)]
+struct Form {
+    #[multipart(rename = "files[]")]
+    files: Vec<TempFile>,
+}
+

§Field Limits

+

You can use the #[multipart(limit = "<size>")] attribute to set field level limits. The limit +string is parsed using parse_size.

+

Note: the form is also subject to the global limits configured using MultipartFormConfig.

+ +
use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
+
+#[derive(MultipartForm)]
+struct Form {
+    #[multipart(limit = "2 KiB")]
+    description: Text<String>,
+
+    #[multipart(limit = "512 MiB")]
+    files: Vec<TempFile>,
+}
+

§Unknown Fields

+

By default fields with an unknown name are ignored. They can be rejected using the +#[multipart(deny_unknown_fields)] attribute:

+ +
#[derive(MultipartForm)]
+#[multipart(deny_unknown_fields)]
+struct Form { }
+

§Duplicate Fields

+

The behaviour for when multiple fields with the same name are received can be changed using the +#[multipart(duplicate_field = "<behavior>")] attribute:

+
    +
  • “ignore”: (default) Extra fields are ignored. I.e., the first one is persisted.
  • +
  • “deny”: A MultipartError::UnsupportedField error response is returned.
  • +
  • “replace”: Each field is processed, but only the last one is persisted.
  • +
+

Note that Vec fields will ignore this option.

+ +
#[derive(MultipartForm)]
+#[multipart(duplicate_field = "deny")]
+struct Form { }
+
\ No newline at end of file diff --git a/actix_multipart/form/index.html b/actix_multipart/form/index.html new file mode 100644 index 000000000..15b7dc6e0 --- /dev/null +++ b/actix_multipart/form/index.html @@ -0,0 +1,3 @@ +actix_multipart::form - Rust

Module actix_multipart::form

source ·
Expand description

Process and extract typed data from a multipart stream.

+

Modules§

  • Reads a field into memory.
  • Deserializes a field as JSON.
  • tempfiletempfile
    Writes a field to a temporary file on disk.
  • Deserializes a field from plain text.

Structs§

Traits§

Derive Macros§

  • Implements MultipartCollect for a struct so that it can be used with the MultipartForm +extractor.
\ No newline at end of file diff --git a/actix_multipart/form/json/enum.JsonFieldError.html b/actix_multipart/form/json/enum.JsonFieldError.html new file mode 100644 index 000000000..58dadc886 --- /dev/null +++ b/actix_multipart/form/json/enum.JsonFieldError.html @@ -0,0 +1,23 @@ +JsonFieldError in actix_multipart::form::json - Rust

Enum actix_multipart::form::json::JsonFieldError

source ·
#[non_exhaustive]
pub enum JsonFieldError { + Deserialize(Error), + ContentType, +}

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Deserialize(Error)

Deserialize error.

+
§

ContentType

Content type error.

+

Trait Implementations§

source§

impl Debug for JsonFieldError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for JsonFieldError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for JsonFieldError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl ResponseError for JsonFieldError

source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
§

fn error_response(&self) -> HttpResponse

Creates full response for error. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_multipart/form/json/index.html b/actix_multipart/form/json/index.html new file mode 100644 index 000000000..f972547f0 --- /dev/null +++ b/actix_multipart/form/json/index.html @@ -0,0 +1,2 @@ +actix_multipart::form::json - Rust

Module actix_multipart::form::json

source ·
Expand description

Deserializes a field as JSON.

+

Structs§

Enums§

\ No newline at end of file diff --git a/actix_multipart/form/json/sidebar-items.js b/actix_multipart/form/json/sidebar-items.js new file mode 100644 index 000000000..238047cb2 --- /dev/null +++ b/actix_multipart/form/json/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["JsonFieldError"],"struct":["Json","JsonConfig"]}; \ No newline at end of file diff --git a/actix_multipart/form/json/struct.Json.html b/actix_multipart/form/json/struct.Json.html new file mode 100644 index 000000000..bac8659af --- /dev/null +++ b/actix_multipart/form/json/struct.Json.html @@ -0,0 +1,33 @@ +Json in actix_multipart::form::json - Rust

Struct actix_multipart::form::json::Json

source ·
pub struct Json<T: DeserializeOwned>(pub T);
Expand description

Deserialize from JSON.

+

Tuple Fields§

§0: T

Implementations§

source§

impl<T: DeserializeOwned> Json<T>

source

pub fn into_inner(self) -> T

Trait Implementations§

source§

impl<T: Debug + DeserializeOwned> Debug for Json<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: DeserializeOwned> Deref for Json<T>

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl<T: DeserializeOwned> DerefMut for Json<T>

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl<'t, T> FieldReader<'t> for Json<T>
where + T: DeserializeOwned + 'static,

§

type Future = Pin<Box<dyn Future<Output = Result<Json<T>, MultipartError>> + 't>>

Future that resolves to a Self.
source§

fn read_field( + req: &'t HttpRequest, + field: Field, + limits: &'t mut Limits +) -> Self::Future

The form will call this function to handle the field.

Auto Trait Implementations§

§

impl<T> Freeze for Json<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for Json<T>
where + T: RefUnwindSafe,

§

impl<T> Send for Json<T>
where + T: Send,

§

impl<T> Sync for Json<T>
where + T: Sync,

§

impl<T> Unpin for Json<T>
where + T: Unpin,

§

impl<T> UnwindSafe for Json<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

impl<T> Formattable for T
where + T: Deref, + <T as Deref>::Target: Formattable,

§

impl<T> Parsable for T
where + T: Deref, + <T as Deref>::Target: Parsable,

\ No newline at end of file diff --git a/actix_multipart/form/json/struct.JsonConfig.html b/actix_multipart/form/json/struct.JsonConfig.html new file mode 100644 index 000000000..714c4eb19 --- /dev/null +++ b/actix_multipart/form/json/struct.JsonConfig.html @@ -0,0 +1,21 @@ +JsonConfig in actix_multipart::form::json - Rust

Struct actix_multipart::form::json::JsonConfig

source ·
pub struct JsonConfig { /* private fields */ }
Expand description

Configuration for the Json field reader.

+

Implementations§

source§

impl JsonConfig

source

pub fn error_handler<F>(self, f: F) -> Self
where + F: Fn(JsonFieldError, &HttpRequest) -> Error + Send + Sync + 'static,

source

pub fn validate_content_type(self, validate_content_type: bool) -> Self

Sets whether or not the field must have a valid Content-Type header to be parsed.

+

Trait Implementations§

source§

impl Clone for JsonConfig

source§

fn clone(&self) -> JsonConfig

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Default for JsonConfig

source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_multipart/form/sidebar-items.js b/actix_multipart/form/sidebar-items.js new file mode 100644 index 000000000..65c7f4e9c --- /dev/null +++ b/actix_multipart/form/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"derive":["MultipartForm"],"mod":["bytes","json","tempfile","text"],"struct":["Limits","MultipartForm","MultipartFormConfig"],"trait":["FieldReader","MultipartCollect"]}; \ No newline at end of file diff --git a/actix_multipart/form/struct.Limits.html b/actix_multipart/form/struct.Limits.html new file mode 100644 index 000000000..946f03a0a --- /dev/null +++ b/actix_multipart/form/struct.Limits.html @@ -0,0 +1,33 @@ +Limits in actix_multipart::form - Rust

Struct actix_multipart::form::Limits

source ·
pub struct Limits {
+    pub total_limit_remaining: usize,
+    pub memory_limit_remaining: usize,
+    pub field_limit_remaining: Option<usize>,
+}
Expand description

Used to keep track of the remaining limits for the form and current field.

+

Fields§

§total_limit_remaining: usize§memory_limit_remaining: usize§field_limit_remaining: Option<usize>

Implementations§

source§

impl Limits

source

pub fn new(total_limit: usize, memory_limit: usize) -> Self

source

pub fn try_consume_limits( + &mut self, + bytes: usize, + in_memory: bool +) -> Result<(), MultipartError>

This function should be called within a FieldReader when reading each chunk of a field +to ensure that the form limits are not exceeded.

+
§Arguments
+
    +
  • bytes - The number of bytes being read from this chunk
  • +
  • in_memory - Whether to consume from the memory limits
  • +
+

Auto Trait Implementations§

§

impl Freeze for Limits

§

impl RefUnwindSafe for Limits

§

impl Send for Limits

§

impl Sync for Limits

§

impl Unpin for Limits

§

impl UnwindSafe for Limits

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_multipart/form/struct.MultipartForm.html b/actix_multipart/form/struct.MultipartForm.html new file mode 100644 index 000000000..1ea23aa02 --- /dev/null +++ b/actix_multipart/form/struct.MultipartForm.html @@ -0,0 +1,34 @@ +MultipartForm in actix_multipart::form - Rust

Struct actix_multipart::form::MultipartForm

source ·
pub struct MultipartForm<T: MultipartCollect>(pub T);
Expand description

Typed multipart/form-data extractor.

+

To extract typed data from a multipart stream, the inner type T must implement the +MultipartCollect trait. You should use the MultipartForm macro to derive this +for your struct.

+

Add a MultipartFormConfig to your app data to configure extraction.

+

Tuple Fields§

§0: T

Implementations§

source§

impl<T: MultipartCollect> MultipartForm<T>

source

pub fn into_inner(self) -> T

Unwrap into inner T value.

+

Trait Implementations§

source§

impl<T: MultipartCollect> Deref for MultipartForm<T>

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl<T: MultipartCollect> DerefMut for MultipartForm<T>

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl<T> FromRequest for MultipartForm<T>
where + T: MultipartCollect,

§

type Error = Error

The associated error which can be returned.
§

type Future = Pin<Box<dyn Future<Output = Result<MultipartForm<T>, <MultipartForm<T> as FromRequest>::Error>>>>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more

Auto Trait Implementations§

§

impl<T> Freeze for MultipartForm<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for MultipartForm<T>
where + T: RefUnwindSafe,

§

impl<T> Send for MultipartForm<T>
where + T: Send,

§

impl<T> Sync for MultipartForm<T>
where + T: Sync,

§

impl<T> Unpin for MultipartForm<T>
where + T: Unpin,

§

impl<T> UnwindSafe for MultipartForm<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

impl<T> Formattable for T
where + T: Deref, + <T as Deref>::Target: Formattable,

§

impl<T> Parsable for T
where + T: Deref, + <T as Deref>::Target: Parsable,

\ No newline at end of file diff --git a/actix_multipart/form/struct.MultipartFormConfig.html b/actix_multipart/form/struct.MultipartFormConfig.html new file mode 100644 index 000000000..24237b750 --- /dev/null +++ b/actix_multipart/form/struct.MultipartFormConfig.html @@ -0,0 +1,24 @@ +MultipartFormConfig in actix_multipart::form - Rust

Struct actix_multipart::form::MultipartFormConfig

source ·
pub struct MultipartFormConfig { /* private fields */ }
Expand description

MultipartForm extractor configuration.

+

Add to your app data to have it picked up by MultipartForm extractors.

+

Implementations§

source§

impl MultipartFormConfig

source

pub fn total_limit(self, total_limit: usize) -> Self

Sets maximum accepted payload size for the entire form. By default this limit is 50MiB.

+
source

pub fn memory_limit(self, memory_limit: usize) -> Self

Sets maximum accepted data that will be read into memory. By default this limit is 2MiB.

+
source

pub fn error_handler<F>(self, f: F) -> Self
where + F: Fn(MultipartError, &HttpRequest) -> Error + Send + Sync + 'static,

Sets custom error handler.

+

Trait Implementations§

source§

impl Clone for MultipartFormConfig

source§

fn clone(&self) -> MultipartFormConfig

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Default for MultipartFormConfig

source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_multipart/form/tempfile/enum.TempFileError.html b/actix_multipart/form/tempfile/enum.TempFileError.html new file mode 100644 index 000000000..b45fd20c2 --- /dev/null +++ b/actix_multipart/form/tempfile/enum.TempFileError.html @@ -0,0 +1,21 @@ +TempFileError in actix_multipart::form::tempfile - Rust

Enum actix_multipart::form::tempfile::TempFileError

source ·
#[non_exhaustive]
pub enum TempFileError { + FileIo(Error), +}
Available on crate feature tempfile only.

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

FileIo(Error)

File I/O Error

+

Trait Implementations§

source§

impl Debug for TempFileError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for TempFileError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for TempFileError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl ResponseError for TempFileError

source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
§

fn error_response(&self) -> HttpResponse

Creates full response for error. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_multipart/form/tempfile/index.html b/actix_multipart/form/tempfile/index.html new file mode 100644 index 000000000..a4343da5b --- /dev/null +++ b/actix_multipart/form/tempfile/index.html @@ -0,0 +1,2 @@ +actix_multipart::form::tempfile - Rust

Module actix_multipart::form::tempfile

source ·
Available on crate feature tempfile only.
Expand description

Writes a field to a temporary file on disk.

+

Structs§

Enums§

\ No newline at end of file diff --git a/actix_multipart/form/tempfile/sidebar-items.js b/actix_multipart/form/tempfile/sidebar-items.js new file mode 100644 index 000000000..c86d70665 --- /dev/null +++ b/actix_multipart/form/tempfile/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["TempFileError"],"struct":["TempFile","TempFileConfig"]}; \ No newline at end of file diff --git a/actix_multipart/form/tempfile/struct.TempFile.html b/actix_multipart/form/tempfile/struct.TempFile.html new file mode 100644 index 000000000..01212c7dd --- /dev/null +++ b/actix_multipart/form/tempfile/struct.TempFile.html @@ -0,0 +1,31 @@ +TempFile in actix_multipart::form::tempfile - Rust

Struct actix_multipart::form::tempfile::TempFile

source ·
pub struct TempFile {
+    pub file: NamedTempFile,
+    pub content_type: Option<Mime>,
+    pub file_name: Option<String>,
+    pub size: usize,
+}
Available on crate feature tempfile only.
Expand description

Write the field to a temporary file on disk.

+

Fields§

§file: NamedTempFile

The temporary file on disk.

+
§content_type: Option<Mime>

The value of the content-type header.

+
§file_name: Option<String>

The filename value in the content-disposition header.

+
§size: usize

The size in bytes of the file.

+

Trait Implementations§

source§

impl Debug for TempFile

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'t> FieldReader<'t> for TempFile

§

type Future = Pin<Box<dyn Future<Output = Result<TempFile, MultipartError>> + 't>>

Future that resolves to a Self.
source§

fn read_field( + req: &'t HttpRequest, + field: Field, + limits: &'t mut Limits +) -> Self::Future

The form will call this function to handle the field.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_multipart/form/tempfile/struct.TempFileConfig.html b/actix_multipart/form/tempfile/struct.TempFileConfig.html new file mode 100644 index 000000000..906f4e68d --- /dev/null +++ b/actix_multipart/form/tempfile/struct.TempFileConfig.html @@ -0,0 +1,23 @@ +TempFileConfig in actix_multipart::form::tempfile - Rust

Struct actix_multipart::form::tempfile::TempFileConfig

source ·
pub struct TempFileConfig { /* private fields */ }
Available on crate feature tempfile only.
Expand description

Configuration for the TempFile field reader.

+

Implementations§

source§

impl TempFileConfig

source

pub fn error_handler<F>(self, f: F) -> Self
where + F: Fn(TempFileError, &HttpRequest) -> Error + Send + Sync + 'static,

Sets custom error handler.

+
source

pub fn directory(self, dir: impl AsRef<Path>) -> Self

Sets the directory that temp files will be created in.

+

The default temporary file location is platform dependent.

+

Trait Implementations§

source§

impl Clone for TempFileConfig

source§

fn clone(&self) -> TempFileConfig

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Default for TempFileConfig

source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_multipart/form/text/enum.TextError.html b/actix_multipart/form/text/enum.TextError.html new file mode 100644 index 000000000..c7c94dd55 --- /dev/null +++ b/actix_multipart/form/text/enum.TextError.html @@ -0,0 +1,25 @@ +TextError in actix_multipart::form::text - Rust

Enum actix_multipart::form::text::TextError

source ·
#[non_exhaustive]
pub enum TextError { + Utf8Error(Utf8Error), + Deserialize(Error), + ContentType, +}

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Utf8Error(Utf8Error)

UTF-8 decoding error.

+
§

Deserialize(Error)

Deserialize error.

+
§

ContentType

Content type error.

+

Trait Implementations§

source§

impl Debug for TextError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for TextError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for TextError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl ResponseError for TextError

source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
§

fn error_response(&self) -> HttpResponse

Creates full response for error. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_multipart/form/text/index.html b/actix_multipart/form/text/index.html new file mode 100644 index 000000000..7278bf1e0 --- /dev/null +++ b/actix_multipart/form/text/index.html @@ -0,0 +1,2 @@ +actix_multipart::form::text - Rust

Module actix_multipart::form::text

source ·
Expand description

Deserializes a field from plain text.

+

Structs§

Enums§

\ No newline at end of file diff --git a/actix_multipart/form/text/sidebar-items.js b/actix_multipart/form/text/sidebar-items.js new file mode 100644 index 000000000..7bb0b3e14 --- /dev/null +++ b/actix_multipart/form/text/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["TextError"],"struct":["Text","TextConfig"]}; \ No newline at end of file diff --git a/actix_multipart/form/text/struct.Text.html b/actix_multipart/form/text/struct.Text.html new file mode 100644 index 000000000..f7b393a13 --- /dev/null +++ b/actix_multipart/form/text/struct.Text.html @@ -0,0 +1,36 @@ +Text in actix_multipart::form::text - Rust

Struct actix_multipart::form::text::Text

source ·
pub struct Text<T: DeserializeOwned>(pub T);
Expand description

Deserialize from plain text.

+

Internally this uses [serde_plain] for deserialization, which supports primitive types +including strings, numbers, and simple enums.

+

Tuple Fields§

§0: T

Implementations§

source§

impl<T: DeserializeOwned> Text<T>

source

pub fn into_inner(self) -> T

Unwraps into inner value.

+

Trait Implementations§

source§

impl<T: Debug + DeserializeOwned> Debug for Text<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: DeserializeOwned> Deref for Text<T>

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl<T: DeserializeOwned> DerefMut for Text<T>

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl<'t, T> FieldReader<'t> for Text<T>
where + T: DeserializeOwned + 'static,

§

type Future = Pin<Box<dyn Future<Output = Result<Text<T>, MultipartError>> + 't>>

Future that resolves to a Self.
source§

fn read_field( + req: &'t HttpRequest, + field: Field, + limits: &'t mut Limits +) -> Self::Future

The form will call this function to handle the field.

Auto Trait Implementations§

§

impl<T> Freeze for Text<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for Text<T>
where + T: RefUnwindSafe,

§

impl<T> Send for Text<T>
where + T: Send,

§

impl<T> Sync for Text<T>
where + T: Sync,

§

impl<T> Unpin for Text<T>
where + T: Unpin,

§

impl<T> UnwindSafe for Text<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

impl<T> Formattable for T
where + T: Deref, + <T as Deref>::Target: Formattable,

§

impl<T> Parsable for T
where + T: Deref, + <T as Deref>::Target: Parsable,

\ No newline at end of file diff --git a/actix_multipart/form/text/struct.TextConfig.html b/actix_multipart/form/text/struct.TextConfig.html new file mode 100644 index 000000000..b64febff9 --- /dev/null +++ b/actix_multipart/form/text/struct.TextConfig.html @@ -0,0 +1,24 @@ +TextConfig in actix_multipart::form::text - Rust

Struct actix_multipart::form::text::TextConfig

source ·
pub struct TextConfig { /* private fields */ }
Expand description

Configuration for the Text field reader.

+

Implementations§

source§

impl TextConfig

source

pub fn error_handler<F>(self, f: F) -> Self
where + F: Fn(TextError, &HttpRequest) -> Error + Send + Sync + 'static,

Sets custom error handler.

+
source

pub fn validate_content_type(self, validate_content_type: bool) -> Self

Sets whether or not the field must have a valid Content-Type header to be parsed.

+

Note that an empty Content-Type is also accepted, as the multipart specification defines +text/plain as the default for text fields.

+

Trait Implementations§

source§

impl Clone for TextConfig

source§

fn clone(&self) -> TextConfig

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Default for TextConfig

source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_multipart/form/trait.FieldReader.html b/actix_multipart/form/trait.FieldReader.html new file mode 100644 index 000000000..10bc86699 --- /dev/null +++ b/actix_multipart/form/trait.FieldReader.html @@ -0,0 +1,20 @@ +FieldReader in actix_multipart::form - Rust

Trait actix_multipart::form::FieldReader

source ·
pub trait FieldReader<'t>: Sized + Any {
+    type Future: Future<Output = Result<Self, MultipartError>>;
+
+    // Required method
+    fn read_field(
+        req: &'t HttpRequest,
+        field: Field,
+        limits: &'t mut Limits
+    ) -> Self::Future;
+}
Expand description

Trait that data types to be used in a multipart form struct should implement.

+

It represents an asynchronous handler that processes a multipart field to produce Self.

+

Required Associated Types§

source

type Future: Future<Output = Result<Self, MultipartError>>

Future that resolves to a Self.

+

Required Methods§

source

fn read_field( + req: &'t HttpRequest, + field: Field, + limits: &'t mut Limits +) -> Self::Future

The form will call this function to handle the field.

+

Object Safety§

This trait is not object safe.

Implementors§

source§

impl<'t> FieldReader<'t> for Bytes

§

type Future = Pin<Box<dyn Future<Output = Result<Bytes, MultipartError>> + 't>>

source§

impl<'t> FieldReader<'t> for TempFile

Available on crate feature tempfile only.
§

type Future = Pin<Box<dyn Future<Output = Result<TempFile, MultipartError>> + 't>>

source§

impl<'t, T> FieldReader<'t> for Json<T>
where + T: DeserializeOwned + 'static,

§

type Future = Pin<Box<dyn Future<Output = Result<Json<T>, MultipartError>> + 't>>

source§

impl<'t, T> FieldReader<'t> for Text<T>
where + T: DeserializeOwned + 'static,

§

type Future = Pin<Box<dyn Future<Output = Result<Text<T>, MultipartError>> + 't>>

\ No newline at end of file diff --git a/actix_multipart/form/trait.MultipartCollect.html b/actix_multipart/form/trait.MultipartCollect.html new file mode 100644 index 000000000..dee2cba62 --- /dev/null +++ b/actix_multipart/form/trait.MultipartCollect.html @@ -0,0 +1,24 @@ +MultipartCollect in actix_multipart::form - Rust

Trait actix_multipart::form::MultipartCollect

source ·
pub trait MultipartCollect: Sized {
+    // Required methods
+    fn limit(field_name: &str) -> Option<usize>;
+    fn handle_field<'t>(
+        req: &'t HttpRequest,
+        field: Field,
+        limits: &'t mut Limits,
+        state: &'t mut State
+    ) -> LocalBoxFuture<'t, Result<(), MultipartError>>;
+    fn from_state(state: State) -> Result<Self, MultipartError>;
+}
Expand description

Trait that allows a type to be used in the MultipartForm extractor.

+

You should use the MultipartForm macro to derive this for your struct.

+

Required Methods§

source

fn limit(field_name: &str) -> Option<usize>

An optional limit in bytes to be applied a given field name. Note this limit will be shared +across all fields sharing the same name.

+
source

fn handle_field<'t>( + req: &'t HttpRequest, + field: Field, + limits: &'t mut Limits, + state: &'t mut State +) -> LocalBoxFuture<'t, Result<(), MultipartError>>

The extractor will call this function for each incoming field, the state can be updated +with the processed field data.

+
source

fn from_state(state: State) -> Result<Self, MultipartError>

Once all the fields have been processed and stored in the state, this is called +to convert into the struct representation.

+

Object Safety§

This trait is not object safe.

Implementors§

\ No newline at end of file diff --git a/actix_multipart/index.html b/actix_multipart/index.html new file mode 100644 index 000000000..fab0ecad1 --- /dev/null +++ b/actix_multipart/index.html @@ -0,0 +1,35 @@ +actix_multipart - Rust

Crate actix_multipart

source ·
Expand description

Multipart form support for Actix Web.

+

§Examples

+
use actix_web::{post, App, HttpServer, Responder};
+
+use actix_multipart::form::{json::Json as MPJson, tempfile::TempFile, MultipartForm};
+use serde::Deserialize;
+
+#[derive(Debug, Deserialize)]
+struct Metadata {
+    name: String,
+}
+
+#[derive(Debug, MultipartForm)]
+struct UploadForm {
+    #[multipart(limit = "100MB")]
+    file: TempFile,
+    json: MPJson<Metadata>,
+}
+
+#[post("/videos")]
+pub async fn post_video(MultipartForm(form): MultipartForm<UploadForm>) -> impl Responder {
+    format!(
+        "Uploaded file {}, with size: {}",
+        form.json.name, form.file.size
+    )
+}
+
+#[actix_web::main]
+async fn main() -> std::io::Result<()> {
+    HttpServer::new(move || App::new().service(post_video))
+        .bind(("127.0.0.1", 8080))?
+        .run()
+        .await
+}
+

Re-exports§

Modules§

  • Process and extract typed data from a multipart stream.

Structs§

  • A single field in a multipart stream
  • The server-side implementation of multipart/form-data requests.

Enums§

  • A set of errors that can occur during parsing multipart streams.
\ No newline at end of file diff --git a/actix_multipart/server/struct.Field.html b/actix_multipart/server/struct.Field.html new file mode 100644 index 000000000..9c7bc4534 --- /dev/null +++ b/actix_multipart/server/struct.Field.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_multipart/struct.Field.html...

+ + + \ No newline at end of file diff --git a/actix_multipart/server/struct.Multipart.html b/actix_multipart/server/struct.Multipart.html new file mode 100644 index 000000000..20905d509 --- /dev/null +++ b/actix_multipart/server/struct.Multipart.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_multipart/struct.Multipart.html...

+ + + \ No newline at end of file diff --git a/actix_multipart/sidebar-items.js b/actix_multipart/sidebar-items.js new file mode 100644 index 000000000..2a680e625 --- /dev/null +++ b/actix_multipart/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["MultipartError"],"mod":["form","test"],"struct":["Field","Multipart"]}; \ No newline at end of file diff --git a/actix_multipart/struct.Field.html b/actix_multipart/struct.Field.html new file mode 100644 index 000000000..feac5f638 --- /dev/null +++ b/actix_multipart/struct.Field.html @@ -0,0 +1,269 @@ +Field in actix_multipart - Rust

Struct actix_multipart::Field

source ·
pub struct Field { /* private fields */ }
Expand description

A single field in a multipart stream

+

Implementations§

source§

impl Field

source

pub fn headers(&self) -> &HeaderMap

Returns a reference to the field’s header map.

+
source

pub fn content_type(&self) -> Option<&Mime>

Returns a reference to the field’s content (mime) type, if it is supplied by the client.

+

According to RFC 7578, if it is not +present, it should default to “text/plain”. Note it is the responsibility of the client to +provide the appropriate content type, there is no attempt to validate this by the server.

+
source

pub fn content_disposition(&self) -> &ContentDisposition

Returns the field’s Content-Disposition.

+

Per RFC 7578 §4.2: “Each part MUST contain a Content-Disposition header field where the +disposition type is form-data. The Content-Disposition header field MUST also contain an +additional parameter of name; the value of the name parameter is the original field name +from the form.”

+

This crate validates that it exists before returning a Field. As such, it is safe to +unwrap .content_disposition().get_name(). The name method is provided as +a convenience.

+
source

pub fn name(&self) -> &str

Returns the field’s name.

+

See content_disposition regarding guarantees about existence of +the name field.

+

Trait Implementations§

source§

impl Debug for Field

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Stream for Field

§

type Item = Result<Bytes, MultipartError>

Values yielded by the stream.
source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Self::Item>>

Attempt to pull out the next value of this stream, registering the +current task for wakeup if the value is not yet available, and returning +None if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more

Auto Trait Implementations§

§

impl !Freeze for Field

§

impl !RefUnwindSafe for Field

§

impl !Send for Field

§

impl !Sync for Field

§

impl Unpin for Field

§

impl !UnwindSafe for Field

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<T> StreamExt for T
where + T: Stream + ?Sized,

§

fn next(&mut self) -> Next<'_, Self>
where + Self: Unpin,

Creates a future that resolves to the next item in the stream. Read more
§

fn into_future(self) -> StreamFuture<Self>
where + Self: Sized + Unpin,

Converts this stream into a future of (next_item, tail_of_stream). +If the stream terminates, then the next item is None. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + F: FnMut(Self::Item) -> T, + Self: Sized,

Maps this stream’s items to a different type, returning a new stream of +the resulting type. Read more
§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates a stream which gives the current iteration count as well as +the next value. Read more
§

fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Filters the values produced by this stream according to the provided +asynchronous predicate. Read more
§

fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = Option<T>>, + Self: Sized,

Filters the values produced by this stream while simultaneously mapping +them to a different type according to the provided asynchronous closure. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized,

Computes from this stream’s items new items of a different type using +an asynchronous closure. Read more
§

fn collect<C>(self) -> Collect<Self, C>
where + C: Default + Extend<Self::Item>, + Self: Sized,

Transforms a stream into a collection, returning a +future representing the result of that computation. Read more
§

fn unzip<A, B, FromA, FromB>(self) -> Unzip<Self, FromA, FromB>
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Stream<Item = (A, B)>,

Converts a stream of pairs into a future, which +resolves to pair of containers. Read more
§

fn concat(self) -> Concat<Self>
where + Self: Sized, + Self::Item: Extend<<Self::Item as IntoIterator>::Item> + IntoIterator + Default,

Concatenate all items of a stream into a single extendable +destination, returning a future representing the end result. Read more
§

fn count(self) -> Count<Self>
where + Self: Sized,

Drives the stream to completion, counting the number of items. Read more
§

fn cycle(self) -> Cycle<Self>
where + Self: Sized + Clone,

Repeats a stream endlessly. Read more
§

fn fold<T, Fut, F>(self, init: T, f: F) -> Fold<Self, Fut, T, F>
where + F: FnMut(T, Self::Item) -> Fut, + Fut: Future<Output = T>, + Self: Sized,

Execute an accumulating asynchronous computation over a stream, +collecting all the values into one final result. Read more
§

fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if any element in stream satisfied a predicate. Read more
§

fn all<Fut, F>(self, f: F) -> All<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if all element in stream satisfied a predicate. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Item: Stream, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> FlattenUnorderedWithFlowController<Self, ()>
where + Self::Item: Stream + Unpin, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Polls +inner streams produced by the base stream concurrently. Read more
§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + F: FnMut(Self::Item) -> U, + U: Stream, + Self: Sized,

Maps a stream like [StreamExt::map] but flattens nested Streams. Read more
§

fn flat_map_unordered<U, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> FlatMapUnordered<Self, U, F>
where + U: Stream + Unpin, + F: FnMut(Self::Item) -> U, + Self: Sized,

Available on crate feature alloc only.
Maps a stream like [StreamExt::map] but flattens nested Streams +and polls them concurrently, yielding items in any order, as they made +available. Read more
§

fn scan<S, B, Fut, F>(self, initial_state: S, f: F) -> Scan<Self, S, Fut, F>
where + F: FnMut(&mut S, Self::Item) -> Fut, + Fut: Future<Output = Option<B>>, + Self: Sized,

Combinator similar to [StreamExt::fold] that holds internal state +and produces a new stream. Read more
§

fn skip_while<Fut, F>(self, f: F) -> SkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_while<Fut, F>(self, f: F) -> TakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Take elements from this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_until<Fut>(self, fut: Fut) -> TakeUntil<Self, Fut>
where + Fut: Future, + Self: Sized,

Take elements from this stream until the provided future resolves. Read more
§

fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream. Read more
§

fn for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> ForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Available on crate feature alloc only.
Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates a new stream of at most n items of the underlying stream. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates a new stream which skips n items of the underlying stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a stream such that poll_next will never +again be called once it has finished. This method can be used to turn +any Stream into a FusedStream. Read more
§

fn by_ref(&mut self) -> &mut Self

Borrows a stream, rather than consuming it. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the stream. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn buffered(self, n: usize) -> Buffered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures. Read more
§

fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures (unordered). Read more
§

fn zip<St>(self, other: St) -> Zip<Self, St>
where + St: Stream, + Self: Sized,

An adapter for zipping two streams together. Read more
§

fn chain<St>(self, other: St) -> Chain<Self, St>
where + St: Stream<Item = Self::Item>, + Self: Sized,

Adapter for chaining two streams. Read more
§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates a new stream which exposes a peek method. Read more
§

fn chunks(self, capacity: usize) -> Chunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up items of the stream inside a vector. Read more
§

fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up ready items of the stream inside a vector. Read more
§

fn forward<S>(self, sink: S) -> Forward<Self, S>
where + S: Sink<Self::Ok, Error = Self::Error>, + Self: Sized + TryStream,

Available on crate feature sink only.
A future that completes after the given stream has been fully processed +into the sink and the sink has been flushed and closed. Read more
§

fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
where + Self: Sized + Sink<Item>,

Available on crate features sink and alloc only.
Splits this Stream + Sink object into separate Sink and Stream +objects. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnMut(&Self::Item), + Self: Sized,

Do something with each item of this stream, afterwards passing it on. Read more
§

fn left_stream<B>(self) -> Either<Self, B>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the left-hand variant +of that Either. Read more
§

fn right_stream<B>(self) -> Either<B, Self>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the right-hand variant +of that Either. Read more
§

fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>
where + Self: Unpin,

A convenience method for calling [Stream::poll_next] on Unpin +stream types.
§

fn select_next_some(&mut self) -> SelectNextSome<'_, Self>
where + Self: Unpin + FusedStream,

Returns a Future that resolves when the next item in this stream is +ready. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<S, T, E> TryStream for S
where + S: Stream<Item = 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
§

fn try_poll_next( + self: Pin<&mut S>, + cx: &mut Context<'_> +) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>>

Poll this TryStream as if it were a Stream. Read more
§

impl<S> TryStreamExt for S
where + S: TryStream + ?Sized,

§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Wraps the current stream in a new stream which converts the error type +into the one provided. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> T,

Wraps the current stream in a new stream which maps the success value +using the provided closure. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + Self: Sized, + F: FnMut(Self::Error) -> E,

Wraps the current stream in a new stream which maps the error value +using the provided closure. Read more
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Chain on a computation for when a value is ready, passing the successful +results to the provided closure f. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnMut(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Chain on a computation for when an error happens, passing the +erroneous result to the provided closure f. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnMut(&Self::Ok), + Self: Sized,

Do something with the success value of this stream, afterwards passing +it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnMut(&Self::Error), + Self: Sized,

Do something with the error value of this stream, afterwards passing it on. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Wraps a [TryStream] into a type that implements +Stream Read more
§

fn try_next(&mut self) -> TryNext<'_, Self>
where + Self: Unpin,

Creates a future that attempts to resolve the next item in the stream. +If an error is encountered before the next item, the error is returned +instead. Read more
§

fn try_for_each<Fut, F>(self, f: F) -> TryForEach<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Ok = (), Error = Self::Error>, + Self: Sized,

Attempts to run this stream to completion, executing the provided +asynchronous closure for each element on the stream. Read more
§

fn try_skip_while<Fut, F>(self, f: F) -> TrySkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_take_while<Fut, F>(self, f: F) -> TryTakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Take elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> TryForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = Result<(), Self::Error>>, + Self: Sized,

Available on crate feature alloc only.
Attempts to run this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available, exiting as soon as an error occurs. Read more
§

fn try_collect<C>(self) -> TryCollect<Self, C>
where + C: Default + Extend<Self::Ok>, + Self: Sized,

Attempt to transform a stream into a collection, +returning a future representing the result of that computation. Read more
§

fn try_chunks(self, capacity: usize) -> TryChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful items of the stream inside a vector. Read more
§

fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful, ready items of the stream inside a vector. Read more
§

fn try_filter<Fut, F>(self, f: F) -> TryFilter<Self, Fut, F>
where + Fut: Future<Output = bool>, + F: FnMut(&Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream according to the +provided asynchronous closure. Read more
§

fn try_filter_map<Fut, F, T>(self, f: F) -> TryFilterMap<Self, Fut, F>
where + Fut: TryFuture<Ok = Option<T>, Error = Self::Error>, + F: FnMut(Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream while +simultaneously mapping them to a different type according to the +provided asynchronous closure. Read more
§

fn try_flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> TryFlattenUnordered<Self>
where + Self::Ok: TryStream + Unpin, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Produced streams +will be polled concurrently and any errors will be passed through without looking at them. +If the underlying base stream returns an error, it will be immediately propagated. Read more
§

fn try_flatten(self) -> TryFlatten<Self>
where + Self::Ok: TryStream, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn try_fold<T, Fut, F>(self, init: T, f: F) -> TryFold<Self, Fut, T, F>
where + F: FnMut(T, Self::Ok) -> Fut, + Fut: TryFuture<Ok = T, Error = Self::Error>, + Self: Sized,

Attempt to execute an accumulating asynchronous computation over a +stream, collecting all the values into one final result. Read more
§

fn try_concat(self) -> TryConcat<Self>
where + Self: Sized, + Self::Ok: Extend<<Self::Ok as IntoIterator>::Item> + IntoIterator + Default,

Attempt to concatenate all items of a stream into a single +extendable destination, returning a future representing the end result. Read more
§

fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently (unordered). Read more
§

fn try_buffered(self, n: usize) -> TryBuffered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently. Read more
§

fn try_poll_next_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Option<Result<Self::Ok, Self::Error>>>
where + Self: Unpin,

A convenience method for calling [TryStream::try_poll_next] on Unpin +stream types.
§

fn try_all<Fut, F>(self, f: F) -> TryAll<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if all items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that does not satisfy the predicate. Read more
§

fn try_any<Fut, F>(self, f: F) -> TryAny<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if any items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that satisfies the predicate. Read more
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_multipart/struct.Multipart.html b/actix_multipart/struct.Multipart.html new file mode 100644 index 000000000..81b3b70dd --- /dev/null +++ b/actix_multipart/struct.Multipart.html @@ -0,0 +1,279 @@ +Multipart in actix_multipart - Rust

Struct actix_multipart::Multipart

source ·
pub struct Multipart { /* private fields */ }
Expand description

The server-side implementation of multipart/form-data requests.

+

This will parse the incoming stream into MultipartItem instances via its +Stream implementation. +MultipartItem::Field contains multipart field. MultipartItem::Multipart +is used for nested multipart streams.

+

Implementations§

source§

impl Multipart

source

pub fn new<S>(headers: &HeaderMap, stream: S) -> Multipart
where + S: Stream<Item = Result<Bytes, PayloadError>> + 'static,

Create multipart instance for boundary.

+

Trait Implementations§

source§

impl FromRequest for Multipart

Get request’s payload as multipart stream.

+

Content-type: multipart/form-data;

+

§Examples

+
use actix_web::{web, HttpResponse, Error};
+use actix_multipart::Multipart;
+use futures_util::StreamExt as _;
+
+async fn index(mut payload: Multipart) -> Result<HttpResponse, Error> {
+    // iterate over multipart stream
+    while let Some(item) = payload.next().await {
+           let mut field = item?;
+
+           // Field in turn is stream of *Bytes* object
+           while let Some(chunk) = field.next().await {
+               println!("-- CHUNK: \n{:?}", std::str::from_utf8(&chunk?));
+           }
+    }
+
+    Ok(HttpResponse::Ok().into())
+}
+
§

type Error = Error

The associated error which can be returned.
§

type Future = Ready<Result<Multipart, Error>>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more
source§

impl Stream for Multipart

§

type Item = Result<Field, MultipartError>

Values yielded by the stream.
source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Self::Item>>

Attempt to pull out the next value of this stream, registering the +current task for wakeup if the value is not yet available, and returning +None if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<T> StreamExt for T
where + T: Stream + ?Sized,

§

fn next(&mut self) -> Next<'_, Self>
where + Self: Unpin,

Creates a future that resolves to the next item in the stream. Read more
§

fn into_future(self) -> StreamFuture<Self>
where + Self: Sized + Unpin,

Converts this stream into a future of (next_item, tail_of_stream). +If the stream terminates, then the next item is None. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + F: FnMut(Self::Item) -> T, + Self: Sized,

Maps this stream’s items to a different type, returning a new stream of +the resulting type. Read more
§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates a stream which gives the current iteration count as well as +the next value. Read more
§

fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Filters the values produced by this stream according to the provided +asynchronous predicate. Read more
§

fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = Option<T>>, + Self: Sized,

Filters the values produced by this stream while simultaneously mapping +them to a different type according to the provided asynchronous closure. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized,

Computes from this stream’s items new items of a different type using +an asynchronous closure. Read more
§

fn collect<C>(self) -> Collect<Self, C>
where + C: Default + Extend<Self::Item>, + Self: Sized,

Transforms a stream into a collection, returning a +future representing the result of that computation. Read more
§

fn unzip<A, B, FromA, FromB>(self) -> Unzip<Self, FromA, FromB>
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Stream<Item = (A, B)>,

Converts a stream of pairs into a future, which +resolves to pair of containers. Read more
§

fn concat(self) -> Concat<Self>
where + Self: Sized, + Self::Item: Extend<<Self::Item as IntoIterator>::Item> + IntoIterator + Default,

Concatenate all items of a stream into a single extendable +destination, returning a future representing the end result. Read more
§

fn count(self) -> Count<Self>
where + Self: Sized,

Drives the stream to completion, counting the number of items. Read more
§

fn cycle(self) -> Cycle<Self>
where + Self: Sized + Clone,

Repeats a stream endlessly. Read more
§

fn fold<T, Fut, F>(self, init: T, f: F) -> Fold<Self, Fut, T, F>
where + F: FnMut(T, Self::Item) -> Fut, + Fut: Future<Output = T>, + Self: Sized,

Execute an accumulating asynchronous computation over a stream, +collecting all the values into one final result. Read more
§

fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if any element in stream satisfied a predicate. Read more
§

fn all<Fut, F>(self, f: F) -> All<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if all element in stream satisfied a predicate. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Item: Stream, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> FlattenUnorderedWithFlowController<Self, ()>
where + Self::Item: Stream + Unpin, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Polls +inner streams produced by the base stream concurrently. Read more
§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + F: FnMut(Self::Item) -> U, + U: Stream, + Self: Sized,

Maps a stream like [StreamExt::map] but flattens nested Streams. Read more
§

fn flat_map_unordered<U, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> FlatMapUnordered<Self, U, F>
where + U: Stream + Unpin, + F: FnMut(Self::Item) -> U, + Self: Sized,

Available on crate feature alloc only.
Maps a stream like [StreamExt::map] but flattens nested Streams +and polls them concurrently, yielding items in any order, as they made +available. Read more
§

fn scan<S, B, Fut, F>(self, initial_state: S, f: F) -> Scan<Self, S, Fut, F>
where + F: FnMut(&mut S, Self::Item) -> Fut, + Fut: Future<Output = Option<B>>, + Self: Sized,

Combinator similar to [StreamExt::fold] that holds internal state +and produces a new stream. Read more
§

fn skip_while<Fut, F>(self, f: F) -> SkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_while<Fut, F>(self, f: F) -> TakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Take elements from this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_until<Fut>(self, fut: Fut) -> TakeUntil<Self, Fut>
where + Fut: Future, + Self: Sized,

Take elements from this stream until the provided future resolves. Read more
§

fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream. Read more
§

fn for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> ForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Available on crate feature alloc only.
Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates a new stream of at most n items of the underlying stream. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates a new stream which skips n items of the underlying stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a stream such that poll_next will never +again be called once it has finished. This method can be used to turn +any Stream into a FusedStream. Read more
§

fn by_ref(&mut self) -> &mut Self

Borrows a stream, rather than consuming it. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the stream. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn buffered(self, n: usize) -> Buffered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures. Read more
§

fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures (unordered). Read more
§

fn zip<St>(self, other: St) -> Zip<Self, St>
where + St: Stream, + Self: Sized,

An adapter for zipping two streams together. Read more
§

fn chain<St>(self, other: St) -> Chain<Self, St>
where + St: Stream<Item = Self::Item>, + Self: Sized,

Adapter for chaining two streams. Read more
§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates a new stream which exposes a peek method. Read more
§

fn chunks(self, capacity: usize) -> Chunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up items of the stream inside a vector. Read more
§

fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up ready items of the stream inside a vector. Read more
§

fn forward<S>(self, sink: S) -> Forward<Self, S>
where + S: Sink<Self::Ok, Error = Self::Error>, + Self: Sized + TryStream,

Available on crate feature sink only.
A future that completes after the given stream has been fully processed +into the sink and the sink has been flushed and closed. Read more
§

fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
where + Self: Sized + Sink<Item>,

Available on crate features sink and alloc only.
Splits this Stream + Sink object into separate Sink and Stream +objects. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnMut(&Self::Item), + Self: Sized,

Do something with each item of this stream, afterwards passing it on. Read more
§

fn left_stream<B>(self) -> Either<Self, B>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the left-hand variant +of that Either. Read more
§

fn right_stream<B>(self) -> Either<B, Self>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the right-hand variant +of that Either. Read more
§

fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>
where + Self: Unpin,

A convenience method for calling [Stream::poll_next] on Unpin +stream types.
§

fn select_next_some(&mut self) -> SelectNextSome<'_, Self>
where + Self: Unpin + FusedStream,

Returns a Future that resolves when the next item in this stream is +ready. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<S, T, E> TryStream for S
where + S: Stream<Item = 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
§

fn try_poll_next( + self: Pin<&mut S>, + cx: &mut Context<'_> +) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>>

Poll this TryStream as if it were a Stream. Read more
§

impl<S> TryStreamExt for S
where + S: TryStream + ?Sized,

§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Wraps the current stream in a new stream which converts the error type +into the one provided. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> T,

Wraps the current stream in a new stream which maps the success value +using the provided closure. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + Self: Sized, + F: FnMut(Self::Error) -> E,

Wraps the current stream in a new stream which maps the error value +using the provided closure. Read more
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Chain on a computation for when a value is ready, passing the successful +results to the provided closure f. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnMut(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Chain on a computation for when an error happens, passing the +erroneous result to the provided closure f. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnMut(&Self::Ok), + Self: Sized,

Do something with the success value of this stream, afterwards passing +it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnMut(&Self::Error), + Self: Sized,

Do something with the error value of this stream, afterwards passing it on. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Wraps a [TryStream] into a type that implements +Stream Read more
§

fn try_next(&mut self) -> TryNext<'_, Self>
where + Self: Unpin,

Creates a future that attempts to resolve the next item in the stream. +If an error is encountered before the next item, the error is returned +instead. Read more
§

fn try_for_each<Fut, F>(self, f: F) -> TryForEach<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Ok = (), Error = Self::Error>, + Self: Sized,

Attempts to run this stream to completion, executing the provided +asynchronous closure for each element on the stream. Read more
§

fn try_skip_while<Fut, F>(self, f: F) -> TrySkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_take_while<Fut, F>(self, f: F) -> TryTakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Take elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> TryForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = Result<(), Self::Error>>, + Self: Sized,

Available on crate feature alloc only.
Attempts to run this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available, exiting as soon as an error occurs. Read more
§

fn try_collect<C>(self) -> TryCollect<Self, C>
where + C: Default + Extend<Self::Ok>, + Self: Sized,

Attempt to transform a stream into a collection, +returning a future representing the result of that computation. Read more
§

fn try_chunks(self, capacity: usize) -> TryChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful items of the stream inside a vector. Read more
§

fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful, ready items of the stream inside a vector. Read more
§

fn try_filter<Fut, F>(self, f: F) -> TryFilter<Self, Fut, F>
where + Fut: Future<Output = bool>, + F: FnMut(&Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream according to the +provided asynchronous closure. Read more
§

fn try_filter_map<Fut, F, T>(self, f: F) -> TryFilterMap<Self, Fut, F>
where + Fut: TryFuture<Ok = Option<T>, Error = Self::Error>, + F: FnMut(Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream while +simultaneously mapping them to a different type according to the +provided asynchronous closure. Read more
§

fn try_flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> TryFlattenUnordered<Self>
where + Self::Ok: TryStream + Unpin, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Produced streams +will be polled concurrently and any errors will be passed through without looking at them. +If the underlying base stream returns an error, it will be immediately propagated. Read more
§

fn try_flatten(self) -> TryFlatten<Self>
where + Self::Ok: TryStream, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn try_fold<T, Fut, F>(self, init: T, f: F) -> TryFold<Self, Fut, T, F>
where + F: FnMut(T, Self::Ok) -> Fut, + Fut: TryFuture<Ok = T, Error = Self::Error>, + Self: Sized,

Attempt to execute an accumulating asynchronous computation over a +stream, collecting all the values into one final result. Read more
§

fn try_concat(self) -> TryConcat<Self>
where + Self: Sized, + Self::Ok: Extend<<Self::Ok as IntoIterator>::Item> + IntoIterator + Default,

Attempt to concatenate all items of a stream into a single +extendable destination, returning a future representing the end result. Read more
§

fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently (unordered). Read more
§

fn try_buffered(self, n: usize) -> TryBuffered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently. Read more
§

fn try_poll_next_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Option<Result<Self::Ok, Self::Error>>>
where + Self: Unpin,

A convenience method for calling [TryStream::try_poll_next] on Unpin +stream types.
§

fn try_all<Fut, F>(self, f: F) -> TryAll<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if all items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that does not satisfy the predicate. Read more
§

fn try_any<Fut, F>(self, f: F) -> TryAny<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if any items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that satisfies the predicate. Read more
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_multipart/test/fn.create_form_data_payload_and_headers.html b/actix_multipart/test/fn.create_form_data_payload_and_headers.html new file mode 100644 index 000000000..67252ee31 --- /dev/null +++ b/actix_multipart/test/fn.create_form_data_payload_and_headers.html @@ -0,0 +1,44 @@ +create_form_data_payload_and_headers in actix_multipart::test - Rust
pub fn create_form_data_payload_and_headers(
+    name: &str,
+    filename: Option<String>,
+    content_type: Option<Mime>,
+    file: Bytes
+) -> (Bytes, HeaderMap)
Expand description

Constructs a multipart/form-data payload from bytes and metadata.

+

Returned header map can be extended or merged with existing headers.

+

Multipart boundary used is a random alphanumeric string.

+

§Examples

+
use actix_multipart::test::create_form_data_payload_and_headers;
+use actix_web::test::TestRequest;
+use bytes::Bytes;
+use memchr::memmem::find;
+
+let (body, headers) = create_form_data_payload_and_headers(
+    "foo",
+    Some("lorem.txt".to_owned()),
+    Some(mime::TEXT_PLAIN_UTF_8),
+    Bytes::from_static(b"Lorem ipsum."),
+);
+
+assert!(find(&body, b"foo").is_some());
+assert!(find(&body, b"lorem.txt").is_some());
+assert!(find(&body, b"text/plain; charset=utf-8").is_some());
+assert!(find(&body, b"Lorem ipsum.").is_some());
+
+let req = TestRequest::default();
+
+// merge header map into existing test request and set multipart body
+let req = headers
+    .into_iter()
+    .fold(req, |req, hdr| req.insert_header(hdr))
+    .set_payload(body)
+    .to_http_request();
+
+assert!(
+    req.headers()
+        .get("content-type")
+        .unwrap()
+        .to_str()
+        .unwrap()
+        .starts_with("multipart/form-data; boundary=\"")
+);
+
\ No newline at end of file diff --git a/actix_multipart/test/fn.create_form_data_payload_and_headers_with_boundary.html b/actix_multipart/test/fn.create_form_data_payload_and_headers_with_boundary.html new file mode 100644 index 000000000..a38b0baa2 --- /dev/null +++ b/actix_multipart/test/fn.create_form_data_payload_and_headers_with_boundary.html @@ -0,0 +1,9 @@ +create_form_data_payload_and_headers_with_boundary in actix_multipart::test - Rust
pub fn create_form_data_payload_and_headers_with_boundary(
+    boundary: &str,
+    name: &str,
+    filename: Option<String>,
+    content_type: Option<Mime>,
+    file: Bytes
+) -> (Bytes, HeaderMap)
Expand description

Constructs a multipart/form-data payload from bytes and metadata with a fixed boundary.

+

See create_form_data_payload_and_headers for more details.

+
\ No newline at end of file diff --git a/actix_multipart/test/index.html b/actix_multipart/test/index.html new file mode 100644 index 000000000..d8efa8f99 --- /dev/null +++ b/actix_multipart/test/index.html @@ -0,0 +1 @@ +actix_multipart::test - Rust

Module actix_multipart::test

source ·

Functions§

\ No newline at end of file diff --git a/actix_multipart/test/sidebar-items.js b/actix_multipart/test/sidebar-items.js new file mode 100644 index 000000000..45a75ad48 --- /dev/null +++ b/actix_multipart/test/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["create_form_data_payload_and_headers","create_form_data_payload_and_headers_with_boundary"]}; \ No newline at end of file diff --git a/actix_multipart_derive/all.html b/actix_multipart_derive/all.html new file mode 100644 index 000000000..e33d4d087 --- /dev/null +++ b/actix_multipart_derive/all.html @@ -0,0 +1 @@ +List of all items in this crate

List of all items

Derive Macros

\ No newline at end of file diff --git a/actix_multipart_derive/derive.MultipartForm.html b/actix_multipart_derive/derive.MultipartForm.html new file mode 100644 index 000000000..b0c728820 --- /dev/null +++ b/actix_multipart_derive/derive.MultipartForm.html @@ -0,0 +1,76 @@ +MultipartForm in actix_multipart_derive - Rust

Derive Macro actix_multipart_derive::MultipartForm

source ·
#[derive(MultipartForm)]
+{
+    // Attributes available to this derive:
+    #[multipart]
+}
+
Expand description

Implements MultipartCollect for a struct so that it can be used with the MultipartForm +extractor.

+

§Basic Use

+

Each field type should implement the FieldReader trait:

+ +
use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
+
+#[derive(MultipartForm)]
+struct ImageUpload {
+    description: Text<String>,
+    timestamp: Text<i64>,
+    image: TempFile,
+}
+

§Optional and List Fields

+

You can also use Vec<T> and Option<T> provided that T: FieldReader.

+

A Vec field corresponds to an upload with multiple parts under the same field +name.

+ +
use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
+
+#[derive(MultipartForm)]
+struct Form {
+    category: Option<Text<String>>,
+    files: Vec<TempFile>,
+}
+

§Field Renaming

+

You can use the #[multipart(rename = "foo")] attribute to receive a field by a different name.

+ +
use actix_multipart::form::{tempfile::TempFile, MultipartForm};
+
+#[derive(MultipartForm)]
+struct Form {
+    #[multipart(rename = "files[]")]
+    files: Vec<TempFile>,
+}
+

§Field Limits

+

You can use the #[multipart(limit = "<size>")] attribute to set field level limits. The limit +string is parsed using parse_size.

+

Note: the form is also subject to the global limits configured using MultipartFormConfig.

+ +
use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
+
+#[derive(MultipartForm)]
+struct Form {
+    #[multipart(limit = "2 KiB")]
+    description: Text<String>,
+
+    #[multipart(limit = "512 MiB")]
+    files: Vec<TempFile>,
+}
+

§Unknown Fields

+

By default fields with an unknown name are ignored. They can be rejected using the +#[multipart(deny_unknown_fields)] attribute:

+ +
#[derive(MultipartForm)]
+#[multipart(deny_unknown_fields)]
+struct Form { }
+

§Duplicate Fields

+

The behaviour for when multiple fields with the same name are received can be changed using the +#[multipart(duplicate_field = "<behavior>")] attribute:

+
    +
  • “ignore”: (default) Extra fields are ignored. I.e., the first one is persisted.
  • +
  • “deny”: A MultipartError::UnsupportedField error response is returned.
  • +
  • “replace”: Each field is processed, but only the last one is persisted.
  • +
+

Note that Vec fields will ignore this option.

+ +
#[derive(MultipartForm)]
+#[multipart(duplicate_field = "deny")]
+struct Form { }
+
\ No newline at end of file diff --git a/actix_multipart_derive/index.html b/actix_multipart_derive/index.html new file mode 100644 index 000000000..3952a286e --- /dev/null +++ b/actix_multipart_derive/index.html @@ -0,0 +1,4 @@ +actix_multipart_derive - Rust

Crate actix_multipart_derive

source ·
Expand description

Multipart form derive macro for Actix Web.

+

See MultipartForm for usage examples.

+

Derive Macros§

  • Implements MultipartCollect for a struct so that it can be used with the MultipartForm +extractor.
\ No newline at end of file diff --git a/actix_multipart_derive/sidebar-items.js b/actix_multipart_derive/sidebar-items.js new file mode 100644 index 000000000..94ea38e93 --- /dev/null +++ b/actix_multipart_derive/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"derive":["MultipartForm"]}; \ No newline at end of file diff --git a/actix_router/all.html b/actix_router/all.html new file mode 100644 index 000000000..3a4206616 --- /dev/null +++ b/actix_router/all.html @@ -0,0 +1 @@ +List of all items in this crate
\ No newline at end of file diff --git a/actix_router/de/struct.PathDeserializer.html b/actix_router/de/struct.PathDeserializer.html new file mode 100644 index 000000000..15fadea4e --- /dev/null +++ b/actix_router/de/struct.PathDeserializer.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_router/struct.PathDeserializer.html...

+ + + \ No newline at end of file diff --git a/actix_router/enum.Patterns.html b/actix_router/enum.Patterns.html new file mode 100644 index 000000000..228ef0f35 --- /dev/null +++ b/actix_router/enum.Patterns.html @@ -0,0 +1,25 @@ +Patterns in actix_router - Rust

Enum actix_router::Patterns

source ·
pub enum Patterns {
+    Single(String),
+    List(Vec<String>),
+}
Expand description

One or many patterns.

+

Variants§

§

Single(String)

§

List(Vec<String>)

Implementations§

source§

impl Patterns

source

pub fn is_empty(&self) -> bool

Trait Implementations§

source§

impl Clone for Patterns

source§

fn clone(&self) -> Patterns

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Patterns

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Hash for Patterns

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl IntoPatterns for Patterns

source§

impl PartialEq for Patterns

source§

fn eq(&self, other: &Patterns) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for Patterns

source§

impl StructuralPartialEq for Patterns

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_router/index.html b/actix_router/index.html new file mode 100644 index 000000000..73d77b6b8 --- /dev/null +++ b/actix_router/index.html @@ -0,0 +1,2 @@ +actix_router - Rust

Crate actix_router

source ·
Expand description

Resource path matching and router.

+

Structs§

Enums§

Traits§

\ No newline at end of file diff --git a/actix_router/path/struct.Path.html b/actix_router/path/struct.Path.html new file mode 100644 index 000000000..7166fdc8a --- /dev/null +++ b/actix_router/path/struct.Path.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_router/struct.Path.html...

+ + + \ No newline at end of file diff --git a/actix_router/pattern/enum.Patterns.html b/actix_router/pattern/enum.Patterns.html new file mode 100644 index 000000000..e201a50e6 --- /dev/null +++ b/actix_router/pattern/enum.Patterns.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_router/enum.Patterns.html...

+ + + \ No newline at end of file diff --git a/actix_router/pattern/trait.IntoPatterns.html b/actix_router/pattern/trait.IntoPatterns.html new file mode 100644 index 000000000..be3d8382b --- /dev/null +++ b/actix_router/pattern/trait.IntoPatterns.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_router/trait.IntoPatterns.html...

+ + + \ No newline at end of file diff --git a/actix_router/quoter/struct.Quoter.html b/actix_router/quoter/struct.Quoter.html new file mode 100644 index 000000000..849066cdc --- /dev/null +++ b/actix_router/quoter/struct.Quoter.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_router/struct.Quoter.html...

+ + + \ No newline at end of file diff --git a/actix_router/resource/struct.ResourceDef.html b/actix_router/resource/struct.ResourceDef.html new file mode 100644 index 000000000..bb29ef4ab --- /dev/null +++ b/actix_router/resource/struct.ResourceDef.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_router/struct.ResourceDef.html...

+ + + \ No newline at end of file diff --git a/actix_router/resource_path/trait.Resource.html b/actix_router/resource_path/trait.Resource.html new file mode 100644 index 000000000..91c500d7d --- /dev/null +++ b/actix_router/resource_path/trait.Resource.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_router/trait.Resource.html...

+ + + \ No newline at end of file diff --git a/actix_router/resource_path/trait.ResourcePath.html b/actix_router/resource_path/trait.ResourcePath.html new file mode 100644 index 000000000..81f91b65d --- /dev/null +++ b/actix_router/resource_path/trait.ResourcePath.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_router/trait.ResourcePath.html...

+ + + \ No newline at end of file diff --git a/actix_router/router/struct.ResourceId.html b/actix_router/router/struct.ResourceId.html new file mode 100644 index 000000000..9f70e7c88 --- /dev/null +++ b/actix_router/router/struct.ResourceId.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_router/struct.ResourceId.html...

+ + + \ No newline at end of file diff --git a/actix_router/router/struct.Router.html b/actix_router/router/struct.Router.html new file mode 100644 index 000000000..c249a70f4 --- /dev/null +++ b/actix_router/router/struct.Router.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_router/struct.Router.html...

+ + + \ No newline at end of file diff --git a/actix_router/router/struct.RouterBuilder.html b/actix_router/router/struct.RouterBuilder.html new file mode 100644 index 000000000..fdf2501bb --- /dev/null +++ b/actix_router/router/struct.RouterBuilder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_router/struct.RouterBuilder.html...

+ + + \ No newline at end of file diff --git a/actix_router/sidebar-items.js b/actix_router/sidebar-items.js new file mode 100644 index 000000000..49979aea9 --- /dev/null +++ b/actix_router/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Patterns"],"struct":["Path","PathDeserializer","Quoter","ResourceDef","ResourceId","Router","RouterBuilder","Url"],"trait":["IntoPatterns","Resource","ResourcePath"]}; \ No newline at end of file diff --git a/actix_router/struct.Path.html b/actix_router/struct.Path.html new file mode 100644 index 000000000..1e4f86db0 --- /dev/null +++ b/actix_router/struct.Path.html @@ -0,0 +1,42 @@ +Path in actix_router - Rust

Struct actix_router::Path

source ·
pub struct Path<T> { /* private fields */ }
Expand description

Resource path match information.

+

If resource path contains variable patterns, Path stores them.

+

Implementations§

source§

impl<T: ResourcePath> Path<T>

source

pub fn new(path: T) -> Path<T>

source

pub fn get_ref(&self) -> &T

Returns reference to inner path instance.

+
source

pub fn get_mut(&mut self) -> &mut T

Returns mutable reference to inner path instance.

+
source

pub fn as_str(&self) -> &str

Returns full path as a string.

+
source

pub fn unprocessed(&self) -> &str

Returns unprocessed part of the path.

+

Returns empty string if no more is to be processed.

+
source

pub fn set(&mut self, path: T)

Set new path.

+
source

pub fn reset(&mut self)

Reset state.

+
source

pub fn skip(&mut self, n: u16)

Skip first n chars in path.

+
source

pub fn is_empty(&self) -> bool

Check if there are any matched patterns.

+
source

pub fn segment_count(&self) -> usize

Returns number of interpolated segments.

+
source

pub fn get(&self, name: &str) -> Option<&str>

Get matched parameter by name without type conversion

+
source

pub fn query(&self, key: &str) -> &str

Returns matched parameter by name.

+

If keyed parameter is not available empty string is used as default value.

+
source

pub fn iter(&self) -> PathIter<'_, T>

Return iterator to items in parameter container.

+
source

pub fn load<'de, U: Deserialize<'de>>(&'de self) -> Result<U, Error>

Deserializes matching parameters to a specified type U.

+
§Errors
+

Returns error when dynamic path segments cannot be deserialized into a U type.

+

Trait Implementations§

source§

impl<T: Clone> Clone for Path<T>

source§

fn clone(&self) -> Path<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for Path<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: Default> Default for Path<T>

source§

fn default() -> Path<T>

Returns the “default value” for a type. Read more
source§

impl<'a, T: ResourcePath> Index<&'a str> for Path<T>

§

type Output = str

The returned type after indexing.
source§

fn index(&self, name: &'a str) -> &str

Performs the indexing (container[index]) operation. Read more
source§

impl<T: ResourcePath> Index<usize> for Path<T>

§

type Output = str

The returned type after indexing.
source§

fn index(&self, idx: usize) -> &str

Performs the indexing (container[index]) operation. Read more
source§

impl<T: ResourcePath> Resource for Path<T>

§

type Path = T

Type of resource’s path returned in resource_path.
source§

fn resource_path(&mut self) -> &mut Path<Self::Path>

Auto Trait Implementations§

§

impl<T> Freeze for Path<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for Path<T>
where + T: RefUnwindSafe,

§

impl<T> Send for Path<T>
where + T: Send,

§

impl<T> Sync for Path<T>
where + T: Sync,

§

impl<T> Unpin for Path<T>
where + T: Unpin,

§

impl<T> UnwindSafe for Path<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_router/struct.PathDeserializer.html b/actix_router/struct.PathDeserializer.html new file mode 100644 index 000000000..301038773 --- /dev/null +++ b/actix_router/struct.PathDeserializer.html @@ -0,0 +1,103 @@ +PathDeserializer in actix_router - Rust

Struct actix_router::PathDeserializer

source ·
pub struct PathDeserializer<'de, T: ResourcePath> { /* private fields */ }

Implementations§

source§

impl<'de, T: ResourcePath + 'de> PathDeserializer<'de, T>

source

pub fn new(path: &'de Path<T>) -> Self

Trait Implementations§

source§

impl<'de, T: ResourcePath + 'de> Deserializer<'de> for PathDeserializer<'de, T>

§

type Error = Error

The error type that can be returned if some error occurs during +deserialization.
source§

fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a map of key-value pairs.
source§

fn deserialize_struct<V>( + self, + _: &'static str, + _: &'static [&'static str], + visitor: V +) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a struct with a particular +name and fields.
source§

fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a unit value.
source§

fn deserialize_unit_struct<V>( + self, + _: &'static str, + visitor: V +) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a unit struct with a +particular name.
source§

fn deserialize_newtype_struct<V>( + self, + _: &'static str, + visitor: V +) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a newtype struct with a +particular name.
source§

fn deserialize_tuple<V>( + self, + len: usize, + visitor: V +) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a sequence of values and +knows how many values there are without looking at the serialized data.
source§

fn deserialize_tuple_struct<V>( + self, + _: &'static str, + len: usize, + visitor: V +) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a tuple struct with a +particular name and number of fields.
source§

fn deserialize_enum<V>( + self, + _: &'static str, + _: &'static [&'static str], + visitor: V +) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting an enum value with a +particular name and possible variants.
source§

fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a sequence of values.
source§

fn deserialize_any<V>(self, _: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Require the Deserializer to figure out how to drive the visitor based +on what data type is in the input. Read more
source§

fn deserialize_option<V>(self, _: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting an optional value. Read more
source§

fn deserialize_identifier<V>(self, _: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting the name of a struct +field or the discriminant of an enum variant.
source§

fn deserialize_ignored_any<V>(self, _: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type needs to deserialize a value whose type +doesn’t matter because it is ignored. Read more
source§

fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a bool value.
source§

fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting an i8 value.
source§

fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting an i16 value.
source§

fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting an i32 value.
source§

fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting an i64 value.
source§

fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a u8 value.
source§

fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a u16 value.
source§

fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a u32 value.
source§

fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a u64 value.
source§

fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a f32 value.
source§

fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a f64 value.
source§

fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a string value and does +not benefit from taking ownership of buffered data owned by the +Deserializer. Read more
source§

fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a string value and would +benefit from taking ownership of buffered data owned by the +Deserializer. Read more
source§

fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a byte array and does not +benefit from taking ownership of buffered data owned by the +Deserializer. Read more
source§

fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a byte array and would +benefit from taking ownership of buffered data owned by the +Deserializer. Read more
source§

fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting a char value.
source§

fn deserialize_i128<V>( + self, + visitor: V +) -> Result<<V as Visitor<'de>>::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting an i128 value. Read more
source§

fn deserialize_u128<V>( + self, + visitor: V +) -> Result<<V as Visitor<'de>>::Value, Self::Error>
where + V: Visitor<'de>,

Hint that the Deserialize type is expecting an u128 value. Read more
source§

fn is_human_readable(&self) -> bool

Determine whether Deserialize implementations should expect to +deserialize their human-readable form. Read more

Auto Trait Implementations§

§

impl<'de, T> Freeze for PathDeserializer<'de, T>

§

impl<'de, T> RefUnwindSafe for PathDeserializer<'de, T>
where + T: RefUnwindSafe,

§

impl<'de, T> Send for PathDeserializer<'de, T>
where + T: Sync,

§

impl<'de, T> Sync for PathDeserializer<'de, T>
where + T: Sync,

§

impl<'de, T> Unpin for PathDeserializer<'de, T>

§

impl<'de, T> UnwindSafe for PathDeserializer<'de, T>
where + T: RefUnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_router/struct.Quoter.html b/actix_router/struct.Quoter.html new file mode 100644 index 000000000..0f5ae381e --- /dev/null +++ b/actix_router/struct.Quoter.html @@ -0,0 +1,32 @@ +Quoter in actix_router - Rust

Struct actix_router::Quoter

source ·
pub struct Quoter { /* private fields */ }
Expand description

Partial percent-decoding.

+

Performs percent-decoding on a slice but can selectively skip decoding certain sequences.

+

§Examples

+
// + is set as a protected character and will not be decoded...
+let q = Quoter::new(&[], b"+");
+
+// ...but the other encoded characters (like the hyphen below) will.
+assert_eq!(q.requote(b"/a%2Db%2Bc").unwrap(), b"/a-b%2Bc");
+

Implementations§

source§

impl Quoter

source

pub fn new(_: &[u8], protected: &[u8]) -> Quoter

Constructs a new Quoter instance given a set of protected ASCII bytes.

+

The first argument is ignored but is kept for backward compatibility.

+
§Panics
+

Panics if any of the protected bytes are not in the 0-127 ASCII range.

+
source

pub fn requote(&self, val: &[u8]) -> Option<Vec<u8>>

Partially percent-decodes the given bytes.

+

Escape sequences of the protected set are not decoded.

+

Returns None when no modification to the original bytes was required.

+

Invalid/incomplete percent-encoding sequences are passed unmodified.

+

Auto Trait Implementations§

§

impl Freeze for Quoter

§

impl RefUnwindSafe for Quoter

§

impl Send for Quoter

§

impl Sync for Quoter

§

impl Unpin for Quoter

§

impl UnwindSafe for Quoter

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_router/struct.ResourceDef.html b/actix_router/struct.ResourceDef.html new file mode 100644 index 000000000..688cea4d4 --- /dev/null +++ b/actix_router/struct.ResourceDef.html @@ -0,0 +1,403 @@ +ResourceDef in actix_router - Rust

Struct actix_router::ResourceDef

source ·
pub struct ResourceDef { /* private fields */ }
Expand description

Describes the set of paths that match to a resource.

+

ResourceDefs are effectively a way to transform the a custom resource pattern syntax into +suitable regular expressions from which to check matches with paths and capture portions of a +matched path into variables. Common cases are on a fast path that avoids going through the +regex engine.

+

§Pattern Format and Matching Behavior

+

Resource pattern is defined as a string of zero or more segments where each segment is +preceded by a slash /.

+

This means that pattern string must either be empty or begin with a slash (/). This also +implies that a trailing slash in pattern defines an empty segment. For example, the pattern +"/user/" has two segments: ["user", ""]

+

A key point to understand is that ResourceDef matches segments, not strings. Segments are +matched individually. For example, the pattern /user/ is not considered a prefix for the path +/user/123/456, because the second segment doesn’t match: ["user", ""] +vs ["user", "123", "456"].

+

This definition is consistent with the definition of absolute URL path in +RFC 3986 §3.3

+

§Static Resources

+

A static resource is the most basic type of definition. Pass a pattern to new. +Conforming paths must match the pattern exactly.

+

§Examples

+
let resource = ResourceDef::new("/home");
+
+assert!(resource.is_match("/home"));
+
+assert!(!resource.is_match("/home/"));
+assert!(!resource.is_match("/home/new"));
+assert!(!resource.is_match("/homes"));
+assert!(!resource.is_match("/search"));
+

§Dynamic Segments

+

Also known as “path parameters”. Resources can define sections of a pattern that be extracted +from a conforming path, if it conforms to (one of) the resource pattern(s).

+

The marker for a dynamic segment is curly braces wrapping an identifier. For example, +/user/{id} would match paths like /user/123 or /user/james and be able to extract the user +IDs “123” and “james”, respectively.

+

However, this resource pattern (/user/{id}) would, not cover /user/123/stars (unless +constructed as a prefix; see next section) since the default pattern for segments matches all +characters until it finds a / character (or the end of the path). Custom segment patterns are +covered further down.

+

Dynamic segments do not need to be delimited by / characters, they can be defined within a +path segment. For example, /rust-is-{opinion} can match the paths /rust-is-cool and +/rust-is-hard.

+

For information on capturing segment values from paths or other custom resource types, +see capture_match_info +and capture_match_info_fn.

+

A resource definition can contain at most 16 dynamic segments.

+

§Examples

+
use actix_router::{Path, ResourceDef};
+
+let resource = ResourceDef::prefix("/user/{id}");
+
+assert!(resource.is_match("/user/123"));
+assert!(!resource.is_match("/user"));
+assert!(!resource.is_match("/user/"));
+
+let mut path = Path::new("/user/123");
+resource.capture_match_info(&mut path);
+assert_eq!(path.get("id").unwrap(), "123");
+

§Prefix Resources

+

A prefix resource is defined as pattern that can match just the start of a path, up to a +segment boundary.

+

Prefix patterns with a trailing slash may have an unexpected, though correct, behavior. +They define and therefore require an empty segment in order to match. It is easier to understand +this behavior after reading the matching behavior section. Examples are given below.

+

The empty pattern (""), as a prefix, matches any path.

+

Prefix resources can contain dynamic segments.

+

§Examples

+
let resource = ResourceDef::prefix("/home");
+assert!(resource.is_match("/home"));
+assert!(resource.is_match("/home/new"));
+assert!(!resource.is_match("/homes"));
+
+// prefix pattern with a trailing slash
+let resource = ResourceDef::prefix("/user/{id}/");
+assert!(resource.is_match("/user/123/"));
+assert!(resource.is_match("/user/123//stars"));
+assert!(!resource.is_match("/user/123/stars"));
+assert!(!resource.is_match("/user/123"));
+

§Custom Regex Segments

+

Dynamic segments can be customised to only match a specific regular expression. It can be +helpful to do this if resource definitions would otherwise conflict and cause one to +be inaccessible.

+

The regex used when capturing segment values can be specified explicitly using this syntax: +{name:regex}. For example, /user/{id:\d+} will only match paths where the user ID +is numeric.

+

The regex could potentially match multiple segments. If this is not wanted, then care must be +taken to avoid matching a slash /. It is guaranteed, however, that the match ends at a +segment boundary; the pattern r"(/|$) is always appended to the regex.

+

By default, dynamic segments use this regex: [^/]+. This shows why it is the case, as shown in +the earlier section, that segments capture a slice of the path up to the next / character.

+

Custom regex segments can be used in static and prefix resource definition variants.

+

§Examples

+
let resource = ResourceDef::new(r"/user/{id:\d+}");
+assert!(resource.is_match("/user/123"));
+assert!(resource.is_match("/user/314159"));
+assert!(!resource.is_match("/user/abc"));
+

§Tail Segments

+

As a shortcut to defining a custom regex for matching all remaining characters (not just those +up until a / character), there is a special pattern to match (and capture) the remaining +path portion.

+

To do this, use the segment pattern: {name}*. Since a tail segment also has a name, values are +extracted in the same way as non-tail dynamic segments.

+

§Examples

+
let resource = ResourceDef::new("/blob/{tail}*");
+assert!(resource.is_match("/blob/HEAD/Cargo.toml"));
+assert!(resource.is_match("/blob/HEAD/README.md"));
+
+let mut path = Path::new("/blob/main/LICENSE");
+resource.capture_match_info(&mut path);
+assert_eq!(path.get("tail").unwrap(), "main/LICENSE");
+

§Multi-Pattern Resources

+

For resources that can map to multiple distinct paths, it may be suitable to use +multi-pattern resources by passing an array/vec to new. They will be combined +into a regex set which is usually quicker to check matches on than checking each +pattern individually.

+

Multi-pattern resources can contain dynamic segments just like single pattern ones. +However, take care to use consistent and semantically-equivalent segment names; it could affect +expectations in the router using these definitions and cause runtime panics.

+

§Examples

+
let resource = ResourceDef::new(["/home", "/index"]);
+assert!(resource.is_match("/home"));
+assert!(resource.is_match("/index"));
+

§Trailing Slashes

+

It should be noted that this library takes no steps to normalize intra-path or trailing slashes. +As such, all resource definitions implicitly expect a pre-processing step to normalize paths if +you wish to accommodate “recoverable” path errors. Below are several examples of resource-path +pairs that would not be compatible.

+

§Examples

+
assert!(!ResourceDef::new("/root").is_match("/root/"));
+assert!(!ResourceDef::new("/root/").is_match("/root"));
+assert!(!ResourceDef::prefix("/root/").is_match("/root"));
+

Implementations§

source§

impl ResourceDef

source

pub fn new<T: IntoPatterns>(paths: T) -> Self

Constructs a new resource definition from patterns.

+

Multi-pattern resources can be constructed by providing a slice (or vec) of patterns.

+
§Panics
+

Panics if any path patterns are malformed.

+
§Examples
+
use actix_router::ResourceDef;
+
+let resource = ResourceDef::new("/user/{id}");
+assert!(resource.is_match("/user/123"));
+assert!(!resource.is_match("/user/123/stars"));
+assert!(!resource.is_match("user/1234"));
+assert!(!resource.is_match("/foo"));
+
+let resource = ResourceDef::new(["/profile", "/user/{id}"]);
+assert!(resource.is_match("/profile"));
+assert!(resource.is_match("/user/123"));
+assert!(!resource.is_match("user/123"));
+assert!(!resource.is_match("/foo"));
+
source

pub fn prefix<T: IntoPatterns>(paths: T) -> Self

Constructs a new resource definition using a pattern that performs prefix matching.

+

More specifically, the regular expressions generated for matching are different when using +this method vs using new; they will not be appended with the $ meta-character that +matches the end of an input.

+

Although it will compile and run correctly, it is meaningless to construct a prefix +resource definition with a tail segment; use new in this case.

+
§Panics
+

Panics if path pattern is malformed.

+
§Examples
+
use actix_router::ResourceDef;
+
+let resource = ResourceDef::prefix("/user/{id}");
+assert!(resource.is_match("/user/123"));
+assert!(resource.is_match("/user/123/stars"));
+assert!(!resource.is_match("user/123"));
+assert!(!resource.is_match("user/123/stars"));
+assert!(!resource.is_match("/foo"));
+
source

pub fn root_prefix(path: &str) -> Self

Constructs a new resource definition using a string pattern that performs prefix matching, +ensuring a leading / if pattern is not empty.

+
§Panics
+

Panics if path pattern is malformed.

+
§Examples
+
use actix_router::ResourceDef;
+
+let resource = ResourceDef::root_prefix("user/{id}");
+
+assert_eq!(&resource, &ResourceDef::prefix("/user/{id}"));
+assert_eq!(&resource, &ResourceDef::root_prefix("/user/{id}"));
+assert_ne!(&resource, &ResourceDef::new("user/{id}"));
+assert_ne!(&resource, &ResourceDef::new("/user/{id}"));
+
+assert!(resource.is_match("/user/123"));
+assert!(!resource.is_match("user/123"));
+
source

pub fn id(&self) -> u16

Returns a numeric resource ID.

+

If not explicitly set using set_id, this will return 0.

+
§Examples
+
let mut resource = ResourceDef::new("/root");
+assert_eq!(resource.id(), 0);
+
+resource.set_id(42);
+assert_eq!(resource.id(), 42);
+
source

pub fn set_id(&mut self, id: u16)

Set numeric resource ID.

+
§Examples
+
let mut resource = ResourceDef::new("/root");
+resource.set_id(42);
+assert_eq!(resource.id(), 42);
+
source

pub fn name(&self) -> Option<&str>

Returns resource definition name, if set.

+
§Examples
+
let mut resource = ResourceDef::new("/root");
+assert!(resource.name().is_none());
+
+resource.set_name("root");
+assert_eq!(resource.name().unwrap(), "root");
+
source

pub fn set_name(&mut self, name: impl Into<String>)

Assigns a new name to the resource.

+
§Panics
+

Panics if name is an empty string.

+
§Examples
+
let mut resource = ResourceDef::new("/root");
+resource.set_name("root");
+assert_eq!(resource.name().unwrap(), "root");
+
source

pub fn is_prefix(&self) -> bool

Returns true if pattern type is prefix.

+
§Examples
+
assert!(ResourceDef::prefix("/user").is_prefix());
+assert!(!ResourceDef::new("/user").is_prefix());
+
source

pub fn pattern(&self) -> Option<&str>

Returns the pattern string that generated the resource definition.

+

If definition is constructed with multiple patterns, the first pattern is returned. To get +all patterns, use patterns_iter. If resource has 0 patterns, +returns None.

+
§Examples
+
let mut resource = ResourceDef::new("/user/{id}");
+assert_eq!(resource.pattern().unwrap(), "/user/{id}");
+
+let mut resource = ResourceDef::new(["/profile", "/user/{id}"]);
+assert_eq!(resource.pattern(), Some("/profile"));
+
source

pub fn pattern_iter(&self) -> impl Iterator<Item = &str>

Returns iterator of pattern strings that generated the resource definition.

+
§Examples
+
let mut resource = ResourceDef::new("/root");
+let mut iter = resource.pattern_iter();
+assert_eq!(iter.next().unwrap(), "/root");
+assert!(iter.next().is_none());
+
+let mut resource = ResourceDef::new(["/root", "/backup"]);
+let mut iter = resource.pattern_iter();
+assert_eq!(iter.next().unwrap(), "/root");
+assert_eq!(iter.next().unwrap(), "/backup");
+assert!(iter.next().is_none());
+
source

pub fn join(&self, other: &ResourceDef) -> ResourceDef

Joins two resources.

+

Resulting resource is prefix if other is prefix.

+
§Examples
+
let joined = ResourceDef::prefix("/root").join(&ResourceDef::prefix("/seg"));
+assert_eq!(joined, ResourceDef::prefix("/root/seg"));
+
source

pub fn is_match(&self, path: &str) -> bool

Returns true if path matches this resource.

+

The behavior of this method depends on how the ResourceDef was constructed. For example, +static resources will not be able to match as many paths as dynamic and prefix resources. +See ResourceDef struct docs for details on resource definition types.

+

This method will always agree with find_match on whether the path +matches or not.

+
§Examples
+
use actix_router::ResourceDef;
+
+// static resource
+let resource = ResourceDef::new("/user");
+assert!(resource.is_match("/user"));
+assert!(!resource.is_match("/users"));
+assert!(!resource.is_match("/user/123"));
+assert!(!resource.is_match("/foo"));
+
+// dynamic resource
+let resource = ResourceDef::new("/user/{user_id}");
+assert!(resource.is_match("/user/123"));
+assert!(!resource.is_match("/user/123/stars"));
+
+// prefix resource
+let resource = ResourceDef::prefix("/root");
+assert!(resource.is_match("/root"));
+assert!(resource.is_match("/root/leaf"));
+assert!(!resource.is_match("/roots"));
+
+// more examples are shown in the `ResourceDef` struct docs
+
source

pub fn find_match(&self, path: &str) -> Option<usize>

Tries to match path to this resource, returning the position in the path where the +match ends.

+

This method will always agree with is_match on whether the path matches +or not.

+
§Examples
+
use actix_router::ResourceDef;
+
+// static resource
+let resource = ResourceDef::new("/user");
+assert_eq!(resource.find_match("/user"), Some(5));
+assert!(resource.find_match("/user/").is_none());
+assert!(resource.find_match("/user/123").is_none());
+assert!(resource.find_match("/foo").is_none());
+
+// constant prefix resource
+let resource = ResourceDef::prefix("/user");
+assert_eq!(resource.find_match("/user"), Some(5));
+assert_eq!(resource.find_match("/user/"), Some(5));
+assert_eq!(resource.find_match("/user/123"), Some(5));
+
+// dynamic prefix resource
+let resource = ResourceDef::prefix("/user/{id}");
+assert_eq!(resource.find_match("/user/123"), Some(9));
+assert_eq!(resource.find_match("/user/1234/"), Some(10));
+assert_eq!(resource.find_match("/user/12345/stars"), Some(11));
+assert!(resource.find_match("/user/").is_none());
+
+// multi-pattern resource
+let resource = ResourceDef::new(["/user/{id}", "/profile/{id}"]);
+assert_eq!(resource.find_match("/user/123"), Some(9));
+assert_eq!(resource.find_match("/profile/1234"), Some(13));
+
source

pub fn capture_match_info<R: Resource>(&self, resource: &mut R) -> bool

Collects dynamic segment values into resource.

+

Returns true if path matches this resource.

+
§Examples
+
use actix_router::{Path, ResourceDef};
+
+let resource = ResourceDef::prefix("/user/{id}");
+let mut path = Path::new("/user/123/stars");
+assert!(resource.capture_match_info(&mut path));
+assert_eq!(path.get("id").unwrap(), "123");
+assert_eq!(path.unprocessed(), "/stars");
+
+let resource = ResourceDef::new("/blob/{path}*");
+let mut path = Path::new("/blob/HEAD/Cargo.toml");
+assert!(resource.capture_match_info(&mut path));
+assert_eq!(path.get("path").unwrap(), "HEAD/Cargo.toml");
+assert_eq!(path.unprocessed(), "");
+
source

pub fn capture_match_info_fn<R, F>(&self, resource: &mut R, check_fn: F) -> bool
where + R: Resource, + F: FnOnce(&R) -> bool,

Collects dynamic segment values into resource after matching paths and executing +check function.

+

The check function is given a reference to the passed resource and optional arbitrary data. +This is useful if you want to conditionally match on some non-path related aspect of the +resource type.

+

Returns true if resource path matches this resource definition and satisfies the +given check function.

+
§Examples
+
use actix_router::{Path, ResourceDef};
+
+fn try_match(resource: &ResourceDef, path: &mut Path<&str>) -> bool {
+    let admin_allowed = std::env::var("ADMIN_ALLOWED").is_ok();
+
+    resource.capture_match_info_fn(
+        path,
+        // when env var is not set, reject when path contains "admin"
+        |path| !(!admin_allowed && path.as_str().contains("admin")),
+    )
+}
+
+let resource = ResourceDef::prefix("/user/{id}");
+
+// path matches; segment values are collected into path
+let mut path = Path::new("/user/james/stars");
+assert!(try_match(&resource, &mut path));
+assert_eq!(path.get("id").unwrap(), "james");
+assert_eq!(path.unprocessed(), "/stars");
+
+// path matches but fails check function; no segments are collected
+let mut path = Path::new("/user/admin/stars");
+assert!(!try_match(&resource, &mut path));
+assert_eq!(path.unprocessed(), "/user/admin/stars");
+
source

pub fn resource_path_from_iter<I>(&self, path: &mut String, values: I) -> bool
where + I: IntoIterator, + I::Item: AsRef<str>,

Assembles full resource path from iterator of dynamic segment values.

+

Returns true on success.

+

For multi-pattern resources, the first pattern is used under the assumption that it would be +equivalent to any other choice.

+
§Examples
+
let mut s = String::new();
+let resource = ResourceDef::new("/user/{id}/post/{title}");
+
+assert!(resource.resource_path_from_iter(&mut s, &["123", "my-post"]));
+assert_eq!(s, "/user/123/post/my-post");
+
source

pub fn resource_path_from_map<K, V, S>( + &self, + path: &mut String, + values: &HashMap<K, V, S> +) -> bool
where + K: Borrow<str> + Eq + Hash, + V: AsRef<str>, + S: BuildHasher,

Assembles resource path from map of dynamic segment values.

+

Returns true on success.

+

For multi-pattern resources, the first pattern is used under the assumption that it would be +equivalent to any other choice.

+
§Examples
+
let mut s = String::new();
+let resource = ResourceDef::new("/user/{id}/post/{title}");
+
+let mut map = HashMap::new();
+map.insert("id", "123");
+map.insert("title", "my-post");
+
+assert!(resource.resource_path_from_map(&mut s, &map));
+assert_eq!(s, "/user/123/post/my-post");
+

Trait Implementations§

source§

impl Clone for ResourceDef

source§

fn clone(&self) -> ResourceDef

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ResourceDef

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a str> for ResourceDef

source§

fn from(path: &'a str) -> ResourceDef

Converts to this type from the input type.
source§

impl From<String> for ResourceDef

source§

fn from(path: String) -> ResourceDef

Converts to this type from the input type.
source§

impl Hash for ResourceDef

source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq for ResourceDef

source§

fn eq(&self, other: &ResourceDef) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for ResourceDef

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_router/struct.ResourceId.html b/actix_router/struct.ResourceId.html new file mode 100644 index 000000000..d006e3439 --- /dev/null +++ b/actix_router/struct.ResourceId.html @@ -0,0 +1,19 @@ +ResourceId in actix_router - Rust

Struct actix_router::ResourceId

source ·
pub struct ResourceId(pub u16);

Tuple Fields§

§0: u16

Trait Implementations§

source§

impl Clone for ResourceId

source§

fn clone(&self) -> ResourceId

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ResourceId

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq for ResourceId

source§

fn eq(&self, other: &ResourceId) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for ResourceId

source§

impl Eq for ResourceId

source§

impl StructuralPartialEq for ResourceId

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_router/struct.Router.html b/actix_router/struct.Router.html new file mode 100644 index 000000000..ba64279d1 --- /dev/null +++ b/actix_router/struct.Router.html @@ -0,0 +1,64 @@ +Router in actix_router - Rust

Struct actix_router::Router

source ·
pub struct Router<T, U = ()> { /* private fields */ }
Expand description

Resource router.

+

It matches a routing resource to an ordered list of routes. Each is defined by a +single ResourceDef and contains two types of custom data:

+
    +
  1. The route value, of the generic type T.
  2. +
  3. Some context data, of the generic type U, which is only provided to the check function in +recognize_fn. This parameter defaults to () and can be omitted if +not required.
  4. +
+

Implementations§

source§

impl<T, U> Router<T, U>

source

pub fn build() -> RouterBuilder<T, U>

Constructs new RouterBuilder with empty route list.

+
source

pub fn recognize<R>(&self, resource: &mut R) -> Option<(&T, ResourceId)>
where + R: Resource,

Finds the value in the router that matches a given routing resource.

+

The match result, including the captured dynamic segments, in the resource.

+
source

pub fn recognize_mut<R>( + &mut self, + resource: &mut R +) -> Option<(&mut T, ResourceId)>
where + R: Resource,

Same as recognize but returns a mutable reference to the matched value.

+
source

pub fn recognize_fn<R, F>( + &self, + resource: &mut R, + check: F +) -> Option<(&T, ResourceId)>
where + R: Resource, + F: FnMut(&R, &U) -> bool,

Finds the value in the router that matches a given routing resource and passes +an additional predicate check using context data.

+

Similar to recognize. However, before accepting the route as matched, +the check closure is executed, passing the resource and each route’s context data. If the +closure returns true then the match result is stored into resource and a reference to +the matched value is returned.

+
source

pub fn recognize_mut_fn<R, F>( + &mut self, + resource: &mut R, + check: F +) -> Option<(&mut T, ResourceId)>
where + R: Resource, + F: FnMut(&R, &U) -> bool,

Same as recognize_fn but returns a mutable reference to the matched +value.

+

Auto Trait Implementations§

§

impl<T, U> Freeze for Router<T, U>

§

impl<T, U> RefUnwindSafe for Router<T, U>
where + T: RefUnwindSafe, + U: RefUnwindSafe,

§

impl<T, U> Send for Router<T, U>
where + T: Send, + U: Send,

§

impl<T, U> Sync for Router<T, U>
where + T: Sync, + U: Sync,

§

impl<T, U> Unpin for Router<T, U>
where + T: Unpin, + U: Unpin,

§

impl<T, U> UnwindSafe for Router<T, U>
where + T: UnwindSafe, + U: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_router/struct.RouterBuilder.html b/actix_router/struct.RouterBuilder.html new file mode 100644 index 000000000..159ceffc1 --- /dev/null +++ b/actix_router/struct.RouterBuilder.html @@ -0,0 +1,52 @@ +RouterBuilder in actix_router - Rust

Struct actix_router::RouterBuilder

source ·
pub struct RouterBuilder<T, U = ()> { /* private fields */ }
Expand description

Builder for an ordered routing list.

+

Implementations§

source§

impl<T, U> RouterBuilder<T, U>

source

pub fn push( + &mut self, + rdef: ResourceDef, + val: T, + ctx: U +) -> (&mut ResourceDef, &mut T, &mut U)

Adds a new route to the end of the routing list.

+

Returns mutable references to elements of the new route.

+
source

pub fn finish(self) -> Router<T, U>

Finish configuration and create router instance.

+
source§

impl<T, U> RouterBuilder<T, U>
where + U: Default,

Convenience methods provided when context data impls Default

+
source

pub fn path( + &mut self, + path: impl IntoPatterns, + val: T +) -> (&mut ResourceDef, &mut T, &mut U)

Registers resource for specified path.

+
source

pub fn prefix( + &mut self, + prefix: impl IntoPatterns, + val: T +) -> (&mut ResourceDef, &mut T, &mut U)

Registers resource for specified path prefix.

+
source

pub fn rdef( + &mut self, + rdef: ResourceDef, + val: T +) -> (&mut ResourceDef, &mut T, &mut U)

Registers resource for ResourceDef.

+

Auto Trait Implementations§

§

impl<T, U> Freeze for RouterBuilder<T, U>

§

impl<T, U> RefUnwindSafe for RouterBuilder<T, U>
where + T: RefUnwindSafe, + U: RefUnwindSafe,

§

impl<T, U> Send for RouterBuilder<T, U>
where + T: Send, + U: Send,

§

impl<T, U> Sync for RouterBuilder<T, U>
where + T: Sync, + U: Sync,

§

impl<T, U> Unpin for RouterBuilder<T, U>
where + T: Unpin, + U: Unpin,

§

impl<T, U> UnwindSafe for RouterBuilder<T, U>
where + T: UnwindSafe, + U: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_router/struct.Url.html b/actix_router/struct.Url.html new file mode 100644 index 000000000..c4aec0585 --- /dev/null +++ b/actix_router/struct.Url.html @@ -0,0 +1,19 @@ +Url in actix_router - Rust

Struct actix_router::Url

source ·
pub struct Url { /* private fields */ }
Available on crate feature http only.

Implementations§

source§

impl Url

source

pub fn new(uri: Uri) -> Url

source

pub fn new_with_quoter(uri: Uri, quoter: &Quoter) -> Url

source

pub fn uri(&self) -> &Uri

Returns URI.

+
source

pub fn path(&self) -> &str

Returns path.

+
source

pub fn update(&mut self, uri: &Uri)

source

pub fn update_with_quoter(&mut self, uri: &Uri, quoter: &Quoter)

Trait Implementations§

source§

impl Clone for Url

source§

fn clone(&self) -> Url

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Url

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Url

source§

fn default() -> Url

Returns the “default value” for a type. Read more
source§

impl ResourcePath for Url

source§

fn path(&self) -> &str

Auto Trait Implementations§

§

impl !Freeze for Url

§

impl RefUnwindSafe for Url

§

impl Send for Url

§

impl Sync for Url

§

impl Unpin for Url

§

impl UnwindSafe for Url

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_router/trait.IntoPatterns.html b/actix_router/trait.IntoPatterns.html new file mode 100644 index 000000000..148321d50 --- /dev/null +++ b/actix_router/trait.IntoPatterns.html @@ -0,0 +1,5 @@ +IntoPatterns in actix_router - Rust

Trait actix_router::IntoPatterns

source ·
pub trait IntoPatterns {
+    // Required method
+    fn patterns(&self) -> Patterns;
+}
Expand description

Helper trait for type that could be converted to one or more path patterns.

+

Required Methods§

Implementations on Foreign Types§

source§

impl IntoPatterns for &str

source§

impl IntoPatterns for &String

source§

impl IntoPatterns for str

source§

impl IntoPatterns for String

source§

impl IntoPatterns for ByteString

source§

impl IntoPatterns for [&str; 1]

source§

impl IntoPatterns for [&str; 2]

source§

impl IntoPatterns for [&str; 3]

source§

impl IntoPatterns for [&str; 4]

source§

impl IntoPatterns for [&str; 5]

source§

impl IntoPatterns for [&str; 6]

source§

impl IntoPatterns for [&str; 7]

source§

impl IntoPatterns for [&str; 8]

source§

impl IntoPatterns for [&str; 9]

source§

impl IntoPatterns for [&str; 10]

source§

impl IntoPatterns for [&str; 11]

source§

impl IntoPatterns for [&str; 12]

source§

impl IntoPatterns for [&str; 13]

source§

impl IntoPatterns for [&str; 14]

source§

impl IntoPatterns for [&str; 15]

source§

impl IntoPatterns for [&str; 16]

source§

impl IntoPatterns for [String; 1]

source§

impl IntoPatterns for [String; 2]

source§

impl IntoPatterns for [String; 3]

source§

impl IntoPatterns for [String; 4]

source§

impl IntoPatterns for [String; 5]

source§

impl IntoPatterns for [String; 6]

source§

impl IntoPatterns for [String; 7]

source§

impl IntoPatterns for [String; 8]

source§

impl IntoPatterns for [String; 9]

source§

impl IntoPatterns for [String; 10]

source§

impl IntoPatterns for [String; 11]

source§

impl IntoPatterns for [String; 12]

source§

impl IntoPatterns for [String; 13]

source§

impl IntoPatterns for [String; 14]

source§

impl IntoPatterns for [String; 15]

source§

impl IntoPatterns for [String; 16]

source§

impl<T: AsRef<str>> IntoPatterns for Vec<T>

Implementors§

\ No newline at end of file diff --git a/actix_router/trait.Resource.html b/actix_router/trait.Resource.html new file mode 100644 index 000000000..35e38e178 --- /dev/null +++ b/actix_router/trait.Resource.html @@ -0,0 +1,9 @@ +Resource in actix_router - Rust

Trait actix_router::Resource

source ·
pub trait Resource {
+    type Path: ResourcePath;
+
+    // Required method
+    fn resource_path(&mut self) -> &mut Path<Self::Path>;
+}

Required Associated Types§

source

type Path: ResourcePath

Type of resource’s path returned in resource_path.

+

Required Methods§

source

fn resource_path(&mut self) -> &mut Path<Self::Path>

Implementors§

source§

impl<T, P> Resource for T
where + T: DerefMut<Target = Path<P>>, + P: ResourcePath,

§

type Path = P

source§

impl<T: ResourcePath> Resource for Path<T>

§

type Path = T

\ No newline at end of file diff --git a/actix_router/trait.ResourcePath.html b/actix_router/trait.ResourcePath.html new file mode 100644 index 000000000..a28670e49 --- /dev/null +++ b/actix_router/trait.ResourcePath.html @@ -0,0 +1,4 @@ +ResourcePath in actix_router - Rust

Trait actix_router::ResourcePath

source ·
pub trait ResourcePath {
+    // Required method
+    fn path(&self) -> &str;
+}

Required Methods§

source

fn path(&self) -> &str

Implementations on Foreign Types§

source§

impl ResourcePath for String

source§

fn path(&self) -> &str

source§

impl ResourcePath for Uri

Available on crate feature http only.
source§

fn path(&self) -> &str

source§

impl ResourcePath for ByteString

source§

fn path(&self) -> &str

source§

impl<'a> ResourcePath for &'a str

source§

fn path(&self) -> &str

Implementors§

source§

impl ResourcePath for Url

Available on crate feature http only.
\ No newline at end of file diff --git a/actix_router/url/struct.Url.html b/actix_router/url/struct.Url.html new file mode 100644 index 000000000..84903123f --- /dev/null +++ b/actix_router/url/struct.Url.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_router/struct.Url.html...

+ + + \ No newline at end of file diff --git a/actix_test/all.html b/actix_test/all.html new file mode 100644 index 000000000..cf8a5588b --- /dev/null +++ b/actix_test/all.html @@ -0,0 +1 @@ +List of all items in this crate
\ No newline at end of file diff --git a/actix_test/enum.PayloadError.html b/actix_test/enum.PayloadError.html new file mode 100644 index 000000000..90a53244f --- /dev/null +++ b/actix_test/enum.PayloadError.html @@ -0,0 +1,35 @@ +PayloadError in actix_test - Rust

Enum actix_test::PayloadError

#[non_exhaustive]
pub enum PayloadError { + Incomplete(Option<Error>), + EncodingCorrupted, + Overflow, + UnknownLength, + Http2Payload(Error), + Io(Error), +}
Expand description

A set of errors that can occur during payload parsing.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Incomplete(Option<Error>)

A payload reached EOF, but is not complete.

+
§

EncodingCorrupted

Content encoding stream corruption.

+
§

Overflow

Payload reached size limit.

+
§

UnknownLength

Payload length is unknown.

+
§

Http2Payload(Error)

Available on crate feature http2 only.

HTTP/2 payload error.

+
§

Io(Error)

Generic I/O error.

+

Trait Implementations§

§

impl Debug for PayloadError

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for PayloadError

§

fn fmt( + &self, + _derive_more_display_formatter: &mut Formatter<'_> +) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for PayloadError

§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<Error> for PayloadError

§

fn from(err: Error) -> PayloadError

Converts to this type from the input type.
§

impl From<Error> for PayloadError

Available on crate feature http2 only.
§

fn from(err: Error) -> PayloadError

Converts to this type from the input type.
§

impl From<Option<Error>> for PayloadError

§

fn from(err: Option<Error>) -> PayloadError

Converts to this type from the input type.
§

impl ResponseError for PayloadError

§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
§

fn error_response(&self) -> HttpResponse

Creates full response for error. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_test/fn.call_and_read_body.html b/actix_test/fn.call_and_read_body.html new file mode 100644 index 000000000..4a1acbbb9 --- /dev/null +++ b/actix_test/fn.call_and_read_body.html @@ -0,0 +1,32 @@ +call_and_read_body in actix_test - Rust

Function actix_test::call_and_read_body

pub async fn call_and_read_body<S, B>(app: &S, req: Request) -> Bytes
where + S: Service<Request, Response = ServiceResponse<B>, Error = Error>, + B: MessageBody,
Expand description

Helper function that returns a response body of a TestRequest

+

§Examples

+
use actix_web::{test, web, App, HttpResponse, http::header};
+use bytes::Bytes;
+
+#[actix_web::test]
+async fn test_index() {
+    let app = test::init_service(
+        App::new().service(
+            web::resource("/index.html")
+                .route(web::post().to(|| async {
+                    HttpResponse::Ok().body("welcome!")
+                })))
+    ).await;
+
+    let req = test::TestRequest::post()
+        .uri("/index.html")
+        .header(header::CONTENT_TYPE, "application/json")
+        .to_request();
+
+    let result = test::call_and_read_body(&app, req).await;
+    assert_eq!(result, Bytes::from_static(b"welcome!"));
+}
+

§Panics

+

Panics if:

+
    +
  • service call returns error;
  • +
  • body yields an error while it is being read.
  • +
+
\ No newline at end of file diff --git a/actix_test/fn.call_and_read_body_json.html b/actix_test/fn.call_and_read_body_json.html new file mode 100644 index 000000000..364956b62 --- /dev/null +++ b/actix_test/fn.call_and_read_body_json.html @@ -0,0 +1,43 @@ +call_and_read_body_json in actix_test - Rust

Function actix_test::call_and_read_body_json

pub async fn call_and_read_body_json<S, B, T>(app: &S, req: Request) -> T
where + S: Service<Request, Response = ServiceResponse<B>, Error = Error>, + B: MessageBody, + T: DeserializeOwned,
Expand description

Helper function that returns a deserialized response body of a TestRequest

+

§Examples

+
use actix_web::{App, test, web, HttpResponse, http::header};
+use serde::{Serialize, Deserialize};
+
+#[derive(Serialize, Deserialize)]
+pub struct Person {
+    id: String,
+    name: String
+}
+
+#[actix_web::test]
+async fn test_add_person() {
+    let app = test::init_service(
+        App::new().service(
+            web::resource("/people")
+                .route(web::post().to(|person: web::Json<Person>| async {
+                    HttpResponse::Ok()
+                        .json(person)})
+                    ))
+    ).await;
+
+    let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes();
+
+    let req = test::TestRequest::post()
+        .uri("/people")
+        .header(header::CONTENT_TYPE, "application/json")
+        .set_payload(payload)
+        .to_request();
+
+    let result: Person = test::call_and_read_body_json(&mut app, req).await;
+}
+

§Panics

+

Panics if:

+
    +
  • service call returns an error body yields an error while it is being read;
  • +
  • body yields an error while it is being read;
  • +
  • received body is not a valid JSON representation of T.
  • +
+
\ No newline at end of file diff --git a/actix_test/fn.call_service.html b/actix_test/fn.call_service.html new file mode 100644 index 000000000..20acf391e --- /dev/null +++ b/actix_test/fn.call_service.html @@ -0,0 +1,28 @@ +call_service in actix_test - Rust

Function actix_test::call_service

pub async fn call_service<S, R, B, E>(
+    app: &S,
+    req: R
+) -> <S as Service<R>>::Response
where + S: Service<R, Response = ServiceResponse<B>, Error = E>, + E: Debug,
Expand description

Calls service and waits for response future completion.

+

§Examples

+
use actix_web::{test, web, App, HttpResponse, http::StatusCode};
+
+#[actix_web::test]
+async fn test_response() {
+    let app = test::init_service(
+        App::new()
+            .service(web::resource("/test").to(|| async {
+                HttpResponse::Ok()
+            }))
+    ).await;
+
+    // Create request object
+    let req = test::TestRequest::with_uri("/test").to_request();
+
+    // Call application
+    let res = test::call_service(&app, req).await;
+    assert_eq!(res.status(), StatusCode::OK);
+}
+

§Panics

+

Panics if service call returns error. To handle errors use app.call(req).

+
\ No newline at end of file diff --git a/actix_test/fn.config.html b/actix_test/fn.config.html new file mode 100644 index 000000000..9058cf1fd --- /dev/null +++ b/actix_test/fn.config.html @@ -0,0 +1,2 @@ +config in actix_test - Rust

Function actix_test::config

source ·
pub fn config() -> TestServerConfig
Expand description

Create default test server config.

+
\ No newline at end of file diff --git a/actix_test/fn.init_service.html b/actix_test/fn.init_service.html new file mode 100644 index 000000000..d78e90af1 --- /dev/null +++ b/actix_test/fn.init_service.html @@ -0,0 +1,27 @@ +init_service in actix_test - Rust

Function actix_test::init_service

pub async fn init_service<R, S, B, E>(
+    app: R
+) -> impl Service<Request, Response = ServiceResponse<B>, Error = E>
where + R: IntoServiceFactory<S, Request>, + S: ServiceFactory<Request, Config = AppConfig, Response = ServiceResponse<B>, Error = E>, + <S as ServiceFactory<Request>>::InitError: Debug,
Expand description

Initialize service from application builder instance.

+

§Examples

+
use actix_service::Service;
+use actix_web::{test, web, App, HttpResponse, http::StatusCode};
+
+#[actix_web::test]
+async fn test_init_service() {
+    let app = test::init_service(
+        App::new()
+            .service(web::resource("/test").to(|| async { "OK" }))
+    ).await;
+
+    // Create request object
+    let req = test::TestRequest::with_uri("/test").to_request();
+
+    // Execute application
+    let res = app.call(req).await.unwrap();
+    assert_eq!(res.status(), StatusCode::OK);
+}
+

§Panics

+

Panics if service initialization returns an error.

+
\ No newline at end of file diff --git a/actix_test/fn.ok_service.html b/actix_test/fn.ok_service.html new file mode 100644 index 000000000..f15e84986 --- /dev/null +++ b/actix_test/fn.ok_service.html @@ -0,0 +1,3 @@ +ok_service in actix_test - Rust

Function actix_test::ok_service

pub fn ok_service(
+) -> impl Service<ServiceRequest, Response = ServiceResponse, Error = Error>
Expand description

Creates service that always responds with 200 OK and no body.

+
\ No newline at end of file diff --git a/actix_test/fn.read_body.html b/actix_test/fn.read_body.html new file mode 100644 index 000000000..bc9ebc936 --- /dev/null +++ b/actix_test/fn.read_body.html @@ -0,0 +1,28 @@ +read_body in actix_test - Rust

Function actix_test::read_body

pub async fn read_body<B>(res: ServiceResponse<B>) -> Bytes
where + B: MessageBody,
Expand description

Helper function that returns a response body of a ServiceResponse.

+

§Examples

+
use actix_web::{test, web, App, HttpResponse, http::header};
+use bytes::Bytes;
+
+#[actix_web::test]
+async fn test_index() {
+    let app = test::init_service(
+        App::new().service(
+            web::resource("/index.html")
+                .route(web::post().to(|| async {
+                    HttpResponse::Ok().body("welcome!")
+                })))
+    ).await;
+
+    let req = test::TestRequest::post()
+        .uri("/index.html")
+        .header(header::CONTENT_TYPE, "application/json")
+        .to_request();
+
+    let res = test::call_service(&app, req).await;
+    let result = test::read_body(res).await;
+    assert_eq!(result, Bytes::from_static(b"welcome!"));
+}
+

§Panics

+

Panics if body yields an error while it is being read.

+
\ No newline at end of file diff --git a/actix_test/fn.read_body_json.html b/actix_test/fn.read_body_json.html new file mode 100644 index 000000000..0ad702999 --- /dev/null +++ b/actix_test/fn.read_body_json.html @@ -0,0 +1,44 @@ +read_body_json in actix_test - Rust

Function actix_test::read_body_json

pub async fn read_body_json<T, B>(res: ServiceResponse<B>) -> T
where + B: MessageBody, + T: DeserializeOwned,
Expand description

Helper function that returns a deserialized response body of a ServiceResponse.

+

§Examples

+
use actix_web::{App, test, web, HttpResponse, http::header};
+use serde::{Serialize, Deserialize};
+
+#[derive(Serialize, Deserialize)]
+pub struct Person {
+    id: String,
+    name: String,
+}
+
+#[actix_web::test]
+async fn test_post_person() {
+    let app = test::init_service(
+        App::new().service(
+            web::resource("/people")
+                .route(web::post().to(|person: web::Json<Person>| async {
+                    HttpResponse::Ok()
+                        .json(person)})
+                    ))
+    ).await;
+
+    let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes();
+
+    let res = test::TestRequest::post()
+        .uri("/people")
+        .header(header::CONTENT_TYPE, "application/json")
+        .set_payload(payload)
+        .send_request(&mut app)
+        .await;
+
+    assert!(res.status().is_success());
+
+    let result: Person = test::read_body_json(res).await;
+}
+

§Panics

+

Panics if:

+
    +
  • body yields an error while it is being read;
  • +
  • received body is not a valid JSON representation of T.
  • +
+
\ No newline at end of file diff --git a/actix_test/fn.start.html b/actix_test/fn.start.html new file mode 100644 index 000000000..fcafe9281 --- /dev/null +++ b/actix_test/fn.start.html @@ -0,0 +1,29 @@ +start in actix_test - Rust

Function actix_test::start

source ·
pub fn start<F, I, S, B>(factory: F) -> TestServer
where + F: Fn() -> I + Send + Clone + 'static, + I: IntoServiceFactory<S, Request>, + S: ServiceFactory<Request, Config = AppConfig> + 'static, + S::Error: Into<Error> + 'static, + S::InitError: Debug, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static,
Expand description

Start default TestServer.

+

§Examples

+
use actix_web::{get, web, test, App, HttpResponse, Error, Responder};
+
+#[get("/")]
+async fn my_handler() -> Result<impl Responder, Error> {
+    Ok(HttpResponse::Ok())
+}
+
+#[actix_web::test]
+async fn test_example() {
+    let srv = actix_test::start(||
+        App::new().service(my_handler)
+    );
+
+    let req = srv.get("/");
+    let res = req.send().await.unwrap();
+
+    assert!(res.status().is_success());
+}
+
\ No newline at end of file diff --git a/actix_test/fn.start_with.html b/actix_test/fn.start_with.html new file mode 100644 index 000000000..13a2922b3 --- /dev/null +++ b/actix_test/fn.start_with.html @@ -0,0 +1,30 @@ +start_with in actix_test - Rust

Function actix_test::start_with

source ·
pub fn start_with<F, I, S, B>(cfg: TestServerConfig, factory: F) -> TestServer
where + F: Fn() -> I + Send + Clone + 'static, + I: IntoServiceFactory<S, Request>, + S: ServiceFactory<Request, Config = AppConfig> + 'static, + S::Error: Into<Error> + 'static, + S::InitError: Debug, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static,
Expand description

Start test server with custom configuration

+

Check TestServerConfig docs for configuration options.

+

§Examples

+
use actix_web::{get, web, test, App, HttpResponse, Error, Responder};
+
+#[get("/")]
+async fn my_handler() -> Result<impl Responder, Error> {
+    Ok(HttpResponse::Ok())
+}
+
+#[actix_web::test]
+async fn test_example() {
+    let srv = actix_test::start_with(actix_test::config().h1(), ||
+        App::new().service(my_handler)
+    );
+
+    let req = srv.get("/");
+    let res = req.send().await.unwrap();
+
+    assert!(res.status().is_success());
+}
+
\ No newline at end of file diff --git a/actix_test/fn.status_service.html b/actix_test/fn.status_service.html new file mode 100644 index 000000000..9a10877e8 --- /dev/null +++ b/actix_test/fn.status_service.html @@ -0,0 +1,4 @@ +status_service in actix_test - Rust

Function actix_test::status_service

pub fn status_service(
+    status_code: StatusCode
+) -> impl Service<ServiceRequest, Response = ServiceResponse, Error = Error>
Expand description

Creates service that always responds with given status code and no body.

+
\ No newline at end of file diff --git a/actix_test/fn.to_bytes.html b/actix_test/fn.to_bytes.html new file mode 100644 index 000000000..da99b437e --- /dev/null +++ b/actix_test/fn.to_bytes.html @@ -0,0 +1,16 @@ +to_bytes in actix_test - Rust

Function actix_test::to_bytes

pub async fn to_bytes<B>(body: B) -> Result<Bytes, <B as MessageBody>::Error>
where + B: MessageBody,
Expand description

Collects all the bytes produced by body.

+

Any errors produced by the body stream are returned immediately.

+

Consider using [to_bytes_limited] instead to protect against memory exhaustion.

+

§Examples

+
use actix_http::body::{self, to_bytes};
+use bytes::Bytes;
+
+let body = body::None::new();
+let bytes = to_bytes(body).await.unwrap();
+assert!(bytes.is_empty());
+
+let body = Bytes::from_static(b"123");
+let bytes = to_bytes(body).await.unwrap();
+assert_eq!(bytes, "123");
+
\ No newline at end of file diff --git a/actix_test/fn.unused_addr.html b/actix_test/fn.unused_addr.html new file mode 100644 index 000000000..411685c17 --- /dev/null +++ b/actix_test/fn.unused_addr.html @@ -0,0 +1,2 @@ +unused_addr in actix_test - Rust

Function actix_test::unused_addr

pub fn unused_addr() -> SocketAddr
Expand description

Get a localhost socket address with random, unused port.

+
\ No newline at end of file diff --git a/actix_test/index.html b/actix_test/index.html new file mode 100644 index 000000000..91185fb7e --- /dev/null +++ b/actix_test/index.html @@ -0,0 +1,25 @@ +actix_test - Rust

Crate actix_test

source ·
Expand description

Integration testing tools for Actix Web applications.

+

The main integration testing tool is TestServer. It spawns a real HTTP server on an +unused port and provides methods that use a real HTTP client. Therefore, it is much closer to +real-world cases than using init_service, which skips HTTP encoding and decoding.

+

§Examples

+
use actix_web::{get, web, test, App, HttpResponse, Error, Responder};
+
+#[get("/")]
+async fn my_handler() -> Result<impl Responder, Error> {
+    Ok(HttpResponse::Ok())
+}
+
+#[actix_rt::test]
+async fn test_example() {
+    let srv = actix_test::start(||
+        App::new().service(my_handler)
+    );
+
+    let req = srv.get("/");
+    let res = req.send().await.unwrap();
+
+    assert!(res.status().is_success());
+}
+

Structs§

Enums§

  • A set of errors that can occur during payload parsing.

Functions§

  • Helper function that returns a response body of a TestRequest
  • Helper function that returns a deserialized response body of a TestRequest
  • Calls service and waits for response future completion.
  • Create default test server config.
  • Initialize service from application builder instance.
  • Creates service that always responds with 200 OK and no body.
  • Helper function that returns a response body of a ServiceResponse.
  • Helper function that returns a deserialized response body of a ServiceResponse.
  • Start default TestServer.
  • Start test server with custom configuration
  • Creates service that always responds with given status code and no body.
  • Collects all the bytes produced by body.
  • Get a localhost socket address with random, unused port.
\ No newline at end of file diff --git a/actix_test/sidebar-items.js b/actix_test/sidebar-items.js new file mode 100644 index 000000000..b35b82bf3 --- /dev/null +++ b/actix_test/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["PayloadError"],"fn":["call_and_read_body","call_and_read_body_json","call_service","config","init_service","ok_service","read_body","read_body_json","start","start_with","status_service","to_bytes","unused_addr"],"struct":["Client","ClientRequest","ClientResponse","Connector","TestBuffer","TestRequest","TestServer","TestServerConfig"]}; \ No newline at end of file diff --git a/actix_test/struct.Client.html b/actix_test/struct.Client.html new file mode 100644 index 000000000..d2a65ccb2 --- /dev/null +++ b/actix_test/struct.Client.html @@ -0,0 +1,75 @@ +Client in actix_test - Rust

Struct actix_test::Client

pub struct Client(/* private fields */);
Expand description

An asynchronous HTTP and WebSocket client.

+

You should take care to create, at most, one Client per thread. Otherwise, expect higher CPU +and memory usage.

+

§Examples

+
use awc::Client;
+
+#[actix_rt::main]
+async fn main() {
+    let mut client = Client::default();
+
+    let res = client.get("http://www.rust-lang.org")
+        .insert_header(("User-Agent", "my-app/1.2"))
+        .send()
+        .await;
+
+     println!("Response: {:?}", res);
+}
+

Implementations§

§

impl Client

pub fn new() -> Client

Constructs new client instance with default settings.

+

pub fn builder( +) -> ClientBuilder<impl Service<ConnectInfo<Uri>, Response = Connection<Uri, TcpStream>, Error = ConnectError> + Clone>

Constructs new Client builder.

+

This function is equivalent of ClientBuilder::new().

+

pub fn request<U>(&self, method: Method, url: U) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<Error>,

Construct HTTP request.

+

pub fn request_from<U>(&self, url: U, head: &RequestHead) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<Error>,

Create ClientRequest from RequestHead

+

It is useful for proxy requests. This implementation +copies all headers and the method.

+

pub fn get<U>(&self, url: U) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<Error>,

Construct HTTP GET request.

+

pub fn head<U>(&self, url: U) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<Error>,

Construct HTTP HEAD request.

+

pub fn put<U>(&self, url: U) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<Error>,

Construct HTTP PUT request.

+

pub fn post<U>(&self, url: U) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<Error>,

Construct HTTP POST request.

+

pub fn patch<U>(&self, url: U) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<Error>,

Construct HTTP PATCH request.

+

pub fn delete<U>(&self, url: U) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<Error>,

Construct HTTP DELETE request.

+

pub fn options<U>(&self, url: U) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<Error>,

Construct HTTP OPTIONS request.

+

pub fn ws<U>(&self, url: U) -> WebsocketsRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<Error>,

Initialize a WebSocket connection. +Returns a WebSocket connection builder.

+

pub fn headers(&mut self) -> Option<&mut HeaderMap>

Get default HeaderMap of Client.

+

Returns Some(&mut HeaderMap) when Client object is unique +(No other clone of client exists at the same time).

+

Trait Implementations§

§

impl Clone for Client

§

fn clone(&self) -> Client

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Default for Client

§

fn default() -> Client

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl Freeze for Client

§

impl !RefUnwindSafe for Client

§

impl !Send for Client

§

impl !Sync for Client

§

impl Unpin for Client

§

impl !UnwindSafe for Client

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_test/struct.ClientRequest.html b/actix_test/struct.ClientRequest.html new file mode 100644 index 000000000..85db22fd8 --- /dev/null +++ b/actix_test/struct.ClientRequest.html @@ -0,0 +1,100 @@ +ClientRequest in actix_test - Rust

Struct actix_test::ClientRequest

pub struct ClientRequest { /* private fields */ }
Expand description

An HTTP Client request builder

+

This type can be used to construct an instance of ClientRequest through a +builder-like pattern.

+ +
let response = awc::Client::new()
+     .get("http://www.rust-lang.org") // <- Create request builder
+     .insert_header(("User-Agent", "Actix-web"))
+     .send()                          // <- Send HTTP request
+     .await;
+
+response.and_then(|response| {   // <- server HTTP response
+     println!("Response: {:?}", response);
+     Ok(())
+});
+

Implementations§

§

impl ClientRequest

pub fn uri<U>(self, uri: U) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<Error>,

Set HTTP URI of request.

+

pub fn get_uri(&self) -> &Uri

Get HTTP URI of request.

+

pub fn address(self, addr: SocketAddr) -> ClientRequest

Set socket address of the server.

+

This address is used for connection. If address is not +provided url’s host name get resolved.

+

pub fn method(self, method: Method) -> ClientRequest

Set HTTP method of this request.

+

pub fn get_method(&self) -> &Method

Get HTTP method of this request

+

pub fn get_version(&self) -> &Version

Get HTTP version of this request.

+

pub fn get_peer_addr(&self) -> &Option<SocketAddr>

Get peer address of this request.

+

pub fn headers(&self) -> &HeaderMap

Returns request’s headers.

+

pub fn headers_mut(&mut self) -> &mut HeaderMap

Returns request’s mutable headers.

+

pub fn insert_header(self, header: impl TryIntoHeaderPair) -> ClientRequest

Insert a header, replacing any that were set with an equivalent field name.

+

pub fn insert_header_if_none( + self, + header: impl TryIntoHeaderPair +) -> ClientRequest

Insert a header only if it is not yet set.

+

pub fn append_header(self, header: impl TryIntoHeaderPair) -> ClientRequest

Append a header, keeping any that were set with an equivalent field name.

+ +
use awc::{http::header, Client};
+
+Client::new()
+    .get("http://www.rust-lang.org")
+    .insert_header(("X-TEST", "value"))
+    .insert_header((header::CONTENT_TYPE, mime::APPLICATION_JSON));
+

pub fn camel_case(self) -> ClientRequest

Send headers in Camel-Case form.

+

pub fn force_close(self) -> ClientRequest

Force close connection instead of returning it back to connections pool. +This setting affect only HTTP/1 connections.

+

pub fn content_type<V>(self, value: V) -> ClientRequest

Set request’s content type

+

pub fn content_length(self, len: u64) -> ClientRequest

Set content length

+

pub fn basic_auth( + self, + username: impl Display, + password: impl Display +) -> ClientRequest

Set HTTP basic authorization header.

+

If no password is needed, just provide an empty string.

+

pub fn bearer_auth(self, token: impl Display) -> ClientRequest

Set HTTP bearer authentication header

+

pub fn cookie(self, cookie: Cookie<'_>) -> ClientRequest

Available on crate feature cookies only.

Set a cookie

+ +
use awc::{cookie::Cookie, Client};
+
+let res = Client::new().get("https://httpbin.org/cookies")
+    .cookie(Cookie::new("name", "value"))
+    .send()
+    .await;
+
+println!("Response: {:?}", res);
+

pub fn no_decompress(self) -> ClientRequest

Disable automatic decompress of response’s body

+

pub fn timeout(self, timeout: Duration) -> ClientRequest

Set request timeout. Overrides client wide timeout setting.

+

Request timeout is the total time before a response must be received. +Default value is 5 seconds.

+

pub fn query<T>(self, query: &T) -> Result<ClientRequest, Error>
where + T: Serialize,

Sets the query part of the request

+

pub fn freeze(self) -> Result<FrozenClientRequest, FreezeRequestError>

Freeze request builder and construct FrozenClientRequest, +which could be used for sending same request multiple times.

+

pub fn send_body<B>(self, body: B) -> SendClientRequest
where + B: MessageBody + 'static,

Complete request construction and send body.

+

pub fn send_json<T>(self, value: &T) -> SendClientRequest
where + T: Serialize,

Set a JSON body and generate ClientRequest

+

pub fn send_form<T>(self, value: &T) -> SendClientRequest
where + T: Serialize,

Set a urlencoded body and generate ClientRequest

+

ClientRequestBuilder can not be used after this call.

+

pub fn send_stream<S, E>(self, stream: S) -> SendClientRequest
where + S: Stream<Item = Result<Bytes, E>> + 'static, + E: Into<Box<dyn Error>> + 'static,

Set an streaming body and generate ClientRequest.

+

pub fn send(self) -> SendClientRequest

Set an empty body and generate ClientRequest.

+

Trait Implementations§

§

impl Debug for ClientRequest

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_test/struct.ClientResponse.html b/actix_test/struct.ClientResponse.html new file mode 100644 index 000000000..c02840418 --- /dev/null +++ b/actix_test/struct.ClientResponse.html @@ -0,0 +1,293 @@ +ClientResponse in actix_test - Rust

Struct actix_test::ClientResponse

pub struct ClientResponse<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> { /* private fields */ }
Expand description

Client Response

+

Implementations§

§

impl<S> ClientResponse<S>

pub fn version(&self) -> Version

Read the Request Version.

+

pub fn status(&self) -> StatusCode

Get the status from the server.

+

pub fn headers(&self) -> &HeaderMap

Returns request’s headers.

+

pub fn map_body<F, U>(self, f: F) -> ClientResponse<U>
where + F: FnOnce(&mut ResponseHead, Payload<S>) -> Payload<U>,

Map the current body type to another using a closure. Returns a new response.

+

Closure receives the response head and the current body type.

+

pub fn timeout(self, dur: Duration) -> ClientResponse<S>

Set a timeout duration for ClientResponse.

+

This duration covers the duration of processing the response body stream +and would end it as timeout error when deadline met.

+

Disabled by default.

+

pub fn cookies(&self) -> Result<Ref<'_, Vec<Cookie<'static>>>, ParseError>

Available on crate feature cookies only.

Load request cookies.

+

pub fn cookie(&self, name: &str) -> Option<Cookie<'static>>

Available on crate feature cookies only.

Return request cookie.

+
§

impl<S> ClientResponse<S>
where + S: Stream<Item = Result<Bytes, PayloadError>>,

pub fn body(&mut self) -> ResponseBody<S>

Returns a Future that consumes the body stream and resolves to [Bytes].

+
§Errors
+

Future implementation returns error if:

+
    +
  • content length is greater than limit (default: 2 MiB)
  • +
+
§Examples
+
let client = Client::default();
+let mut res = client.get("https://httpbin.org/robots.txt").send().await?;
+let body: Bytes = res.body().await?;
+

pub fn json<T>(&mut self) -> JsonBody<S, T>
where + T: DeserializeOwned,

Returns a Future consumes the body stream, parses JSON, and resolves to a deserialized +T value.

+
§Errors
+

Future returns error if:

+
    +
  • content type is not application/json;
  • +
  • content length is greater than limit (default: 2 MiB).
  • +
+
§Examples
+
let client = Client::default();
+let mut res = client.get("https://httpbin.org/json").send().await?;
+let val = res.json::<serde_json::Value>().await?;
+assert!(val.is_object());
+

Trait Implementations§

§

impl<S> Debug for ClientResponse<S>

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<S> HttpMessage for ClientResponse<S>

§

type Stream = S

Type of message payload stream
§

fn headers(&self) -> &HeaderMap

Read the message headers.
§

fn take_payload(&mut self) -> Payload<S>

Message payload stream
§

fn extensions(&self) -> Ref<'_, Extensions>

Returns a reference to the request-local data/extensions container.
§

fn extensions_mut(&self) -> RefMut<'_, Extensions>

Returns a mutable reference to the request-local data/extensions container.
§

fn content_type(&self) -> &str

Read the request content type. If request did not contain a Content-Type header, an empty +string is returned.
§

fn encoding(&self) -> Result<&'static Encoding, ContentTypeError>

Get content type encoding. Read more
§

fn mime_type(&self) -> Result<Option<Mime>, ContentTypeError>

Convert the request content type to a known mime type.
§

fn chunked(&self) -> Result<bool, ParseError>

Check if request has chunked transfer encoding.
§

impl<S> Stream for ClientResponse<S>
where + S: Stream<Item = Result<Bytes, PayloadError>> + Unpin,

§

type Item = Result<Bytes, PayloadError>

Values yielded by the stream.
§

fn poll_next( + self: Pin<&mut ClientResponse<S>>, + cx: &mut Context<'_> +) -> Poll<Option<<ClientResponse<S> as Stream>::Item>>

Attempt to pull out the next value of this stream, registering the +current task for wakeup if the value is not yet available, and returning +None if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more
§

impl<'__pin, S> Unpin for ClientResponse<S>
where + __Origin<'__pin, S>: Unpin,

Auto Trait Implementations§

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Freeze for ClientResponse<S>

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !RefUnwindSafe for ClientResponse<S>

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Send for ClientResponse<S>

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Sync for ClientResponse<S>

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !UnwindSafe for ClientResponse<S>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<T> StreamExt for T
where + T: Stream + ?Sized,

§

fn next(&mut self) -> Next<'_, Self>
where + Self: Unpin,

Creates a future that resolves to the next item in the stream. Read more
§

fn into_future(self) -> StreamFuture<Self>
where + Self: Sized + Unpin,

Converts this stream into a future of (next_item, tail_of_stream). +If the stream terminates, then the next item is None. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + F: FnMut(Self::Item) -> T, + Self: Sized,

Maps this stream’s items to a different type, returning a new stream of +the resulting type. Read more
§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates a stream which gives the current iteration count as well as +the next value. Read more
§

fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Filters the values produced by this stream according to the provided +asynchronous predicate. Read more
§

fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = Option<T>>, + Self: Sized,

Filters the values produced by this stream while simultaneously mapping +them to a different type according to the provided asynchronous closure. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized,

Computes from this stream’s items new items of a different type using +an asynchronous closure. Read more
§

fn collect<C>(self) -> Collect<Self, C>
where + C: Default + Extend<Self::Item>, + Self: Sized,

Transforms a stream into a collection, returning a +future representing the result of that computation. Read more
§

fn unzip<A, B, FromA, FromB>(self) -> Unzip<Self, FromA, FromB>
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Stream<Item = (A, B)>,

Converts a stream of pairs into a future, which +resolves to pair of containers. Read more
§

fn concat(self) -> Concat<Self>
where + Self: Sized, + Self::Item: Extend<<Self::Item as IntoIterator>::Item> + IntoIterator + Default,

Concatenate all items of a stream into a single extendable +destination, returning a future representing the end result. Read more
§

fn count(self) -> Count<Self>
where + Self: Sized,

Drives the stream to completion, counting the number of items. Read more
§

fn cycle(self) -> Cycle<Self>
where + Self: Sized + Clone,

Repeats a stream endlessly. Read more
§

fn fold<T, Fut, F>(self, init: T, f: F) -> Fold<Self, Fut, T, F>
where + F: FnMut(T, Self::Item) -> Fut, + Fut: Future<Output = T>, + Self: Sized,

Execute an accumulating asynchronous computation over a stream, +collecting all the values into one final result. Read more
§

fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if any element in stream satisfied a predicate. Read more
§

fn all<Fut, F>(self, f: F) -> All<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if all element in stream satisfied a predicate. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Item: Stream, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> FlattenUnorderedWithFlowController<Self, ()>
where + Self::Item: Stream + Unpin, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Polls +inner streams produced by the base stream concurrently. Read more
§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + F: FnMut(Self::Item) -> U, + U: Stream, + Self: Sized,

Maps a stream like [StreamExt::map] but flattens nested Streams. Read more
§

fn flat_map_unordered<U, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> FlatMapUnordered<Self, U, F>
where + U: Stream + Unpin, + F: FnMut(Self::Item) -> U, + Self: Sized,

Available on crate feature alloc only.
Maps a stream like [StreamExt::map] but flattens nested Streams +and polls them concurrently, yielding items in any order, as they made +available. Read more
§

fn scan<S, B, Fut, F>(self, initial_state: S, f: F) -> Scan<Self, S, Fut, F>
where + F: FnMut(&mut S, Self::Item) -> Fut, + Fut: Future<Output = Option<B>>, + Self: Sized,

Combinator similar to [StreamExt::fold] that holds internal state +and produces a new stream. Read more
§

fn skip_while<Fut, F>(self, f: F) -> SkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_while<Fut, F>(self, f: F) -> TakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Take elements from this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_until<Fut>(self, fut: Fut) -> TakeUntil<Self, Fut>
where + Fut: Future, + Self: Sized,

Take elements from this stream until the provided future resolves. Read more
§

fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream. Read more
§

fn for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> ForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Available on crate feature alloc only.
Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates a new stream of at most n items of the underlying stream. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates a new stream which skips n items of the underlying stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a stream such that poll_next will never +again be called once it has finished. This method can be used to turn +any Stream into a FusedStream. Read more
§

fn by_ref(&mut self) -> &mut Self

Borrows a stream, rather than consuming it. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the stream. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn buffered(self, n: usize) -> Buffered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures. Read more
§

fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures (unordered). Read more
§

fn zip<St>(self, other: St) -> Zip<Self, St>
where + St: Stream, + Self: Sized,

An adapter for zipping two streams together. Read more
§

fn chain<St>(self, other: St) -> Chain<Self, St>
where + St: Stream<Item = Self::Item>, + Self: Sized,

Adapter for chaining two streams. Read more
§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates a new stream which exposes a peek method. Read more
§

fn chunks(self, capacity: usize) -> Chunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up items of the stream inside a vector. Read more
§

fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up ready items of the stream inside a vector. Read more
§

fn forward<S>(self, sink: S) -> Forward<Self, S>
where + S: Sink<Self::Ok, Error = Self::Error>, + Self: Sized + TryStream,

Available on crate feature sink only.
A future that completes after the given stream has been fully processed +into the sink and the sink has been flushed and closed. Read more
§

fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
where + Self: Sized + Sink<Item>,

Available on crate features sink and alloc only.
Splits this Stream + Sink object into separate Sink and Stream +objects. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnMut(&Self::Item), + Self: Sized,

Do something with each item of this stream, afterwards passing it on. Read more
§

fn left_stream<B>(self) -> Either<Self, B>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the left-hand variant +of that Either. Read more
§

fn right_stream<B>(self) -> Either<B, Self>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the right-hand variant +of that Either. Read more
§

fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>
where + Self: Unpin,

A convenience method for calling [Stream::poll_next] on Unpin +stream types.
§

fn select_next_some(&mut self) -> SelectNextSome<'_, Self>
where + Self: Unpin + FusedStream,

Returns a Future that resolves when the next item in this stream is +ready. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<S, T, E> TryStream for S
where + S: Stream<Item = 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
§

fn try_poll_next( + self: Pin<&mut S>, + cx: &mut Context<'_> +) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>>

Poll this TryStream as if it were a Stream. Read more
§

impl<S> TryStreamExt for S
where + S: TryStream + ?Sized,

§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Wraps the current stream in a new stream which converts the error type +into the one provided. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> T,

Wraps the current stream in a new stream which maps the success value +using the provided closure. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + Self: Sized, + F: FnMut(Self::Error) -> E,

Wraps the current stream in a new stream which maps the error value +using the provided closure. Read more
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Chain on a computation for when a value is ready, passing the successful +results to the provided closure f. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnMut(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Chain on a computation for when an error happens, passing the +erroneous result to the provided closure f. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnMut(&Self::Ok), + Self: Sized,

Do something with the success value of this stream, afterwards passing +it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnMut(&Self::Error), + Self: Sized,

Do something with the error value of this stream, afterwards passing it on. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Wraps a [TryStream] into a type that implements +Stream Read more
§

fn try_next(&mut self) -> TryNext<'_, Self>
where + Self: Unpin,

Creates a future that attempts to resolve the next item in the stream. +If an error is encountered before the next item, the error is returned +instead. Read more
§

fn try_for_each<Fut, F>(self, f: F) -> TryForEach<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Ok = (), Error = Self::Error>, + Self: Sized,

Attempts to run this stream to completion, executing the provided +asynchronous closure for each element on the stream. Read more
§

fn try_skip_while<Fut, F>(self, f: F) -> TrySkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_take_while<Fut, F>(self, f: F) -> TryTakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Take elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> TryForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = Result<(), Self::Error>>, + Self: Sized,

Available on crate feature alloc only.
Attempts to run this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available, exiting as soon as an error occurs. Read more
§

fn try_collect<C>(self) -> TryCollect<Self, C>
where + C: Default + Extend<Self::Ok>, + Self: Sized,

Attempt to transform a stream into a collection, +returning a future representing the result of that computation. Read more
§

fn try_chunks(self, capacity: usize) -> TryChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful items of the stream inside a vector. Read more
§

fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful, ready items of the stream inside a vector. Read more
§

fn try_filter<Fut, F>(self, f: F) -> TryFilter<Self, Fut, F>
where + Fut: Future<Output = bool>, + F: FnMut(&Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream according to the +provided asynchronous closure. Read more
§

fn try_filter_map<Fut, F, T>(self, f: F) -> TryFilterMap<Self, Fut, F>
where + Fut: TryFuture<Ok = Option<T>, Error = Self::Error>, + F: FnMut(Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream while +simultaneously mapping them to a different type according to the +provided asynchronous closure. Read more
§

fn try_flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> TryFlattenUnordered<Self>
where + Self::Ok: TryStream + Unpin, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Produced streams +will be polled concurrently and any errors will be passed through without looking at them. +If the underlying base stream returns an error, it will be immediately propagated. Read more
§

fn try_flatten(self) -> TryFlatten<Self>
where + Self::Ok: TryStream, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn try_fold<T, Fut, F>(self, init: T, f: F) -> TryFold<Self, Fut, T, F>
where + F: FnMut(T, Self::Ok) -> Fut, + Fut: TryFuture<Ok = T, Error = Self::Error>, + Self: Sized,

Attempt to execute an accumulating asynchronous computation over a +stream, collecting all the values into one final result. Read more
§

fn try_concat(self) -> TryConcat<Self>
where + Self: Sized, + Self::Ok: Extend<<Self::Ok as IntoIterator>::Item> + IntoIterator + Default,

Attempt to concatenate all items of a stream into a single +extendable destination, returning a future representing the end result. Read more
§

fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently (unordered). Read more
§

fn try_buffered(self, n: usize) -> TryBuffered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently. Read more
§

fn try_poll_next_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Option<Result<Self::Ok, Self::Error>>>
where + Self: Unpin,

A convenience method for calling [TryStream::try_poll_next] on Unpin +stream types.
§

fn try_all<Fut, F>(self, f: F) -> TryAll<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if all items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that does not satisfy the predicate. Read more
§

fn try_any<Fut, F>(self, f: F) -> TryAny<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if any items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that satisfies the predicate. Read more
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_test/struct.Connector.html b/actix_test/struct.Connector.html new file mode 100644 index 000000000..793210986 --- /dev/null +++ b/actix_test/struct.Connector.html @@ -0,0 +1,90 @@ +Connector in actix_test - Rust

Struct actix_test::Connector

pub struct Connector<T> { /* private fields */ }
Expand description

Manages HTTP client network connectivity.

+

The Connector type uses a builder-like combinator pattern for service construction that +finishes by calling the .finish() method.

+ +
use std::time::Duration;
+
+let connector = awc::Connector::new()
+     .timeout(Duration::from_secs(5))
+     .finish();
+

Implementations§

§

impl Connector<()>

pub fn new( +) -> Connector<impl Service<ConnectInfo<Uri>, Response = Connection<Uri, TcpStream>, Error = ConnectError> + Clone>

Create a new connector with default TLS settings

+
§Panics
+
    +
  • When the rustls-0_23-webpki-roots or rustls-0_23-native-roots features are enabled +and no default crypto provider has been loaded, this method will panic.
  • +
  • When the rustls-0_23-native-roots or rustls-0_22-native-roots features are enabled +and the runtime system has no native root certificates, this method will panic.
  • +
+
§

impl<S> Connector<S>

pub fn connector<S1, Io1>(self, connector: S1) -> Connector<S1>
where + Io1: ActixStream + Debug + 'static, + S1: Service<ConnectInfo<Uri>, Response = Connection<Uri, Io1>, Error = ConnectError> + Clone,

Sets custom connector.

+
§

impl<S, IO> Connector<S>
where + IO: ActixStream + Debug + 'static, + S: Service<ConnectInfo<Uri>, Response = Connection<Uri, IO>, Error = ConnectError> + Clone + 'static,

pub fn timeout(self, timeout: Duration) -> Connector<S>

Sets TCP connection timeout.

+

This is the max time allowed to connect to remote host, including DNS name resolution.

+

By default, the timeout is 5 seconds.

+

pub fn handshake_timeout(self, timeout: Duration) -> Connector<S>

Sets TLS handshake timeout.

+

This is the max time allowed to perform the TLS handshake with remote host after TCP +connection is established.

+

By default, the timeout is 5 seconds.

+

pub fn openssl(self, connector: SslConnector) -> Connector<S>

Available on crate feature openssl only.

Sets custom OpenSSL SslConnector instance.

+

pub fn rustls(self, connector: Arc<ClientConfig>) -> Connector<S>

Available on crate feature rustls-0_20 only.

Sets custom Rustls v0.20 ClientConfig instance.

+

pub fn rustls_021(self, connector: Arc<ClientConfig>) -> Connector<S>

Available on crate feature rustls-0_21 only.

Sets custom Rustls v0.21 ClientConfig instance.

+

pub fn rustls_0_22(self, connector: Arc<ClientConfig>) -> Connector<S>

Available on crate features rustls-0_22-webpki-roots or rustls-0_22-native-roots only.

Sets custom Rustls v0.22 ClientConfig instance.

+

pub fn rustls_0_23(self, connector: Arc<ClientConfig>) -> Connector<S>

Available on crate feature rustls-0_23 only.

Sets custom Rustls v0.23 ClientConfig instance.

+

In order to enable ALPN, set the .alpn_protocols field on the ClientConfig to the +following:

+ +
vec![b"h2".to_vec(), b"http/1.1".to_vec()]
+

pub fn max_http_version(self, val: Version) -> Connector<S>

Sets maximum supported HTTP major version.

+

Supported versions are HTTP/1.1 and HTTP/2.

+

pub fn initial_window_size(self, size: u32) -> Connector<S>

Sets the initial window size (in bytes) for HTTP/2 stream-level flow control for received +data.

+

The default value is 65,535 and is good for APIs, but not for big objects.

+

pub fn initial_connection_window_size(self, size: u32) -> Connector<S>

Sets the initial window size (in bytes) for HTTP/2 connection-level flow control for +received data.

+

The default value is 65,535 and is good for APIs, but not for big objects.

+

pub fn limit(self, limit: usize) -> Connector<S>

Set total number of simultaneous connections per type of scheme.

+

If limit is 0, the connector has no limit.

+

The default limit size is 100.

+

pub fn conn_keep_alive(self, dur: Duration) -> Connector<S>

Set keep-alive period for opened connection.

+

Keep-alive period is the period between connection usage. If +the delay between repeated usages of the same connection +exceeds this period, the connection is closed. +Default keep-alive period is 15 seconds.

+

pub fn conn_lifetime(self, dur: Duration) -> Connector<S>

Set max lifetime period for connection.

+

Connection lifetime is max lifetime of any opened connection +until it is closed regardless of keep-alive period. +Default lifetime period is 75 seconds.

+

pub fn disconnect_timeout(self, dur: Duration) -> Connector<S>

Set server connection disconnect timeout in milliseconds.

+

Defines a timeout for disconnect connection. If a disconnect procedure does not complete +within this time, the socket get dropped. This timeout affects only secure connections.

+

To disable timeout set value to 0.

+

By default disconnect timeout is set to 3000 milliseconds.

+

pub fn local_address(self, addr: IpAddr) -> Connector<S>

Set local IP Address the connector would use for establishing connection.

+

pub fn finish( + self +) -> ConnectorServicePriv<TcpConnectorService<TcpConnectorInnerService<S>>, Rc<dyn Service<Connect, Future = Pin<Box<dyn Future<Output = Result<(Box<dyn ConnectionIo>, Protocol), ConnectError>>>>, Response = (Box<dyn ConnectionIo>, Protocol), Error = ConnectError>>, IO, Box<dyn ConnectionIo>>

Finish configuration process and create connector service.

+

The Connector builder always concludes by calling finish() last in its combinator chain.

+

Auto Trait Implementations§

§

impl<T> Freeze for Connector<T>
where + T: Freeze,

§

impl<T> !RefUnwindSafe for Connector<T>

§

impl<T> Send for Connector<T>
where + T: Send,

§

impl<T> Sync for Connector<T>
where + T: Sync,

§

impl<T> Unpin for Connector<T>
where + T: Unpin,

§

impl<T> !UnwindSafe for Connector<T>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_test/struct.TestBuffer.html b/actix_test/struct.TestBuffer.html new file mode 100644 index 000000000..7eec81fd6 --- /dev/null +++ b/actix_test/struct.TestBuffer.html @@ -0,0 +1,179 @@ +TestBuffer in actix_test - Rust

Struct actix_test::TestBuffer

pub struct TestBuffer {
+    pub read_buf: Rc<RefCell<BytesMut>>,
+    pub write_buf: Rc<RefCell<BytesMut>>,
+    pub err: Option<Rc<Error>>,
+}
Expand description

Async I/O test buffer.

+

Fields§

§read_buf: Rc<RefCell<BytesMut>>§write_buf: Rc<RefCell<BytesMut>>§err: Option<Rc<Error>>

Implementations§

§

impl TestBuffer

pub fn new<T>(data: T) -> TestBuffer
where + T: Into<BytesMut>,

Create new TestBuffer instance with initial read buffer.

+

pub fn empty() -> TestBuffer

Create new empty TestBuffer instance.

+

pub fn extend_read_buf<T>(&mut self, data: T)
where + T: AsRef<[u8]>,

Add data to read buffer.

+

Trait Implementations§

§

impl AsyncRead for TestBuffer

§

fn poll_read( + self: Pin<&mut TestBuffer>, + _: &mut Context<'_>, + buf: &mut ReadBuf<'_> +) -> Poll<Result<(), Error>>

Attempts to read from the AsyncRead into buf. Read more
§

impl AsyncWrite for TestBuffer

§

fn poll_write( + self: Pin<&mut TestBuffer>, + _: &mut Context<'_>, + buf: &[u8] +) -> Poll<Result<usize, Error>>

Attempt to write bytes from buf into the object. Read more
§

fn poll_flush( + self: Pin<&mut TestBuffer>, + _: &mut Context<'_> +) -> Poll<Result<(), Error>>

Attempts to flush the object, ensuring that any buffered data reach +their destination. Read more
§

fn poll_shutdown( + self: Pin<&mut TestBuffer>, + _: &mut Context<'_> +) -> Poll<Result<(), Error>>

Initiates or attempts to shut down this writer, returning success when +the I/O connection has completely shut down. Read more
§

fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[IoSlice<'_>] +) -> Poll<Result<usize, Error>>

Like poll_write, except that it writes from a slice of buffers. Read more
§

fn is_write_vectored(&self) -> bool

Determines if this writer has an efficient poll_write_vectored +implementation. Read more
§

impl Debug for TestBuffer

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Read for TestBuffer

§

fn read(&mut self, dst: &mut [u8]) -> Result<usize, Error>

Pull some bytes from this source into the specified buffer, returning +how many bytes were read. Read more
1.36.0 · source§

fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize, Error>

Like read, except that it reads into a slice of buffers. Read more
source§

fn is_read_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Reader has an efficient read_vectored +implementation. Read more
1.0.0 · source§

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, Error>

Read all bytes until EOF in this source, placing them into buf. Read more
1.0.0 · source§

fn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>

Read all bytes until EOF in this source, appending them to buf. Read more
1.6.0 · source§

fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>

Read the exact number of bytes required to fill buf. Read more
source§

fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<(), Error>

🔬This is a nightly-only experimental API. (read_buf)
Pull some bytes from this source into the specified buffer. Read more
source§

fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<(), Error>

🔬This is a nightly-only experimental API. (read_buf)
Read the exact number of bytes required to fill cursor. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Creates a “by reference” adaptor for this instance of Read. Read more
1.0.0 · source§

fn bytes(self) -> Bytes<Self>
where + Self: Sized,

Transforms this Read instance to an Iterator over its bytes. Read more
1.0.0 · source§

fn chain<R>(self, next: R) -> Chain<Self, R>
where + R: Read, + Self: Sized,

Creates an adapter which will chain this stream with another. Read more
1.0.0 · source§

fn take(self, limit: u64) -> Take<Self>
where + Self: Sized,

Creates an adapter which will read at most limit bytes from it. Read more
§

impl Write for TestBuffer

§

fn write(&mut self, buf: &[u8]) -> Result<usize, Error>

Write a buffer into this writer, returning how many bytes were written. Read more
§

fn flush(&mut self) -> Result<(), Error>

Flush this output stream, ensuring that all intermediately buffered +contents reach their destination. Read more
1.36.0 · source§

fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize, Error>

Like write, except that it writes from a slice of buffers. Read more
source§

fn is_write_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Writer has an efficient write_vectored +implementation. Read more
1.0.0 · source§

fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>

Attempts to write an entire buffer into this writer. Read more
source§

fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>

🔬This is a nightly-only experimental API. (write_all_vectored)
Attempts to write multiple buffers into this writer. Read more
1.0.0 · source§

fn write_fmt(&mut self, fmt: Arguments<'_>) -> Result<(), Error>

Writes a formatted string into this writer, returning any error +encountered. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Creates a “by reference” adapter for this instance of Write. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<R> AsyncReadExt for R
where + R: AsyncRead + ?Sized,

§

fn chain<R>(self, next: R) -> Chain<Self, R>
where + Self: Sized, + R: AsyncRead,

Creates a new AsyncRead instance that chains this stream with +next. Read more
§

fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>
where + Self: Unpin,

Pulls some bytes from this source into the specified buffer, +returning how many bytes were read. Read more
§

fn read_buf<'a, B>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B>
where + Self: Unpin, + B: BufMut + ?Sized,

Pulls some bytes from this source into the specified buffer, +advancing the buffer’s internal cursor. Read more
§

fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self>
where + Self: Unpin,

Reads the exact number of bytes required to fill buf. Read more
§

fn read_u8(&mut self) -> ReadU8<&mut Self>
where + Self: Unpin,

Reads an unsigned 8 bit integer from the underlying reader. Read more
§

fn read_i8(&mut self) -> ReadI8<&mut Self>
where + Self: Unpin,

Reads a signed 8 bit integer from the underlying reader. Read more
§

fn read_u16(&mut self) -> ReadU16<&mut Self>
where + Self: Unpin,

Reads an unsigned 16-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i16(&mut self) -> ReadI16<&mut Self>
where + Self: Unpin,

Reads a signed 16-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u32(&mut self) -> ReadU32<&mut Self>
where + Self: Unpin,

Reads an unsigned 32-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i32(&mut self) -> ReadI32<&mut Self>
where + Self: Unpin,

Reads a signed 32-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u64(&mut self) -> ReadU64<&mut Self>
where + Self: Unpin,

Reads an unsigned 64-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i64(&mut self) -> ReadI64<&mut Self>
where + Self: Unpin,

Reads an signed 64-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u128(&mut self) -> ReadU128<&mut Self>
where + Self: Unpin,

Reads an unsigned 128-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i128(&mut self) -> ReadI128<&mut Self>
where + Self: Unpin,

Reads an signed 128-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_f32(&mut self) -> ReadF32<&mut Self>
where + Self: Unpin,

Reads an 32-bit floating point type in big-endian order from the +underlying reader. Read more
§

fn read_f64(&mut self) -> ReadF64<&mut Self>
where + Self: Unpin,

Reads an 64-bit floating point type in big-endian order from the +underlying reader. Read more
§

fn read_u16_le(&mut self) -> ReadU16Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 16-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i16_le(&mut self) -> ReadI16Le<&mut Self>
where + Self: Unpin,

Reads a signed 16-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u32_le(&mut self) -> ReadU32Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 32-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i32_le(&mut self) -> ReadI32Le<&mut Self>
where + Self: Unpin,

Reads a signed 32-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u64_le(&mut self) -> ReadU64Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 64-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i64_le(&mut self) -> ReadI64Le<&mut Self>
where + Self: Unpin,

Reads an signed 64-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u128_le(&mut self) -> ReadU128Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 128-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i128_le(&mut self) -> ReadI128Le<&mut Self>
where + Self: Unpin,

Reads an signed 128-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_f32_le(&mut self) -> ReadF32Le<&mut Self>
where + Self: Unpin,

Reads an 32-bit floating point type in little-endian order from the +underlying reader. Read more
§

fn read_f64_le(&mut self) -> ReadF64Le<&mut Self>
where + Self: Unpin,

Reads an 64-bit floating point type in little-endian order from the +underlying reader. Read more
§

fn read_to_end<'a>(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEnd<'a, Self>
where + Self: Unpin,

Reads all bytes until EOF in this source, placing them into buf. Read more
§

fn read_to_string<'a>( + &'a mut self, + dst: &'a mut String +) -> ReadToString<'a, Self>
where + Self: Unpin,

Reads all bytes until EOF in this source, appending them to buf. Read more
§

fn take(self, limit: u64) -> Take<Self>
where + Self: Sized,

Creates an adaptor which reads at most limit bytes from it. Read more
§

impl<W> AsyncWriteExt for W
where + W: AsyncWrite + ?Sized,

§

fn write<'a>(&'a mut self, src: &'a [u8]) -> Write<'a, Self>
where + Self: Unpin,

Writes a buffer into this writer, returning how many bytes were +written. Read more
§

fn write_vectored<'a, 'b>( + &'a mut self, + bufs: &'a [IoSlice<'b>] +) -> WriteVectored<'a, 'b, Self>
where + Self: Unpin,

Like write, except that it writes from a slice of buffers. Read more
§

fn write_buf<'a, B>(&'a mut self, src: &'a mut B) -> WriteBuf<'a, Self, B>
where + Self: Sized + Unpin, + B: Buf,

Writes a buffer into this writer, advancing the buffer’s internal +cursor. Read more
§

fn write_all_buf<'a, B>( + &'a mut self, + src: &'a mut B +) -> WriteAllBuf<'a, Self, B>
where + Self: Sized + Unpin, + B: Buf,

Attempts to write an entire buffer into this writer. Read more
§

fn write_all<'a>(&'a mut self, src: &'a [u8]) -> WriteAll<'a, Self>
where + Self: Unpin,

Attempts to write an entire buffer into this writer. Read more
§

fn write_u8(&mut self, n: u8) -> WriteU8<&mut Self>
where + Self: Unpin,

Writes an unsigned 8-bit integer to the underlying writer. Read more
§

fn write_i8(&mut self, n: i8) -> WriteI8<&mut Self>
where + Self: Unpin,

Writes a signed 8-bit integer to the underlying writer. Read more
§

fn write_u16(&mut self, n: u16) -> WriteU16<&mut Self>
where + Self: Unpin,

Writes an unsigned 16-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i16(&mut self, n: i16) -> WriteI16<&mut Self>
where + Self: Unpin,

Writes a signed 16-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u32(&mut self, n: u32) -> WriteU32<&mut Self>
where + Self: Unpin,

Writes an unsigned 32-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i32(&mut self, n: i32) -> WriteI32<&mut Self>
where + Self: Unpin,

Writes a signed 32-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u64(&mut self, n: u64) -> WriteU64<&mut Self>
where + Self: Unpin,

Writes an unsigned 64-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i64(&mut self, n: i64) -> WriteI64<&mut Self>
where + Self: Unpin,

Writes an signed 64-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u128(&mut self, n: u128) -> WriteU128<&mut Self>
where + Self: Unpin,

Writes an unsigned 128-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i128(&mut self, n: i128) -> WriteI128<&mut Self>
where + Self: Unpin,

Writes an signed 128-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_f32(&mut self, n: f32) -> WriteF32<&mut Self>
where + Self: Unpin,

Writes an 32-bit floating point type in big-endian order to the +underlying writer. Read more
§

fn write_f64(&mut self, n: f64) -> WriteF64<&mut Self>
where + Self: Unpin,

Writes an 64-bit floating point type in big-endian order to the +underlying writer. Read more
§

fn write_u16_le(&mut self, n: u16) -> WriteU16Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 16-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i16_le(&mut self, n: i16) -> WriteI16Le<&mut Self>
where + Self: Unpin,

Writes a signed 16-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u32_le(&mut self, n: u32) -> WriteU32Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 32-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i32_le(&mut self, n: i32) -> WriteI32Le<&mut Self>
where + Self: Unpin,

Writes a signed 32-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u64_le(&mut self, n: u64) -> WriteU64Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 64-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i64_le(&mut self, n: i64) -> WriteI64Le<&mut Self>
where + Self: Unpin,

Writes an signed 64-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u128_le(&mut self, n: u128) -> WriteU128Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 128-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i128_le(&mut self, n: i128) -> WriteI128Le<&mut Self>
where + Self: Unpin,

Writes an signed 128-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_f32_le(&mut self, n: f32) -> WriteF32Le<&mut Self>
where + Self: Unpin,

Writes an 32-bit floating point type in little-endian order to the +underlying writer. Read more
§

fn write_f64_le(&mut self, n: f64) -> WriteF64Le<&mut Self>
where + Self: Unpin,

Writes an 64-bit floating point type in little-endian order to the +underlying writer. Read more
§

fn flush(&mut self) -> Flush<'_, Self>
where + Self: Unpin,

Flushes this output stream, ensuring that all intermediately buffered +contents reach their destination. Read more
§

fn shutdown(&mut self) -> Shutdown<'_, Self>
where + Self: Unpin,

Shuts down the output stream, ensuring that the value can be dropped +cleanly. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_test/struct.TestRequest.html b/actix_test/struct.TestRequest.html new file mode 100644 index 000000000..f801c3afb --- /dev/null +++ b/actix_test/struct.TestRequest.html @@ -0,0 +1,93 @@ +TestRequest in actix_test - Rust

Struct actix_test::TestRequest

pub struct TestRequest { /* private fields */ }
Expand description

Test Request builder.

+

For unit testing, actix provides a request builder type and a simple handler runner. TestRequest implements a builder-like pattern. +You can generate various types of request via TestRequest’s methods:

+ + +
use actix_web::{test, HttpRequest, HttpResponse, HttpMessage};
+use actix_web::http::{header, StatusCode};
+
+async fn handler(req: HttpRequest) -> HttpResponse {
+    if let Some(hdr) = req.headers().get(header::CONTENT_TYPE) {
+        HttpResponse::Ok().into()
+    } else {
+        HttpResponse::BadRequest().into()
+    }
+}
+
+#[actix_web::test]
+async fn test_index() {
+    let req = test::TestRequest::default()
+        .insert_header(header::ContentType::plaintext())
+        .to_http_request();
+
+    let resp = handler(req).await;
+    assert_eq!(resp.status(), StatusCode::OK);
+
+    let req = test::TestRequest::default().to_http_request();
+    let resp = handler(req).await;
+    assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+}
+

Implementations§

§

impl TestRequest

pub fn with_uri(uri: &str) -> TestRequest

Constructs test request and sets request URI.

+

pub fn get() -> TestRequest

Constructs test request with GET method.

+

pub fn post() -> TestRequest

Constructs test request with POST method.

+

pub fn put() -> TestRequest

Constructs test request with PUT method.

+

pub fn patch() -> TestRequest

Constructs test request with PATCH method.

+

pub fn delete() -> TestRequest

Constructs test request with DELETE method.

+

pub fn version(self, ver: Version) -> TestRequest

Sets HTTP version of this request.

+

pub fn method(self, meth: Method) -> TestRequest

Sets method of this request.

+

pub fn uri(self, path: &str) -> TestRequest

Sets URI of this request.

+

pub fn insert_header(self, header: impl TryIntoHeaderPair) -> TestRequest

Inserts a header, replacing any that were set with an equivalent field name.

+

pub fn append_header(self, header: impl TryIntoHeaderPair) -> TestRequest

Appends a header, keeping any that were set with an equivalent field name.

+

pub fn cookie(self, cookie: Cookie<'_>) -> TestRequest

Available on crate feature cookies only.

Sets cookie for this request.

+

pub fn param( + self, + name: impl Into<Cow<'static, str>>, + value: impl Into<Cow<'static, str>> +) -> TestRequest

Sets request path pattern parameter.

+
§Examples
+
use actix_web::test::TestRequest;
+
+let req = TestRequest::default().param("foo", "bar");
+let req = TestRequest::default().param("foo".to_owned(), "bar".to_owned());
+

pub fn peer_addr(self, addr: SocketAddr) -> TestRequest

Sets peer address.

+

pub fn set_payload(self, data: impl Into<Bytes>) -> TestRequest

Sets request payload.

+

pub fn set_form(self, data: impl Serialize) -> TestRequest

Serializes data to a URL encoded form and set it as the request payload.

+

The Content-Type header is set to application/x-www-form-urlencoded.

+

pub fn set_json(self, data: impl Serialize) -> TestRequest

Serializes data to JSON and set it as the request payload.

+

The Content-Type header is set to application/json.

+

pub fn app_data<T>(self, data: T) -> TestRequest
where + T: 'static,

Inserts application data.

+

This is equivalent of App::app_data() method for testing purpose.

+

pub fn to_request(self) -> Request

Finalizes request creation and returns Request instance.

+

pub fn to_srv_request(self) -> ServiceRequest

Finalizes request creation and returns ServiceRequest instance.

+

pub fn to_srv_response<B>(self, res: HttpResponse<B>) -> ServiceResponse<B>

Finalizes request creation and returns ServiceResponse instance.

+

pub fn to_http_request(self) -> HttpRequest

Finalizes request creation and returns HttpRequest instance.

+

pub fn to_http_parts(self) -> (HttpRequest, Payload)

Finalizes request creation and returns HttpRequest and Payload pair.

+

pub async fn send_request<S, B, E>( + self, + app: &S +) -> <S as Service<Request>>::Response
where + S: Service<Request, Response = ServiceResponse<B>, Error = E>, + E: Debug,

Finalizes request creation, calls service, and waits for response future completion.

+

Trait Implementations§

§

impl Default for TestRequest

§

fn default() -> TestRequest

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_test/struct.TestServer.html b/actix_test/struct.TestServer.html new file mode 100644 index 000000000..8f11ebb20 --- /dev/null +++ b/actix_test/struct.TestServer.html @@ -0,0 +1,46 @@ +TestServer in actix_test - Rust

Struct actix_test::TestServer

source ·
pub struct TestServer { /* private fields */ }
Expand description

A basic HTTP server controller that simplifies the process of writing integration tests for +Actix Web applications.

+

See start for usage example.

+

Implementations§

source§

impl TestServer

source

pub fn addr(&self) -> SocketAddr

Construct test server url

+
source

pub fn url(&self, uri: &str) -> String

Construct test server url

+
source

pub fn get(&self, path: impl AsRef<str>) -> ClientRequest

Create GET request.

+
source

pub fn post(&self, path: impl AsRef<str>) -> ClientRequest

Create POST request.

+
source

pub fn head(&self, path: impl AsRef<str>) -> ClientRequest

Create HEAD request.

+
source

pub fn put(&self, path: impl AsRef<str>) -> ClientRequest

Create PUT request.

+
source

pub fn patch(&self, path: impl AsRef<str>) -> ClientRequest

Create PATCH request.

+
source

pub fn delete(&self, path: impl AsRef<str>) -> ClientRequest

Create DELETE request.

+
source

pub fn options(&self, path: impl AsRef<str>) -> ClientRequest

Create OPTIONS request.

+
source

pub fn request(&self, method: Method, path: impl AsRef<str>) -> ClientRequest

Connect request with given method and path.

+
source

pub async fn load_body<S>( + &mut self, + response: ClientResponse<S> +) -> Result<Bytes, PayloadError>
where + S: Stream<Item = Result<Bytes, PayloadError>> + Unpin + 'static,

source

pub async fn ws_at( + &mut self, + path: &str +) -> Result<Framed<impl AsyncRead + AsyncWrite, Codec>, WsClientError>

Connect to WebSocket server at a given path.

+
source

pub async fn ws( + &mut self +) -> Result<Framed<impl AsyncRead + AsyncWrite, Codec>, WsClientError>

Connect to a WebSocket server.

+
source

pub fn client_headers(&mut self) -> Option<&mut HeaderMap>

Get default HeaderMap of Client.

+

Returns Some(&mut HeaderMap) when Client object is unique +(No other clone of client exists at the same time).

+
source

pub async fn stop(self)

Stop HTTP server.

+

Waits for spawned Server and System to shutdown (force) shutdown.

+

Trait Implementations§

source§

impl Drop for TestServer

source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_test/struct.TestServerConfig.html b/actix_test/struct.TestServerConfig.html new file mode 100644 index 000000000..8fb0a7e94 --- /dev/null +++ b/actix_test/struct.TestServerConfig.html @@ -0,0 +1,30 @@ +TestServerConfig in actix_test - Rust

Struct actix_test::TestServerConfig

source ·
pub struct TestServerConfig { /* private fields */ }

Implementations§

source§

impl TestServerConfig

source

pub fn h1(self) -> Self

Accepts HTTP/1.1 only.

+
source

pub fn h2(self) -> Self

Accepts HTTP/2 only.

+
source

pub fn openssl(self, acceptor: SslAcceptor) -> Self

Available on crate feature openssl only.

Accepts secure connections via OpenSSL.

+
source

pub fn rustls_0_20(self, config: ServerConfig) -> Self

Available on crate feature rustls-0_20 only.

Accepts secure connections via Rustls v0.20.

+
source

pub fn rustls_0_21(self, config: ServerConfig) -> Self

Available on crate feature rustls-0_21 only.

Accepts secure connections via Rustls v0.21.

+
source

pub fn rustls_0_22(self, config: ServerConfig) -> Self

Available on crate feature rustls-0_22 only.

Accepts secure connections via Rustls v0.22.

+
source

pub fn rustls_0_23(self, config: ServerConfig) -> Self

Available on crate feature rustls-0_23 only.

Accepts secure connections via Rustls v0.23.

+
source

pub fn client_request_timeout(self, dur: Duration) -> Self

Sets client timeout for first request.

+
source

pub fn port(self, port: u16) -> Self

Sets test server port.

+

By default, a random free port is determined by the OS.

+
source

pub fn workers(self, workers: usize) -> Self

Sets number of workers for the test server.

+

By default, the server uses 1 worker

+

Trait Implementations§

source§

impl Clone for TestServerConfig

source§

fn clone(&self) -> TestServerConfig

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Default for TestServerConfig

source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/all.html b/actix_web/all.html new file mode 100644 index 000000000..a1304fe5a --- /dev/null +++ b/actix_web/all.html @@ -0,0 +1 @@ +List of all items in this crate

List of all items

Structs

Enums

Traits

Macros

Attribute Macros

Functions

Type Aliases

Constants

\ No newline at end of file diff --git a/actix_web/app/struct.App.html b/actix_web/app/struct.App.html new file mode 100644 index 000000000..ae314cc3c --- /dev/null +++ b/actix_web/app/struct.App.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/struct.App.html...

+ + + \ No newline at end of file diff --git a/actix_web/attr.connect.html b/actix_web/attr.connect.html new file mode 100644 index 000000000..d8bee8b0a --- /dev/null +++ b/actix_web/attr.connect.html @@ -0,0 +1,19 @@ +connect in actix_web - Rust

Attribute Macro actix_web::connect

source ·
#[connect]
Available on crate feature macros only.
Expand description

Creates route handler with actix_web::guard::Connect.

+

§Syntax

#[connect("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[connect("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web/attr.delete.html b/actix_web/attr.delete.html new file mode 100644 index 000000000..d0bdd1a62 --- /dev/null +++ b/actix_web/attr.delete.html @@ -0,0 +1,19 @@ +delete in actix_web - Rust

Attribute Macro actix_web::delete

source ·
#[delete]
Available on crate feature macros only.
Expand description

Creates route handler with actix_web::guard::Delete.

+

§Syntax

#[delete("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[delete("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web/attr.get.html b/actix_web/attr.get.html new file mode 100644 index 000000000..16d0aff63 --- /dev/null +++ b/actix_web/attr.get.html @@ -0,0 +1,19 @@ +get in actix_web - Rust

Attribute Macro actix_web::get

source ·
#[get]
Available on crate feature macros only.
Expand description

Creates route handler with actix_web::guard::Get.

+

§Syntax

#[get("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[get("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web/attr.head.html b/actix_web/attr.head.html new file mode 100644 index 000000000..acd0f172b --- /dev/null +++ b/actix_web/attr.head.html @@ -0,0 +1,19 @@ +head in actix_web - Rust

Attribute Macro actix_web::head

source ·
#[head]
Available on crate feature macros only.
Expand description

Creates route handler with actix_web::guard::Head.

+

§Syntax

#[head("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[head("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web/attr.main.html b/actix_web/attr.main.html new file mode 100644 index 000000000..48ea2e2d8 --- /dev/null +++ b/actix_web/attr.main.html @@ -0,0 +1,10 @@ +main in actix_web - Rust

Attribute Macro actix_web::main

source ·
#[main]
Available on crate feature macros only.
Expand description

Marks async main function as the Actix Web system entry-point.

+

Note that Actix Web also works under #[tokio::main] since version 4.0. However, this macro is +still necessary for actor support (since actors use a System). Read more in the +actix_web::rt module docs.

+

§Examples

+
#[actix_web::main]
+async fn main() {
+    async { println!("Hello world"); }.await
+}
+
\ No newline at end of file diff --git a/actix_web/attr.options.html b/actix_web/attr.options.html new file mode 100644 index 000000000..0298d661b --- /dev/null +++ b/actix_web/attr.options.html @@ -0,0 +1,19 @@ +options in actix_web - Rust

Attribute Macro actix_web::options

source ·
#[options]
Available on crate feature macros only.
Expand description

Creates route handler with actix_web::guard::Options.

+

§Syntax

#[options("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[options("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web/attr.patch.html b/actix_web/attr.patch.html new file mode 100644 index 000000000..4b20c4318 --- /dev/null +++ b/actix_web/attr.patch.html @@ -0,0 +1,19 @@ +patch in actix_web - Rust

Attribute Macro actix_web::patch

source ·
#[patch]
Available on crate feature macros only.
Expand description

Creates route handler with actix_web::guard::Patch.

+

§Syntax

#[patch("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[patch("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web/attr.post.html b/actix_web/attr.post.html new file mode 100644 index 000000000..4d2e0b6e2 --- /dev/null +++ b/actix_web/attr.post.html @@ -0,0 +1,19 @@ +post in actix_web - Rust

Attribute Macro actix_web::post

source ·
#[post]
Available on crate feature macros only.
Expand description

Creates route handler with actix_web::guard::Post.

+

§Syntax

#[post("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[post("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web/attr.put.html b/actix_web/attr.put.html new file mode 100644 index 000000000..b35dfca5c --- /dev/null +++ b/actix_web/attr.put.html @@ -0,0 +1,19 @@ +put in actix_web - Rust

Attribute Macro actix_web::put

source ·
#[put]
Available on crate feature macros only.
Expand description

Creates route handler with actix_web::guard::Put.

+

§Syntax

#[put("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[put("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web/attr.route.html b/actix_web/attr.route.html new file mode 100644 index 000000000..a7b22871b --- /dev/null +++ b/actix_web/attr.route.html @@ -0,0 +1,21 @@ +route in actix_web - Rust

Attribute Macro actix_web::route

source ·
#[route]
Available on crate feature macros only.
Expand description

Creates resource handler, allowing multiple HTTP method guards.

+

§Syntax

#[route("path", method="HTTP_METHOD"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the function +name of handler is used.
  • +
  • method = "HTTP_METHOD": Registers HTTP method to provide guard for. Upper-case string, +“GET”, “POST” for example.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the generate +code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[route("/test", method = "GET", method = "HEAD", method = "CUSTOM")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web/attr.routes.html b/actix_web/attr.routes.html new file mode 100644 index 000000000..508f0adb8 --- /dev/null +++ b/actix_web/attr.routes.html @@ -0,0 +1,18 @@ +routes in actix_web - Rust

Attribute Macro actix_web::routes

source ·
#[routes]
Available on crate feature macros only.
Expand description

Creates resource handler, allowing multiple HTTP methods and paths.

+

§Syntax

#[routes]
+#[<method>("path", ...)]
+#[<method>("path", ...)]
+...
+

§Attributes

+

The routes macro itself has no parameters, but allows specifying the attribute macros for +the multiple paths and/or methods, e.g. GET and POST.

+

These helper attributes take the same parameters as the single method handlers.

+

§Examples

+
#[routes]
+#[get("/test")]
+#[get("/test2")]
+#[delete("/test")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web/attr.test.html b/actix_web/attr.test.html new file mode 100644 index 000000000..1f902d8c2 --- /dev/null +++ b/actix_web/attr.test.html @@ -0,0 +1,7 @@ +test in actix_web - Rust

Attribute Macro actix_web::test

source ·
#[test]
Available on crate feature macros only.
Expand description

Marks async test functions to use the Actix Web system entry-point.

+

§Examples

+
#[actix_web::test]
+async fn test() {
+    assert_eq!(async { "Hello world" }.await, "Hello world");
+}
+
\ No newline at end of file diff --git a/actix_web/attr.trace.html b/actix_web/attr.trace.html new file mode 100644 index 000000000..79226d6a9 --- /dev/null +++ b/actix_web/attr.trace.html @@ -0,0 +1,19 @@ +trace in actix_web - Rust

Attribute Macro actix_web::trace

source ·
#[trace]
Available on crate feature macros only.
Expand description

Creates route handler with actix_web::guard::Trace.

+

§Syntax

#[trace("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[trace("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web/body/enum.BodySize.html b/actix_web/body/enum.BodySize.html new file mode 100644 index 000000000..c719e2052 --- /dev/null +++ b/actix_web/body/enum.BodySize.html @@ -0,0 +1,46 @@ +BodySize in actix_web::body - Rust

Enum actix_web::body::BodySize

source ·
pub enum BodySize {
+    None,
+    Sized(u64),
+    Stream,
+}
Expand description

Body size hint.

+

Variants§

§

None

Implicitly empty body.

+

Will omit the Content-Length header. Used for responses to certain methods (e.g., HEAD) or +with particular status codes (e.g., 204 No Content). Consumers that read this as a body size +hint are allowed to make optimizations that skip reading or writing the payload.

+
§

Sized(u64)

Known size body.

+

Will write Content-Length: N header.

+
§

Stream

Unknown size body.

+

Will not write Content-Length header. Can be used with chunked Transfer-Encoding.

+

Implementations§

source§

impl BodySize

source

pub const ZERO: BodySize = _

Equivalent to BodySize::Sized(0);

+
source

pub fn is_eof(&self) -> bool

Returns true if size hint indicates omitted or empty body.

+

Streams will return false because it cannot be known without reading the stream.

+ +
assert!(BodySize::None.is_eof());
+assert!(BodySize::Sized(0).is_eof());
+
+assert!(!BodySize::Sized(64).is_eof());
+assert!(!BodySize::Stream.is_eof());
+

Trait Implementations§

source§

impl Clone for BodySize

source§

fn clone(&self) -> BodySize

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for BodySize

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl PartialEq for BodySize

source§

fn eq(&self, other: &BodySize) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for BodySize

source§

impl Eq for BodySize

source§

impl StructuralPartialEq for BodySize

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/body/enum.EitherBody.html b/actix_web/body/enum.EitherBody.html new file mode 100644 index 000000000..b8a37d0a3 --- /dev/null +++ b/actix_web/body/enum.EitherBody.html @@ -0,0 +1,61 @@ +EitherBody in actix_web::body - Rust

Enum actix_web::body::EitherBody

source ·
pub enum EitherBody<L, R = BoxBody> {
+    Left {
+        body: L,
+    },
+    Right {
+        body: R,
+    },
+}
Expand description

An “either” type specialized for body types.

+

It is common, in middleware especially, to conditionally return an inner service’s unknown/ +generic body B type or return early with a new response. This type’s “right” variant +defaults to BoxBody since error responses are the common case.

+

For example, middleware will often have type Response = ServiceResponse<EitherBody<B>>. +This means that the inner service’s response body type maps to the Left variant and the +middleware’s own error responses use the default Right variant of BoxBody. Of course, +there’s no reason it couldn’t use EitherBody<B, String> instead if its alternative +responses have a known type.

+

Variants§

§

Left

A body of type L.

+

Fields

§body: L
§

Right

A body of type R.

+

Fields

§body: R

Implementations§

source§

impl<L> EitherBody<L>

source

pub fn new(body: L) -> EitherBody<L>

Creates new EitherBody left variant with a boxed right variant.

+

If the expected R type will be inferred and is not BoxBody then use the +left constructor instead.

+
source§

impl<L, R> EitherBody<L, R>

source

pub fn left(body: L) -> EitherBody<L, R>

Creates new EitherBody using left variant.

+
source

pub fn right(body: R) -> EitherBody<L, R>

Creates new EitherBody using right variant.

+

Trait Implementations§

source§

impl<L, R> Clone for EitherBody<L, R>
where + L: Clone, + R: Clone,

source§

fn clone(&self) -> EitherBody<L, R>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<L, R> Debug for EitherBody<L, R>
where + L: Debug, + R: Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<L, R> MessageBody for EitherBody<L, R>
where + L: MessageBody + 'static, + R: MessageBody + 'static,

§

type Error = Error

The type of error that will be returned if streaming body fails. Read more
source§

fn size(&self) -> BodySize

Body size hint. Read more
source§

fn poll_next( + self: Pin<&mut EitherBody<L, R>>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <EitherBody<L, R> as MessageBody>::Error>>>

Attempt to pull out the next chunk of body bytes. Read more
source§

fn try_into_bytes(self) -> Result<Bytes, EitherBody<L, R>>

Try to convert into the complete chunk of body bytes. Read more
source§

fn boxed(self) -> BoxBody

Wraps this body into a BoxBody. Read more
source§

impl<'__pin, L, R> Unpin for EitherBody<L, R>
where + __Origin<'__pin, L, R>: Unpin,

Auto Trait Implementations§

§

impl<L, R> Freeze for EitherBody<L, R>
where + L: Freeze, + R: Freeze,

§

impl<L, R> RefUnwindSafe for EitherBody<L, R>
where + L: RefUnwindSafe, + R: RefUnwindSafe,

§

impl<L, R> Send for EitherBody<L, R>
where + L: Send, + R: Send,

§

impl<L, R> Sync for EitherBody<L, R>
where + L: Sync, + R: Sync,

§

impl<L, R> UnwindSafe for EitherBody<L, R>
where + L: UnwindSafe, + R: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/body/fn.to_bytes.html b/actix_web/body/fn.to_bytes.html new file mode 100644 index 000000000..b26969d4f --- /dev/null +++ b/actix_web/body/fn.to_bytes.html @@ -0,0 +1,16 @@ +to_bytes in actix_web::body - Rust

Function actix_web::body::to_bytes

source ·
pub async fn to_bytes<B>(body: B) -> Result<Bytes, <B as MessageBody>::Error>
where + B: MessageBody,
Expand description

Collects all the bytes produced by body.

+

Any errors produced by the body stream are returned immediately.

+

Consider using to_bytes_limited instead to protect against memory exhaustion.

+

§Examples

+
use actix_http::body::{self, to_bytes};
+use bytes::Bytes;
+
+let body = body::None::new();
+let bytes = to_bytes(body).await.unwrap();
+assert!(bytes.is_empty());
+
+let body = Bytes::from_static(b"123");
+let bytes = to_bytes(body).await.unwrap();
+assert_eq!(bytes, "123");
+
\ No newline at end of file diff --git a/actix_web/body/fn.to_bytes_limited.html b/actix_web/body/fn.to_bytes_limited.html new file mode 100644 index 000000000..045ac244a --- /dev/null +++ b/actix_web/body/fn.to_bytes_limited.html @@ -0,0 +1,23 @@ +to_bytes_limited in actix_web::body - Rust

Function actix_web::body::to_bytes_limited

source ·
pub async fn to_bytes_limited<B>(
+    body: B,
+    limit: usize
+) -> Result<Result<Bytes, <B as MessageBody>::Error>, BodyLimitExceeded>
where + B: MessageBody,
Expand description

Collects the bytes produced by body, up to limit bytes.

+

If a chunk read from poll_next causes the total number of bytes read to exceed limit, an +Err(BodyLimitExceeded) is returned.

+

Any errors produced by the body stream are returned immediately as Ok(Err(B::Error)).

+

§Examples

+
use actix_http::body::{self, to_bytes_limited};
+use bytes::Bytes;
+
+let body = body::None::new();
+let bytes = to_bytes_limited(body, 10).await.unwrap().unwrap();
+assert!(bytes.is_empty());
+
+let body = Bytes::from_static(b"123");
+let bytes = to_bytes_limited(body, 10).await.unwrap().unwrap();
+assert_eq!(bytes, "123");
+
+let body = Bytes::from_static(b"123");
+assert!(to_bytes_limited(body, 2).await.is_err());
+
\ No newline at end of file diff --git a/actix_web/body/index.html b/actix_web/body/index.html new file mode 100644 index 000000000..18ebcede3 --- /dev/null +++ b/actix_web/body/index.html @@ -0,0 +1,3 @@ +actix_web::body - Rust

Module actix_web::body

source ·
Expand description

Traits and structures to aid consuming and writing HTTP payloads.

+

“Body” and “payload” are used somewhat interchangeably in this documentation.

+

Structs§

Enums§

Traits§

  • An interface for types that can be used as a response body.

Functions§

\ No newline at end of file diff --git a/actix_web/body/sidebar-items.js b/actix_web/body/sidebar-items.js new file mode 100644 index 000000000..02571f400 --- /dev/null +++ b/actix_web/body/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["BodySize","EitherBody"],"fn":["to_bytes","to_bytes_limited"],"struct":["BodyLimitExceeded","BodyStream","BoxBody","None","SizedStream"],"trait":["MessageBody"]}; \ No newline at end of file diff --git a/actix_web/body/struct.BodyLimitExceeded.html b/actix_web/body/struct.BodyLimitExceeded.html new file mode 100644 index 000000000..78ae700cf --- /dev/null +++ b/actix_web/body/struct.BodyLimitExceeded.html @@ -0,0 +1,22 @@ +BodyLimitExceeded in actix_web::body - Rust

Struct actix_web::body::BodyLimitExceeded

source ·
#[non_exhaustive]
pub struct BodyLimitExceeded;
Expand description

Error type returned from to_bytes_limited when body produced exceeds limit.

+

Trait Implementations§

source§

impl Debug for BodyLimitExceeded

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for BodyLimitExceeded

source§

fn fmt( + &self, + _derive_more_display_formatter: &mut Formatter<'_> +) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for BodyLimitExceeded

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/body/struct.BodyStream.html b/actix_web/body/struct.BodyStream.html new file mode 100644 index 000000000..361308664 --- /dev/null +++ b/actix_web/body/struct.BodyStream.html @@ -0,0 +1,37 @@ +BodyStream in actix_web::body - Rust

Struct actix_web::body::BodyStream

source ·
pub struct BodyStream<S> { /* private fields */ }
Expand description

Streaming response wrapper.

+

Response does not contain Content-Length header and appropriate transfer encoding is used.

+

Implementations§

source§

impl<S, E> BodyStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn Error>> + 'static,

source

pub fn new(stream: S) -> BodyStream<S>

Trait Implementations§

source§

impl<S, E> MessageBody for BodyStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn Error>> + 'static,

source§

fn poll_next( + self: Pin<&mut BodyStream<S>>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <BodyStream<S> as MessageBody>::Error>>>

Attempts to pull out the next value of the underlying [Stream].

+

Empty values are skipped to prevent BodyStream’s transmission being ended on a +zero-length chunk, but rather proceed until the underlying [Stream] ends.

+
§

type Error = E

The type of error that will be returned if streaming body fails. Read more
source§

fn size(&self) -> BodySize

Body size hint. Read more
source§

fn try_into_bytes(self) -> Result<Bytes, Self>
where + Self: Sized,

Try to convert into the complete chunk of body bytes. Read more
source§

fn boxed(self) -> BoxBody
where + Self: Sized + 'static,

Wraps this body into a BoxBody. Read more
source§

impl<'__pin, S> Unpin for BodyStream<S>
where + __Origin<'__pin, S>: Unpin,

Auto Trait Implementations§

§

impl<S> Freeze for BodyStream<S>
where + S: Freeze,

§

impl<S> RefUnwindSafe for BodyStream<S>
where + S: RefUnwindSafe,

§

impl<S> Send for BodyStream<S>
where + S: Send,

§

impl<S> Sync for BodyStream<S>
where + S: Sync,

§

impl<S> UnwindSafe for BodyStream<S>
where + S: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/body/struct.BoxBody.html b/actix_web/body/struct.BoxBody.html new file mode 100644 index 000000000..3b05f9117 --- /dev/null +++ b/actix_web/body/struct.BoxBody.html @@ -0,0 +1,26 @@ +BoxBody in actix_web::body - Rust

Struct actix_web::body::BoxBody

source ·
pub struct BoxBody(/* private fields */);
Expand description

A boxed message body with boxed errors.

+

Implementations§

source§

impl BoxBody

source

pub fn new<B>(body: B) -> BoxBody
where + B: MessageBody + 'static,

Boxes body type, erasing type information.

+

If the body type to wrap is unknown or generic it is better to use MessageBody::boxed to +avoid double boxing.

+
source

pub fn as_pin_mut(&mut self) -> Pin<&mut BoxBody>

Returns a mutable pinned reference to the inner message body type.

+

Trait Implementations§

source§

impl Debug for BoxBody

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl MessageBody for BoxBody

§

type Error = Box<dyn Error>

The type of error that will be returned if streaming body fails. Read more
source§

fn size(&self) -> BodySize

Body size hint. Read more
source§

fn poll_next( + self: Pin<&mut BoxBody>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <BoxBody as MessageBody>::Error>>>

Attempt to pull out the next chunk of body bytes. Read more
source§

fn try_into_bytes(self) -> Result<Bytes, BoxBody>

Try to convert into the complete chunk of body bytes. Read more
source§

fn boxed(self) -> BoxBody

Wraps this body into a BoxBody. Read more

Auto Trait Implementations§

§

impl !Freeze for BoxBody

§

impl !RefUnwindSafe for BoxBody

§

impl !Send for BoxBody

§

impl !Sync for BoxBody

§

impl Unpin for BoxBody

§

impl !UnwindSafe for BoxBody

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/body/struct.None.html b/actix_web/body/struct.None.html new file mode 100644 index 000000000..34abbaa3f --- /dev/null +++ b/actix_web/body/struct.None.html @@ -0,0 +1,29 @@ +None in actix_web::body - Rust

Struct actix_web::body::None

source ·
#[non_exhaustive]
pub struct None;
Expand description

Body type for responses that forbid payloads.

+

This is distinct from an “empty” response which would contain a Content-Length header. +For an “empty” body, use () or Bytes::new().

+

For example, the HTTP spec forbids a payload to be sent with a 204 No Content response. +In this case, the payload (or lack thereof) is implicit from the status code, so a +Content-Length header is not required.

+

Implementations§

source§

impl None

source

pub fn new() -> None

Constructs new “none” body.

+

Trait Implementations§

source§

impl Clone for None

source§

fn clone(&self) -> None

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for None

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for None

source§

fn default() -> None

Returns the “default value” for a type. Read more
source§

impl MessageBody for None

§

type Error = Infallible

The type of error that will be returned if streaming body fails. Read more
source§

fn size(&self) -> BodySize

Body size hint. Read more
source§

fn poll_next( + self: Pin<&mut None>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <None as MessageBody>::Error>>>

Attempt to pull out the next chunk of body bytes. Read more
source§

fn try_into_bytes(self) -> Result<Bytes, None>

Try to convert into the complete chunk of body bytes. Read more
source§

fn boxed(self) -> BoxBody
where + Self: Sized + 'static,

Wraps this body into a BoxBody. Read more
source§

impl Copy for None

Auto Trait Implementations§

§

impl Freeze for None

§

impl RefUnwindSafe for None

§

impl Send for None

§

impl Sync for None

§

impl Unpin for None

§

impl UnwindSafe for None

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/body/struct.SizedStream.html b/actix_web/body/struct.SizedStream.html new file mode 100644 index 000000000..388345ca4 --- /dev/null +++ b/actix_web/body/struct.SizedStream.html @@ -0,0 +1,39 @@ +SizedStream in actix_web::body - Rust

Struct actix_web::body::SizedStream

source ·
pub struct SizedStream<S> { /* private fields */ }
Expand description

Known sized streaming response wrapper.

+

This body implementation should be used if total size of stream is known. Data is sent as-is +without using chunked transfer encoding.

+

Implementations§

source§

impl<S, E> SizedStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn Error>> + 'static,

source

pub fn new(size: u64, stream: S) -> SizedStream<S>

Trait Implementations§

source§

impl<S, E> MessageBody for SizedStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn Error>> + 'static,

source§

fn poll_next( + self: Pin<&mut SizedStream<S>>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <SizedStream<S> as MessageBody>::Error>>>

Attempts to pull out the next value of the underlying [Stream].

+

Empty values are skipped to prevent SizedStream’s transmission being +ended on a zero-length chunk, but rather proceed until the underlying +[Stream] ends.

+
§

type Error = E

The type of error that will be returned if streaming body fails. Read more
source§

fn size(&self) -> BodySize

Body size hint. Read more
source§

fn try_into_bytes(self) -> Result<Bytes, Self>
where + Self: Sized,

Try to convert into the complete chunk of body bytes. Read more
source§

fn boxed(self) -> BoxBody
where + Self: Sized + 'static,

Wraps this body into a BoxBody. Read more
source§

impl<'__pin, S> Unpin for SizedStream<S>
where + __Origin<'__pin, S>: Unpin,

Auto Trait Implementations§

§

impl<S> Freeze for SizedStream<S>
where + S: Freeze,

§

impl<S> RefUnwindSafe for SizedStream<S>
where + S: RefUnwindSafe,

§

impl<S> Send for SizedStream<S>
where + S: Send,

§

impl<S> Sync for SizedStream<S>
where + S: Sync,

§

impl<S> UnwindSafe for SizedStream<S>
where + S: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/body/trait.MessageBody.html b/actix_web/body/trait.MessageBody.html new file mode 100644 index 000000000..9af9d4d57 --- /dev/null +++ b/actix_web/body/trait.MessageBody.html @@ -0,0 +1,133 @@ +MessageBody in actix_web::body - Rust

Trait actix_web::body::MessageBody

source ·
pub trait MessageBody {
+    type Error: Into<Box<dyn Error>>;
+
+    // Required methods
+    fn size(&self) -> BodySize;
+    fn poll_next(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>
+    ) -> Poll<Option<Result<Bytes, Self::Error>>>;
+
+    // Provided methods
+    fn try_into_bytes(self) -> Result<Bytes, Self>
+       where Self: Sized { ... }
+    fn boxed(self) -> BoxBody
+       where Self: Sized + 'static { ... }
+}
Expand description

An interface for types that can be used as a response body.

+

It is not usually necessary to create custom body types, this trait is already implemented for +a large number of sensible body types including:

+ +

§Examples

+
struct Repeat {
+    chunk: String,
+    n_times: usize,
+}
+
+impl MessageBody for Repeat {
+    type Error = Infallible;
+
+    fn size(&self) -> BodySize {
+        BodySize::Sized((self.chunk.len() * self.n_times) as u64)
+    }
+
+    fn poll_next(
+        self: Pin<&mut Self>,
+        _cx: &mut Context<'_>,
+    ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+        let payload_string = self.chunk.repeat(self.n_times);
+        let payload_bytes = Bytes::from(payload_string);
+        Poll::Ready(Some(Ok(payload_bytes)))
+    }
+}
+

Required Associated Types§

source

type Error: Into<Box<dyn Error>>

The type of error that will be returned if streaming body fails.

+

Since it is not appropriate to generate a response mid-stream, it only requires Error for +internal use and logging.

+

Required Methods§

source

fn size(&self) -> BodySize

Body size hint.

+

If BodySize::None is returned, optimizations that skip reading the body are allowed.

+
source

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

Attempt to pull out the next chunk of body bytes.

+
§Return Value
+

Similar to the Stream interface, there are several possible return values, each indicating +a distinct state:

+
    +
  • Poll::Pending means that this body’s next chunk is not ready yet. Implementations must +ensure that the current task will be notified when the next chunk may be ready.
  • +
  • Poll::Ready(Some(val)) means that the body has successfully produced a chunk, val, +and may produce further values on subsequent poll_next calls.
  • +
  • Poll::Ready(None) means that the body is complete, and poll_next should not be +invoked again.
  • +
+
§Panics
+

Once a body is complete (i.e., poll_next returned Ready(None)), calling its poll_next +method again may panic, block forever, or cause other kinds of problems; this trait places +no requirements on the effects of such a call. However, as the poll_next method is not +marked unsafe, Rust’s usual rules apply: calls must never cause UB, regardless of its state.

+

Provided Methods§

source

fn try_into_bytes(self) -> Result<Bytes, Self>
where + Self: Sized,

Try to convert into the complete chunk of body bytes.

+

Override this method if the complete body can be trivially extracted. This is useful for +optimizations where poll_next calls can be avoided.

+

Body types with BodySize::None are allowed to return empty Bytes. Although, if calling +this method, it is recommended to check size first and return early.

+
§Errors
+

The default implementation will error and return the original type back to the caller for +further use.

+
source

fn boxed(self) -> BoxBody
where + Self: Sized + 'static,

Wraps this body into a BoxBody.

+

No-op when called on a BoxBody, meaning there is no risk of double boxing when calling +this on a generic MessageBody. Prefer this over BoxBody::new when a boxed body +is required.

+

Implementations on Foreign Types§

source§

impl MessageBody for &'static str

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut &'static str>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <&'static str as MessageBody>::Error>>>

source§

fn try_into_bytes(self) -> Result<Bytes, &'static str>

source§

impl MessageBody for &'static [u8]

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut &'static [u8]>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <&'static [u8] as MessageBody>::Error>>>

source§

fn try_into_bytes(self) -> Result<Bytes, &'static [u8]>

source§

impl MessageBody for Cow<'static, str>

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Cow<'static, str>>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <Cow<'static, str> as MessageBody>::Error>>>

source§

fn try_into_bytes(self) -> Result<Bytes, Cow<'static, str>>

source§

impl MessageBody for Cow<'static, [u8]>

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Cow<'static, [u8]>>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <Cow<'static, [u8]> as MessageBody>::Error>>>

source§

fn try_into_bytes(self) -> Result<Bytes, Cow<'static, [u8]>>

source§

impl MessageBody for Infallible

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Infallible>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <Infallible as MessageBody>::Error>>>

source§

impl MessageBody for ()

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut ()>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <() as MessageBody>::Error>>>

source§

fn try_into_bytes(self) -> Result<Bytes, ()>

source§

impl MessageBody for String

source§

impl MessageBody for Vec<u8>

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Vec<u8>>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <Vec<u8> as MessageBody>::Error>>>

source§

fn try_into_bytes(self) -> Result<Bytes, Vec<u8>>

source§

impl MessageBody for ByteString

§

type Error = Infallible

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut ByteString>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <ByteString as MessageBody>::Error>>>

source§

fn try_into_bytes(self) -> Result<Bytes, ByteString>

source§

impl<B> MessageBody for &mut B
where + B: MessageBody + Unpin + ?Sized,

§

type Error = <B as MessageBody>::Error

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut &mut B>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <&mut B as MessageBody>::Error>>>

source§

impl<B> MessageBody for Box<B>
where + B: MessageBody + Unpin + ?Sized,

§

type Error = <B as MessageBody>::Error

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Box<B>>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <Box<B> as MessageBody>::Error>>>

source§

impl<T, B> MessageBody for Pin<T>
where + T: DerefMut<Target = B> + Unpin, + B: MessageBody + ?Sized,

§

type Error = <B as MessageBody>::Error

source§

fn size(&self) -> BodySize

source§

fn poll_next( + self: Pin<&mut Pin<T>>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <Pin<T> as MessageBody>::Error>>>

Implementors§

source§

impl MessageBody for Bytes

source§

impl MessageBody for BytesMut

source§

impl MessageBody for BoxBody

§

type Error = Box<dyn Error>

source§

impl MessageBody for None

source§

impl<B> MessageBody for Encoder<B>
where + B: MessageBody,

§

type Error = EncoderError

source§

impl<L, R> MessageBody for EitherBody<L, R>
where + L: MessageBody + 'static, + R: MessageBody + 'static,

§

type Error = Error

source§

impl<S, E> MessageBody for BodyStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn Error>> + 'static,

§

type Error = E

source§

impl<S, E> MessageBody for SizedStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn Error>> + 'static,

§

type Error = E

\ No newline at end of file diff --git a/actix_web/config/struct.AppConfig.html b/actix_web/config/struct.AppConfig.html new file mode 100644 index 000000000..693e6f1d3 --- /dev/null +++ b/actix_web/config/struct.AppConfig.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/dev/struct.AppConfig.html...

+ + + \ No newline at end of file diff --git a/actix_web/config/struct.AppService.html b/actix_web/config/struct.AppService.html new file mode 100644 index 000000000..3fcf35c06 --- /dev/null +++ b/actix_web/config/struct.AppService.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/dev/struct.AppService.html...

+ + + \ No newline at end of file diff --git a/actix_web/config/struct.ServiceConfig.html b/actix_web/config/struct.ServiceConfig.html new file mode 100644 index 000000000..b90c22749 --- /dev/null +++ b/actix_web/config/struct.ServiceConfig.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/web/struct.ServiceConfig.html...

+ + + \ No newline at end of file diff --git a/actix_web/cookie/enum.Expiration.html b/actix_web/cookie/enum.Expiration.html new file mode 100644 index 000000000..c481ab0af --- /dev/null +++ b/actix_web/cookie/enum.Expiration.html @@ -0,0 +1,103 @@ +Expiration in actix_web::cookie - Rust

Enum actix_web::cookie::Expiration

source ·
pub enum Expiration {
+    DateTime(OffsetDateTime),
+    Session,
+}
Available on crate feature cookies only.
Expand description

A cookie’s expiration: either session or a date-time.

+

An Expiration is constructible via Expiration::from() with an +Option<OffsetDateTime> or an OffsetDateTime:

+
    +
  • None -> Expiration::Session
  • +
  • Some(OffsetDateTime) -> Expiration::DateTime
  • +
  • OffsetDateTime -> Expiration::DateTime
  • +
+ +
use cookie::Expiration;
+use time::OffsetDateTime;
+
+let expires = Expiration::from(None);
+assert_eq!(expires, Expiration::Session);
+
+let now = OffsetDateTime::now_utc();
+let expires = Expiration::from(now);
+assert_eq!(expires, Expiration::DateTime(now));
+
+let expires = Expiration::from(Some(now));
+assert_eq!(expires, Expiration::DateTime(now));
+

Variants§

§

DateTime(OffsetDateTime)

Expiration for a “permanent” cookie at a specific date-time.

+
§

Session

Expiration for a “session” cookie. Browsers define the notion of a +“session” and will automatically expire session cookies when they deem +the “session” to be over. This is typically, but need not be, when the +browser is closed.

+

Implementations§

source§

impl Expiration

source

pub fn is_datetime(&self) -> bool

Returns true if self is an Expiration::DateTime.

+
§Example
+
use cookie::Expiration;
+use time::OffsetDateTime;
+
+let expires = Expiration::from(None);
+assert!(!expires.is_datetime());
+
+let expires = Expiration::from(OffsetDateTime::now_utc());
+assert!(expires.is_datetime());
+
source

pub fn is_session(&self) -> bool

Returns true if self is an Expiration::Session.

+
§Example
+
use cookie::Expiration;
+use time::OffsetDateTime;
+
+let expires = Expiration::from(None);
+assert!(expires.is_session());
+
+let expires = Expiration::from(OffsetDateTime::now_utc());
+assert!(!expires.is_session());
+
source

pub fn datetime(self) -> Option<OffsetDateTime>

Returns the inner OffsetDateTime if self is a DateTime.

+
§Example
+
use cookie::Expiration;
+use time::OffsetDateTime;
+
+let expires = Expiration::from(None);
+assert!(expires.datetime().is_none());
+
+let now = OffsetDateTime::now_utc();
+let expires = Expiration::from(now);
+assert_eq!(expires.datetime(), Some(now));
+
source

pub fn map<F>(self, f: F) -> Expiration

Applied f to the inner OffsetDateTime if self is a DateTime and +returns the mapped Expiration.

+
§Example
+
use cookie::Expiration;
+use time::{OffsetDateTime, Duration};
+
+let now = OffsetDateTime::now_utc();
+let one_week = Duration::weeks(1);
+
+let expires = Expiration::from(now);
+assert_eq!(expires.map(|t| t + one_week).datetime(), Some(now + one_week));
+
+let expires = Expiration::from(None);
+assert_eq!(expires.map(|t| t + one_week).datetime(), None);
+

Trait Implementations§

source§

impl Clone for Expiration

source§

fn clone(&self) -> Expiration

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Expiration

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<T> From<T> for Expiration
where + T: Into<Option<OffsetDateTime>>,

source§

fn from(option: T) -> Expiration

Converts to this type from the input type.
source§

impl Hash for Expiration

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq for Expiration

source§

fn eq(&self, other: &Expiration) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for Expiration

source§

impl Eq for Expiration

source§

impl StructuralPartialEq for Expiration

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/enum.KeyError.html b/actix_web/cookie/enum.KeyError.html new file mode 100644 index 000000000..2c947985f --- /dev/null +++ b/actix_web/cookie/enum.KeyError.html @@ -0,0 +1,23 @@ +KeyError in actix_web::cookie - Rust

Enum actix_web::cookie::KeyError

source ·
#[non_exhaustive]
pub enum KeyError { + TooShort(usize), +}
Available on crate feature cookies only.
Expand description

An error indicating an issue with generating or constructing a key.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

TooShort(usize)

Too few bytes (.0) were provided to generate a key.

+

See Key::from() for minimum requirements.

+

Trait Implementations§

source§

impl Debug for KeyError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for KeyError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for KeyError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/enum.ParseError.html b/actix_web/cookie/enum.ParseError.html new file mode 100644 index 000000000..0e385863d --- /dev/null +++ b/actix_web/cookie/enum.ParseError.html @@ -0,0 +1,34 @@ +ParseError in actix_web::cookie - Rust

Enum actix_web::cookie::ParseError

source ·
#[non_exhaustive]
pub enum ParseError { + MissingPair, + EmptyName, + Utf8Error(Utf8Error), +}
Available on crate feature cookies only.
Expand description

Enum corresponding to a parsing error.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

MissingPair

The cookie did not contain a name/value pair.

+
§

EmptyName

The cookie’s name was empty.

+
§

Utf8Error(Utf8Error)

Decoding the cookie’s name or value resulted in invalid UTF-8.

+

Implementations§

source§

impl ParseError

source

pub fn as_str(&self) -> &'static str

Returns a description of this error as a string

+

Trait Implementations§

source§

impl Clone for ParseError

source§

fn clone(&self) -> ParseError

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ParseError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for ParseError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for ParseError

source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<Utf8Error> for ParseError

source§

fn from(error: Utf8Error) -> ParseError

Converts to this type from the input type.
source§

impl PartialEq for ParseError

source§

fn eq(&self, other: &ParseError) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for ParseError

source§

impl Eq for ParseError

source§

impl StructuralPartialEq for ParseError

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/enum.SameSite.html b/actix_web/cookie/enum.SameSite.html new file mode 100644 index 000000000..9235b8405 --- /dev/null +++ b/actix_web/cookie/enum.SameSite.html @@ -0,0 +1,75 @@ +SameSite in actix_web::cookie - Rust

Enum actix_web::cookie::SameSite

source ·
pub enum SameSite {
+    Strict,
+    Lax,
+    None,
+}
Available on crate feature cookies only.
Expand description

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 +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 +initally or passing None to Cookie::set_same_site()), then the cookie +will be sent as normal.

+

Note: This cookie attribute is an HTTP draft! Its meaning and +definition are subject to change.

+

Variants§

§

Strict

The “Strict” SameSite attribute.

+
§

Lax

The “Lax” SameSite attribute.

+
§

None

The “None” SameSite attribute.

+

Implementations§

source§

impl SameSite

source

pub fn is_strict(&self) -> bool

Returns true if self is SameSite::Strict and false otherwise.

+
§Example
+
use cookie::SameSite;
+
+let strict = SameSite::Strict;
+assert!(strict.is_strict());
+assert!(!strict.is_lax());
+assert!(!strict.is_none());
+
source

pub fn is_lax(&self) -> bool

Returns true if self is SameSite::Lax and false otherwise.

+
§Example
+
use cookie::SameSite;
+
+let lax = SameSite::Lax;
+assert!(lax.is_lax());
+assert!(!lax.is_strict());
+assert!(!lax.is_none());
+
source

pub fn is_none(&self) -> bool

Returns true if self is SameSite::None and false otherwise.

+
§Example
+
use cookie::SameSite;
+
+let none = SameSite::None;
+assert!(none.is_none());
+assert!(!none.is_lax());
+assert!(!none.is_strict());
+

Trait Implementations§

source§

impl Clone for SameSite

source§

fn clone(&self) -> SameSite

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for SameSite

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for SameSite

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Hash for SameSite

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq for SameSite

source§

fn eq(&self, other: &SameSite) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for SameSite

source§

impl Eq for SameSite

source§

impl StructuralPartialEq for SameSite

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/index.html b/actix_web/cookie/index.html new file mode 100644 index 000000000..7c56cf484 --- /dev/null +++ b/actix_web/cookie/index.html @@ -0,0 +1,58 @@ +actix_web::cookie - Rust

Crate actix_web::cookie

source ·
Available on crate feature cookies only.
Expand description

HTTP cookie parsing and cookie jar management.

+

This crates provides the Cookie type, representing an HTTP cookie, and +the CookieJar type, which manages a collection of cookies for session +management, recording changes as they are made, and optional automatic +cookie encryption and signing.

+

§Usage

+

Add the following to the [dependencies] section of your Cargo.toml:

+
cookie = "0.16"
+

§Features

+

This crate exposes several features, all of which are disabled by default:

+
    +
  • +

    percent-encode

    +

    Enables percent encoding and decoding of names and values in cookies.

    +

    When this feature is enabled, the Cookie::encoded() and +Cookie::parse_encoded() methods are available. The encoded method +returns a wrapper around a Cookie whose Display implementation +percent-encodes the name and value of the cookie. The parse_encoded +method percent-decodes the name and value of a Cookie during parsing.

    +
  • +
  • +

    signed

    +

    Enables signed cookies via CookieJar::signed().

    +

    When this feature is enabled, the CookieJar::signed() method, +SignedJar type, and Key type are available. The jar acts as “child +jar”; operations on the jar automatically sign and verify cookies as they +are added and retrieved from the parent jar.

    +
  • +
  • +

    private

    +

    Enables private (authenticated, encrypted) cookies via +CookieJar::private().

    +

    When this feature is enabled, the CookieJar::private() method, +PrivateJar type, and Key type are available. The jar acts as “child +jar”; operations on the jar automatically encrypt and decrypt/authenticate +cookies as they are added and retrieved from the parent jar.

    +
  • +
  • +

    key-expansion

    +

    Enables key expansion or key derivation via Key::derive_from().

    +

    When this feature is enabled, and either signed or private are also +enabled, the Key::derive_from() method is available. The method can be +used to derive a Key structure appropriate for use with signed and +private jars from cryptographically valid key material that is shorter in +length than the full key.

    +
  • +
  • +

    secure

    +

    A meta-feature that simultaneously enables signed, private, and +key-expansion.

    +
  • +
+

You can enable features via Cargo.toml:

+
[dependencies.cookie]
+features = ["secure", "percent-encode"]
+

Modules§

Structs§

  • Representation of an HTTP cookie.
  • Structure that follows the builder pattern for building Cookie structs.
  • A collection of cookies that tracks its modifications.
  • Iterator over the changes to a cookie jar.
  • Wrapper around Cookie whose Display implementation either +percent-encodes the cookie’s name and value, skips displaying the cookie’s +parameters (only displaying it’s name and value), or both.
  • Iterator over all of the cookies in a jar.
  • A cryptographic master key for use with Signed and/or Private jars.
  • A child cookie jar that provides authenticated encryption for its cookies.
  • A child cookie jar that authenticates its cookies.

Enums§

  • A cookie’s expiration: either session or a date-time.
  • An error indicating an issue with generating or constructing a key.
  • Enum corresponding to a parsing error.
  • The SameSite cookie attribute.
\ No newline at end of file diff --git a/actix_web/cookie/sidebar-items.js b/actix_web/cookie/sidebar-items.js new file mode 100644 index 000000000..9d8f306c8 --- /dev/null +++ b/actix_web/cookie/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Expiration","KeyError","ParseError","SameSite"],"mod":["time"],"struct":["Cookie","CookieBuilder","CookieJar","Delta","Display","Iter","Key","PrivateJar","SignedJar"]}; \ No newline at end of file diff --git a/actix_web/cookie/struct.Cookie.html b/actix_web/cookie/struct.Cookie.html new file mode 100644 index 000000000..3b6d1bb6a --- /dev/null +++ b/actix_web/cookie/struct.Cookie.html @@ -0,0 +1,534 @@ +Cookie in actix_web::cookie - Rust

Struct actix_web::cookie::Cookie

source ·
pub struct Cookie<'c> { /* private fields */ }
Available on crate feature cookies only.
Expand description

Representation of an HTTP cookie.

+ +

To construct a cookie with only a name/value, use Cookie::new():

+ +
use cookie::Cookie;
+
+let cookie = Cookie::new("name", "value");
+assert_eq!(&cookie.to_string(), "name=value");
+

To construct more elaborate cookies, use Cookie::build() and +CookieBuilder methods:

+ +
use cookie::Cookie;
+
+let cookie = Cookie::build("name", "value")
+    .domain("www.rust-lang.org")
+    .path("/")
+    .secure(true)
+    .http_only(true)
+    .finish();
+

Implementations§

source§

impl<'c> Cookie<'c>

source

pub fn new<N, V>(name: N, value: V) -> Cookie<'c>
where + N: Into<Cow<'c, str>>, + V: Into<Cow<'c, str>>,

Creates a new Cookie with the given name and value.

+
§Example
+
use cookie::Cookie;
+
+let cookie = Cookie::new("name", "value");
+assert_eq!(cookie.name_value(), ("name", "value"));
+
source

pub fn named<N>(name: N) -> Cookie<'c>
where + N: Into<Cow<'c, str>>,

Creates a new Cookie with the given name and an empty value.

+
§Example
+
use cookie::Cookie;
+
+let cookie = Cookie::named("name");
+assert_eq!(cookie.name(), "name");
+assert!(cookie.value().is_empty());
+
source

pub fn build<N, V>(name: N, value: V) -> CookieBuilder<'c>
where + N: Into<Cow<'c, str>>, + V: Into<Cow<'c, str>>,

Creates a new CookieBuilder instance from the given key and value +strings.

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::build("foo", "bar").finish();
+assert_eq!(c.name_value(), ("foo", "bar"));
+
source

pub fn parse<S>(s: S) -> Result<Cookie<'c>, ParseError>
where + S: Into<Cow<'c, str>>,

Parses a Cookie from the given HTTP cookie header value string. Does +not perform any percent-decoding.

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::parse("foo=bar%20baz; HttpOnly").unwrap();
+assert_eq!(c.name_value(), ("foo", "bar%20baz"));
+assert_eq!(c.http_only(), Some(true));
+
source

pub fn parse_encoded<S>(s: S) -> Result<Cookie<'c>, ParseError>
where + S: Into<Cow<'c, str>>,

Available on crate feature percent-encode only.

Parses a Cookie from the given HTTP cookie header value string where +the name and value fields are percent-encoded. Percent-decodes the +name/value fields.

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::parse_encoded("foo=bar%20baz; HttpOnly").unwrap();
+assert_eq!(c.name_value(), ("foo", "bar baz"));
+assert_eq!(c.http_only(), Some(true));
+
source

pub fn into_owned(self) -> Cookie<'static>

Converts self into a Cookie with a static lifetime with as few +allocations as possible.

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::new("a", "b");
+let owned_cookie = c.into_owned();
+assert_eq!(owned_cookie.name_value(), ("a", "b"));
+
source

pub fn name(&self) -> &str

Returns the name of self.

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::new("name", "value");
+assert_eq!(c.name(), "name");
+
source

pub fn value(&self) -> &str

Returns the value of self.

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::new("name", "value");
+assert_eq!(c.value(), "value");
+
source

pub fn name_value(&self) -> (&str, &str)

Returns the name and value of self as a tuple of (name, value).

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::new("name", "value");
+assert_eq!(c.name_value(), ("name", "value"));
+
source

pub fn http_only(&self) -> Option<bool>

Returns whether this cookie was marked HttpOnly or not. Returns +Some(true) when the cookie was explicitly set (manually or parsed) as +HttpOnly, Some(false) when http_only was manually set to false, +and None otherwise.

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::parse("name=value; httponly").unwrap();
+assert_eq!(c.http_only(), Some(true));
+
+let mut c = Cookie::new("name", "value");
+assert_eq!(c.http_only(), None);
+
+let mut c = Cookie::new("name", "value");
+assert_eq!(c.http_only(), None);
+
+// An explicitly set "false" value.
+c.set_http_only(false);
+assert_eq!(c.http_only(), Some(false));
+
+// An explicitly set "true" value.
+c.set_http_only(true);
+assert_eq!(c.http_only(), Some(true));
+
source

pub fn secure(&self) -> Option<bool>

Returns whether this cookie was marked Secure or not. Returns +Some(true) when the cookie was explicitly set (manually or parsed) as +Secure, Some(false) when secure was manually set to false, and +None otherwise.

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::parse("name=value; Secure").unwrap();
+assert_eq!(c.secure(), Some(true));
+
+let mut c = Cookie::parse("name=value").unwrap();
+assert_eq!(c.secure(), None);
+
+let mut c = Cookie::new("name", "value");
+assert_eq!(c.secure(), None);
+
+// An explicitly set "false" value.
+c.set_secure(false);
+assert_eq!(c.secure(), Some(false));
+
+// An explicitly set "true" value.
+c.set_secure(true);
+assert_eq!(c.secure(), Some(true));
+
source

pub fn same_site(&self) -> Option<SameSite>

Returns the SameSite attribute of this cookie if one was specified.

+
§Example
+
use cookie::{Cookie, SameSite};
+
+let c = Cookie::parse("name=value; SameSite=Lax").unwrap();
+assert_eq!(c.same_site(), Some(SameSite::Lax));
+
source

pub fn max_age(&self) -> Option<Duration>

Returns the specified max-age of the cookie if one was specified.

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::parse("name=value").unwrap();
+assert_eq!(c.max_age(), None);
+
+let c = Cookie::parse("name=value; Max-Age=3600").unwrap();
+assert_eq!(c.max_age().map(|age| age.whole_hours()), Some(1));
+
source

pub fn path(&self) -> Option<&str>

Returns the Path of the cookie if one was specified.

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::parse("name=value").unwrap();
+assert_eq!(c.path(), None);
+
+let c = Cookie::parse("name=value; Path=/").unwrap();
+assert_eq!(c.path(), Some("/"));
+
+let c = Cookie::parse("name=value; path=/sub").unwrap();
+assert_eq!(c.path(), Some("/sub"));
+
source

pub fn domain(&self) -> Option<&str>

Returns the Domain of the cookie if one was specified.

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::parse("name=value").unwrap();
+assert_eq!(c.domain(), None);
+
+let c = Cookie::parse("name=value; Domain=crates.io").unwrap();
+assert_eq!(c.domain(), Some("crates.io"));
+
source

pub fn expires(&self) -> Option<Expiration>

Returns the Expiration of the cookie if one was specified.

+
§Example
+
use cookie::{Cookie, Expiration};
+
+let c = Cookie::parse("name=value").unwrap();
+assert_eq!(c.expires(), None);
+
+// Here, `cookie.expires_datetime()` returns `None`.
+let c = Cookie::build("name", "value").expires(None).finish();
+assert_eq!(c.expires(), Some(Expiration::Session));
+
+let expire_time = "Wed, 21 Oct 2017 07:28:00 GMT";
+let cookie_str = format!("name=value; Expires={}", expire_time);
+let c = Cookie::parse(cookie_str).unwrap();
+assert_eq!(c.expires().and_then(|e| e.datetime()).map(|t| t.year()), Some(2017));
+
source

pub fn expires_datetime(&self) -> Option<OffsetDateTime>

Returns the expiration date-time of the cookie if one was specified.

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::parse("name=value").unwrap();
+assert_eq!(c.expires_datetime(), None);
+
+// Here, `cookie.expires()` returns `Some`.
+let c = Cookie::build("name", "value").expires(None).finish();
+assert_eq!(c.expires_datetime(), None);
+
+let expire_time = "Wed, 21 Oct 2017 07:28:00 GMT";
+let cookie_str = format!("name=value; Expires={}", expire_time);
+let c = Cookie::parse(cookie_str).unwrap();
+assert_eq!(c.expires_datetime().map(|t| t.year()), Some(2017));
+
source

pub fn set_name<N>(&mut self, name: N)
where + N: Into<Cow<'c, str>>,

Sets the name of self to name.

+
§Example
+
use cookie::Cookie;
+
+let mut c = Cookie::new("name", "value");
+assert_eq!(c.name(), "name");
+
+c.set_name("foo");
+assert_eq!(c.name(), "foo");
+
source

pub fn set_value<V>(&mut self, value: V)
where + V: Into<Cow<'c, str>>,

Sets the value of self to value.

+
§Example
+
use cookie::Cookie;
+
+let mut c = Cookie::new("name", "value");
+assert_eq!(c.value(), "value");
+
+c.set_value("bar");
+assert_eq!(c.value(), "bar");
+
source

pub fn set_http_only<T>(&mut self, value: T)
where + T: Into<Option<bool>>,

Sets the value of http_only in self to value. If value is +None, the field is unset.

+
§Example
+
use cookie::Cookie;
+
+let mut c = Cookie::new("name", "value");
+assert_eq!(c.http_only(), None);
+
+c.set_http_only(true);
+assert_eq!(c.http_only(), Some(true));
+
+c.set_http_only(false);
+assert_eq!(c.http_only(), Some(false));
+
+c.set_http_only(None);
+assert_eq!(c.http_only(), None);
+
source

pub fn set_secure<T>(&mut self, value: T)
where + T: Into<Option<bool>>,

Sets the value of secure in self to value. If value is None, +the field is unset.

+
§Example
+
use cookie::Cookie;
+
+let mut c = Cookie::new("name", "value");
+assert_eq!(c.secure(), None);
+
+c.set_secure(true);
+assert_eq!(c.secure(), Some(true));
+
+c.set_secure(false);
+assert_eq!(c.secure(), Some(false));
+
+c.set_secure(None);
+assert_eq!(c.secure(), None);
+
source

pub fn set_same_site<T>(&mut self, value: T)
where + T: Into<Option<SameSite>>,

Sets the value of same_site in self to value. If value is +None, the field is unset. If value is SameSite::None, the “Secure” +flag will be set when the cookie is written out unless secure is +explicitly set to false via Cookie::set_secure() or the equivalent +builder method.

+
§Example
+
use cookie::{Cookie, SameSite};
+
+let mut c = Cookie::new("name", "value");
+assert_eq!(c.same_site(), None);
+
+c.set_same_site(SameSite::None);
+assert_eq!(c.same_site(), Some(SameSite::None));
+assert_eq!(c.to_string(), "name=value; SameSite=None; Secure");
+
+c.set_secure(false);
+assert_eq!(c.to_string(), "name=value; SameSite=None");
+
+let mut c = Cookie::new("name", "value");
+assert_eq!(c.same_site(), None);
+
+c.set_same_site(SameSite::Strict);
+assert_eq!(c.same_site(), Some(SameSite::Strict));
+assert_eq!(c.to_string(), "name=value; SameSite=Strict");
+
+c.set_same_site(None);
+assert_eq!(c.same_site(), None);
+assert_eq!(c.to_string(), "name=value");
+
source

pub fn set_max_age<D>(&mut self, value: D)
where + D: Into<Option<Duration>>,

Sets the value of max_age in self to value. If value is None, +the field is unset.

+
§Example
+
use cookie::Cookie;
+use cookie::time::Duration;
+
+let mut c = Cookie::new("name", "value");
+assert_eq!(c.max_age(), None);
+
+c.set_max_age(Duration::hours(10));
+assert_eq!(c.max_age(), Some(Duration::hours(10)));
+
+c.set_max_age(None);
+assert!(c.max_age().is_none());
+
source

pub fn set_path<P>(&mut self, path: P)
where + P: Into<Cow<'c, str>>,

Sets the path of self to path.

+
§Example
+
use cookie::Cookie;
+
+let mut c = Cookie::new("name", "value");
+assert_eq!(c.path(), None);
+
+c.set_path("/");
+assert_eq!(c.path(), Some("/"));
+
source

pub fn unset_path(&mut self)

Unsets the path of self.

+
§Example
+
use cookie::Cookie;
+
+let mut c = Cookie::new("name", "value");
+assert_eq!(c.path(), None);
+
+c.set_path("/");
+assert_eq!(c.path(), Some("/"));
+
+c.unset_path();
+assert_eq!(c.path(), None);
+
source

pub fn set_domain<D>(&mut self, domain: D)
where + D: Into<Cow<'c, str>>,

Sets the domain of self to domain.

+
§Example
+
use cookie::Cookie;
+
+let mut c = Cookie::new("name", "value");
+assert_eq!(c.domain(), None);
+
+c.set_domain("rust-lang.org");
+assert_eq!(c.domain(), Some("rust-lang.org"));
+
source

pub fn unset_domain(&mut self)

Unsets the domain of self.

+
§Example
+
use cookie::Cookie;
+
+let mut c = Cookie::new("name", "value");
+assert_eq!(c.domain(), None);
+
+c.set_domain("rust-lang.org");
+assert_eq!(c.domain(), Some("rust-lang.org"));
+
+c.unset_domain();
+assert_eq!(c.domain(), None);
+
source

pub fn set_expires<T>(&mut self, time: T)
where + T: Into<Expiration>,

Sets the expires field of self to time. If time is None, an +expiration of Session is set.

+
§Example
+
use cookie::{Cookie, Expiration};
+use cookie::time::{Duration, OffsetDateTime};
+
+let mut c = Cookie::new("name", "value");
+assert_eq!(c.expires(), None);
+
+let mut now = OffsetDateTime::now_utc();
+now += Duration::weeks(52);
+
+c.set_expires(now);
+assert!(c.expires().is_some());
+
+c.set_expires(None);
+assert_eq!(c.expires(), Some(Expiration::Session));
+
source

pub fn unset_expires(&mut self)

Unsets the expires of self.

+
§Example
+
use cookie::{Cookie, Expiration};
+
+let mut c = Cookie::new("name", "value");
+assert_eq!(c.expires(), None);
+
+c.set_expires(None);
+assert_eq!(c.expires(), Some(Expiration::Session));
+
+c.unset_expires();
+assert_eq!(c.expires(), None);
+
source

pub fn make_permanent(&mut self)

Makes self a “permanent” cookie by extending its expiration and max +age 20 years into the future.

+
§Example
+
use cookie::Cookie;
+use cookie::time::Duration;
+
+let mut c = Cookie::new("foo", "bar");
+assert!(c.expires().is_none());
+assert!(c.max_age().is_none());
+
+c.make_permanent();
+assert!(c.expires().is_some());
+assert_eq!(c.max_age(), Some(Duration::days(365 * 20)));
+
source

pub fn make_removal(&mut self)

Make self a “removal” cookie by clearing its value, setting a max-age +of 0, and setting an expiration date far in the past.

+
§Example
+
use cookie::Cookie;
+use cookie::time::Duration;
+
+let mut c = Cookie::new("foo", "bar");
+c.make_permanent();
+assert_eq!(c.max_age(), Some(Duration::days(365 * 20)));
+assert_eq!(c.value(), "bar");
+
+c.make_removal();
+assert_eq!(c.value(), "");
+assert_eq!(c.max_age(), Some(Duration::ZERO));
+
source

pub fn name_raw(&self) -> Option<&'c str>

Returns the name of self as a string slice of the raw string self +was originally parsed from. If self was not originally parsed from a +raw string, returns None.

+

This method differs from Cookie::name() in that it returns a string +with the same lifetime as the originally parsed string. This lifetime +may outlive self. If a longer lifetime is not required, or you’re +unsure if you need a longer lifetime, use Cookie::name().

+
§Example
+
use cookie::Cookie;
+
+let cookie_string = format!("{}={}", "foo", "bar");
+
+// `c` will be dropped at the end of the scope, but `name` will live on
+let name = {
+    let c = Cookie::parse(cookie_string.as_str()).unwrap();
+    c.name_raw()
+};
+
+assert_eq!(name, Some("foo"));
+
source

pub fn value_raw(&self) -> Option<&'c str>

Returns the value of self as a string slice of the raw string self +was originally parsed from. If self was not originally parsed from a +raw string, returns None.

+

This method differs from Cookie::value() in that it returns a +string with the same lifetime as the originally parsed string. This +lifetime may outlive self. If a longer lifetime is not required, or +you’re unsure if you need a longer lifetime, use Cookie::value().

+
§Example
+
use cookie::Cookie;
+
+let cookie_string = format!("{}={}", "foo", "bar");
+
+// `c` will be dropped at the end of the scope, but `value` will live on
+let value = {
+    let c = Cookie::parse(cookie_string.as_str()).unwrap();
+    c.value_raw()
+};
+
+assert_eq!(value, Some("bar"));
+
source

pub fn path_raw(&self) -> Option<&'c str>

Returns the Path of self as a string slice of the raw string self +was originally parsed from. If self was not originally parsed from a +raw string, or if self doesn’t contain a Path, or if the Path has +changed since parsing, returns None.

+

This method differs from Cookie::path() in that it returns a +string with the same lifetime as the originally parsed string. This +lifetime may outlive self. If a longer lifetime is not required, or +you’re unsure if you need a longer lifetime, use Cookie::path().

+
§Example
+
use cookie::Cookie;
+
+let cookie_string = format!("{}={}; Path=/", "foo", "bar");
+
+// `c` will be dropped at the end of the scope, but `path` will live on
+let path = {
+    let c = Cookie::parse(cookie_string.as_str()).unwrap();
+    c.path_raw()
+};
+
+assert_eq!(path, Some("/"));
+
source

pub fn domain_raw(&self) -> Option<&'c str>

Returns the Domain of self as a string slice of the raw string +self was originally parsed from. If self was not originally parsed +from a raw string, or if self doesn’t contain a Domain, or if the +Domain has changed since parsing, returns None.

+

This method differs from Cookie::domain() in that it returns a +string with the same lifetime as the originally parsed string. This +lifetime may outlive self struct. If a longer lifetime is not +required, or you’re unsure if you need a longer lifetime, use +Cookie::domain().

+
§Example
+
use cookie::Cookie;
+
+let cookie_string = format!("{}={}; Domain=crates.io", "foo", "bar");
+
+//`c` will be dropped at the end of the scope, but `domain` will live on
+let domain = {
+    let c = Cookie::parse(cookie_string.as_str()).unwrap();
+    c.domain_raw()
+};
+
+assert_eq!(domain, Some("crates.io"));
+
source

pub fn encoded<'a>(&'a self) -> Display<'a, 'c>

Available on crate feature percent-encode only.

Wraps self in an encoded Display: a cost-free wrapper around +Cookie whose fmt::Display implementation percent-encodes the name +and value of the wrapped Cookie.

+

The returned structure can be chained with Display::stripped() to +display only the name and value.

+
§Example
+
use cookie::Cookie;
+
+let mut c = Cookie::build("my name", "this; value?").secure(true).finish();
+assert_eq!(&c.encoded().to_string(), "my%20name=this%3B%20value%3F; Secure");
+assert_eq!(&c.encoded().stripped().to_string(), "my%20name=this%3B%20value%3F");
+
source

pub fn stripped<'a>(&'a self) -> Display<'a, 'c>

Wraps self in a stripped Display]: a cost-free wrapper around +Cookie whose fmt::Display implementation prints only the name +and value of the wrapped Cookie.

+

The returned structure can be chained with Display::encoded() to +encode the name and value.

+
§Example
+
use cookie::Cookie;
+
+let mut c = Cookie::build("key?", "value").secure(true).path("/").finish();
+assert_eq!(&c.stripped().to_string(), "key?=value");
+// Note: `encoded()` is only available when `percent-encode` is enabled.
+assert_eq!(&c.stripped().encoded().to_string(), "key%3F=value");
+

Trait Implementations§

source§

impl<'c> Clone for Cookie<'c>

source§

fn clone(&self) -> Cookie<'c>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'c> Debug for Cookie<'c>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<'c> Display for Cookie<'c>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the cookie self as a Set-Cookie header value.

+

Does not percent-encode any values. To percent-encode, use +Cookie::encoded().

+
§Example
+
use cookie::Cookie;
+
+let mut cookie = Cookie::build("foo", "bar")
+    .path("/")
+    .finish();
+
+assert_eq!(&cookie.to_string(), "foo=bar; Path=/");
+
source§

impl FromStr for Cookie<'static>

§

type Err = ParseError

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Cookie<'static>, ParseError>

Parses a string s to return a value of this type. Read more
source§

impl<'a, 'b> PartialEq<Cookie<'b>> for Cookie<'a>

source§

fn eq(&self, other: &Cookie<'b>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

§

impl<'c> Freeze for Cookie<'c>

§

impl<'c> RefUnwindSafe for Cookie<'c>

§

impl<'c> Send for Cookie<'c>

§

impl<'c> Sync for Cookie<'c>

§

impl<'c> Unpin for Cookie<'c>

§

impl<'c> UnwindSafe for Cookie<'c>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/struct.CookieBuilder.html b/actix_web/cookie/struct.CookieBuilder.html new file mode 100644 index 000000000..77f8b4701 --- /dev/null +++ b/actix_web/cookie/struct.CookieBuilder.html @@ -0,0 +1,142 @@ +CookieBuilder in actix_web::cookie - Rust

Struct actix_web::cookie::CookieBuilder

source ·
pub struct CookieBuilder<'c> { /* private fields */ }
Available on crate feature cookies only.
Expand description

Structure that follows the builder pattern for building Cookie structs.

+

To construct a cookie:

+
    +
  1. Call Cookie::build to start building.
  2. +
  3. Use any of the builder methods to set fields in the cookie.
  4. +
  5. Call CookieBuilder::finish() to retrieve the built cookie.
  6. +
+

§Example

+
use cookie::Cookie;
+use cookie::time::Duration;
+
+let cookie: Cookie = Cookie::build("name", "value")
+    .domain("www.rust-lang.org")
+    .path("/")
+    .secure(true)
+    .http_only(true)
+    .max_age(Duration::days(1))
+    .finish();
+

Implementations§

source§

impl<'c> CookieBuilder<'c>

source

pub fn new<N, V>(name: N, value: V) -> CookieBuilder<'c>
where + N: Into<Cow<'c, str>>, + V: Into<Cow<'c, str>>,

Creates a new CookieBuilder instance from the given name and value.

+

This method is typically called indirectly via Cookie::build().

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::build("foo", "bar").finish();
+assert_eq!(c.name_value(), ("foo", "bar"));
+
source

pub fn expires<E>(self, when: E) -> CookieBuilder<'c>
where + E: Into<Expiration>,

Sets the expires field in the cookie being built.

+
§Example
+
use cookie::{Cookie, Expiration};
+use cookie::time::OffsetDateTime;
+
+let c = Cookie::build("foo", "bar")
+    .expires(OffsetDateTime::now_utc())
+    .finish();
+
+assert!(c.expires().is_some());
+
+let c = Cookie::build("foo", "bar")
+    .expires(None)
+    .finish();
+
+assert_eq!(c.expires(), Some(Expiration::Session));
+
source

pub fn max_age(self, value: Duration) -> CookieBuilder<'c>

Sets the max_age field in the cookie being built.

+
§Example
+
use cookie::Cookie;
+use cookie::time::Duration;
+
+let c = Cookie::build("foo", "bar")
+    .max_age(Duration::minutes(30))
+    .finish();
+
+assert_eq!(c.max_age(), Some(Duration::seconds(30 * 60)));
+
source

pub fn domain<D>(self, value: D) -> CookieBuilder<'c>
where + D: Into<Cow<'c, str>>,

Sets the domain field in the cookie being built.

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::build("foo", "bar")
+    .domain("www.rust-lang.org")
+    .finish();
+
+assert_eq!(c.domain(), Some("www.rust-lang.org"));
+
source

pub fn path<P>(self, path: P) -> CookieBuilder<'c>
where + P: Into<Cow<'c, str>>,

Sets the path field in the cookie being built.

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::build("foo", "bar")
+    .path("/")
+    .finish();
+
+assert_eq!(c.path(), Some("/"));
+
source

pub fn secure(self, value: bool) -> CookieBuilder<'c>

Sets the secure field in the cookie being built.

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::build("foo", "bar")
+    .secure(true)
+    .finish();
+
+assert_eq!(c.secure(), Some(true));
+
source

pub fn http_only(self, value: bool) -> CookieBuilder<'c>

Sets the http_only field in the cookie being built.

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::build("foo", "bar")
+    .http_only(true)
+    .finish();
+
+assert_eq!(c.http_only(), Some(true));
+
source

pub fn same_site(self, value: SameSite) -> CookieBuilder<'c>

Sets the same_site field in the cookie being built.

+
§Example
+
use cookie::{Cookie, SameSite};
+
+let c = Cookie::build("foo", "bar")
+    .same_site(SameSite::Strict)
+    .finish();
+
+assert_eq!(c.same_site(), Some(SameSite::Strict));
+
source

pub fn permanent(self) -> CookieBuilder<'c>

Makes the cookie being built ‘permanent’ by extending its expiration and +max age 20 years into the future.

+
§Example
+
use cookie::Cookie;
+use cookie::time::Duration;
+
+let c = Cookie::build("foo", "bar")
+    .permanent()
+    .finish();
+
+assert_eq!(c.max_age(), Some(Duration::days(365 * 20)));
+
source

pub fn finish(self) -> Cookie<'c>

Finishes building and returns the built Cookie.

+
§Example
+
use cookie::Cookie;
+
+let c = Cookie::build("foo", "bar")
+    .domain("crates.io")
+    .path("/")
+    .finish();
+
+assert_eq!(c.name_value(), ("foo", "bar"));
+assert_eq!(c.domain(), Some("crates.io"));
+assert_eq!(c.path(), Some("/"));
+

Trait Implementations§

source§

impl<'c> Clone for CookieBuilder<'c>

source§

fn clone(&self) -> CookieBuilder<'c>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<'c> Debug for CookieBuilder<'c>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'c> Freeze for CookieBuilder<'c>

§

impl<'c> RefUnwindSafe for CookieBuilder<'c>

§

impl<'c> Send for CookieBuilder<'c>

§

impl<'c> Sync for CookieBuilder<'c>

§

impl<'c> Unpin for CookieBuilder<'c>

§

impl<'c> UnwindSafe for CookieBuilder<'c>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/struct.CookieJar.html b/actix_web/cookie/struct.CookieJar.html new file mode 100644 index 000000000..b29a2e8e9 --- /dev/null +++ b/actix_web/cookie/struct.CookieJar.html @@ -0,0 +1,351 @@ +CookieJar in actix_web::cookie - Rust

Struct actix_web::cookie::CookieJar

source ·
pub struct CookieJar { /* private fields */ }
Available on crate feature cookies only.
Expand description

A collection of cookies that tracks its modifications.

+

A CookieJar provides storage for any number of cookies. Any changes made +to the jar are tracked; the changes can be retrieved via the +delta method which returns an iterator over the changes.

+

§Usage

+

A jar’s life begins via new and calls to +add_original:

+ +
use cookie::{Cookie, CookieJar};
+
+let mut jar = CookieJar::new();
+jar.add_original(Cookie::new("name", "value"));
+jar.add_original(Cookie::new("second", "another"));
+

Cookies can be added via add and removed via +remove. Finally, cookies can be looked up via +get:

+ +
let mut jar = CookieJar::new();
+jar.add(Cookie::new("a", "one"));
+jar.add(Cookie::new("b", "two"));
+
+assert_eq!(jar.get("a").map(|c| c.value()), Some("one"));
+assert_eq!(jar.get("b").map(|c| c.value()), Some("two"));
+
+jar.remove(Cookie::named("b"));
+assert!(jar.get("b").is_none());
+

§Deltas

+

A jar keeps track of any modifications made to it over time. The +modifications are recorded as cookies. The modifications can be retrieved +via delta. Any new Cookie added to a jar via add +results in the same Cookie appearing in the delta; cookies added via +add_original do not count towards the delta. Any original cookie that is +removed from a jar results in a “removal” cookie appearing in the delta. A +“removal” cookie is a cookie that a server sends so that the cookie is +removed from the client’s machine.

+

Deltas are typically used to create Set-Cookie headers corresponding to +the changes made to a cookie jar over a period of time.

+ +
let mut jar = CookieJar::new();
+
+// original cookies don't affect the delta
+jar.add_original(Cookie::new("original", "value"));
+assert_eq!(jar.delta().count(), 0);
+
+// new cookies result in an equivalent `Cookie` in the delta
+jar.add(Cookie::new("a", "one"));
+jar.add(Cookie::new("b", "two"));
+assert_eq!(jar.delta().count(), 2);
+
+// removing an original cookie adds a "removal" cookie to the delta
+jar.remove(Cookie::named("original"));
+assert_eq!(jar.delta().count(), 3);
+
+// removing a new cookie that was added removes that `Cookie` from the delta
+jar.remove(Cookie::named("a"));
+assert_eq!(jar.delta().count(), 2);
+

Implementations§

source§

impl CookieJar

source

pub fn new() -> CookieJar

Creates an empty cookie jar.

+
§Example
+
use cookie::CookieJar;
+
+let jar = CookieJar::new();
+assert_eq!(jar.iter().count(), 0);
+
source

pub fn get(&self, name: &str) -> Option<&Cookie<'static>>

Returns a reference to the Cookie inside this jar with the name +name. If no such cookie exists, returns None.

+
§Example
+
use cookie::{CookieJar, Cookie};
+
+let mut jar = CookieJar::new();
+assert!(jar.get("name").is_none());
+
+jar.add(Cookie::new("name", "value"));
+assert_eq!(jar.get("name").map(|c| c.value()), Some("value"));
+
source

pub fn add_original(&mut self, cookie: Cookie<'static>)

Adds an “original” cookie to this jar. If an original cookie with the +same name already exists, it is replaced with cookie. Cookies added +with add take precedence and are not replaced by this method.

+

Adding an original cookie does not affect the delta +computation. This method is intended to be used to seed the cookie jar +with cookies received from a client’s HTTP message.

+

For accurate delta computations, this method should not be called +after calling remove.

+
§Example
+
use cookie::{CookieJar, Cookie};
+
+let mut jar = CookieJar::new();
+jar.add_original(Cookie::new("name", "value"));
+jar.add_original(Cookie::new("second", "two"));
+
+assert_eq!(jar.get("name").map(|c| c.value()), Some("value"));
+assert_eq!(jar.get("second").map(|c| c.value()), Some("two"));
+assert_eq!(jar.iter().count(), 2);
+assert_eq!(jar.delta().count(), 0);
+
source

pub fn add(&mut self, cookie: Cookie<'static>)

Adds cookie to this jar. If a cookie with the same name already +exists, it is replaced with cookie.

+
§Example
+
use cookie::{CookieJar, Cookie};
+
+let mut jar = CookieJar::new();
+jar.add(Cookie::new("name", "value"));
+jar.add(Cookie::new("second", "two"));
+
+assert_eq!(jar.get("name").map(|c| c.value()), Some("value"));
+assert_eq!(jar.get("second").map(|c| c.value()), Some("two"));
+assert_eq!(jar.iter().count(), 2);
+assert_eq!(jar.delta().count(), 2);
+
source

pub fn remove(&mut self, cookie: Cookie<'static>)

Removes cookie from this jar. If an original cookie with the same +name as cookie is present in the jar, a removal cookie will be +present in the delta computation. To properly generate the removal +cookie, cookie must contain the same path and domain as the cookie +that was initially set.

+

A “removal” cookie is a cookie that has the same name as the original +cookie but has an empty value, a max-age of 0, and an expiration date +far in the past. See also Cookie::make_removal().

+
§Example
+

Removing an original cookie results in a removal cookie:

+ +
use cookie::{CookieJar, Cookie};
+use cookie::time::Duration;
+
+let mut jar = CookieJar::new();
+
+// Assume this cookie originally had a path of "/" and domain of "a.b".
+jar.add_original(Cookie::new("name", "value"));
+
+// If the path and domain were set, they must be provided to `remove`.
+jar.remove(Cookie::build("name", "").path("/").domain("a.b").finish());
+
+// The delta will contain the removal cookie.
+let delta: Vec<_> = jar.delta().collect();
+assert_eq!(delta.len(), 1);
+assert_eq!(delta[0].name(), "name");
+assert_eq!(delta[0].max_age(), Some(Duration::seconds(0)));
+

Removing a new cookie does not result in a removal cookie unless +there’s an original cookie with the same name:

+ +
use cookie::{CookieJar, Cookie};
+
+let mut jar = CookieJar::new();
+jar.add(Cookie::new("name", "value"));
+assert_eq!(jar.delta().count(), 1);
+
+jar.remove(Cookie::named("name"));
+assert_eq!(jar.delta().count(), 0);
+
+jar.add_original(Cookie::new("name", "value"));
+jar.add(Cookie::new("name", "value"));
+assert_eq!(jar.delta().count(), 1);
+
+jar.remove(Cookie::named("name"));
+assert_eq!(jar.delta().count(), 1);
+
source

pub fn force_remove<'a>(&mut self, cookie: &Cookie<'a>)

Removes cookie from this jar completely. This method differs from +remove in that no delta cookie is created under any condition. Neither +the delta nor iter methods will return a cookie that is removed +using this method.

+
§Example
+

Removing an original cookie; no removal cookie is generated:

+ +
use cookie::{CookieJar, Cookie};
+use cookie::time::Duration;
+
+let mut jar = CookieJar::new();
+
+// Add an original cookie and a new cookie.
+jar.add_original(Cookie::new("name", "value"));
+jar.add(Cookie::new("key", "value"));
+assert_eq!(jar.delta().count(), 1);
+assert_eq!(jar.iter().count(), 2);
+
+// Now force remove the original cookie.
+jar.force_remove(&Cookie::named("name"));
+assert_eq!(jar.delta().count(), 1);
+assert_eq!(jar.iter().count(), 1);
+
+// Now force remove the new cookie.
+jar.force_remove(&Cookie::named("key"));
+assert_eq!(jar.delta().count(), 0);
+assert_eq!(jar.iter().count(), 0);
+
source

pub fn reset_delta(&mut self)

Removes all delta cookies, i.e. all cookies not added via +CookieJar::add_original(), from this CookieJar. This undoes any +changes from CookieJar::add() and CookieJar::remove() +operations.

+
§Example
+
use cookie::{CookieJar, Cookie};
+
+let mut jar = CookieJar::new();
+
+// Only original cookies will remain after calling `reset_delta`.
+jar.add_original(Cookie::new("name", "value"));
+jar.add_original(Cookie::new("language", "Rust"));
+
+// These operations, represented by delta cookies, will be reset.
+jar.add(Cookie::new("language", "C++"));
+jar.remove(Cookie::named("name"));
+
+// All is normal.
+assert_eq!(jar.get("name"), None);
+assert_eq!(jar.get("language").map(Cookie::value), Some("C++"));
+assert_eq!(jar.iter().count(), 1);
+assert_eq!(jar.delta().count(), 2);
+
+// Resetting undoes delta operations.
+jar.reset_delta();
+assert_eq!(jar.get("name").map(Cookie::value), Some("value"));
+assert_eq!(jar.get("language").map(Cookie::value), Some("Rust"));
+assert_eq!(jar.iter().count(), 2);
+assert_eq!(jar.delta().count(), 0);
+
source

pub fn delta(&self) -> Delta<'_>

Returns an iterator over cookies that represent the changes to this jar +over time. These cookies can be rendered directly as Set-Cookie header +values to affect the changes made to this jar on the client.

+
§Example
+
use cookie::{CookieJar, Cookie};
+
+let mut jar = CookieJar::new();
+jar.add_original(Cookie::new("name", "value"));
+jar.add_original(Cookie::new("second", "two"));
+
+// Add new cookies.
+jar.add(Cookie::new("new", "third"));
+jar.add(Cookie::new("another", "fourth"));
+jar.add(Cookie::new("yac", "fifth"));
+
+// Remove some cookies.
+jar.remove(Cookie::named("name"));
+jar.remove(Cookie::named("another"));
+
+// Delta contains two new cookies ("new", "yac") and a removal ("name").
+assert_eq!(jar.delta().count(), 3);
+
source

pub fn iter(&self) -> Iter<'_>

Returns an iterator over all of the cookies present in this jar.

+
§Example
+
use cookie::{CookieJar, Cookie};
+
+let mut jar = CookieJar::new();
+
+jar.add_original(Cookie::new("name", "value"));
+jar.add_original(Cookie::new("second", "two"));
+
+jar.add(Cookie::new("new", "third"));
+jar.add(Cookie::new("another", "fourth"));
+jar.add(Cookie::new("yac", "fifth"));
+
+jar.remove(Cookie::named("name"));
+jar.remove(Cookie::named("another"));
+
+// There are three cookies in the jar: "second", "new", and "yac".
+for cookie in jar.iter() {
+    match cookie.name() {
+        "second" => assert_eq!(cookie.value(), "two"),
+        "new" => assert_eq!(cookie.value(), "third"),
+        "yac" => assert_eq!(cookie.value(), "fifth"),
+        _ => unreachable!("there are only three cookies in the jar")
+    }
+}
+
source

pub fn private<'a>(&'a self, key: &Key) -> PrivateJar<&'a CookieJar>

Available on crate feature private only.

Returns a read-only PrivateJar with self as its parent jar using the +key key to verify/decrypt cookies retrieved from the child jar. Any +retrievals from the child jar will be made from the parent jar.

+
§Example
+
use cookie::{Cookie, CookieJar, Key};
+
+// Generate a secure key.
+let key = Key::generate();
+
+// Add a private (signed + encrypted) cookie.
+let mut jar = CookieJar::new();
+jar.private_mut(&key).add(Cookie::new("private", "text"));
+
+// The cookie's contents are encrypted.
+assert_ne!(jar.get("private").unwrap().value(), "text");
+
+// They can be decrypted and verified through the child jar.
+assert_eq!(jar.private(&key).get("private").unwrap().value(), "text");
+
+// A tampered with cookie does not validate but still exists.
+let mut cookie = jar.get("private").unwrap().clone();
+jar.add(Cookie::new("private", cookie.value().to_string() + "!"));
+assert!(jar.private(&key).get("private").is_none());
+assert!(jar.get("private").is_some());
+
source

pub fn private_mut<'a>(&'a mut self, key: &Key) -> PrivateJar<&'a mut CookieJar>

Available on crate feature private only.

Returns a read/write PrivateJar with self as its parent jar using +the key key to sign/encrypt and verify/decrypt cookies added/retrieved +from the child jar.

+

Any modifications to the child jar will be reflected on the parent jar, +and any retrievals from the child jar will be made from the parent jar.

+
§Example
+
use cookie::{Cookie, CookieJar, Key};
+
+// Generate a secure key.
+let key = Key::generate();
+
+// Add a private (signed + encrypted) cookie.
+let mut jar = CookieJar::new();
+jar.private_mut(&key).add(Cookie::new("private", "text"));
+
+// Remove a cookie using the child jar.
+jar.private_mut(&key).remove(Cookie::named("private"));
+
source

pub fn signed<'a>(&'a self, key: &Key) -> SignedJar<&'a CookieJar>

Available on crate feature signed only.

Returns a read-only SignedJar with self as its parent jar using the +key key to verify cookies retrieved from the child jar. Any retrievals +from the child jar will be made from the parent jar.

+
§Example
+
use cookie::{Cookie, CookieJar, Key};
+
+// Generate a secure key.
+let key = Key::generate();
+
+// Add a signed cookie.
+let mut jar = CookieJar::new();
+jar.signed_mut(&key).add(Cookie::new("signed", "text"));
+
+// The cookie's contents are signed but still in plaintext.
+assert_ne!(jar.get("signed").unwrap().value(), "text");
+assert!(jar.get("signed").unwrap().value().contains("text"));
+
+// They can be verified through the child jar.
+assert_eq!(jar.signed(&key).get("signed").unwrap().value(), "text");
+
+// A tampered with cookie does not validate but still exists.
+let mut cookie = jar.get("signed").unwrap().clone();
+jar.add(Cookie::new("signed", cookie.value().to_string() + "!"));
+assert!(jar.signed(&key).get("signed").is_none());
+assert!(jar.get("signed").is_some());
+
source

pub fn signed_mut<'a>(&'a mut self, key: &Key) -> SignedJar<&'a mut CookieJar>

Available on crate feature signed only.

Returns a read/write SignedJar with self as its parent jar using the +key key to sign/verify cookies added/retrieved from the child jar.

+

Any modifications to the child jar will be reflected on the parent jar, +and any retrievals from the child jar will be made from the parent jar.

+
§Example
+
use cookie::{Cookie, CookieJar, Key};
+
+// Generate a secure key.
+let key = Key::generate();
+
+// Add a signed cookie.
+let mut jar = CookieJar::new();
+jar.signed_mut(&key).add(Cookie::new("signed", "text"));
+
+// Remove a cookie.
+jar.signed_mut(&key).remove(Cookie::named("signed"));
+

Trait Implementations§

source§

impl Clone for CookieJar

source§

fn clone(&self) -> CookieJar

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for CookieJar

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for CookieJar

source§

fn default() -> CookieJar

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/struct.Delta.html b/actix_web/cookie/struct.Delta.html new file mode 100644 index 000000000..b74eb1914 --- /dev/null +++ b/actix_web/cookie/struct.Delta.html @@ -0,0 +1,202 @@ +Delta in actix_web::cookie - Rust

Struct actix_web::cookie::Delta

source ·
pub struct Delta<'a> { /* private fields */ }
Available on crate feature cookies only.
Expand description

Iterator over the changes to a cookie jar.

+

Trait Implementations§

source§

impl<'a> Iterator for Delta<'a>

§

type Item = &'a Cookie<'static>

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<&'a Cookie<'static>>

Advances the iterator and returns the next value. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
1.0.0 · source§

fn count(self) -> usize
where + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>
where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for Delta<'a>

§

impl<'a> RefUnwindSafe for Delta<'a>

§

impl<'a> Send for Delta<'a>

§

impl<'a> Sync for Delta<'a>

§

impl<'a> Unpin for Delta<'a>

§

impl<'a> UnwindSafe for Delta<'a>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for I
where + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<I> IteratorRandom for I
where + I: Iterator,

source§

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where + R: Rng + ?Sized,

Collects values at random from the iterator into a supplied buffer +until that buffer is filled. Read more
source§

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where + R: Rng + ?Sized,

Available on crate feature alloc only.
Collects amount values at random from the iterator into a vector. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/struct.Display.html b/actix_web/cookie/struct.Display.html new file mode 100644 index 000000000..34604c305 --- /dev/null +++ b/actix_web/cookie/struct.Display.html @@ -0,0 +1,37 @@ +Display in actix_web::cookie - Rust

Struct actix_web::cookie::Display

source ·
pub struct Display<'a, 'c>
where + 'c: 'a,
{ /* private fields */ }
Available on crate feature cookies only.
Expand description

Wrapper around Cookie whose Display implementation either +percent-encodes the cookie’s name and value, skips displaying the cookie’s +parameters (only displaying it’s name and value), or both.

+

A value of this type can be obtained via Cookie::encoded() and +Cookie::stripped(), or an arbitrary chaining of the two methods. This +type should only be used for its Display implementation.

+

§Example

+
use cookie::Cookie;
+
+let c = Cookie::build("my name", "this; value%?").secure(true).finish();
+assert_eq!(&c.stripped().to_string(), "my name=this; value%?");
+// Note: `encoded()` is only available when `percent-encode` is enabled.
+assert_eq!(&c.encoded().to_string(), "my%20name=this%3B%20value%25%3F; Secure");
+assert_eq!(&c.stripped().encoded().to_string(), "my%20name=this%3B%20value%25%3F");
+assert_eq!(&c.encoded().stripped().to_string(), "my%20name=this%3B%20value%25%3F");
+

Implementations§

source§

impl<'a, 'c> Display<'a, 'c>

source

pub fn encoded(self) -> Display<'a, 'c>

Available on crate feature percent-encode only.

Percent-encode the name and value pair.

+
source

pub fn stripped(self) -> Display<'a, 'c>

Only display the name and value.

+

Trait Implementations§

source§

impl<'a, 'c> Display for Display<'a, 'c>
where + 'c: 'a,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a, 'c> Freeze for Display<'a, 'c>

§

impl<'a, 'c> RefUnwindSafe for Display<'a, 'c>

§

impl<'a, 'c> Send for Display<'a, 'c>

§

impl<'a, 'c> Sync for Display<'a, 'c>

§

impl<'a, 'c> Unpin for Display<'a, 'c>

§

impl<'a, 'c> UnwindSafe for Display<'a, 'c>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/struct.Iter.html b/actix_web/cookie/struct.Iter.html new file mode 100644 index 000000000..76793a954 --- /dev/null +++ b/actix_web/cookie/struct.Iter.html @@ -0,0 +1,202 @@ +Iter in actix_web::cookie - Rust

Struct actix_web::cookie::Iter

source ·
pub struct Iter<'a> { /* private fields */ }
Available on crate feature cookies only.
Expand description

Iterator over all of the cookies in a jar.

+

Trait Implementations§

source§

impl<'a> Iterator for Iter<'a>

§

type Item = &'a Cookie<'static>

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<&'a Cookie<'static>>

Advances the iterator and returns the next value. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
1.0.0 · source§

fn count(self) -> usize
where + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>
where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for Iter<'a>

§

impl<'a> RefUnwindSafe for Iter<'a>

§

impl<'a> Send for Iter<'a>

§

impl<'a> Sync for Iter<'a>

§

impl<'a> Unpin for Iter<'a>

§

impl<'a> UnwindSafe for Iter<'a>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for I
where + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<I> IteratorRandom for I
where + I: Iterator,

source§

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where + R: Rng + ?Sized,

Collects values at random from the iterator into a supplied buffer +until that buffer is filled. Read more
source§

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where + R: Rng + ?Sized,

Available on crate feature alloc only.
Collects amount values at random from the iterator into a vector. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/struct.Key.html b/actix_web/cookie/struct.Key.html new file mode 100644 index 000000000..2b2280510 --- /dev/null +++ b/actix_web/cookie/struct.Key.html @@ -0,0 +1,99 @@ +Key in actix_web::cookie - Rust

Struct actix_web::cookie::Key

source ·
pub struct Key(/* private fields */);
Available on crate feature cookies only.
Expand description

A cryptographic master key for use with Signed and/or Private jars.

+

This structure encapsulates secure, cryptographic keys for use with both +PrivateJar and SignedJar. A +single instance of a Key can be used for both a PrivateJar and a +SignedJar simultaneously with no notable security implications.

+

Implementations§

source§

impl Key

source

pub fn from(key: &[u8]) -> Key

Creates a new Key from a 512-bit cryptographically random string.

+

The supplied key must be at least 512-bits (64 bytes). For security, the +master key must be cryptographically random.

+
§Panics
+

Panics if key is less than 64 bytes in length.

+

For a non-panicking version, use Key::try_from() or generate a key with +Key::generate() or Key::try_generate().

+
§Example
+
use cookie::Key;
+
+let key = { /* a cryptographically random key >= 64 bytes */ };
+
+let key = Key::from(key);
+
source

pub fn derive_from(master_key: &[u8]) -> Key

Available on crate feature key-expansion only.

Derives new signing/encryption keys from a master key.

+

The master key must be at least 256-bits (32 bytes). For security, the +master key must be cryptographically random. The keys are derived +deterministically from the master key.

+
§Panics
+

Panics if key is less than 32 bytes in length.

+
§Example
+
use cookie::Key;
+
+let master_key = { /* a cryptographically random key >= 32 bytes */ };
+
+let key = Key::derive_from(master_key);
+
source

pub fn generate() -> Key

Generates signing/encryption keys from a secure, random source. Keys are +generated nondeterministically.

+
§Panics
+

Panics if randomness cannot be retrieved from the operating system. See +Key::try_generate() for a non-panicking version.

+
§Example
+
use cookie::Key;
+
+let key = Key::generate();
+
source

pub fn try_generate() -> Option<Key>

Attempts to generate signing/encryption keys from a secure, random +source. Keys are generated nondeterministically. If randomness cannot be +retrieved from the underlying operating system, returns None.

+
§Example
+
use cookie::Key;
+
+let key = Key::try_generate();
+
source

pub fn signing(&self) -> &[u8]

Returns the raw bytes of a key suitable for signing cookies. Guaranteed +to be at least 32 bytes.

+
§Example
+
use cookie::Key;
+
+let key = Key::generate();
+let signing_key = key.signing();
+
source

pub fn encryption(&self) -> &[u8]

Returns the raw bytes of a key suitable for encrypting cookies. +Guaranteed to be at least 32 bytes.

+
§Example
+
use cookie::Key;
+
+let key = Key::generate();
+let encryption_key = key.encryption();
+
source

pub fn master(&self) -> &[u8]

Returns the raw bytes of the master key. Guaranteed to be at least 64 +bytes.

+
§Example
+
use cookie::Key;
+
+let key = Key::generate();
+let master_key = key.master();
+

Trait Implementations§

source§

impl Clone for Key

source§

fn clone(&self) -> Key

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl PartialEq for Key

source§

fn eq(&self, other: &Key) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryFrom<&[u8]> for Key

source§

fn try_from(key: &[u8]) -> Result<Key, <Key as TryFrom<&[u8]>>::Error>

A fallible version of Key::from().

+

Succeeds when Key::from() succeds and returns an error where +Key::from() panics, namely, if key is too short.

+
§Example
+
use cookie::Key;
+
+let key = { /* a cryptographically random key >= 64 bytes */ };
+assert!(Key::try_from(key).is_ok());
+
+// A key that's far too short to use.
+let key = &[1, 2, 3, 4][..];
+assert!(Key::try_from(key).is_err());
+
§

type Error = KeyError

The type returned in the event of a conversion error.

Auto Trait Implementations§

§

impl Freeze for Key

§

impl RefUnwindSafe for Key

§

impl Send for Key

§

impl Sync for Key

§

impl Unpin for Key

§

impl UnwindSafe for Key

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/struct.PrivateJar.html b/actix_web/cookie/struct.PrivateJar.html new file mode 100644 index 000000000..dd4ad6893 --- /dev/null +++ b/actix_web/cookie/struct.PrivateJar.html @@ -0,0 +1,113 @@ +PrivateJar in actix_web::cookie - Rust

Struct actix_web::cookie::PrivateJar

source ·
pub struct PrivateJar<J> { /* private fields */ }
Available on crate feature cookies only.
Expand description

A child cookie jar that provides authenticated encryption for its cookies.

+

A private child jar signs and encrypts all the cookies added to it and +verifies and decrypts cookies retrieved from it. Any cookies stored in a +PrivateJar are simultaneously assured confidentiality, integrity, and +authenticity. In other words, clients cannot discover nor tamper with the +contents of a cookie, nor can they fabricate cookie data.

+

Implementations§

source§

impl<J> PrivateJar<J>

source

pub fn decrypt(&self, cookie: Cookie<'static>) -> Option<Cookie<'static>>

Authenticates and decrypts cookie, returning the plaintext version if +decryption succeeds or None otherwise. Authenticatation and decryption +always succeeds if cookie was generated by a PrivateJar with the +same key as self.

+
§Example
+
use cookie::{CookieJar, Cookie, Key};
+
+let key = Key::generate();
+let mut jar = CookieJar::new();
+assert!(jar.private(&key).get("name").is_none());
+
+jar.private_mut(&key).add(Cookie::new("name", "value"));
+assert_eq!(jar.private(&key).get("name").unwrap().value(), "value");
+
+let plain = jar.get("name").cloned().unwrap();
+assert_ne!(plain.value(), "value");
+let decrypted = jar.private(&key).decrypt(plain).unwrap();
+assert_eq!(decrypted.value(), "value");
+
+let plain = Cookie::new("plaintext", "hello");
+assert!(jar.private(&key).decrypt(plain).is_none());
+
source§

impl<J> PrivateJar<J>
where + J: Borrow<CookieJar>,

source

pub fn get(&self, name: &str) -> Option<Cookie<'static>>

Returns a reference to the Cookie inside this jar with the name name +and authenticates and decrypts the cookie’s value, returning a Cookie +with the decrypted value. If the cookie cannot be found, or the cookie +fails to authenticate or decrypt, None is returned.

+
§Example
+
use cookie::{CookieJar, Cookie, Key};
+
+let key = Key::generate();
+let jar = CookieJar::new();
+assert!(jar.private(&key).get("name").is_none());
+
+let mut jar = jar;
+let mut private_jar = jar.private_mut(&key);
+private_jar.add(Cookie::new("name", "value"));
+assert_eq!(private_jar.get("name").unwrap().value(), "value");
+
source§

impl<J> PrivateJar<J>
where + J: BorrowMut<CookieJar>,

source

pub fn add(&mut self, cookie: Cookie<'static>)

Adds cookie to the parent jar. The cookie’s value is encrypted with +authenticated encryption assuring confidentiality, integrity, and +authenticity.

+
§Example
+
use cookie::{CookieJar, Cookie, Key};
+
+let key = Key::generate();
+let mut jar = CookieJar::new();
+jar.private_mut(&key).add(Cookie::new("name", "value"));
+
+assert_ne!(jar.get("name").unwrap().value(), "value");
+assert_eq!(jar.private(&key).get("name").unwrap().value(), "value");
+
source

pub fn add_original(&mut self, cookie: Cookie<'static>)

Adds an “original” cookie to parent jar. The cookie’s value is +encrypted with authenticated encryption assuring confidentiality, +integrity, and authenticity. Adding an original cookie does not affect +the CookieJar::delta() computation. This method is intended to be +used to seed the cookie jar with cookies received from a client’s HTTP +message.

+

For accurate delta computations, this method should not be called +after calling remove.

+
§Example
+
use cookie::{CookieJar, Cookie, Key};
+
+let key = Key::generate();
+let mut jar = CookieJar::new();
+jar.private_mut(&key).add_original(Cookie::new("name", "value"));
+
+assert_eq!(jar.iter().count(), 1);
+assert_eq!(jar.delta().count(), 0);
+
source

pub fn remove(&mut self, cookie: Cookie<'static>)

Removes cookie from the parent jar.

+

For correct removal, the passed in cookie must contain the same path +and domain as the cookie that was initially set.

+

This is identical to CookieJar::remove(). See the method’s +documentation for more details.

+
§Example
+
use cookie::{CookieJar, Cookie, Key};
+
+let key = Key::generate();
+let mut jar = CookieJar::new();
+let mut private_jar = jar.private_mut(&key);
+
+private_jar.add(Cookie::new("name", "value"));
+assert!(private_jar.get("name").is_some());
+
+private_jar.remove(Cookie::named("name"));
+assert!(private_jar.get("name").is_none());
+

Auto Trait Implementations§

§

impl<J> Freeze for PrivateJar<J>
where + J: Freeze,

§

impl<J> RefUnwindSafe for PrivateJar<J>
where + J: RefUnwindSafe,

§

impl<J> Send for PrivateJar<J>
where + J: Send,

§

impl<J> Sync for PrivateJar<J>
where + J: Sync,

§

impl<J> Unpin for PrivateJar<J>
where + J: Unpin,

§

impl<J> UnwindSafe for PrivateJar<J>
where + J: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/struct.SignedJar.html b/actix_web/cookie/struct.SignedJar.html new file mode 100644 index 000000000..00b592b46 --- /dev/null +++ b/actix_web/cookie/struct.SignedJar.html @@ -0,0 +1,112 @@ +SignedJar in actix_web::cookie - Rust

Struct actix_web::cookie::SignedJar

source ·
pub struct SignedJar<J> { /* private fields */ }
Available on crate feature cookies only.
Expand description

A child cookie jar that authenticates its cookies.

+

A signed child jar signs all the cookies added to it and verifies cookies +retrieved from it. Any cookies stored in a SignedJar are provided +integrity and authenticity. In other words, clients cannot tamper with the +contents of a cookie nor can they fabricate cookie values, but the data is +visible in plaintext.

+

Implementations§

source§

impl<J> SignedJar<J>

source

pub fn verify(&self, cookie: Cookie<'static>) -> Option<Cookie<'static>>

Verifies the authenticity and integrity of cookie, returning the +plaintext version if verification succeeds or None otherwise. +Verification always succeeds if cookie was generated by a +SignedJar with the same key as self.

+
§Example
+
use cookie::{CookieJar, Cookie, Key};
+
+let key = Key::generate();
+let mut jar = CookieJar::new();
+assert!(jar.signed(&key).get("name").is_none());
+
+jar.signed_mut(&key).add(Cookie::new("name", "value"));
+assert_eq!(jar.signed(&key).get("name").unwrap().value(), "value");
+
+let plain = jar.get("name").cloned().unwrap();
+assert_ne!(plain.value(), "value");
+let verified = jar.signed(&key).verify(plain).unwrap();
+assert_eq!(verified.value(), "value");
+
+let plain = Cookie::new("plaintext", "hello");
+assert!(jar.signed(&key).verify(plain).is_none());
+
source§

impl<J> SignedJar<J>
where + J: Borrow<CookieJar>,

source

pub fn get(&self, name: &str) -> Option<Cookie<'static>>

Returns a reference to the Cookie inside this jar with the name name +and verifies the authenticity and integrity of the cookie’s value, +returning a Cookie with the authenticated value. If the cookie cannot +be found, or the cookie fails to verify, None is returned.

+
§Example
+
use cookie::{CookieJar, Cookie, Key};
+
+let key = Key::generate();
+let jar = CookieJar::new();
+assert!(jar.signed(&key).get("name").is_none());
+
+let mut jar = jar;
+let mut signed_jar = jar.signed_mut(&key);
+signed_jar.add(Cookie::new("name", "value"));
+assert_eq!(signed_jar.get("name").unwrap().value(), "value");
+
source§

impl<J> SignedJar<J>
where + J: BorrowMut<CookieJar>,

source

pub fn add(&mut self, cookie: Cookie<'static>)

Adds cookie to the parent jar. The cookie’s value is signed assuring +integrity and authenticity.

+
§Example
+
use cookie::{CookieJar, Cookie, Key};
+
+let key = Key::generate();
+let mut jar = CookieJar::new();
+jar.signed_mut(&key).add(Cookie::new("name", "value"));
+
+assert_ne!(jar.get("name").unwrap().value(), "value");
+assert!(jar.get("name").unwrap().value().contains("value"));
+assert_eq!(jar.signed(&key).get("name").unwrap().value(), "value");
+
source

pub fn add_original(&mut self, cookie: Cookie<'static>)

Adds an “original” cookie to this jar. The cookie’s value is signed +assuring integrity and authenticity. Adding an original cookie does not +affect the CookieJar::delta() computation. This method is intended +to be used to seed the cookie jar with cookies received from a client’s +HTTP message.

+

For accurate delta computations, this method should not be called +after calling remove.

+
§Example
+
use cookie::{CookieJar, Cookie, Key};
+
+let key = Key::generate();
+let mut jar = CookieJar::new();
+jar.signed_mut(&key).add_original(Cookie::new("name", "value"));
+
+assert_eq!(jar.iter().count(), 1);
+assert_eq!(jar.delta().count(), 0);
+
source

pub fn remove(&mut self, cookie: Cookie<'static>)

Removes cookie from the parent jar.

+

For correct removal, the passed in cookie must contain the same path +and domain as the cookie that was initially set.

+

This is identical to CookieJar::remove(). See the method’s +documentation for more details.

+
§Example
+
use cookie::{CookieJar, Cookie, Key};
+
+let key = Key::generate();
+let mut jar = CookieJar::new();
+let mut signed_jar = jar.signed_mut(&key);
+
+signed_jar.add(Cookie::new("name", "value"));
+assert!(signed_jar.get("name").is_some());
+
+signed_jar.remove(Cookie::named("name"));
+assert!(signed_jar.get("name").is_none());
+

Auto Trait Implementations§

§

impl<J> Freeze for SignedJar<J>
where + J: Freeze,

§

impl<J> RefUnwindSafe for SignedJar<J>
where + J: RefUnwindSafe,

§

impl<J> Send for SignedJar<J>
where + J: Send,

§

impl<J> Sync for SignedJar<J>
where + J: Sync,

§

impl<J> Unpin for SignedJar<J>
where + J: Unpin,

§

impl<J> UnwindSafe for SignedJar<J>
where + J: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/convert/index.html b/actix_web/cookie/time/convert/index.html new file mode 100644 index 000000000..330e59d45 --- /dev/null +++ b/actix_web/cookie/time/convert/index.html @@ -0,0 +1,2 @@ +actix_web::cookie::time::convert - Rust

Module actix_web::cookie::time::convert

Available on crate feature cookies only.
Expand description

Conversion between units of time.

+

Structs§

  • A unit of time representing exactly one day.
  • A unit of time representing exactly one hour.
  • A unit of time representing exactly one microsecond.
  • A unit of time representing exactly one millisecond.
  • A unit of time representing exactly one minute.
  • A unit of time representing exactly one nanosecond.
  • A unit of time representing exactly one second.
  • A unit of time representing exactly one week.
\ No newline at end of file diff --git a/actix_web/cookie/time/convert/sidebar-items.js b/actix_web/cookie/time/convert/sidebar-items.js new file mode 100644 index 000000000..0dd5de096 --- /dev/null +++ b/actix_web/cookie/time/convert/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Day","Hour","Microsecond","Millisecond","Minute","Nanosecond","Second","Week"]}; \ No newline at end of file diff --git a/actix_web/cookie/time/convert/struct.Day.html b/actix_web/cookie/time/convert/struct.Day.html new file mode 100644 index 000000000..5fb8ae7eb --- /dev/null +++ b/actix_web/cookie/time/convert/struct.Day.html @@ -0,0 +1,30 @@ +Day in actix_web::cookie::time::convert - Rust

Struct actix_web::cookie::time::convert::Day

pub struct Day;
Available on crate feature cookies only.
Expand description

A unit of time representing exactly one day.

+

Implementations§

§

impl Day

pub const fn per<T>(_larger: T) -> <Day as Per<T>>::Output
where + Day: Per<T>, + T: Copy,

Obtain the number of times Day can fit into T. +If T is smaller than Day, the code will fail to +compile. The return type is the smallest unsigned integer type that can represent +the value.

+

Valid calls:

+
    +
  • Day::per(Day) (returns u8)
  • +
  • Day::per(Week) (returns u8)
  • +
+

Trait Implementations§

§

impl Clone for Day

§

fn clone(&self) -> Day

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Day

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Copy for Day

Auto Trait Implementations§

§

impl Freeze for Day

§

impl RefUnwindSafe for Day

§

impl Send for Day

§

impl Sync for Day

§

impl Unpin for Day

§

impl UnwindSafe for Day

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/convert/struct.Hour.html b/actix_web/cookie/time/convert/struct.Hour.html new file mode 100644 index 000000000..83b0791a5 --- /dev/null +++ b/actix_web/cookie/time/convert/struct.Hour.html @@ -0,0 +1,31 @@ +Hour in actix_web::cookie::time::convert - Rust

Struct actix_web::cookie::time::convert::Hour

pub struct Hour;
Available on crate feature cookies only.
Expand description

A unit of time representing exactly one hour.

+

Implementations§

§

impl Hour

pub const fn per<T>(_larger: T) -> <Hour as Per<T>>::Output
where + Hour: Per<T>, + T: Copy,

Obtain the number of times Hour can fit into T. +If T is smaller than Hour, the code will fail to +compile. The return type is the smallest unsigned integer type that can represent +the value.

+

Valid calls:

+
    +
  • Hour::per(Hour) (returns u8)
  • +
  • Hour::per(Day) (returns u8)
  • +
  • Hour::per(Week) (returns u8)
  • +
+

Trait Implementations§

§

impl Clone for Hour

§

fn clone(&self) -> Hour

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Hour

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Copy for Hour

Auto Trait Implementations§

§

impl Freeze for Hour

§

impl RefUnwindSafe for Hour

§

impl Send for Hour

§

impl Sync for Hour

§

impl Unpin for Hour

§

impl UnwindSafe for Hour

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/convert/struct.Microsecond.html b/actix_web/cookie/time/convert/struct.Microsecond.html new file mode 100644 index 000000000..fb977ccb9 --- /dev/null +++ b/actix_web/cookie/time/convert/struct.Microsecond.html @@ -0,0 +1,35 @@ +Microsecond in actix_web::cookie::time::convert - Rust

Struct actix_web::cookie::time::convert::Microsecond

pub struct Microsecond;
Available on crate feature cookies only.
Expand description

A unit of time representing exactly one microsecond.

+

Implementations§

§

impl Microsecond

pub const fn per<T>(_larger: T) -> <Microsecond as Per<T>>::Output
where + Microsecond: Per<T>, + T: Copy,

Obtain the number of times Microsecond can fit into T. +If T is smaller than Microsecond, the code will fail to +compile. The return type is the smallest unsigned integer type that can represent +the value.

+

Valid calls:

+
    +
  • Microsecond::per(Microsecond) (returns u8)
  • +
  • Microsecond::per(Millisecond) (returns u16)
  • +
  • Microsecond::per(Second) (returns u32)
  • +
  • Microsecond::per(Minute) (returns u32)
  • +
  • Microsecond::per(Hour) (returns u32)
  • +
  • Microsecond::per(Day) (returns u64)
  • +
  • Microsecond::per(Week) (returns u64)
  • +
+

Trait Implementations§

§

impl Clone for Microsecond

§

fn clone(&self) -> Microsecond

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Microsecond

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Copy for Microsecond

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/convert/struct.Millisecond.html b/actix_web/cookie/time/convert/struct.Millisecond.html new file mode 100644 index 000000000..0b765f208 --- /dev/null +++ b/actix_web/cookie/time/convert/struct.Millisecond.html @@ -0,0 +1,34 @@ +Millisecond in actix_web::cookie::time::convert - Rust

Struct actix_web::cookie::time::convert::Millisecond

pub struct Millisecond;
Available on crate feature cookies only.
Expand description

A unit of time representing exactly one millisecond.

+

Implementations§

§

impl Millisecond

pub const fn per<T>(_larger: T) -> <Millisecond as Per<T>>::Output
where + Millisecond: Per<T>, + T: Copy,

Obtain the number of times Millisecond can fit into T. +If T is smaller than Millisecond, the code will fail to +compile. The return type is the smallest unsigned integer type that can represent +the value.

+

Valid calls:

+
    +
  • Millisecond::per(Millisecond) (returns u8)
  • +
  • Millisecond::per(Second) (returns u16)
  • +
  • Millisecond::per(Minute) (returns u16)
  • +
  • Millisecond::per(Hour) (returns u32)
  • +
  • Millisecond::per(Day) (returns u32)
  • +
  • Millisecond::per(Week) (returns u32)
  • +
+

Trait Implementations§

§

impl Clone for Millisecond

§

fn clone(&self) -> Millisecond

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Millisecond

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Copy for Millisecond

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/convert/struct.Minute.html b/actix_web/cookie/time/convert/struct.Minute.html new file mode 100644 index 000000000..879cb2536 --- /dev/null +++ b/actix_web/cookie/time/convert/struct.Minute.html @@ -0,0 +1,32 @@ +Minute in actix_web::cookie::time::convert - Rust

Struct actix_web::cookie::time::convert::Minute

pub struct Minute;
Available on crate feature cookies only.
Expand description

A unit of time representing exactly one minute.

+

Implementations§

§

impl Minute

pub const fn per<T>(_larger: T) -> <Minute as Per<T>>::Output
where + Minute: Per<T>, + T: Copy,

Obtain the number of times Minute can fit into T. +If T is smaller than Minute, the code will fail to +compile. The return type is the smallest unsigned integer type that can represent +the value.

+

Valid calls:

+
    +
  • Minute::per(Minute) (returns u8)
  • +
  • Minute::per(Hour) (returns u8)
  • +
  • Minute::per(Day) (returns u16)
  • +
  • Minute::per(Week) (returns u16)
  • +
+

Trait Implementations§

§

impl Clone for Minute

§

fn clone(&self) -> Minute

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Minute

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Copy for Minute

Auto Trait Implementations§

§

impl Freeze for Minute

§

impl RefUnwindSafe for Minute

§

impl Send for Minute

§

impl Sync for Minute

§

impl Unpin for Minute

§

impl UnwindSafe for Minute

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/convert/struct.Nanosecond.html b/actix_web/cookie/time/convert/struct.Nanosecond.html new file mode 100644 index 000000000..03cccfed3 --- /dev/null +++ b/actix_web/cookie/time/convert/struct.Nanosecond.html @@ -0,0 +1,36 @@ +Nanosecond in actix_web::cookie::time::convert - Rust

Struct actix_web::cookie::time::convert::Nanosecond

pub struct Nanosecond;
Available on crate feature cookies only.
Expand description

A unit of time representing exactly one nanosecond.

+

Implementations§

§

impl Nanosecond

pub const fn per<T>(_larger: T) -> <Nanosecond as Per<T>>::Output
where + Nanosecond: Per<T>, + T: Copy,

Obtain the number of times Nanosecond can fit into T. +If T is smaller than Nanosecond, the code will fail to +compile. The return type is the smallest unsigned integer type that can represent +the value.

+

Valid calls:

+
    +
  • Nanosecond::per(Nanosecond) (returns u8)
  • +
  • Nanosecond::per(Microsecond) (returns u16)
  • +
  • Nanosecond::per(Millisecond) (returns u32)
  • +
  • Nanosecond::per(Second) (returns u32)
  • +
  • Nanosecond::per(Minute) (returns u64)
  • +
  • Nanosecond::per(Hour) (returns u64)
  • +
  • Nanosecond::per(Day) (returns u64)
  • +
  • Nanosecond::per(Week) (returns u64)
  • +
+

Trait Implementations§

§

impl Clone for Nanosecond

§

fn clone(&self) -> Nanosecond

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Nanosecond

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Copy for Nanosecond

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/convert/struct.Second.html b/actix_web/cookie/time/convert/struct.Second.html new file mode 100644 index 000000000..ba546df92 --- /dev/null +++ b/actix_web/cookie/time/convert/struct.Second.html @@ -0,0 +1,33 @@ +Second in actix_web::cookie::time::convert - Rust

Struct actix_web::cookie::time::convert::Second

pub struct Second;
Available on crate feature cookies only.
Expand description

A unit of time representing exactly one second.

+

Implementations§

§

impl Second

pub const fn per<T>(_larger: T) -> <Second as Per<T>>::Output
where + Second: Per<T>, + T: Copy,

Obtain the number of times Second can fit into T. +If T is smaller than Second, the code will fail to +compile. The return type is the smallest unsigned integer type that can represent +the value.

+

Valid calls:

+
    +
  • Second::per(Second) (returns u8)
  • +
  • Second::per(Minute) (returns u8)
  • +
  • Second::per(Hour) (returns u16)
  • +
  • Second::per(Day) (returns u32)
  • +
  • Second::per(Week) (returns u32)
  • +
+

Trait Implementations§

§

impl Clone for Second

§

fn clone(&self) -> Second

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Second

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Copy for Second

Auto Trait Implementations§

§

impl Freeze for Second

§

impl RefUnwindSafe for Second

§

impl Send for Second

§

impl Sync for Second

§

impl Unpin for Second

§

impl UnwindSafe for Second

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/convert/struct.Week.html b/actix_web/cookie/time/convert/struct.Week.html new file mode 100644 index 000000000..fd1dbead2 --- /dev/null +++ b/actix_web/cookie/time/convert/struct.Week.html @@ -0,0 +1,29 @@ +Week in actix_web::cookie::time::convert - Rust

Struct actix_web::cookie::time::convert::Week

pub struct Week;
Available on crate feature cookies only.
Expand description

A unit of time representing exactly one week.

+

Implementations§

§

impl Week

pub const fn per<T>(_larger: T) -> <Week as Per<T>>::Output
where + Week: Per<T>, + T: Copy,

Obtain the number of times Week can fit into T. +If T is smaller than Week, the code will fail to +compile. The return type is the smallest unsigned integer type that can represent +the value.

+

Valid calls:

+
    +
  • Week::per(Week) (returns u8)
  • +
+

Trait Implementations§

§

impl Clone for Week

§

fn clone(&self) -> Week

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Week

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Copy for Week

Auto Trait Implementations§

§

impl Freeze for Week

§

impl RefUnwindSafe for Week

§

impl Send for Week

§

impl Sync for Week

§

impl Unpin for Week

§

impl UnwindSafe for Week

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/enum.Error.html b/actix_web/cookie/time/enum.Error.html new file mode 100644 index 000000000..123695208 --- /dev/null +++ b/actix_web/cookie/time/enum.Error.html @@ -0,0 +1,45 @@ +Error in actix_web::cookie::time - Rust

Enum actix_web::cookie::time::Error

#[non_exhaustive]
pub enum Error { + ConversionRange(ConversionRange), + ComponentRange(ComponentRange), + Format(Format), + ParseFromDescription(ParseFromDescription), + UnexpectedTrailingCharacters, + TryFromParsed(TryFromParsed), + InvalidFormatDescription(InvalidFormatDescription), + DifferentVariant(DifferentVariant), + InvalidVariant(InvalidVariant), +}
Available on crate feature cookies only.
Expand description

A unified error type for anything returned by a method in the time crate.

+

This can be used when you either don’t know or don’t care about the exact error returned. +Result<_, time::Error> (or its alias time::Result<_>) will work in these situations.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

ConversionRange(ConversionRange)

§

ComponentRange(ComponentRange)

§

Format(Format)

Available on crate feature formatting only.
§

ParseFromDescription(ParseFromDescription)

Available on crate feature parsing only.
§

UnexpectedTrailingCharacters

👎Deprecated since 0.3.28: no longer output. moved to the ParseFromDescription variant
Available on crate feature parsing only.
§

TryFromParsed(TryFromParsed)

Available on crate feature parsing only.
§

InvalidFormatDescription(InvalidFormatDescription)

Available on (crate features formatting or parsing) and crate feature alloc only.
§

DifferentVariant(DifferentVariant)

§

InvalidVariant(InvalidVariant)

Trait Implementations§

§

impl Debug for Error

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for Error

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for Error

Available on crate feature std only.
§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<ComponentRange> for Error

§

fn from(original: ComponentRange) -> Error

Converts to this type from the input type.
§

impl From<ConversionRange> for Error

§

fn from(err: ConversionRange) -> Error

Converts to this type from the input type.
§

impl From<DifferentVariant> for Error

§

fn from(err: DifferentVariant) -> Error

Converts to this type from the input type.
§

impl From<Format> for Error

§

fn from(original: Format) -> Error

Converts to this type from the input type.
§

impl From<InvalidFormatDescription> for Error

§

fn from(original: InvalidFormatDescription) -> Error

Converts to this type from the input type.
§

impl From<InvalidVariant> for Error

§

fn from(err: InvalidVariant) -> Error

Converts to this type from the input type.
§

impl From<Parse> for Error

§

fn from(err: Parse) -> Error

Converts to this type from the input type.
§

impl From<ParseFromDescription> for Error

§

fn from(original: ParseFromDescription) -> Error

Converts to this type from the input type.
§

impl From<TryFromParsed> for Error

§

fn from(original: TryFromParsed) -> Error

Converts to this type from the input type.
§

impl TryFrom<Error> for ComponentRange

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<ComponentRange, <ComponentRange as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Error> for ConversionRange

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<ConversionRange, <ConversionRange as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Error> for DifferentVariant

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<DifferentVariant, <DifferentVariant as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Error> for Format

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from(err: Error) -> Result<Format, <Format as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Error> for InvalidFormatDescription

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<InvalidFormatDescription, <InvalidFormatDescription as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Error> for InvalidVariant

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<InvalidVariant, <InvalidVariant as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Error> for Parse

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from(err: Error) -> Result<Parse, <Parse as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Error> for ParseFromDescription

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<ParseFromDescription, <ParseFromDescription as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Error> for TryFromParsed

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<TryFromParsed, <TryFromParsed as TryFrom<Error>>::Error>

Performs the conversion.

Auto Trait Implementations§

§

impl Freeze for Error

§

impl !RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl !UnwindSafe for Error

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/enum.Month.html b/actix_web/cookie/time/enum.Month.html new file mode 100644 index 000000000..33b5d5f19 --- /dev/null +++ b/actix_web/cookie/time/enum.Month.html @@ -0,0 +1,63 @@ +Month in actix_web::cookie::time - Rust

Enum actix_web::cookie::time::Month

#[repr(u8)]
pub enum Month { + January = 1, + February = 2, + March = 3, + April = 4, + May = 5, + June = 6, + July = 7, + August = 8, + September = 9, + October = 10, + November = 11, + December = 12, +}
Available on crate feature cookies only.
Expand description

Months of the year.

+

Variants§

§

January = 1

§

February = 2

§

March = 3

§

April = 4

§

May = 5

§

June = 6

§

July = 7

§

August = 8

§

September = 9

§

October = 10

§

November = 11

§

December = 12

Implementations§

§

impl Month

pub const fn previous(self) -> Month

Get the previous month.

+ +
assert_eq!(Month::January.previous(), Month::December);
+

pub const fn next(self) -> Month

Get the next month.

+ +
assert_eq!(Month::January.next(), Month::February);
+

pub const fn nth_next(self, n: u8) -> Month

Get n-th next month.

+ +
assert_eq!(Month::January.nth_next(4), Month::May);
+assert_eq!(Month::July.nth_next(9), Month::April);
+

pub const fn nth_prev(self, n: u8) -> Month

Get n-th previous month.

+ +
assert_eq!(Month::January.nth_prev(4), Month::September);
+assert_eq!(Month::July.nth_prev(9), Month::October);
+

Trait Implementations§

§

impl Clone for Month

§

fn clone(&self) -> Month

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Month

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for Month

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl FromStr for Month

§

type Err = InvalidVariant

The associated error which can be returned from parsing.
§

fn from_str(s: &str) -> Result<Month, <Month as FromStr>::Err>

Parses a string s to return a value of this type. Read more
§

impl Hash for Month

§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl PartialEq for Month

§

fn eq(&self, other: &Month) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl SmartDisplay for Month

§

type Metadata = MonthMetadata

User-provided metadata type.
§

fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Month>

Compute any information needed to format the value. This must, at a minimum, determine the +width of the value before any padding is added by the formatter. Read more
§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Format the value using the given formatter. This is the same as Display::fmt. Read more
§

fn fmt_with_metadata( + &self, + f: &mut Formatter<'_>, + _metadata: Metadata<'_, Self> +) -> Result<(), Error>

Format the value using the given formatter and metadata. The formatted output should have +the width indicated by the metadata. This is before any padding is added by the +formatter. Read more
§

impl TryFrom<u8> for Month

§

type Error = ComponentRange

The type returned in the event of a conversion error.
§

fn try_from(value: u8) -> Result<Month, <Month as TryFrom<u8>>::Error>

Performs the conversion.
§

impl Copy for Month

§

impl Eq for Month

§

impl StructuralPartialEq for Month

Auto Trait Implementations§

§

impl Freeze for Month

§

impl RefUnwindSafe for Month

§

impl Send for Month

§

impl Sync for Month

§

impl Unpin for Month

§

impl UnwindSafe for Month

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/enum.Weekday.html b/actix_web/cookie/time/enum.Weekday.html new file mode 100644 index 000000000..8335593d9 --- /dev/null +++ b/actix_web/cookie/time/enum.Weekday.html @@ -0,0 +1,72 @@ +Weekday in actix_web::cookie::time - Rust

Enum actix_web::cookie::time::Weekday

pub enum Weekday {
+    Monday,
+    Tuesday,
+    Wednesday,
+    Thursday,
+    Friday,
+    Saturday,
+    Sunday,
+}
Available on crate feature cookies only.
Expand description

Days of the week.

+

As order is dependent on context (Sunday could be either two days after or five days before +Friday), this type does not implement PartialOrd or Ord.

+

Variants§

§

Monday

§

Tuesday

§

Wednesday

§

Thursday

§

Friday

§

Saturday

§

Sunday

Implementations§

§

impl Weekday

pub const fn previous(self) -> Weekday

Get the previous weekday.

+ +
assert_eq!(Weekday::Tuesday.previous(), Weekday::Monday);
+

pub const fn next(self) -> Weekday

Get the next weekday.

+ +
assert_eq!(Weekday::Monday.next(), Weekday::Tuesday);
+

pub const fn nth_next(self, n: u8) -> Weekday

Get n-th next day.

+ +
assert_eq!(Weekday::Monday.nth_next(1), Weekday::Tuesday);
+assert_eq!(Weekday::Sunday.nth_next(10), Weekday::Wednesday);
+

pub const fn nth_prev(self, n: u8) -> Weekday

Get n-th previous day.

+ +
assert_eq!(Weekday::Monday.nth_prev(1), Weekday::Sunday);
+assert_eq!(Weekday::Sunday.nth_prev(10), Weekday::Thursday);
+

pub const fn number_from_monday(self) -> u8

Get the one-indexed number of days from Monday.

+ +
assert_eq!(Weekday::Monday.number_from_monday(), 1);
+

pub const fn number_from_sunday(self) -> u8

Get the one-indexed number of days from Sunday.

+ +
assert_eq!(Weekday::Monday.number_from_sunday(), 2);
+

pub const fn number_days_from_monday(self) -> u8

Get the zero-indexed number of days from Monday.

+ +
assert_eq!(Weekday::Monday.number_days_from_monday(), 0);
+

pub const fn number_days_from_sunday(self) -> u8

Get the zero-indexed number of days from Sunday.

+ +
assert_eq!(Weekday::Monday.number_days_from_sunday(), 1);
+

Trait Implementations§

§

impl Clone for Weekday

§

fn clone(&self) -> Weekday

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Weekday

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for Weekday

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl FromStr for Weekday

§

type Err = InvalidVariant

The associated error which can be returned from parsing.
§

fn from_str(s: &str) -> Result<Weekday, <Weekday as FromStr>::Err>

Parses a string s to return a value of this type. Read more
§

impl Hash for Weekday

§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl PartialEq for Weekday

§

fn eq(&self, other: &Weekday) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl SmartDisplay for Weekday

§

type Metadata = WeekdayMetadata

User-provided metadata type.
§

fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Weekday>

Compute any information needed to format the value. This must, at a minimum, determine the +width of the value before any padding is added by the formatter. Read more
§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Format the value using the given formatter. This is the same as Display::fmt. Read more
§

fn fmt_with_metadata( + &self, + f: &mut Formatter<'_>, + _metadata: Metadata<'_, Self> +) -> Result<(), Error>

Format the value using the given formatter and metadata. The formatted output should have +the width indicated by the metadata. This is before any padding is added by the +formatter. Read more
§

impl Copy for Weekday

§

impl Eq for Weekday

§

impl StructuralPartialEq for Weekday

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/error/enum.Error.html b/actix_web/cookie/time/error/enum.Error.html new file mode 100644 index 000000000..f1762b3a4 --- /dev/null +++ b/actix_web/cookie/time/error/enum.Error.html @@ -0,0 +1,45 @@ +Error in actix_web::cookie::time::error - Rust

Enum actix_web::cookie::time::error::Error

#[non_exhaustive]
pub enum Error { + ConversionRange(ConversionRange), + ComponentRange(ComponentRange), + Format(Format), + ParseFromDescription(ParseFromDescription), + UnexpectedTrailingCharacters, + TryFromParsed(TryFromParsed), + InvalidFormatDescription(InvalidFormatDescription), + DifferentVariant(DifferentVariant), + InvalidVariant(InvalidVariant), +}
Available on crate feature cookies only.
Expand description

A unified error type for anything returned by a method in the time crate.

+

This can be used when you either don’t know or don’t care about the exact error returned. +Result<_, time::Error> (or its alias time::Result<_>) will work in these situations.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

ConversionRange(ConversionRange)

§

ComponentRange(ComponentRange)

§

Format(Format)

Available on crate feature formatting only.
§

ParseFromDescription(ParseFromDescription)

Available on crate feature parsing only.
§

UnexpectedTrailingCharacters

👎Deprecated since 0.3.28: no longer output. moved to the ParseFromDescription variant
Available on crate feature parsing only.
§

TryFromParsed(TryFromParsed)

Available on crate feature parsing only.
§

InvalidFormatDescription(InvalidFormatDescription)

Available on (crate features formatting or parsing) and crate feature alloc only.
§

DifferentVariant(DifferentVariant)

§

InvalidVariant(InvalidVariant)

Trait Implementations§

§

impl Debug for Error

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for Error

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for Error

Available on crate feature std only.
§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<ComponentRange> for Error

§

fn from(original: ComponentRange) -> Error

Converts to this type from the input type.
§

impl From<ConversionRange> for Error

§

fn from(err: ConversionRange) -> Error

Converts to this type from the input type.
§

impl From<DifferentVariant> for Error

§

fn from(err: DifferentVariant) -> Error

Converts to this type from the input type.
§

impl From<Format> for Error

§

fn from(original: Format) -> Error

Converts to this type from the input type.
§

impl From<InvalidFormatDescription> for Error

§

fn from(original: InvalidFormatDescription) -> Error

Converts to this type from the input type.
§

impl From<InvalidVariant> for Error

§

fn from(err: InvalidVariant) -> Error

Converts to this type from the input type.
§

impl From<Parse> for Error

§

fn from(err: Parse) -> Error

Converts to this type from the input type.
§

impl From<ParseFromDescription> for Error

§

fn from(original: ParseFromDescription) -> Error

Converts to this type from the input type.
§

impl From<TryFromParsed> for Error

§

fn from(original: TryFromParsed) -> Error

Converts to this type from the input type.
§

impl TryFrom<Error> for ComponentRange

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<ComponentRange, <ComponentRange as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Error> for ConversionRange

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<ConversionRange, <ConversionRange as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Error> for DifferentVariant

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<DifferentVariant, <DifferentVariant as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Error> for Format

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from(err: Error) -> Result<Format, <Format as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Error> for InvalidFormatDescription

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<InvalidFormatDescription, <InvalidFormatDescription as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Error> for InvalidVariant

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<InvalidVariant, <InvalidVariant as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Error> for Parse

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from(err: Error) -> Result<Parse, <Parse as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Error> for ParseFromDescription

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<ParseFromDescription, <ParseFromDescription as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Error> for TryFromParsed

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<TryFromParsed, <TryFromParsed as TryFrom<Error>>::Error>

Performs the conversion.

Auto Trait Implementations§

§

impl Freeze for Error

§

impl !RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl !UnwindSafe for Error

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/error/enum.Format.html b/actix_web/cookie/time/error/enum.Format.html new file mode 100644 index 000000000..8b9205dfc --- /dev/null +++ b/actix_web/cookie/time/error/enum.Format.html @@ -0,0 +1,27 @@ +Format in actix_web::cookie::time::error - Rust

Enum actix_web::cookie::time::error::Format

#[non_exhaustive]
pub enum Format { + InsufficientTypeInformation, + InvalidComponent(&'static str), + StdIo(Error), +}
Available on crate feature cookies only.
Expand description

An error occurred when formatting.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

InsufficientTypeInformation

The type being formatted does not contain sufficient information to format a component.

+
§

InvalidComponent(&'static str)

The component named has a value that cannot be formatted into the requested format.

+

This variant is only returned when using well-known formats.

+
§

StdIo(Error)

A value of std::io::Error was returned internally.

+

Trait Implementations§

§

impl Debug for Format

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for Format

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for Format

Available on crate feature std only.
§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<Error> for Format

§

fn from(err: Error) -> Format

Converts to this type from the input type.
§

impl From<Format> for Error

§

fn from(original: Format) -> Error

Converts to this type from the input type.
§

impl TryFrom<Error> for Format

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from(err: Error) -> Result<Format, <Format as TryFrom<Error>>::Error>

Performs the conversion.

Auto Trait Implementations§

§

impl Freeze for Format

§

impl !RefUnwindSafe for Format

§

impl Send for Format

§

impl Sync for Format

§

impl Unpin for Format

§

impl !UnwindSafe for Format

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/error/enum.InvalidFormatDescription.html b/actix_web/cookie/time/error/enum.InvalidFormatDescription.html new file mode 100644 index 000000000..844715dee --- /dev/null +++ b/actix_web/cookie/time/error/enum.InvalidFormatDescription.html @@ -0,0 +1,76 @@ +InvalidFormatDescription in actix_web::cookie::time::error - Rust

Enum actix_web::cookie::time::error::InvalidFormatDescription

#[non_exhaustive]
pub enum InvalidFormatDescription { + UnclosedOpeningBracket { + index: usize, + }, + InvalidComponentName { + name: String, + index: usize, + }, + InvalidModifier { + value: String, + index: usize, + }, + MissingComponentName { + index: usize, + }, + MissingRequiredModifier { + name: &'static str, + index: usize, + }, + Expected { + what: &'static str, + index: usize, + }, + NotSupported { + what: &'static str, + context: &'static str, + index: usize, + }, +}
Available on crate feature cookies only.
Expand description

The format description provided was not valid.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

UnclosedOpeningBracket

There was a bracket pair that was opened but not closed.

+

Fields

This variant is marked as non-exhaustive
Non-exhaustive enum variants could have additional fields added in future. Therefore, non-exhaustive enum variants cannot be constructed in external crates and cannot be matched against.
§index: usize

The zero-based index of the opening bracket.

+
§

InvalidComponentName

A component name is not valid.

+

Fields

This variant is marked as non-exhaustive
Non-exhaustive enum variants could have additional fields added in future. Therefore, non-exhaustive enum variants cannot be constructed in external crates and cannot be matched against.
§name: String

The name of the invalid component name.

+
§index: usize

The zero-based index the component name starts at.

+
§

InvalidModifier

A modifier is not valid.

+

Fields

This variant is marked as non-exhaustive
Non-exhaustive enum variants could have additional fields added in future. Therefore, non-exhaustive enum variants cannot be constructed in external crates and cannot be matched against.
§value: String

The value of the invalid modifier.

+
§index: usize

The zero-based index the modifier starts at.

+
§

MissingComponentName

A component name is missing.

+

Fields

This variant is marked as non-exhaustive
Non-exhaustive enum variants could have additional fields added in future. Therefore, non-exhaustive enum variants cannot be constructed in external crates and cannot be matched against.
§index: usize

The zero-based index where the component name should start.

+
§

MissingRequiredModifier

A required modifier is missing.

+

Fields

This variant is marked as non-exhaustive
Non-exhaustive enum variants could have additional fields added in future. Therefore, non-exhaustive enum variants cannot be constructed in external crates and cannot be matched against.
§name: &'static str

The name of the modifier that is missing.

+
§index: usize

The zero-based index of the component.

+
§

Expected

Something was expected, but not found.

+

Fields

This variant is marked as non-exhaustive
Non-exhaustive enum variants could have additional fields added in future. Therefore, non-exhaustive enum variants cannot be constructed in external crates and cannot be matched against.
§what: &'static str

What was expected to be present, but wasn’t.

+
§index: usize

The zero-based index the item was expected to be found at.

+
§

NotSupported

Certain behavior is not supported in the given context.

+

Fields

This variant is marked as non-exhaustive
Non-exhaustive enum variants could have additional fields added in future. Therefore, non-exhaustive enum variants cannot be constructed in external crates and cannot be matched against.
§what: &'static str

The behavior that is not supported.

+
§context: &'static str

The context in which the behavior is not supported.

+
§index: usize

The zero-based index the error occurred at.

+

Trait Implementations§

§

impl Clone for InvalidFormatDescription

§

fn clone(&self) -> InvalidFormatDescription

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for InvalidFormatDescription

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for InvalidFormatDescription

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for InvalidFormatDescription

Available on crate feature std only.
1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<Error> for InvalidFormatDescription

§

fn from(error: Error) -> InvalidFormatDescription

Converts to this type from the input type.
§

impl From<InvalidFormatDescription> for Error

§

fn from(original: InvalidFormatDescription) -> Error

Converts to this type from the input type.
§

impl PartialEq for InvalidFormatDescription

§

fn eq(&self, other: &InvalidFormatDescription) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl TryFrom<Error> for InvalidFormatDescription

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<InvalidFormatDescription, <InvalidFormatDescription as TryFrom<Error>>::Error>

Performs the conversion.
§

impl Eq for InvalidFormatDescription

§

impl StructuralPartialEq for InvalidFormatDescription

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/error/enum.Parse.html b/actix_web/cookie/time/error/enum.Parse.html new file mode 100644 index 000000000..504d01ece --- /dev/null +++ b/actix_web/cookie/time/error/enum.Parse.html @@ -0,0 +1,35 @@ +Parse in actix_web::cookie::time::error - Rust

Enum actix_web::cookie::time::error::Parse

#[non_exhaustive]
pub enum Parse { + TryFromParsed(TryFromParsed), + ParseFromDescription(ParseFromDescription), + UnexpectedTrailingCharacters, +}
Available on crate feature cookies only.
Expand description

An error that occurred at some stage of parsing.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

TryFromParsed(TryFromParsed)

§

ParseFromDescription(ParseFromDescription)

§

UnexpectedTrailingCharacters

👎Deprecated since 0.3.28: no longer output. moved to the ParseFromDescription variant

The input should have ended, but there were characters remaining.

+

Trait Implementations§

§

impl Clone for Parse

§

fn clone(&self) -> Parse

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Parse

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for Parse

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for Parse

Available on crate feature std only.
§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<Parse> for Error

§

fn from(err: Parse) -> Error

Converts to this type from the input type.
§

impl From<ParseFromDescription> for Parse

§

fn from(err: ParseFromDescription) -> Parse

Converts to this type from the input type.
§

impl From<TryFromParsed> for Parse

§

fn from(err: TryFromParsed) -> Parse

Converts to this type from the input type.
§

impl PartialEq for Parse

§

fn eq(&self, other: &Parse) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl TryFrom<Error> for Parse

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from(err: Error) -> Result<Parse, <Parse as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Parse> for ParseFromDescription

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Parse +) -> Result<ParseFromDescription, <ParseFromDescription as TryFrom<Parse>>::Error>

Performs the conversion.
§

impl TryFrom<Parse> for TryFromParsed

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Parse +) -> Result<TryFromParsed, <TryFromParsed as TryFrom<Parse>>::Error>

Performs the conversion.
§

impl Copy for Parse

§

impl Eq for Parse

§

impl StructuralPartialEq for Parse

Auto Trait Implementations§

§

impl Freeze for Parse

§

impl RefUnwindSafe for Parse

§

impl Send for Parse

§

impl Sync for Parse

§

impl Unpin for Parse

§

impl UnwindSafe for Parse

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/error/enum.ParseFromDescription.html b/actix_web/cookie/time/error/enum.ParseFromDescription.html new file mode 100644 index 000000000..4f09024af --- /dev/null +++ b/actix_web/cookie/time/error/enum.ParseFromDescription.html @@ -0,0 +1,37 @@ +ParseFromDescription in actix_web::cookie::time::error - Rust

Enum actix_web::cookie::time::error::ParseFromDescription

#[non_exhaustive]
pub enum ParseFromDescription { + InvalidLiteral, + InvalidComponent(&'static str), + UnexpectedTrailingCharacters, +}
Available on crate feature cookies only.
Expand description

An error that occurred while parsing the input into a Parsed struct.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

InvalidLiteral

A string literal was not what was expected.

+
§

InvalidComponent(&'static str)

A dynamic component was not valid.

+
§

UnexpectedTrailingCharacters

The input was expected to have ended, but there are characters that remain.

+

Trait Implementations§

§

impl Clone for ParseFromDescription

§

fn clone(&self) -> ParseFromDescription

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for ParseFromDescription

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for ParseFromDescription

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for ParseFromDescription

Available on crate feature std only.
1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<ParseFromDescription> for Error

§

fn from(original: ParseFromDescription) -> Error

Converts to this type from the input type.
§

impl From<ParseFromDescription> for Parse

§

fn from(err: ParseFromDescription) -> Parse

Converts to this type from the input type.
§

impl PartialEq for ParseFromDescription

§

fn eq(&self, other: &ParseFromDescription) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl TryFrom<Error> for ParseFromDescription

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<ParseFromDescription, <ParseFromDescription as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Parse> for ParseFromDescription

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Parse +) -> Result<ParseFromDescription, <ParseFromDescription as TryFrom<Parse>>::Error>

Performs the conversion.
§

impl Copy for ParseFromDescription

§

impl Eq for ParseFromDescription

§

impl StructuralPartialEq for ParseFromDescription

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/error/enum.TryFromParsed.html b/actix_web/cookie/time/error/enum.TryFromParsed.html new file mode 100644 index 000000000..c84c43574 --- /dev/null +++ b/actix_web/cookie/time/error/enum.TryFromParsed.html @@ -0,0 +1,38 @@ +TryFromParsed in actix_web::cookie::time::error - Rust

Enum actix_web::cookie::time::error::TryFromParsed

#[non_exhaustive]
pub enum TryFromParsed { + InsufficientInformation, + ComponentRange(ComponentRange), +}
Available on crate feature cookies only.
Expand description

An error that occurred when converting a Parsed to another type.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

InsufficientInformation

The Parsed did not include enough information to construct the +type.

+
§

ComponentRange(ComponentRange)

Some component contained an invalid value for the type.

+

Trait Implementations§

§

impl Clone for TryFromParsed

§

fn clone(&self) -> TryFromParsed

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for TryFromParsed

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for TryFromParsed

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for TryFromParsed

Available on crate feature std only.
§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<ComponentRange> for TryFromParsed

§

fn from(v: ComponentRange) -> TryFromParsed

Converts to this type from the input type.
§

impl From<TryFromParsed> for Error

§

fn from(original: TryFromParsed) -> Error

Converts to this type from the input type.
§

impl From<TryFromParsed> for Parse

§

fn from(err: TryFromParsed) -> Parse

Converts to this type from the input type.
§

impl PartialEq for TryFromParsed

§

fn eq(&self, other: &TryFromParsed) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl TryFrom<Error> for TryFromParsed

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<TryFromParsed, <TryFromParsed as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<Parse> for TryFromParsed

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Parse +) -> Result<TryFromParsed, <TryFromParsed as TryFrom<Parse>>::Error>

Performs the conversion.
§

impl TryFrom<TryFromParsed> for ComponentRange

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: TryFromParsed +) -> Result<ComponentRange, <ComponentRange as TryFrom<TryFromParsed>>::Error>

Performs the conversion.
§

impl Copy for TryFromParsed

§

impl Eq for TryFromParsed

§

impl StructuralPartialEq for TryFromParsed

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/error/index.html b/actix_web/cookie/time/error/index.html new file mode 100644 index 000000000..0d820eecb --- /dev/null +++ b/actix_web/cookie/time/error/index.html @@ -0,0 +1,6 @@ +actix_web::cookie::time::error - Rust

Module actix_web::cookie::time::error

Available on crate feature cookies only.
Expand description

Various error types returned by methods in the time crate.

+

Structs§

  • An error type indicating that a component provided to a method was out of range, causing a +failure.
  • An error type indicating that a conversion failed because the target type could not store the +initial value.
  • An error type indicating that a TryFrom call failed because the +original value was of a different variant.
  • An error type indicating that a FromStr call failed because the value +was not a valid variant.

Enums§

\ No newline at end of file diff --git a/actix_web/cookie/time/error/sidebar-items.js b/actix_web/cookie/time/error/sidebar-items.js new file mode 100644 index 000000000..c7880e64f --- /dev/null +++ b/actix_web/cookie/time/error/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Error","Format","InvalidFormatDescription","Parse","ParseFromDescription","TryFromParsed"],"struct":["ComponentRange","ConversionRange","DifferentVariant","InvalidVariant"]}; \ No newline at end of file diff --git a/actix_web/cookie/time/error/struct.ComponentRange.html b/actix_web/cookie/time/error/struct.ComponentRange.html new file mode 100644 index 000000000..cf2ec259e --- /dev/null +++ b/actix_web/cookie/time/error/struct.ComponentRange.html @@ -0,0 +1,37 @@ +ComponentRange in actix_web::cookie::time::error - Rust

Struct actix_web::cookie::time::error::ComponentRange

pub struct ComponentRange { /* private fields */ }
Available on crate feature cookies only.
Expand description

An error type indicating that a component provided to a method was out of range, causing a +failure.

+

Implementations§

§

impl ComponentRange

pub const fn name(self) -> &'static str

Obtain the name of the component whose value was out of range.

+

pub const fn is_conditional(self) -> bool

Whether the value’s permitted range is conditional, i.e. whether an input with this +value could have succeeded if the values of other components were different.

+

Trait Implementations§

§

impl Clone for ComponentRange

§

fn clone(&self) -> ComponentRange

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for ComponentRange

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for ComponentRange

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for ComponentRange

Available on crate feature std only.
1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<ComponentRange> for Error

§

fn from(original: ComponentRange) -> Error

Converts to this type from the input type.
§

impl From<ComponentRange> for TryFromParsed

§

fn from(v: ComponentRange) -> TryFromParsed

Converts to this type from the input type.
§

impl Hash for ComponentRange

§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl PartialEq for ComponentRange

§

fn eq(&self, other: &ComponentRange) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl TryFrom<Error> for ComponentRange

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<ComponentRange, <ComponentRange as TryFrom<Error>>::Error>

Performs the conversion.
§

impl TryFrom<TryFromParsed> for ComponentRange

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: TryFromParsed +) -> Result<ComponentRange, <ComponentRange as TryFrom<TryFromParsed>>::Error>

Performs the conversion.
§

impl Copy for ComponentRange

§

impl Eq for ComponentRange

§

impl StructuralPartialEq for ComponentRange

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/error/struct.ConversionRange.html b/actix_web/cookie/time/error/struct.ConversionRange.html new file mode 100644 index 000000000..ac41ba4f6 --- /dev/null +++ b/actix_web/cookie/time/error/struct.ConversionRange.html @@ -0,0 +1,29 @@ +ConversionRange in actix_web::cookie::time::error - Rust

Struct actix_web::cookie::time::error::ConversionRange

pub struct ConversionRange;
Available on crate feature cookies only.
Expand description

An error type indicating that a conversion failed because the target type could not store the +initial value.

+

Trait Implementations§

§

impl Clone for ConversionRange

§

fn clone(&self) -> ConversionRange

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for ConversionRange

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for ConversionRange

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for ConversionRange

Available on crate feature std only.
1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<ConversionRange> for Error

§

fn from(err: ConversionRange) -> Error

Converts to this type from the input type.
§

impl PartialEq for ConversionRange

§

fn eq(&self, other: &ConversionRange) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl TryFrom<Error> for ConversionRange

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<ConversionRange, <ConversionRange as TryFrom<Error>>::Error>

Performs the conversion.
§

impl Copy for ConversionRange

§

impl Eq for ConversionRange

§

impl StructuralPartialEq for ConversionRange

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/error/struct.DifferentVariant.html b/actix_web/cookie/time/error/struct.DifferentVariant.html new file mode 100644 index 000000000..3d637defc --- /dev/null +++ b/actix_web/cookie/time/error/struct.DifferentVariant.html @@ -0,0 +1,29 @@ +DifferentVariant in actix_web::cookie::time::error - Rust

Struct actix_web::cookie::time::error::DifferentVariant

pub struct DifferentVariant;
Available on crate feature cookies only.
Expand description

An error type indicating that a TryFrom call failed because the +original value was of a different variant.

+

Trait Implementations§

§

impl Clone for DifferentVariant

§

fn clone(&self) -> DifferentVariant

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for DifferentVariant

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for DifferentVariant

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for DifferentVariant

Available on crate feature std only.
1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<DifferentVariant> for Error

§

fn from(err: DifferentVariant) -> Error

Converts to this type from the input type.
§

impl PartialEq for DifferentVariant

§

fn eq(&self, other: &DifferentVariant) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl TryFrom<Error> for DifferentVariant

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<DifferentVariant, <DifferentVariant as TryFrom<Error>>::Error>

Performs the conversion.
§

impl Copy for DifferentVariant

§

impl Eq for DifferentVariant

§

impl StructuralPartialEq for DifferentVariant

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/error/struct.InvalidVariant.html b/actix_web/cookie/time/error/struct.InvalidVariant.html new file mode 100644 index 000000000..752f5387f --- /dev/null +++ b/actix_web/cookie/time/error/struct.InvalidVariant.html @@ -0,0 +1,29 @@ +InvalidVariant in actix_web::cookie::time::error - Rust

Struct actix_web::cookie::time::error::InvalidVariant

pub struct InvalidVariant;
Available on crate feature cookies only.
Expand description

An error type indicating that a FromStr call failed because the value +was not a valid variant.

+

Trait Implementations§

§

impl Clone for InvalidVariant

§

fn clone(&self) -> InvalidVariant

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for InvalidVariant

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for InvalidVariant

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for InvalidVariant

Available on crate feature std only.
1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<InvalidVariant> for Error

§

fn from(err: InvalidVariant) -> Error

Converts to this type from the input type.
§

impl PartialEq for InvalidVariant

§

fn eq(&self, other: &InvalidVariant) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl TryFrom<Error> for InvalidVariant

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + err: Error +) -> Result<InvalidVariant, <InvalidVariant as TryFrom<Error>>::Error>

Performs the conversion.
§

impl Copy for InvalidVariant

§

impl Eq for InvalidVariant

§

impl StructuralPartialEq for InvalidVariant

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/ext/index.html b/actix_web/cookie/time/ext/index.html new file mode 100644 index 000000000..b43232777 --- /dev/null +++ b/actix_web/cookie/time/ext/index.html @@ -0,0 +1,3 @@ +actix_web::cookie::time::ext - Rust

Module actix_web::cookie::time::ext

Available on crate feature cookies only.
Expand description

Extension traits.

+

Traits§

\ No newline at end of file diff --git a/actix_web/cookie/time/ext/sidebar-items.js b/actix_web/cookie/time/ext/sidebar-items.js new file mode 100644 index 000000000..4a9397bf0 --- /dev/null +++ b/actix_web/cookie/time/ext/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"trait":["InstantExt","NumericalDuration","NumericalStdDuration"]}; \ No newline at end of file diff --git a/actix_web/cookie/time/ext/trait.InstantExt.html b/actix_web/cookie/time/ext/trait.InstantExt.html new file mode 100644 index 000000000..8b9ed3935 --- /dev/null +++ b/actix_web/cookie/time/ext/trait.InstantExt.html @@ -0,0 +1,34 @@ +InstantExt in actix_web::cookie::time::ext - Rust

Trait actix_web::cookie::time::ext::InstantExt

pub trait InstantExt: Sealed {
+    // Required methods
+    fn checked_add_signed(&self, duration: Duration) -> Option<Self>;
+    fn checked_sub_signed(&self, duration: Duration) -> Option<Self>;
+    fn signed_duration_since(&self, earlier: Self) -> Duration;
+
+    // Provided methods
+    fn add_signed(self, duration: Duration) -> Self { ... }
+    fn sub_signed(self, duration: Duration) -> Self { ... }
+}
Available on crate feature cookies only.
Expand description

An extension trait for std::time::Instant that adds methods for +time::Durations.

+

Required Methods§

fn checked_add_signed(&self, duration: Duration) -> Option<Self>

Returns Some(t) where t is the time self.checked_add_signed(duration) if t can be +represented as Instant (which means it’s inside the bounds of the underlying data +structure), None otherwise.

+

fn checked_sub_signed(&self, duration: Duration) -> Option<Self>

Returns Some(t) where t is the time self.checked_sub_signed(duration) if t can be +represented as Instant (which means it’s inside the bounds of the underlying data +structure), None otherwise.

+

fn signed_duration_since(&self, earlier: Self) -> Duration

Returns the amount of time elapsed from another instant to this one. This will be negative +if earlier is later than self.

+
§Example
+
let now = Instant::now();
+sleep(Duration::new(1, 0));
+let new_now = Instant::now();
+println!("{:?}", new_now.signed_duration_since(now)); // positive
+println!("{:?}", now.signed_duration_since(new_now)); // negative
+

Provided Methods§

fn add_signed(self, duration: Duration) -> Self

§Panics
+

This function may panic if the resulting point in time cannot be represented by the +underlying data structure. See InstantExt::checked_add_signed for a non-panicking +version.

+

fn sub_signed(self, duration: Duration) -> Self

§Panics
+

This function may panic if the resulting point in time cannot be represented by the +underlying data structure. See InstantExt::checked_sub_signed for a non-panicking +version.

+

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

§

impl InstantExt for Instant

§

fn checked_add_signed(&self, duration: Duration) -> Option<Instant>

§

fn checked_sub_signed(&self, duration: Duration) -> Option<Instant>

§

fn signed_duration_since(&self, earlier: Instant) -> Duration

Implementors§

\ No newline at end of file diff --git a/actix_web/cookie/time/ext/trait.NumericalDuration.html b/actix_web/cookie/time/ext/trait.NumericalDuration.html new file mode 100644 index 000000000..6a314b465 --- /dev/null +++ b/actix_web/cookie/time/ext/trait.NumericalDuration.html @@ -0,0 +1,48 @@ +NumericalDuration in actix_web::cookie::time::ext - Rust

Trait actix_web::cookie::time::ext::NumericalDuration

pub trait NumericalDuration: Sealed {
+    // Required methods
+    fn nanoseconds(self) -> Duration;
+    fn microseconds(self) -> Duration;
+    fn milliseconds(self) -> Duration;
+    fn seconds(self) -> Duration;
+    fn minutes(self) -> Duration;
+    fn hours(self) -> Duration;
+    fn days(self) -> Duration;
+    fn weeks(self) -> Duration;
+}
Available on crate feature cookies only.
Expand description

Create Durations from numeric literals.

+

§Examples

+

Basic construction of Durations.

+ +
assert_eq!(5.nanoseconds(), Duration::nanoseconds(5));
+assert_eq!(5.microseconds(), Duration::microseconds(5));
+assert_eq!(5.milliseconds(), Duration::milliseconds(5));
+assert_eq!(5.seconds(), Duration::seconds(5));
+assert_eq!(5.minutes(), Duration::minutes(5));
+assert_eq!(5.hours(), Duration::hours(5));
+assert_eq!(5.days(), Duration::days(5));
+assert_eq!(5.weeks(), Duration::weeks(5));
+

Signed integers work as well!

+ +
assert_eq!((-5).nanoseconds(), Duration::nanoseconds(-5));
+assert_eq!((-5).microseconds(), Duration::microseconds(-5));
+assert_eq!((-5).milliseconds(), Duration::milliseconds(-5));
+assert_eq!((-5).seconds(), Duration::seconds(-5));
+assert_eq!((-5).minutes(), Duration::minutes(-5));
+assert_eq!((-5).hours(), Duration::hours(-5));
+assert_eq!((-5).days(), Duration::days(-5));
+assert_eq!((-5).weeks(), Duration::weeks(-5));
+

Just like any other Duration, they can be added, subtracted, etc.

+ +
assert_eq!(2.seconds() + 500.milliseconds(), 2_500.milliseconds());
+assert_eq!(2.seconds() - 500.milliseconds(), 1_500.milliseconds());
+

When called on floating point values, any remainder of the floating point value will be +truncated. Keep in mind that floating point numbers are inherently imprecise and have +limited capacity.

+

Required Methods§

fn nanoseconds(self) -> Duration

Create a Duration from the number of nanoseconds.

+

fn microseconds(self) -> Duration

Create a Duration from the number of microseconds.

+

fn milliseconds(self) -> Duration

Create a Duration from the number of milliseconds.

+

fn seconds(self) -> Duration

Create a Duration from the number of seconds.

+

fn minutes(self) -> Duration

Create a Duration from the number of minutes.

+

fn hours(self) -> Duration

Create a Duration from the number of hours.

+

fn days(self) -> Duration

Create a Duration from the number of days.

+

fn weeks(self) -> Duration

Create a Duration from the number of weeks.

+

Implementations on Foreign Types§

§

impl NumericalDuration for f64

§

fn nanoseconds(self) -> Duration

§

fn microseconds(self) -> Duration

§

fn milliseconds(self) -> Duration

§

fn seconds(self) -> Duration

§

fn minutes(self) -> Duration

§

fn hours(self) -> Duration

§

fn days(self) -> Duration

§

fn weeks(self) -> Duration

§

impl NumericalDuration for i64

§

fn nanoseconds(self) -> Duration

§

fn microseconds(self) -> Duration

§

fn milliseconds(self) -> Duration

§

fn seconds(self) -> Duration

§

fn minutes(self) -> Duration

§

fn hours(self) -> Duration

§

fn days(self) -> Duration

§

fn weeks(self) -> Duration

Implementors§

\ No newline at end of file diff --git a/actix_web/cookie/time/ext/trait.NumericalStdDuration.html b/actix_web/cookie/time/ext/trait.NumericalStdDuration.html new file mode 100644 index 000000000..451fba9d3 --- /dev/null +++ b/actix_web/cookie/time/ext/trait.NumericalStdDuration.html @@ -0,0 +1,68 @@ +NumericalStdDuration in actix_web::cookie::time::ext - Rust

Trait actix_web::cookie::time::ext::NumericalStdDuration

pub trait NumericalStdDuration: Sealed {
+    // Required methods
+    fn std_nanoseconds(self) -> Duration;
+    fn std_microseconds(self) -> Duration;
+    fn std_milliseconds(self) -> Duration;
+    fn std_seconds(self) -> Duration;
+    fn std_minutes(self) -> Duration;
+    fn std_hours(self) -> Duration;
+    fn std_days(self) -> Duration;
+    fn std_weeks(self) -> Duration;
+}
Available on crate feature cookies only.
Expand description

Create std::time::Durations from numeric literals.

+

§Examples

+

Basic construction of std::time::Durations.

+ +
assert_eq!(5.std_nanoseconds(), Duration::from_nanos(5));
+assert_eq!(5.std_microseconds(), Duration::from_micros(5));
+assert_eq!(5.std_milliseconds(), Duration::from_millis(5));
+assert_eq!(5.std_seconds(), Duration::from_secs(5));
+assert_eq!(5.std_minutes(), Duration::from_secs(5 * 60));
+assert_eq!(5.std_hours(), Duration::from_secs(5 * 3_600));
+assert_eq!(5.std_days(), Duration::from_secs(5 * 86_400));
+assert_eq!(5.std_weeks(), Duration::from_secs(5 * 604_800));
+

Just like any other std::time::Duration, they can be added, subtracted, etc.

+ +
assert_eq!(
+    2.std_seconds() + 500.std_milliseconds(),
+    2_500.std_milliseconds()
+);
+assert_eq!(
+    2.std_seconds() - 500.std_milliseconds(),
+    1_500.std_milliseconds()
+);
+

When called on floating point values, any remainder of the floating point value will be +truncated. Keep in mind that floating point numbers are inherently imprecise and have +limited capacity.

+

Required Methods§

fn std_nanoseconds(self) -> Duration

Create a std::time::Duration from the number of nanoseconds.

+

fn std_microseconds(self) -> Duration

Create a std::time::Duration from the number of microseconds.

+

fn std_milliseconds(self) -> Duration

Create a std::time::Duration from the number of milliseconds.

+

fn std_seconds(self) -> Duration

Create a std::time::Duration from the number of seconds.

+

fn std_minutes(self) -> Duration

Create a std::time::Duration from the number of minutes.

+

fn std_hours(self) -> Duration

Create a std::time::Duration from the number of hours.

+

fn std_days(self) -> Duration

Create a std::time::Duration from the number of days.

+

fn std_weeks(self) -> Duration

Create a std::time::Duration from the number of weeks.

+

Implementations on Foreign Types§

§

impl NumericalStdDuration for f64

§

fn std_nanoseconds(self) -> Duration

§Panics
+

This will panic if self is negative.

+
§

fn std_microseconds(self) -> Duration

§Panics
+

This will panic if self is negative.

+
§

fn std_milliseconds(self) -> Duration

§Panics
+

This will panic if self is negative.

+
§

fn std_seconds(self) -> Duration

§Panics
+

This will panic if self is negative.

+
§

fn std_minutes(self) -> Duration

§Panics
+

This will panic if self is negative.

+
§

fn std_hours(self) -> Duration

§Panics
+

This will panic if self is negative.

+
§

fn std_days(self) -> Duration

§Panics
+

This will panic if self is negative.

+
§

fn std_weeks(self) -> Duration

§Panics
+

This will panic if self is negative.

+
§

impl NumericalStdDuration for u64

§

fn std_minutes(self) -> Duration

§Panics
+

This may panic if an overflow occurs.

+
§

fn std_hours(self) -> Duration

§Panics
+

This may panic if an overflow occurs.

+
§

fn std_days(self) -> Duration

§Panics
+

This may panic if an overflow occurs.

+
§

fn std_weeks(self) -> Duration

§Panics
+

This may panic if an overflow occurs.

+
§

fn std_nanoseconds(self) -> Duration

§

fn std_microseconds(self) -> Duration

§

fn std_milliseconds(self) -> Duration

§

fn std_seconds(self) -> Duration

Implementors§

\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/enum.BorrowedFormatItem.html b/actix_web/cookie/time/format_description/enum.BorrowedFormatItem.html new file mode 100644 index 000000000..fbb17c4ab --- /dev/null +++ b/actix_web/cookie/time/format_description/enum.BorrowedFormatItem.html @@ -0,0 +1,57 @@ +BorrowedFormatItem in actix_web::cookie::time::format_description - Rust
#[non_exhaustive]
pub enum BorrowedFormatItem<'a> { + Literal(&'a [u8]), + Component(Component), + Compound(&'a [BorrowedFormatItem<'a>]), + Optional(&'a BorrowedFormatItem<'a>), + First(&'a [BorrowedFormatItem<'a>]), +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

A complete description of how to format and parse a type.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Literal(&'a [u8])

Bytes that are formatted as-is.

+

Note: These bytes should be UTF-8, but are not required to be. The value is passed +through String::from_utf8_lossy when necessary.

+
§

Component(Component)

A minimal representation of a single non-literal item.

+
§

Compound(&'a [BorrowedFormatItem<'a>])

A series of literals or components that collectively form a partial or complete +description.

+
§

Optional(&'a BorrowedFormatItem<'a>)

A FormatItem that may or may not be present when parsing. If parsing fails, there +will be no effect on the resulting struct.

+

This variant has no effect on formatting, as the value is guaranteed to be present.

+
§

First(&'a [BorrowedFormatItem<'a>])

A series of FormatItems where, when parsing, the first successful parse is used. When +formatting, the first element of the slice is used. An empty slice is a no-op when +formatting or parsing.

+

Trait Implementations§

§

impl<'a> Clone for BorrowedFormatItem<'a>

§

fn clone(&self) -> BorrowedFormatItem<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for BorrowedFormatItem<'_>

Available on crate feature alloc only.
§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<'a> From<&'a [BorrowedFormatItem<'_>]> for BorrowedFormatItem<'a>

§

fn from(items: &'a [BorrowedFormatItem<'_>]) -> BorrowedFormatItem<'a>

Converts to this type from the input type.
§

impl From<&BorrowedFormatItem<'_>> for OwnedFormatItem

§

fn from(item: &BorrowedFormatItem<'_>) -> OwnedFormatItem

Converts to this type from the input type.
§

impl From<BorrowedFormatItem<'_>> for OwnedFormatItem

§

fn from(item: BorrowedFormatItem<'_>) -> OwnedFormatItem

Converts to this type from the input type.
§

impl From<Component> for BorrowedFormatItem<'_>

§

fn from(component: Component) -> BorrowedFormatItem<'_>

Converts to this type from the input type.
§

impl PartialEq<&[BorrowedFormatItem<'_>]> for BorrowedFormatItem<'_>

§

fn eq(&self, rhs: &&[BorrowedFormatItem<'_>]) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<BorrowedFormatItem<'_>> for &[BorrowedFormatItem<'_>]

§

fn eq(&self, rhs: &BorrowedFormatItem<'_>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<BorrowedFormatItem<'_>> for Component

§

fn eq(&self, rhs: &BorrowedFormatItem<'_>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<Component> for BorrowedFormatItem<'_>

§

fn eq(&self, rhs: &Component) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a> PartialEq for BorrowedFormatItem<'a>

§

fn eq(&self, other: &BorrowedFormatItem<'a>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl TryFrom<BorrowedFormatItem<'_>> for Component

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + value: BorrowedFormatItem<'_> +) -> Result<Component, <Component as TryFrom<BorrowedFormatItem<'_>>>::Error>

Performs the conversion.
§

impl<'a> TryFrom<BorrowedFormatItem<'a>> for &[BorrowedFormatItem<'a>]

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + value: BorrowedFormatItem<'a> +) -> Result<&[BorrowedFormatItem<'a>], <&[BorrowedFormatItem<'a>] as TryFrom<BorrowedFormatItem<'a>>>::Error>

Performs the conversion.
§

impl<'a> TryFrom<Item<'a>> for BorrowedFormatItem<'a>

§

type Error = Error

The type returned in the event of a conversion error.
§

fn try_from( + item: Item<'a> +) -> Result<BorrowedFormatItem<'a>, <BorrowedFormatItem<'a> as TryFrom<Item<'a>>>::Error>

Performs the conversion.
§

impl<'a> Eq for BorrowedFormatItem<'a>

§

impl Formattable for BorrowedFormatItem<'_>

§

impl Parsable for BorrowedFormatItem<'_>

§

impl<'a> StructuralPartialEq for BorrowedFormatItem<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for BorrowedFormatItem<'a>

§

impl<'a> RefUnwindSafe for BorrowedFormatItem<'a>

§

impl<'a> Send for BorrowedFormatItem<'a>

§

impl<'a> Sync for BorrowedFormatItem<'a>

§

impl<'a> Unpin for BorrowedFormatItem<'a>

§

impl<'a> UnwindSafe for BorrowedFormatItem<'a>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/enum.Component.html b/actix_web/cookie/time/format_description/enum.Component.html new file mode 100644 index 000000000..658111905 --- /dev/null +++ b/actix_web/cookie/time/format_description/enum.Component.html @@ -0,0 +1,73 @@ +Component in actix_web::cookie::time::format_description - Rust

Enum actix_web::cookie::time::format_description::Component

#[non_exhaustive]
pub enum Component { +
Show 17 variants Day(Day), + Month(Month), + Ordinal(Ordinal), + Weekday(Weekday), + WeekNumber(WeekNumber), + Year(Year), + Hour(Hour), + Minute(Minute), + Period(Period), + Second(Second), + Subsecond(Subsecond), + OffsetHour(OffsetHour), + OffsetMinute(OffsetMinute), + OffsetSecond(OffsetSecond), + Ignore(Ignore), + UnixTimestamp(UnixTimestamp), + End(End), +
}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

A component of a larger format description.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Day(Day)

Day of the month.

+
§

Month(Month)

Month of the year.

+
§

Ordinal(Ordinal)

Ordinal day of the year.

+
§

Weekday(Weekday)

Day of the week.

+
§

WeekNumber(WeekNumber)

Week within the year.

+
§

Year(Year)

Year of the date.

+
§

Hour(Hour)

Hour of the day.

+
§

Minute(Minute)

Minute within the hour.

+
§

Period(Period)

AM/PM part of the time.

+
§

Second(Second)

Second within the minute.

+
§

Subsecond(Subsecond)

Subsecond within the second.

+
§

OffsetHour(OffsetHour)

Hour of the UTC offset.

+
§

OffsetMinute(OffsetMinute)

Minute within the hour of the UTC offset.

+
§

OffsetSecond(OffsetSecond)

Second within the minute of the UTC offset.

+
§

Ignore(Ignore)

A number of bytes to ignore when parsing. This has no effect on formatting.

+
§

UnixTimestamp(UnixTimestamp)

A Unix timestamp.

+
§

End(End)

The end of input. Parsing this component will fail if there is any input remaining. This +component neither affects formatting nor consumes any input when parsing.

+

Trait Implementations§

§

impl Clone for Component

§

fn clone(&self) -> Component

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Component

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl From<Component> for BorrowedFormatItem<'_>

§

fn from(component: Component) -> BorrowedFormatItem<'_>

Converts to this type from the input type.
§

impl From<Component> for Component

§

fn from(component: Component) -> Component

Converts to this type from the input type.
§

impl From<Component> for OwnedFormatItem

§

fn from(component: Component) -> OwnedFormatItem

Converts to this type from the input type.
§

impl PartialEq<BorrowedFormatItem<'_>> for Component

§

fn eq(&self, rhs: &BorrowedFormatItem<'_>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<Component> for BorrowedFormatItem<'_>

§

fn eq(&self, rhs: &Component) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<Component> for OwnedFormatItem

§

fn eq(&self, rhs: &Component) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<OwnedFormatItem> for Component

§

fn eq(&self, rhs: &OwnedFormatItem) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq for Component

§

fn eq(&self, other: &Component) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl TryFrom<BorrowedFormatItem<'_>> for Component

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + value: BorrowedFormatItem<'_> +) -> Result<Component, <Component as TryFrom<BorrowedFormatItem<'_>>>::Error>

Performs the conversion.
§

impl TryFrom<OwnedFormatItem> for Component

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + value: OwnedFormatItem +) -> Result<Component, <Component as TryFrom<OwnedFormatItem>>::Error>

Performs the conversion.
§

impl Copy for Component

§

impl Eq for Component

§

impl StructuralPartialEq for Component

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/enum.FormatItem.html b/actix_web/cookie/time/format_description/enum.FormatItem.html new file mode 100644 index 000000000..059a75063 --- /dev/null +++ b/actix_web/cookie/time/format_description/enum.FormatItem.html @@ -0,0 +1,57 @@ +FormatItem in actix_web::cookie::time::format_description - Rust

Enum actix_web::cookie::time::format_description::FormatItem

#[non_exhaustive]
pub enum FormatItem<'a> { + Literal(&'a [u8]), + Component(Component), + Compound(&'a [BorrowedFormatItem<'a>]), + Optional(&'a BorrowedFormatItem<'a>), + First(&'a [BorrowedFormatItem<'a>]), +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

A complete description of how to format and parse a type.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Literal(&'a [u8])

Bytes that are formatted as-is.

+

Note: These bytes should be UTF-8, but are not required to be. The value is passed +through String::from_utf8_lossy when necessary.

+
§

Component(Component)

A minimal representation of a single non-literal item.

+
§

Compound(&'a [BorrowedFormatItem<'a>])

A series of literals or components that collectively form a partial or complete +description.

+
§

Optional(&'a BorrowedFormatItem<'a>)

A FormatItem that may or may not be present when parsing. If parsing fails, there +will be no effect on the resulting struct.

+

This variant has no effect on formatting, as the value is guaranteed to be present.

+
§

First(&'a [BorrowedFormatItem<'a>])

A series of FormatItems where, when parsing, the first successful parse is used. When +formatting, the first element of the slice is used. An empty slice is a no-op when +formatting or parsing.

+

Trait Implementations§

§

impl<'a> Clone for BorrowedFormatItem<'a>

§

fn clone(&self) -> BorrowedFormatItem<'a>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for BorrowedFormatItem<'_>

Available on crate feature alloc only.
§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<'a> From<&'a [BorrowedFormatItem<'_>]> for BorrowedFormatItem<'a>

§

fn from(items: &'a [BorrowedFormatItem<'_>]) -> BorrowedFormatItem<'a>

Converts to this type from the input type.
§

impl From<&BorrowedFormatItem<'_>> for OwnedFormatItem

§

fn from(item: &BorrowedFormatItem<'_>) -> OwnedFormatItem

Converts to this type from the input type.
§

impl From<BorrowedFormatItem<'_>> for OwnedFormatItem

§

fn from(item: BorrowedFormatItem<'_>) -> OwnedFormatItem

Converts to this type from the input type.
§

impl From<Component> for BorrowedFormatItem<'_>

§

fn from(component: Component) -> BorrowedFormatItem<'_>

Converts to this type from the input type.
§

impl PartialEq<&[BorrowedFormatItem<'_>]> for BorrowedFormatItem<'_>

§

fn eq(&self, rhs: &&[BorrowedFormatItem<'_>]) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<BorrowedFormatItem<'_>> for &[BorrowedFormatItem<'_>]

§

fn eq(&self, rhs: &BorrowedFormatItem<'_>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<BorrowedFormatItem<'_>> for Component

§

fn eq(&self, rhs: &BorrowedFormatItem<'_>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<Component> for BorrowedFormatItem<'_>

§

fn eq(&self, rhs: &Component) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a> PartialEq for BorrowedFormatItem<'a>

§

fn eq(&self, other: &BorrowedFormatItem<'a>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl TryFrom<BorrowedFormatItem<'_>> for Component

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + value: BorrowedFormatItem<'_> +) -> Result<Component, <Component as TryFrom<BorrowedFormatItem<'_>>>::Error>

Performs the conversion.
§

impl<'a> TryFrom<BorrowedFormatItem<'a>> for &[BorrowedFormatItem<'a>]

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + value: BorrowedFormatItem<'a> +) -> Result<&[BorrowedFormatItem<'a>], <&[BorrowedFormatItem<'a>] as TryFrom<BorrowedFormatItem<'a>>>::Error>

Performs the conversion.
§

impl<'a> TryFrom<Item<'a>> for BorrowedFormatItem<'a>

§

type Error = Error

The type returned in the event of a conversion error.
§

fn try_from( + item: Item<'a> +) -> Result<BorrowedFormatItem<'a>, <BorrowedFormatItem<'a> as TryFrom<Item<'a>>>::Error>

Performs the conversion.
§

impl<'a> Eq for BorrowedFormatItem<'a>

§

impl Formattable for BorrowedFormatItem<'_>

§

impl Parsable for BorrowedFormatItem<'_>

§

impl<'a> StructuralPartialEq for BorrowedFormatItem<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for BorrowedFormatItem<'a>

§

impl<'a> RefUnwindSafe for BorrowedFormatItem<'a>

§

impl<'a> Send for BorrowedFormatItem<'a>

§

impl<'a> Sync for BorrowedFormatItem<'a>

§

impl<'a> Unpin for BorrowedFormatItem<'a>

§

impl<'a> UnwindSafe for BorrowedFormatItem<'a>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/enum.OwnedFormatItem.html b/actix_web/cookie/time/format_description/enum.OwnedFormatItem.html new file mode 100644 index 000000000..35299d6a9 --- /dev/null +++ b/actix_web/cookie/time/format_description/enum.OwnedFormatItem.html @@ -0,0 +1,56 @@ +OwnedFormatItem in actix_web::cookie::time::format_description - Rust
#[non_exhaustive]
pub enum OwnedFormatItem { + Literal(Box<[u8]>), + Component(Component), + Compound(Box<[OwnedFormatItem]>), + Optional(Box<OwnedFormatItem>), + First(Box<[OwnedFormatItem]>), +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

A complete description of how to format and parse a type.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Literal(Box<[u8]>)

Bytes that are formatted as-is.

+

Note: These bytes should be UTF-8, but are not required to be. The value is passed +through String::from_utf8_lossy when necessary.

+
§

Component(Component)

A minimal representation of a single non-literal item.

+
§

Compound(Box<[OwnedFormatItem]>)

A series of literals or components that collectively form a partial or complete +description.

+
§

Optional(Box<OwnedFormatItem>)

A FormatItem that may or may not be present when parsing. If parsing fails, there +will be no effect on the resulting struct.

+

This variant has no effect on formatting, as the value is guaranteed to be present.

+
§

First(Box<[OwnedFormatItem]>)

A series of FormatItems where, when parsing, the first successful parse is used. When +formatting, the first element of the Vec is used. An empty Vec is a no-op when +formatting or parsing.

+

Trait Implementations§

§

impl Clone for OwnedFormatItem

§

fn clone(&self) -> OwnedFormatItem

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for OwnedFormatItem

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl From<&BorrowedFormatItem<'_>> for OwnedFormatItem

§

fn from(item: &BorrowedFormatItem<'_>) -> OwnedFormatItem

Converts to this type from the input type.
§

impl<'a, T> From<&T> for OwnedFormatItem
where + T: AsRef<[BorrowedFormatItem<'a>]> + ?Sized,

§

fn from(items: &T) -> OwnedFormatItem

Converts to this type from the input type.
§

impl From<BorrowedFormatItem<'_>> for OwnedFormatItem

§

fn from(item: BorrowedFormatItem<'_>) -> OwnedFormatItem

Converts to this type from the input type.
§

impl<'a> From<Box<[Item<'a>]>> for OwnedFormatItem

§

fn from(items: Box<[Item<'a>]>) -> OwnedFormatItem

Converts to this type from the input type.
§

impl From<Component> for OwnedFormatItem

§

fn from(component: Component) -> OwnedFormatItem

Converts to this type from the input type.
§

impl From<Item<'_>> for OwnedFormatItem

§

fn from(item: Item<'_>) -> OwnedFormatItem

Converts to this type from the input type.
§

impl From<Vec<BorrowedFormatItem<'_>>> for OwnedFormatItem

§

fn from(items: Vec<BorrowedFormatItem<'_>>) -> OwnedFormatItem

Converts to this type from the input type.
§

impl From<Vec<OwnedFormatItem>> for OwnedFormatItem

§

fn from(items: Vec<OwnedFormatItem>) -> OwnedFormatItem

Converts to this type from the input type.
§

impl PartialEq<&[OwnedFormatItem]> for OwnedFormatItem

§

fn eq(&self, rhs: &&[OwnedFormatItem]) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<Component> for OwnedFormatItem

§

fn eq(&self, rhs: &Component) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<OwnedFormatItem> for &[OwnedFormatItem]

§

fn eq(&self, rhs: &OwnedFormatItem) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<OwnedFormatItem> for Component

§

fn eq(&self, rhs: &OwnedFormatItem) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq for OwnedFormatItem

§

fn eq(&self, other: &OwnedFormatItem) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl TryFrom<OwnedFormatItem> for Component

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + value: OwnedFormatItem +) -> Result<Component, <Component as TryFrom<OwnedFormatItem>>::Error>

Performs the conversion.
§

impl TryFrom<OwnedFormatItem> for Vec<OwnedFormatItem>

§

type Error = DifferentVariant

The type returned in the event of a conversion error.
§

fn try_from( + value: OwnedFormatItem +) -> Result<Vec<OwnedFormatItem>, <Vec<OwnedFormatItem> as TryFrom<OwnedFormatItem>>::Error>

Performs the conversion.
§

impl Eq for OwnedFormatItem

§

impl Formattable for OwnedFormatItem

§

impl Parsable for OwnedFormatItem

Available on crate feature alloc only.
§

impl StructuralPartialEq for OwnedFormatItem

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/fn.parse.html b/actix_web/cookie/time/format_description/fn.parse.html new file mode 100644 index 000000000..d7472193d --- /dev/null +++ b/actix_web/cookie/time/format_description/fn.parse.html @@ -0,0 +1,9 @@ +parse in actix_web::cookie::time::format_description - Rust

Function actix_web::cookie::time::format_description::parse

pub fn parse(
+    s: &str
+) -> Result<Vec<BorrowedFormatItem<'_>>, InvalidFormatDescription>
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Parse a sequence of items from the format description.

+

The syntax for the format description can be found in the +book.

+

This function exists for backward compatibility reasons. It is equivalent to calling +parse_borrowed::<1>(s). In the future, this function will be deprecated in favor of +parse_borrowed.

+
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/fn.parse_borrowed.html b/actix_web/cookie/time/format_description/fn.parse_borrowed.html new file mode 100644 index 000000000..e50d055ec --- /dev/null +++ b/actix_web/cookie/time/format_description/fn.parse_borrowed.html @@ -0,0 +1,7 @@ +parse_borrowed in actix_web::cookie::time::format_description - Rust

Function actix_web::cookie::time::format_description::parse_borrowed

pub fn parse_borrowed<const VERSION: usize>(
+    s: &str
+) -> Result<Vec<BorrowedFormatItem<'_>>, InvalidFormatDescription>
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Parse a sequence of items from the format description.

+

The syntax for the format description can be found in the +book. The version of the format +description is provided as the const parameter. It is recommended to use version 2.

+
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/fn.parse_owned.html b/actix_web/cookie/time/format_description/fn.parse_owned.html new file mode 100644 index 000000000..63f334ac7 --- /dev/null +++ b/actix_web/cookie/time/format_description/fn.parse_owned.html @@ -0,0 +1,9 @@ +parse_owned in actix_web::cookie::time::format_description - Rust

Function actix_web::cookie::time::format_description::parse_owned

pub fn parse_owned<const VERSION: usize>(
+    s: &str
+) -> Result<OwnedFormatItem, InvalidFormatDescription>
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Parse a sequence of items from the format description.

+

The syntax for the format description can be found in the +book. The version of the format +description is provided as the const parameter.

+

Unlike parse, this function returns OwnedFormatItem, which owns its contents. This means +that there is no lifetime that needs to be handled. It is recommended to use version 2.

+
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/index.html b/actix_web/cookie/time/format_description/index.html new file mode 100644 index 000000000..c33ecc483 --- /dev/null +++ b/actix_web/cookie/time/format_description/index.html @@ -0,0 +1,7 @@ +actix_web::cookie::time::format_description - Rust

Module actix_web::cookie::time::format_description

Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Description of how types should be formatted and parsed.

+

The formatted value will be output to the provided writer. Format descriptions can be +well-known or obtained by using the +format_description! macro or a function listed below.

+

For examples, see the implementors of Formattable, +e.g. well_known::Rfc3339.

+

Modules§

  • Various modifiers for components.
  • Well-known formats, typically standards.

Enums§

  • A complete description of how to format and parse a type.
  • A component of a larger format description.
  • A complete description of how to format and parse a type.
  • A complete description of how to format and parse a type.

Functions§

  • Parse a sequence of items from the format description.
  • Parse a sequence of items from the format description.
  • Parse a sequence of items from the format description.
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/enum.MonthRepr.html b/actix_web/cookie/time/format_description/modifier/enum.MonthRepr.html new file mode 100644 index 000000000..f5f82657d --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/enum.MonthRepr.html @@ -0,0 +1,34 @@ +MonthRepr in actix_web::cookie::time::format_description::modifier - Rust
#[non_exhaustive]
pub enum MonthRepr { + Numerical, + Long, + Short, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

The representation of a month.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Numerical

The number of the month (January is 1, December is 12).

+
§

Long

The long form of the month name (e.g. “January”).

+
§

Short

The short form of the month name (e.g. “Jan”).

+

Trait Implementations§

§

impl Clone for MonthRepr

§

fn clone(&self) -> MonthRepr

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for MonthRepr

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for MonthRepr

Creates a modifier that indicates the value uses the +Numerical representation.

+
§

fn default() -> MonthRepr

Returns the “default value” for a type. Read more
§

impl From<MonthRepr> for MonthRepr

§

fn from(modifier: MonthRepr) -> MonthRepr

Converts to this type from the input type.
§

impl PartialEq for MonthRepr

§

fn eq(&self, other: &MonthRepr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for MonthRepr

§

impl Eq for MonthRepr

§

impl StructuralPartialEq for MonthRepr

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/enum.Padding.html b/actix_web/cookie/time/format_description/modifier/enum.Padding.html new file mode 100644 index 000000000..86538da1a --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/enum.Padding.html @@ -0,0 +1,34 @@ +Padding in actix_web::cookie::time::format_description::modifier - Rust
#[non_exhaustive]
pub enum Padding { + Space, + Zero, + None, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Type of padding to ensure a minimum width.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Space

A space character ( ) should be used as padding.

+
§

Zero

A zero character (0) should be used as padding.

+
§

None

There is no padding. This can result in a width below the otherwise minimum number of +characters.

+

Trait Implementations§

§

impl Clone for Padding

§

fn clone(&self) -> Padding

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Padding

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for Padding

Creates a modifier that indicates the value is padded with zeroes.

+
§

fn default() -> Padding

Returns the “default value” for a type. Read more
§

impl From<Padding> for Padding

§

fn from(modifier: Padding) -> Padding

Converts to this type from the input type.
§

impl PartialEq for Padding

§

fn eq(&self, other: &Padding) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for Padding

§

impl Eq for Padding

§

impl StructuralPartialEq for Padding

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/enum.SubsecondDigits.html b/actix_web/cookie/time/format_description/modifier/enum.SubsecondDigits.html new file mode 100644 index 000000000..9f6f9f462 --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/enum.SubsecondDigits.html @@ -0,0 +1,49 @@ +SubsecondDigits in actix_web::cookie::time::format_description::modifier - Rust
#[non_exhaustive]
pub enum SubsecondDigits { + One, + Two, + Three, + Four, + Five, + Six, + Seven, + Eight, + Nine, + OneOrMore, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

The number of digits present in a subsecond representation.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

One

Exactly one digit.

+
§

Two

Exactly two digits.

+
§

Three

Exactly three digits.

+
§

Four

Exactly four digits.

+
§

Five

Exactly five digits.

+
§

Six

Exactly six digits.

+
§

Seven

Exactly seven digits.

+
§

Eight

Exactly eight digits.

+
§

Nine

Exactly nine digits.

+
§

OneOrMore

Any number of digits (up to nine) that is at least one. When formatting, the minimum digits +necessary will be used.

+

Trait Implementations§

§

impl Clone for SubsecondDigits

§

fn clone(&self) -> SubsecondDigits

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for SubsecondDigits

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for SubsecondDigits

Creates a modifier that indicates the stringified value contains one or more +digits.

+
§

fn default() -> SubsecondDigits

Returns the “default value” for a type. Read more
§

impl From<SubsecondDigits> for SubsecondDigits

§

fn from(modifier: SubsecondDigits) -> SubsecondDigits

Converts to this type from the input type.
§

impl PartialEq for SubsecondDigits

§

fn eq(&self, other: &SubsecondDigits) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for SubsecondDigits

§

impl Eq for SubsecondDigits

§

impl StructuralPartialEq for SubsecondDigits

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/enum.UnixTimestampPrecision.html b/actix_web/cookie/time/format_description/modifier/enum.UnixTimestampPrecision.html new file mode 100644 index 000000000..697821d8d --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/enum.UnixTimestampPrecision.html @@ -0,0 +1,36 @@ +UnixTimestampPrecision in actix_web::cookie::time::format_description::modifier - Rust
#[non_exhaustive]
pub enum UnixTimestampPrecision { + Second, + Millisecond, + Microsecond, + Nanosecond, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

The precision of a Unix timestamp.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Second

Seconds since the Unix epoch.

+
§

Millisecond

Milliseconds since the Unix epoch.

+
§

Microsecond

Microseconds since the Unix epoch.

+
§

Nanosecond

Nanoseconds since the Unix epoch.

+

Trait Implementations§

§

impl Clone for UnixTimestampPrecision

§

fn clone(&self) -> UnixTimestampPrecision

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for UnixTimestampPrecision

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for UnixTimestampPrecision

Creates a modifier that indicates the value represents the number of seconds +since the Unix epoch.

+
§

fn default() -> UnixTimestampPrecision

Returns the “default value” for a type. Read more
§

impl From<UnixTimestampPrecision> for UnixTimestampPrecision

§

fn from(modifier: UnixTimestampPrecision) -> UnixTimestampPrecision

Converts to this type from the input type.
§

impl PartialEq for UnixTimestampPrecision

§

fn eq(&self, other: &UnixTimestampPrecision) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for UnixTimestampPrecision

§

impl Eq for UnixTimestampPrecision

§

impl StructuralPartialEq for UnixTimestampPrecision

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/enum.WeekNumberRepr.html b/actix_web/cookie/time/format_description/modifier/enum.WeekNumberRepr.html new file mode 100644 index 000000000..05407ac24 --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/enum.WeekNumberRepr.html @@ -0,0 +1,33 @@ +WeekNumberRepr in actix_web::cookie::time::format_description::modifier - Rust
#[non_exhaustive]
pub enum WeekNumberRepr { + Iso, + Sunday, + Monday, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

The representation used for the week number.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Iso

Week 1 is the week that contains January 4.

+
§

Sunday

Week 1 begins on the first Sunday of the calendar year.

+
§

Monday

Week 1 begins on the first Monday of the calendar year.

+

Trait Implementations§

§

impl Clone for WeekNumberRepr

§

fn clone(&self) -> WeekNumberRepr

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for WeekNumberRepr

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for WeekNumberRepr

Creates a modifier that indicates that the value uses the Iso representation.

+
§

fn default() -> WeekNumberRepr

Returns the “default value” for a type. Read more
§

impl From<WeekNumberRepr> for WeekNumberRepr

§

fn from(modifier: WeekNumberRepr) -> WeekNumberRepr

Converts to this type from the input type.
§

impl PartialEq for WeekNumberRepr

§

fn eq(&self, other: &WeekNumberRepr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for WeekNumberRepr

§

impl Eq for WeekNumberRepr

§

impl StructuralPartialEq for WeekNumberRepr

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/enum.WeekdayRepr.html b/actix_web/cookie/time/format_description/modifier/enum.WeekdayRepr.html new file mode 100644 index 000000000..24a8e5c63 --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/enum.WeekdayRepr.html @@ -0,0 +1,37 @@ +WeekdayRepr in actix_web::cookie::time::format_description::modifier - Rust
#[non_exhaustive]
pub enum WeekdayRepr { + Short, + Long, + Sunday, + Monday, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

The representation used for the day of the week.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Short

The short form of the weekday (e.g. “Mon”).

+
§

Long

The long form of the weekday (e.g. “Monday”).

+
§

Sunday

A numerical representation using Sunday as the first day of the week.

+

Sunday is either 0 or 1, depending on the other modifier’s value.

+
§

Monday

A numerical representation using Monday as the first day of the week.

+

Monday is either 0 or 1, depending on the other modifier’s value.

+

Trait Implementations§

§

impl Clone for WeekdayRepr

§

fn clone(&self) -> WeekdayRepr

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for WeekdayRepr

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for WeekdayRepr

Creates a modifier that indicates the value uses the Long representation.

+
§

fn default() -> WeekdayRepr

Returns the “default value” for a type. Read more
§

impl From<WeekdayRepr> for WeekdayRepr

§

fn from(modifier: WeekdayRepr) -> WeekdayRepr

Converts to this type from the input type.
§

impl PartialEq for WeekdayRepr

§

fn eq(&self, other: &WeekdayRepr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for WeekdayRepr

§

impl Eq for WeekdayRepr

§

impl StructuralPartialEq for WeekdayRepr

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/enum.YearRepr.html b/actix_web/cookie/time/format_description/modifier/enum.YearRepr.html new file mode 100644 index 000000000..1822931f0 --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/enum.YearRepr.html @@ -0,0 +1,31 @@ +YearRepr in actix_web::cookie::time::format_description::modifier - Rust
#[non_exhaustive]
pub enum YearRepr { + Full, + LastTwo, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

The representation used for a year value.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Full

The full value of the year.

+
§

LastTwo

Only the last two digits of the year.

+

Trait Implementations§

§

impl Clone for YearRepr

§

fn clone(&self) -> YearRepr

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for YearRepr

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for YearRepr

Creates a modifier that indicates the value uses the Full representation.

+
§

fn default() -> YearRepr

Returns the “default value” for a type. Read more
§

impl From<YearRepr> for YearRepr

§

fn from(modifier: YearRepr) -> YearRepr

Converts to this type from the input type.
§

impl PartialEq for YearRepr

§

fn eq(&self, other: &YearRepr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for YearRepr

§

impl Eq for YearRepr

§

impl StructuralPartialEq for YearRepr

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/index.html b/actix_web/cookie/time/format_description/modifier/index.html new file mode 100644 index 000000000..d968c71b0 --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/index.html @@ -0,0 +1,2 @@ +actix_web::cookie::time::format_description::modifier - Rust

Module actix_web::cookie::time::format_description::modifier

Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Various modifiers for components.

+

Structs§

Enums§

\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/sidebar-items.js b/actix_web/cookie/time/format_description/modifier/sidebar-items.js new file mode 100644 index 000000000..392b09c8a --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["MonthRepr","Padding","SubsecondDigits","UnixTimestampPrecision","WeekNumberRepr","WeekdayRepr","YearRepr"],"struct":["Day","End","Hour","Ignore","Minute","Month","OffsetHour","OffsetMinute","OffsetSecond","Ordinal","Period","Second","Subsecond","UnixTimestamp","WeekNumber","Weekday","Year"]}; \ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/struct.Day.html b/actix_web/cookie/time/format_description/modifier/struct.Day.html new file mode 100644 index 000000000..e2f360db5 --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/struct.Day.html @@ -0,0 +1,35 @@ +Day in actix_web::cookie::time::format_description::modifier - Rust

Struct actix_web::cookie::time::format_description::modifier::Day

#[non_exhaustive]
pub struct Day { + pub padding: Padding, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Day of the month.

+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§padding: Padding

The padding to obtain the minimum width.

+

Implementations§

§

impl Day

pub const fn default() -> Day

Creates a modifier that indicates the value is padded with zeroes.

+

This function exists since Default::default() cannot be used in a const context. +It may be removed once that becomes possible. As the Default trait is in the +prelude, removing this function in the future will not cause any resolution failures for +the overwhelming majority of users; only users who use #![no_implicit_prelude] will be +affected. As such it will not be considered a breaking change.

+

Trait Implementations§

§

impl Clone for Day

§

fn clone(&self) -> Day

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Day

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for Day

Creates a modifier that indicates the value is padded with zeroes.

+
§

fn default() -> Day

Returns the “default value” for a type. Read more
§

impl PartialEq for Day

§

fn eq(&self, other: &Day) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for Day

§

impl Eq for Day

§

impl StructuralPartialEq for Day

Auto Trait Implementations§

§

impl Freeze for Day

§

impl RefUnwindSafe for Day

§

impl Send for Day

§

impl Sync for Day

§

impl Unpin for Day

§

impl UnwindSafe for Day

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/struct.End.html b/actix_web/cookie/time/format_description/modifier/struct.End.html new file mode 100644 index 000000000..c99b40721 --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/struct.End.html @@ -0,0 +1,33 @@ +End in actix_web::cookie::time::format_description::modifier - Rust

Struct actix_web::cookie::time::format_description::modifier::End

#[non_exhaustive]
pub struct End;
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

The end of input.

+

There is currently not customization for this modifier.

+

Implementations§

§

impl End

pub const fn default() -> End

Creates a modifier used to represent the end of input.

+

This function exists since Default::default() cannot be used in a const context. +It may be removed once that becomes possible. As the Default trait is in the +prelude, removing this function in the future will not cause any resolution failures for +the overwhelming majority of users; only users who use #![no_implicit_prelude] will be +affected. As such it will not be considered a breaking change.

+

Trait Implementations§

§

impl Clone for End

§

fn clone(&self) -> End

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for End

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for End

Creates a modifier used to represent the end of input.

+
§

fn default() -> End

Returns the “default value” for a type. Read more
§

impl PartialEq for End

§

fn eq(&self, other: &End) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for End

§

impl Eq for End

§

impl StructuralPartialEq for End

Auto Trait Implementations§

§

impl Freeze for End

§

impl RefUnwindSafe for End

§

impl Send for End

§

impl Sync for End

§

impl Unpin for End

§

impl UnwindSafe for End

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/struct.Hour.html b/actix_web/cookie/time/format_description/modifier/struct.Hour.html new file mode 100644 index 000000000..00d8834f1 --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/struct.Hour.html @@ -0,0 +1,39 @@ +Hour in actix_web::cookie::time::format_description::modifier - Rust

Struct actix_web::cookie::time::format_description::modifier::Hour

#[non_exhaustive]
pub struct Hour { + pub padding: Padding, + pub is_12_hour_clock: bool, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Hour of the day.

+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§padding: Padding

The padding to obtain the minimum width.

+
§is_12_hour_clock: bool

Is the hour displayed using a 12 or 24-hour clock?

+

Implementations§

§

impl Hour

pub const fn default() -> Hour

Creates a modifier that indicates the value is padded with zeroes and +has the 24-hour representation.

+

This function exists since Default::default() cannot be used in a const context. +It may be removed once that becomes possible. As the Default trait is in the +prelude, removing this function in the future will not cause any resolution failures for +the overwhelming majority of users; only users who use #![no_implicit_prelude] will be +affected. As such it will not be considered a breaking change.

+

Trait Implementations§

§

impl Clone for Hour

§

fn clone(&self) -> Hour

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Hour

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for Hour

Creates a modifier that indicates the value is padded with zeroes and +has the 24-hour representation.

+
§

fn default() -> Hour

Returns the “default value” for a type. Read more
§

impl PartialEq for Hour

§

fn eq(&self, other: &Hour) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for Hour

§

impl Eq for Hour

§

impl StructuralPartialEq for Hour

Auto Trait Implementations§

§

impl Freeze for Hour

§

impl RefUnwindSafe for Hour

§

impl Send for Hour

§

impl Sync for Hour

§

impl Unpin for Hour

§

impl UnwindSafe for Hour

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/struct.Ignore.html b/actix_web/cookie/time/format_description/modifier/struct.Ignore.html new file mode 100644 index 000000000..743b57d2e --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/struct.Ignore.html @@ -0,0 +1,30 @@ +Ignore in actix_web::cookie::time::format_description::modifier - Rust

Struct actix_web::cookie::time::format_description::modifier::Ignore

#[non_exhaustive]
pub struct Ignore { + pub count: NonZero<u16>, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Ignore some number of bytes.

+

This has no effect when formatting.

+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§count: NonZero<u16>

The number of bytes to ignore.

+

Implementations§

§

impl Ignore

pub const fn count(count: NonZero<u16>) -> Ignore

Create an instance of Ignore with the provided number of bytes to ignore.

+

Trait Implementations§

§

impl Clone for Ignore

§

fn clone(&self) -> Ignore

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Ignore

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl PartialEq for Ignore

§

fn eq(&self, other: &Ignore) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for Ignore

§

impl Eq for Ignore

§

impl StructuralPartialEq for Ignore

Auto Trait Implementations§

§

impl Freeze for Ignore

§

impl RefUnwindSafe for Ignore

§

impl Send for Ignore

§

impl Sync for Ignore

§

impl Unpin for Ignore

§

impl UnwindSafe for Ignore

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/struct.Minute.html b/actix_web/cookie/time/format_description/modifier/struct.Minute.html new file mode 100644 index 000000000..183555fda --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/struct.Minute.html @@ -0,0 +1,35 @@ +Minute in actix_web::cookie::time::format_description::modifier - Rust

Struct actix_web::cookie::time::format_description::modifier::Minute

#[non_exhaustive]
pub struct Minute { + pub padding: Padding, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Minute within the hour.

+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§padding: Padding

The padding to obtain the minimum width.

+

Implementations§

§

impl Minute

pub const fn default() -> Minute

Creates a modifier that indicates the value is padded with zeroes.

+

This function exists since Default::default() cannot be used in a const context. +It may be removed once that becomes possible. As the Default trait is in the +prelude, removing this function in the future will not cause any resolution failures for +the overwhelming majority of users; only users who use #![no_implicit_prelude] will be +affected. As such it will not be considered a breaking change.

+

Trait Implementations§

§

impl Clone for Minute

§

fn clone(&self) -> Minute

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Minute

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for Minute

Creates a modifier that indicates the value is padded with zeroes.

+
§

fn default() -> Minute

Returns the “default value” for a type. Read more
§

impl PartialEq for Minute

§

fn eq(&self, other: &Minute) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for Minute

§

impl Eq for Minute

§

impl StructuralPartialEq for Minute

Auto Trait Implementations§

§

impl Freeze for Minute

§

impl RefUnwindSafe for Minute

§

impl Send for Minute

§

impl Sync for Minute

§

impl Unpin for Minute

§

impl UnwindSafe for Minute

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/struct.Month.html b/actix_web/cookie/time/format_description/modifier/struct.Month.html new file mode 100644 index 000000000..6b84b58d8 --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/struct.Month.html @@ -0,0 +1,43 @@ +Month in actix_web::cookie::time::format_description::modifier - Rust

Struct actix_web::cookie::time::format_description::modifier::Month

#[non_exhaustive]
pub struct Month { + pub padding: Padding, + pub repr: MonthRepr, + pub case_sensitive: bool, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Month of the year.

+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§padding: Padding

The padding to obtain the minimum width.

+
§repr: MonthRepr

What form of representation should be used?

+
§case_sensitive: bool

Is the value case sensitive when parsing?

+

Implementations§

§

impl Month

pub const fn default() -> Month

Creates an instance of this type that indicates the value uses the +Numerical representation, is padded with zeroes, +and is case-sensitive when parsing.

+

This function exists since Default::default() cannot be used in a const context. +It may be removed once that becomes possible. As the Default trait is in the +prelude, removing this function in the future will not cause any resolution failures for +the overwhelming majority of users; only users who use #![no_implicit_prelude] will be +affected. As such it will not be considered a breaking change.

+

Trait Implementations§

§

impl Clone for Month

§

fn clone(&self) -> Month

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Month

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for Month

Creates an instance of this type that indicates the value uses the +Numerical representation, is padded with zeroes, +and is case-sensitive when parsing.

+
§

fn default() -> Month

Returns the “default value” for a type. Read more
§

impl PartialEq for Month

§

fn eq(&self, other: &Month) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for Month

§

impl Eq for Month

§

impl StructuralPartialEq for Month

Auto Trait Implementations§

§

impl Freeze for Month

§

impl RefUnwindSafe for Month

§

impl Send for Month

§

impl Sync for Month

§

impl Unpin for Month

§

impl UnwindSafe for Month

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/struct.OffsetHour.html b/actix_web/cookie/time/format_description/modifier/struct.OffsetHour.html new file mode 100644 index 000000000..b141022f4 --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/struct.OffsetHour.html @@ -0,0 +1,39 @@ +OffsetHour in actix_web::cookie::time::format_description::modifier - Rust
#[non_exhaustive]
pub struct OffsetHour { + pub sign_is_mandatory: bool, + pub padding: Padding, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Hour of the UTC offset.

+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§sign_is_mandatory: bool

Whether the + sign is present on positive values.

+
§padding: Padding

The padding to obtain the minimum width.

+

Implementations§

§

impl OffsetHour

pub const fn default() -> OffsetHour

Creates a modifier that indicates the value only uses a sign for negative values and is +padded with zeroes.

+

This function exists since Default::default() cannot be used in a const context. +It may be removed once that becomes possible. As the Default trait is in the +prelude, removing this function in the future will not cause any resolution failures for +the overwhelming majority of users; only users who use #![no_implicit_prelude] will be +affected. As such it will not be considered a breaking change.

+

Trait Implementations§

§

impl Clone for OffsetHour

§

fn clone(&self) -> OffsetHour

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for OffsetHour

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for OffsetHour

Creates a modifier that indicates the value only uses a sign for negative values and is +padded with zeroes.

+
§

fn default() -> OffsetHour

Returns the “default value” for a type. Read more
§

impl PartialEq for OffsetHour

§

fn eq(&self, other: &OffsetHour) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for OffsetHour

§

impl Eq for OffsetHour

§

impl StructuralPartialEq for OffsetHour

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/struct.OffsetMinute.html b/actix_web/cookie/time/format_description/modifier/struct.OffsetMinute.html new file mode 100644 index 000000000..28ba6f494 --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/struct.OffsetMinute.html @@ -0,0 +1,35 @@ +OffsetMinute in actix_web::cookie::time::format_description::modifier - Rust
#[non_exhaustive]
pub struct OffsetMinute { + pub padding: Padding, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Minute within the hour of the UTC offset.

+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§padding: Padding

The padding to obtain the minimum width.

+

Implementations§

§

impl OffsetMinute

pub const fn default() -> OffsetMinute

Creates a modifier that indicates the value is padded with zeroes.

+

This function exists since Default::default() cannot be used in a const context. +It may be removed once that becomes possible. As the Default trait is in the +prelude, removing this function in the future will not cause any resolution failures for +the overwhelming majority of users; only users who use #![no_implicit_prelude] will be +affected. As such it will not be considered a breaking change.

+

Trait Implementations§

§

impl Clone for OffsetMinute

§

fn clone(&self) -> OffsetMinute

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for OffsetMinute

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for OffsetMinute

Creates a modifier that indicates the value is padded with zeroes.

+
§

fn default() -> OffsetMinute

Returns the “default value” for a type. Read more
§

impl PartialEq for OffsetMinute

§

fn eq(&self, other: &OffsetMinute) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for OffsetMinute

§

impl Eq for OffsetMinute

§

impl StructuralPartialEq for OffsetMinute

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/struct.OffsetSecond.html b/actix_web/cookie/time/format_description/modifier/struct.OffsetSecond.html new file mode 100644 index 000000000..bb68e00e9 --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/struct.OffsetSecond.html @@ -0,0 +1,35 @@ +OffsetSecond in actix_web::cookie::time::format_description::modifier - Rust
#[non_exhaustive]
pub struct OffsetSecond { + pub padding: Padding, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Second within the minute of the UTC offset.

+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§padding: Padding

The padding to obtain the minimum width.

+

Implementations§

§

impl OffsetSecond

pub const fn default() -> OffsetSecond

Creates a modifier that indicates the value is padded with zeroes.

+

This function exists since Default::default() cannot be used in a const context. +It may be removed once that becomes possible. As the Default trait is in the +prelude, removing this function in the future will not cause any resolution failures for +the overwhelming majority of users; only users who use #![no_implicit_prelude] will be +affected. As such it will not be considered a breaking change.

+

Trait Implementations§

§

impl Clone for OffsetSecond

§

fn clone(&self) -> OffsetSecond

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for OffsetSecond

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for OffsetSecond

Creates a modifier that indicates the value is padded with zeroes.

+
§

fn default() -> OffsetSecond

Returns the “default value” for a type. Read more
§

impl PartialEq for OffsetSecond

§

fn eq(&self, other: &OffsetSecond) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for OffsetSecond

§

impl Eq for OffsetSecond

§

impl StructuralPartialEq for OffsetSecond

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/struct.Ordinal.html b/actix_web/cookie/time/format_description/modifier/struct.Ordinal.html new file mode 100644 index 000000000..8c51999ca --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/struct.Ordinal.html @@ -0,0 +1,35 @@ +Ordinal in actix_web::cookie::time::format_description::modifier - Rust

Struct actix_web::cookie::time::format_description::modifier::Ordinal

#[non_exhaustive]
pub struct Ordinal { + pub padding: Padding, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Ordinal day of the year.

+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§padding: Padding

The padding to obtain the minimum width.

+

Implementations§

§

impl Ordinal

pub const fn default() -> Ordinal

Creates a modifier that indicates the value is padded with zeroes.

+

This function exists since Default::default() cannot be used in a const context. +It may be removed once that becomes possible. As the Default trait is in the +prelude, removing this function in the future will not cause any resolution failures for +the overwhelming majority of users; only users who use #![no_implicit_prelude] will be +affected. As such it will not be considered a breaking change.

+

Trait Implementations§

§

impl Clone for Ordinal

§

fn clone(&self) -> Ordinal

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Ordinal

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for Ordinal

Creates a modifier that indicates the value is padded with zeroes.

+
§

fn default() -> Ordinal

Returns the “default value” for a type. Read more
§

impl PartialEq for Ordinal

§

fn eq(&self, other: &Ordinal) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for Ordinal

§

impl Eq for Ordinal

§

impl StructuralPartialEq for Ordinal

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/struct.Period.html b/actix_web/cookie/time/format_description/modifier/struct.Period.html new file mode 100644 index 000000000..6bb74a729 --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/struct.Period.html @@ -0,0 +1,40 @@ +Period in actix_web::cookie::time::format_description::modifier - Rust

Struct actix_web::cookie::time::format_description::modifier::Period

#[non_exhaustive]
pub struct Period { + pub is_uppercase: bool, + pub case_sensitive: bool, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

AM/PM part of the time.

+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§is_uppercase: bool

Is the period uppercase or lowercase?

+
§case_sensitive: bool

Is the value case sensitive when parsing?

+

Note that when false, the is_uppercase field has no effect on parsing behavior.

+

Implementations§

§

impl Period

pub const fn default() -> Period

Creates a modifier that indicates the value uses the upper-case representation and is +case-sensitive when parsing.

+

This function exists since Default::default() cannot be used in a const context. +It may be removed once that becomes possible. As the Default trait is in the +prelude, removing this function in the future will not cause any resolution failures for +the overwhelming majority of users; only users who use #![no_implicit_prelude] will be +affected. As such it will not be considered a breaking change.

+

Trait Implementations§

§

impl Clone for Period

§

fn clone(&self) -> Period

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Period

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for Period

Creates a modifier that indicates the value uses the upper-case representation and is +case-sensitive when parsing.

+
§

fn default() -> Period

Returns the “default value” for a type. Read more
§

impl PartialEq for Period

§

fn eq(&self, other: &Period) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for Period

§

impl Eq for Period

§

impl StructuralPartialEq for Period

Auto Trait Implementations§

§

impl Freeze for Period

§

impl RefUnwindSafe for Period

§

impl Send for Period

§

impl Sync for Period

§

impl Unpin for Period

§

impl UnwindSafe for Period

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/struct.Second.html b/actix_web/cookie/time/format_description/modifier/struct.Second.html new file mode 100644 index 000000000..f29bd244f --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/struct.Second.html @@ -0,0 +1,35 @@ +Second in actix_web::cookie::time::format_description::modifier - Rust

Struct actix_web::cookie::time::format_description::modifier::Second

#[non_exhaustive]
pub struct Second { + pub padding: Padding, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Second within the minute.

+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§padding: Padding

The padding to obtain the minimum width.

+

Implementations§

§

impl Second

pub const fn default() -> Second

Creates a modifier that indicates the value is padded with zeroes.

+

This function exists since Default::default() cannot be used in a const context. +It may be removed once that becomes possible. As the Default trait is in the +prelude, removing this function in the future will not cause any resolution failures for +the overwhelming majority of users; only users who use #![no_implicit_prelude] will be +affected. As such it will not be considered a breaking change.

+

Trait Implementations§

§

impl Clone for Second

§

fn clone(&self) -> Second

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Second

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for Second

Creates a modifier that indicates the value is padded with zeroes.

+
§

fn default() -> Second

Returns the “default value” for a type. Read more
§

impl PartialEq for Second

§

fn eq(&self, other: &Second) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for Second

§

impl Eq for Second

§

impl StructuralPartialEq for Second

Auto Trait Implementations§

§

impl Freeze for Second

§

impl RefUnwindSafe for Second

§

impl Send for Second

§

impl Sync for Second

§

impl Unpin for Second

§

impl UnwindSafe for Second

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/struct.Subsecond.html b/actix_web/cookie/time/format_description/modifier/struct.Subsecond.html new file mode 100644 index 000000000..53b2ff4be --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/struct.Subsecond.html @@ -0,0 +1,37 @@ +Subsecond in actix_web::cookie::time::format_description::modifier - Rust

Struct actix_web::cookie::time::format_description::modifier::Subsecond

#[non_exhaustive]
pub struct Subsecond { + pub digits: SubsecondDigits, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Subsecond within the second.

+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§digits: SubsecondDigits

How many digits are present in the component?

+

Implementations§

§

impl Subsecond

pub const fn default() -> Subsecond

Creates a modifier that indicates the stringified value contains one or more +digits.

+

This function exists since Default::default() cannot be used in a const context. +It may be removed once that becomes possible. As the Default trait is in the +prelude, removing this function in the future will not cause any resolution failures for +the overwhelming majority of users; only users who use #![no_implicit_prelude] will be +affected. As such it will not be considered a breaking change.

+

Trait Implementations§

§

impl Clone for Subsecond

§

fn clone(&self) -> Subsecond

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Subsecond

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for Subsecond

Creates a modifier that indicates the stringified value contains one or more +digits.

+
§

fn default() -> Subsecond

Returns the “default value” for a type. Read more
§

impl PartialEq for Subsecond

§

fn eq(&self, other: &Subsecond) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for Subsecond

§

impl Eq for Subsecond

§

impl StructuralPartialEq for Subsecond

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/struct.UnixTimestamp.html b/actix_web/cookie/time/format_description/modifier/struct.UnixTimestamp.html new file mode 100644 index 000000000..7566d6682 --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/struct.UnixTimestamp.html @@ -0,0 +1,39 @@ +UnixTimestamp in actix_web::cookie::time::format_description::modifier - Rust
#[non_exhaustive]
pub struct UnixTimestamp { + pub precision: UnixTimestampPrecision, + pub sign_is_mandatory: bool, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

A Unix timestamp.

+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§precision: UnixTimestampPrecision

The precision of the timestamp.

+
§sign_is_mandatory: bool

Whether the + sign must be present for a non-negative timestamp.

+

Implementations§

§

impl UnixTimestamp

pub const fn default() -> UnixTimestamp

Creates a modifier that indicates the value represents the number of +seconds since the Unix epoch. The sign is not mandatory.

+

This function exists since Default::default() cannot be used in a const context. +It may be removed once that becomes possible. As the Default trait is in the +prelude, removing this function in the future will not cause any resolution failures for +the overwhelming majority of users; only users who use #![no_implicit_prelude] will be +affected. As such it will not be considered a breaking change.

+

Trait Implementations§

§

impl Clone for UnixTimestamp

§

fn clone(&self) -> UnixTimestamp

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for UnixTimestamp

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for UnixTimestamp

Creates a modifier that indicates the value represents the number of +seconds since the Unix epoch. The sign is not mandatory.

+
§

fn default() -> UnixTimestamp

Returns the “default value” for a type. Read more
§

impl PartialEq for UnixTimestamp

§

fn eq(&self, other: &UnixTimestamp) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for UnixTimestamp

§

impl Eq for UnixTimestamp

§

impl StructuralPartialEq for UnixTimestamp

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/struct.WeekNumber.html b/actix_web/cookie/time/format_description/modifier/struct.WeekNumber.html new file mode 100644 index 000000000..d71deb016 --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/struct.WeekNumber.html @@ -0,0 +1,39 @@ +WeekNumber in actix_web::cookie::time::format_description::modifier - Rust
#[non_exhaustive]
pub struct WeekNumber { + pub padding: Padding, + pub repr: WeekNumberRepr, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Week within the year.

+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§padding: Padding

The padding to obtain the minimum width.

+
§repr: WeekNumberRepr

What kind of representation should be used?

+

Implementations§

§

impl WeekNumber

pub const fn default() -> WeekNumber

Creates a modifier that indicates that the value is padded with zeroes +and uses the Iso representation.

+

This function exists since Default::default() cannot be used in a const context. +It may be removed once that becomes possible. As the Default trait is in the +prelude, removing this function in the future will not cause any resolution failures for +the overwhelming majority of users; only users who use #![no_implicit_prelude] will be +affected. As such it will not be considered a breaking change.

+

Trait Implementations§

§

impl Clone for WeekNumber

§

fn clone(&self) -> WeekNumber

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for WeekNumber

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for WeekNumber

Creates a modifier that indicates that the value is padded with zeroes +and uses the Iso representation.

+
§

fn default() -> WeekNumber

Returns the “default value” for a type. Read more
§

impl PartialEq for WeekNumber

§

fn eq(&self, other: &WeekNumber) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for WeekNumber

§

impl Eq for WeekNumber

§

impl StructuralPartialEq for WeekNumber

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/struct.Weekday.html b/actix_web/cookie/time/format_description/modifier/struct.Weekday.html new file mode 100644 index 000000000..152b99c7a --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/struct.Weekday.html @@ -0,0 +1,43 @@ +Weekday in actix_web::cookie::time::format_description::modifier - Rust

Struct actix_web::cookie::time::format_description::modifier::Weekday

#[non_exhaustive]
pub struct Weekday { + pub repr: WeekdayRepr, + pub one_indexed: bool, + pub case_sensitive: bool, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Day of the week.

+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§repr: WeekdayRepr

What form of representation should be used?

+
§one_indexed: bool

When using a numerical representation, should it be zero or one-indexed?

+
§case_sensitive: bool

Is the value case sensitive when parsing?

+

Implementations§

§

impl Weekday

pub const fn default() -> Weekday

Creates a modifier that indicates the value uses the Long +representation and is case-sensitive when parsing. If the representation is changed to a +numerical one, the instance defaults to one-based indexing.

+

This function exists since Default::default() cannot be used in a const context. +It may be removed once that becomes possible. As the Default trait is in the +prelude, removing this function in the future will not cause any resolution failures for +the overwhelming majority of users; only users who use #![no_implicit_prelude] will be +affected. As such it will not be considered a breaking change.

+

Trait Implementations§

§

impl Clone for Weekday

§

fn clone(&self) -> Weekday

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Weekday

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for Weekday

Creates a modifier that indicates the value uses the Long +representation and is case-sensitive when parsing. If the representation is changed to a +numerical one, the instance defaults to one-based indexing.

+
§

fn default() -> Weekday

Returns the “default value” for a type. Read more
§

impl PartialEq for Weekday

§

fn eq(&self, other: &Weekday) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for Weekday

§

impl Eq for Weekday

§

impl StructuralPartialEq for Weekday

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/modifier/struct.Year.html b/actix_web/cookie/time/format_description/modifier/struct.Year.html new file mode 100644 index 000000000..b71dcf5fb --- /dev/null +++ b/actix_web/cookie/time/format_description/modifier/struct.Year.html @@ -0,0 +1,45 @@ +Year in actix_web::cookie::time::format_description::modifier - Rust

Struct actix_web::cookie::time::format_description::modifier::Year

#[non_exhaustive]
pub struct Year { + pub padding: Padding, + pub repr: YearRepr, + pub iso_week_based: bool, + pub sign_is_mandatory: bool, +}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Year of the date.

+

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§padding: Padding

The padding to obtain the minimum width.

+
§repr: YearRepr

What kind of representation should be used?

+
§iso_week_based: bool

Whether the value is based on the ISO week number or the Gregorian calendar.

+
§sign_is_mandatory: bool

Whether the + sign is present when a positive year contains fewer than five digits.

+

Implementations§

§

impl Year

pub const fn default() -> Year

Creates a modifier that indicates the value uses the Full +representation, is padded with zeroes, uses the Gregorian calendar as its +base, and only includes the year’s sign if necessary.

+

This function exists since Default::default() cannot be used in a const context. +It may be removed once that becomes possible. As the Default trait is in the +prelude, removing this function in the future will not cause any resolution failures for +the overwhelming majority of users; only users who use #![no_implicit_prelude] will be +affected. As such it will not be considered a breaking change.

+

Trait Implementations§

§

impl Clone for Year

§

fn clone(&self) -> Year

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Year

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for Year

Creates a modifier that indicates the value uses the Full +representation, is padded with zeroes, uses the Gregorian calendar as its +base, and only includes the year’s sign if necessary.

+
§

fn default() -> Year

Returns the “default value” for a type. Read more
§

impl PartialEq for Year

§

fn eq(&self, other: &Year) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for Year

§

impl Eq for Year

§

impl StructuralPartialEq for Year

Auto Trait Implementations§

§

impl Freeze for Year

§

impl RefUnwindSafe for Year

§

impl Send for Year

§

impl Sync for Year

§

impl Unpin for Year

§

impl UnwindSafe for Year

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/sidebar-items.js b/actix_web/cookie/time/format_description/sidebar-items.js new file mode 100644 index 000000000..49ddc9e8e --- /dev/null +++ b/actix_web/cookie/time/format_description/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["BorrowedFormatItem","Component","FormatItem","OwnedFormatItem"],"fn":["parse","parse_borrowed","parse_owned"],"mod":["modifier","well_known"]}; \ No newline at end of file diff --git a/actix_web/cookie/time/format_description/well_known/index.html b/actix_web/cookie/time/format_description/well_known/index.html new file mode 100644 index 000000000..fd5b6aecc --- /dev/null +++ b/actix_web/cookie/time/format_description/well_known/index.html @@ -0,0 +1,2 @@ +actix_web::cookie::time::format_description::well_known - Rust

Module actix_web::cookie::time::format_description::well_known

Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Well-known formats, typically standards.

+

Modules§

  • The format described in ISO 8601.

Structs§

\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/well_known/iso8601/enum.DateKind.html b/actix_web/cookie/time/format_description/well_known/iso8601/enum.DateKind.html new file mode 100644 index 000000000..b107cfbb2 --- /dev/null +++ b/actix_web/cookie/time/format_description/well_known/iso8601/enum.DateKind.html @@ -0,0 +1,32 @@ +DateKind in actix_web::cookie::time::format_description::well_known::iso8601 - Rust
pub enum DateKind {
+    Calendar,
+    Week,
+    Ordinal,
+}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Which format to use for the date.

+

Variants§

§

Calendar

Use the year-month-day format.

+
§

Week

Use the year-week-weekday format.

+
§

Ordinal

Use the week-ordinal format.

+

Trait Implementations§

§

impl Clone for DateKind

§

fn clone(&self) -> DateKind

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for DateKind

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl PartialEq for DateKind

§

fn eq(&self, other: &DateKind) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for DateKind

§

impl Eq for DateKind

§

impl StructuralPartialEq for DateKind

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/well_known/iso8601/enum.FormattedComponents.html b/actix_web/cookie/time/format_description/well_known/iso8601/enum.FormattedComponents.html new file mode 100644 index 000000000..f17ac2ff1 --- /dev/null +++ b/actix_web/cookie/time/format_description/well_known/iso8601/enum.FormattedComponents.html @@ -0,0 +1,41 @@ +FormattedComponents in actix_web::cookie::time::format_description::well_known::iso8601 - Rust
pub enum FormattedComponents {
+    None,
+    Date,
+    Time,
+    Offset,
+    DateTime,
+    DateTimeOffset,
+    TimeOffset,
+}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Which components to format.

+

Variants§

§

None

The configuration can only be used for parsing. Using this to format a value is +unspecified behavior.

+
§

Date

Format only the date.

+
§

Time

Format only the time.

+
§

Offset

Format only the UTC offset.

+
§

DateTime

Format the date and time.

+
§

DateTimeOffset

Format the date, time, and UTC offset.

+
§

TimeOffset

Format the time and UTC offset.

+

Trait Implementations§

§

impl Clone for FormattedComponents

§

fn clone(&self) -> FormattedComponents

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for FormattedComponents

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl PartialEq for FormattedComponents

§

fn eq(&self, other: &FormattedComponents) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for FormattedComponents

§

impl Eq for FormattedComponents

§

impl StructuralPartialEq for FormattedComponents

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/well_known/iso8601/enum.OffsetPrecision.html b/actix_web/cookie/time/format_description/well_known/iso8601/enum.OffsetPrecision.html new file mode 100644 index 000000000..724e2e8e7 --- /dev/null +++ b/actix_web/cookie/time/format_description/well_known/iso8601/enum.OffsetPrecision.html @@ -0,0 +1,30 @@ +OffsetPrecision in actix_web::cookie::time::format_description::well_known::iso8601 - Rust
pub enum OffsetPrecision {
+    Hour,
+    Minute,
+}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

The precision for the UTC offset.

+

Variants§

§

Hour

Format only the offset hour. Requires the offset minute to be zero.

+
§

Minute

Format both the offset hour and minute.

+

Trait Implementations§

§

impl Clone for OffsetPrecision

§

fn clone(&self) -> OffsetPrecision

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for OffsetPrecision

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl PartialEq for OffsetPrecision

§

fn eq(&self, other: &OffsetPrecision) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for OffsetPrecision

§

impl Eq for OffsetPrecision

§

impl StructuralPartialEq for OffsetPrecision

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/well_known/iso8601/enum.TimePrecision.html b/actix_web/cookie/time/format_description/well_known/iso8601/enum.TimePrecision.html new file mode 100644 index 000000000..55b71cd92 --- /dev/null +++ b/actix_web/cookie/time/format_description/well_known/iso8601/enum.TimePrecision.html @@ -0,0 +1,41 @@ +TimePrecision in actix_web::cookie::time::format_description::well_known::iso8601 - Rust
pub enum TimePrecision {
+    Hour {
+        decimal_digits: Option<NonZero<u8>>,
+    },
+    Minute {
+        decimal_digits: Option<NonZero<u8>>,
+    },
+    Second {
+        decimal_digits: Option<NonZero<u8>>,
+    },
+}
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

The precision and number of decimal digits present for the time.

+

Variants§

§

Hour

Format the hour only. Minutes, seconds, and nanoseconds will be represented with the +specified number of decimal digits, if any.

+

Fields

§decimal_digits: Option<NonZero<u8>>
§

Minute

Format the hour and minute. Seconds and nanoseconds will be represented with the specified +number of decimal digits, if any.

+

Fields

§decimal_digits: Option<NonZero<u8>>
§

Second

Format the hour, minute, and second. Nanoseconds will be represented with the specified +number of decimal digits, if any.

+

Fields

§decimal_digits: Option<NonZero<u8>>

Trait Implementations§

§

impl Clone for TimePrecision

§

fn clone(&self) -> TimePrecision

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for TimePrecision

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl PartialEq for TimePrecision

§

fn eq(&self, other: &TimePrecision) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for TimePrecision

§

impl Eq for TimePrecision

§

impl StructuralPartialEq for TimePrecision

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/well_known/iso8601/index.html b/actix_web/cookie/time/format_description/well_known/iso8601/index.html new file mode 100644 index 000000000..d783222e2 --- /dev/null +++ b/actix_web/cookie/time/format_description/well_known/iso8601/index.html @@ -0,0 +1,2 @@ +actix_web::cookie::time::format_description::well_known::iso8601 - Rust

Module actix_web::cookie::time::format_description::well_known::iso8601

Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

The format described in ISO 8601.

+

Structs§

Enums§

Type Aliases§

\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/well_known/iso8601/sidebar-items.js b/actix_web/cookie/time/format_description/well_known/iso8601/sidebar-items.js new file mode 100644 index 000000000..0797cf48e --- /dev/null +++ b/actix_web/cookie/time/format_description/well_known/iso8601/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["DateKind","FormattedComponents","OffsetPrecision","TimePrecision"],"struct":["Config","Iso8601"],"type":["EncodedConfig"]}; \ No newline at end of file diff --git a/actix_web/cookie/time/format_description/well_known/iso8601/struct.Config.html b/actix_web/cookie/time/format_description/well_known/iso8601/struct.Config.html new file mode 100644 index 000000000..f161207eb --- /dev/null +++ b/actix_web/cookie/time/format_description/well_known/iso8601/struct.Config.html @@ -0,0 +1,45 @@ +Config in actix_web::cookie::time::format_description::well_known::iso8601 - Rust
pub struct Config { /* private fields */ }
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

Configuration for Iso8601.

+

Implementations§

§

impl Config

pub const fn encode(&self) -> u128

Encode the configuration, permitting it to be used as a const parameter of Iso8601.

+

The value returned by this method must only be used as a const parameter to Iso8601. Any +other usage is unspecified behavior.

+
§

impl Config

pub const DEFAULT: Config = _

A configuration for the Iso8601 format.

+

The following is the default behavior:

+
    +
  • The configuration can be used for both formatting and parsing.
  • +
  • The date, time, and UTC offset are all formatted.
  • +
  • Separators (such as - and :) are included.
  • +
  • The year contains four digits, such that the year must be between 0 and 9999.
  • +
  • The date uses the calendar format.
  • +
  • The time has precision to the second and nine decimal digits.
  • +
  • The UTC offset has precision to the minute.
  • +
+

If you need different behavior, use the setter methods on this struct.

+

pub const fn set_formatted_components( + self, + formatted_components: FormattedComponents +) -> Config

Set whether the format the date, time, and/or UTC offset.

+

pub const fn set_use_separators(self, use_separators: bool) -> Config

Set whether the format contains separators (such as - or :).

+

pub const fn set_year_is_six_digits(self, year_is_six_digits: bool) -> Config

Set whether the year is six digits.

+

pub const fn set_date_kind(self, date_kind: DateKind) -> Config

Set the format used for the date.

+

pub const fn set_time_precision(self, time_precision: TimePrecision) -> Config

Set the precision and number of decimal digits present for the time.

+

pub const fn set_offset_precision( + self, + offset_precision: OffsetPrecision +) -> Config

Set the precision for the UTC offset.

+

Trait Implementations§

§

impl Debug for Config

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Config

§

impl RefUnwindSafe for Config

§

impl Send for Config

§

impl Sync for Config

§

impl Unpin for Config

§

impl UnwindSafe for Config

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/well_known/iso8601/struct.Iso8601.html b/actix_web/cookie/time/format_description/well_known/iso8601/struct.Iso8601.html new file mode 100644 index 000000000..ffe6cf594 --- /dev/null +++ b/actix_web/cookie/time/format_description/well_known/iso8601/struct.Iso8601.html @@ -0,0 +1,59 @@ +Iso8601 in actix_web::cookie::time::format_description::well_known::iso8601 - Rust
pub struct Iso8601<const CONFIG: u128 = time::::format_description::well_known::iso8601::Iso8601::{constant#0}>;
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

The format described in ISO 8601.

+

This implementation is of ISO 8601-1:2019. It may not be compatible with other versions.

+

The const parameter CONFIG must be a value that was returned by Config::encode. +Passing any other value is unspecified behavior.

+

Example: 1997-11-21T09:55:06.000000000-06:00

+

§Examples

+
assert_eq!(
+    datetime!(1997-11-12 9:55:06 -6:00).format(&Iso8601::DEFAULT)?,
+    "1997-11-12T09:55:06.000000000-06:00"
+);
+

Implementations§

§

impl Iso8601<time::::format_description::well_known::iso8601::{impl#7}::{constant#0}>

pub const DEFAULT: Iso8601<time::::format_description::well_known::iso8601::{impl#7}::{constant#0}> = Self

An Iso8601 with the default configuration.

+

The following is the default behavior:

+
    +
  • The configuration can be used for both formatting and parsing.
  • +
  • The date, time, and UTC offset are all formatted.
  • +
  • Separators (such as - and :) are included.
  • +
  • The year contains four digits, such that the year must be between 0 and 9999.
  • +
  • The date uses the calendar format.
  • +
  • The time has precision to the second and nine decimal digits.
  • +
  • The UTC offset has precision to the minute.
  • +
+

If you need different behavior, use another associated constant. For full customization, use +Config::DEFAULT and Config’s methods to create a custom configuration.

+
§

impl Iso8601<time::::format_description::well_known::iso8601::{impl#8}::{constant#0}>

pub const PARSING: Iso8601<time::::format_description::well_known::iso8601::{impl#8}::{constant#0}> = Self

An Iso8601 that can only be used for parsing. Using this to format a value is +unspecified behavior.

+
§

impl Iso8601<time::::format_description::well_known::iso8601::{impl#9}::{constant#0}>

pub const DATE: Iso8601<time::::format_description::well_known::iso8601::{impl#9}::{constant#0}> = Self

An Iso8601 that handles only the date, but is otherwise the same as Config::DEFAULT.

+
§

impl Iso8601<time::::format_description::well_known::iso8601::{impl#10}::{constant#0}>

pub const TIME: Iso8601<time::::format_description::well_known::iso8601::{impl#10}::{constant#0}> = Self

An Iso8601 that handles only the time, but is otherwise the same as Config::DEFAULT.

+
§

impl Iso8601<time::::format_description::well_known::iso8601::{impl#11}::{constant#0}>

pub const OFFSET: Iso8601<time::::format_description::well_known::iso8601::{impl#11}::{constant#0}> = Self

An Iso8601 that handles only the UTC offset, but is otherwise the same as +Config::DEFAULT.

+
§

impl Iso8601<time::::format_description::well_known::iso8601::{impl#12}::{constant#0}>

pub const DATE_TIME: Iso8601<time::::format_description::well_known::iso8601::{impl#12}::{constant#0}> = Self

An Iso8601 that handles the date and time, but is otherwise the same as +Config::DEFAULT.

+
§

impl Iso8601<time::::format_description::well_known::iso8601::{impl#13}::{constant#0}>

pub const DATE_TIME_OFFSET: Iso8601<time::::format_description::well_known::iso8601::{impl#13}::{constant#0}> = Self

An Iso8601 that handles the date, time, and UTC offset. This is the same as +Config::DEFAULT.

+
§

impl Iso8601<time::::format_description::well_known::iso8601::{impl#14}::{constant#0}>

pub const TIME_OFFSET: Iso8601<time::::format_description::well_known::iso8601::{impl#14}::{constant#0}> = Self

An Iso8601 that handles the time and UTC offset, but is otherwise the same as +Config::DEFAULT.

+

Trait Implementations§

§

impl<const CONFIG: u128> Clone for Iso8601<CONFIG>

§

fn clone(&self) -> Iso8601<CONFIG>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl<const CONFIG: u128> Debug for Iso8601<CONFIG>

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<const CONFIG: u128> PartialEq for Iso8601<CONFIG>

§

fn eq(&self, other: &Iso8601<CONFIG>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<const CONFIG: u128> Copy for Iso8601<CONFIG>

§

impl<const CONFIG: u128> Eq for Iso8601<CONFIG>

§

impl<const CONFIG: u128> Formattable for Iso8601<CONFIG>

§

impl<const CONFIG: u128> Parsable for Iso8601<CONFIG>

§

impl<const CONFIG: u128> StructuralPartialEq for Iso8601<CONFIG>

Auto Trait Implementations§

§

impl<const CONFIG: u128> Freeze for Iso8601<CONFIG>

§

impl<const CONFIG: u128> RefUnwindSafe for Iso8601<CONFIG>

§

impl<const CONFIG: u128> Send for Iso8601<CONFIG>

§

impl<const CONFIG: u128> Sync for Iso8601<CONFIG>

§

impl<const CONFIG: u128> Unpin for Iso8601<CONFIG>

§

impl<const CONFIG: u128> UnwindSafe for Iso8601<CONFIG>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/well_known/iso8601/type.EncodedConfig.html b/actix_web/cookie/time/format_description/well_known/iso8601/type.EncodedConfig.html new file mode 100644 index 000000000..763ec73f9 --- /dev/null +++ b/actix_web/cookie/time/format_description/well_known/iso8601/type.EncodedConfig.html @@ -0,0 +1,4 @@ +EncodedConfig in actix_web::cookie::time::format_description::well_known::iso8601 - Rust
pub type EncodedConfig = u128;
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

An encoded Config that can be used as a const parameter to Iso8601.

+

The type this is aliased to must not be relied upon. It can change in any release without +notice.

+
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/well_known/sidebar-items.js b/actix_web/cookie/time/format_description/well_known/sidebar-items.js new file mode 100644 index 000000000..6d7ac2a5e --- /dev/null +++ b/actix_web/cookie/time/format_description/well_known/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"mod":["iso8601"],"struct":["Iso8601","Rfc2822","Rfc3339"]}; \ No newline at end of file diff --git a/actix_web/cookie/time/format_description/well_known/struct.Iso8601.html b/actix_web/cookie/time/format_description/well_known/struct.Iso8601.html new file mode 100644 index 000000000..11e89fa31 --- /dev/null +++ b/actix_web/cookie/time/format_description/well_known/struct.Iso8601.html @@ -0,0 +1,59 @@ +Iso8601 in actix_web::cookie::time::format_description::well_known - Rust

Struct actix_web::cookie::time::format_description::well_known::Iso8601

pub struct Iso8601<const CONFIG: u128 = time::::format_description::well_known::iso8601::Iso8601::{constant#0}>;
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

The format described in ISO 8601.

+

This implementation is of ISO 8601-1:2019. It may not be compatible with other versions.

+

The const parameter CONFIG must be a value that was returned by Config::encode. +Passing any other value is unspecified behavior.

+

Example: 1997-11-21T09:55:06.000000000-06:00

+

§Examples

+
assert_eq!(
+    datetime!(1997-11-12 9:55:06 -6:00).format(&Iso8601::DEFAULT)?,
+    "1997-11-12T09:55:06.000000000-06:00"
+);
+

Implementations§

§

impl Iso8601<time::::format_description::well_known::iso8601::{impl#7}::{constant#0}>

pub const DEFAULT: Iso8601<time::::format_description::well_known::iso8601::{impl#7}::{constant#0}> = Self

An Iso8601 with the default configuration.

+

The following is the default behavior:

+
    +
  • The configuration can be used for both formatting and parsing.
  • +
  • The date, time, and UTC offset are all formatted.
  • +
  • Separators (such as - and :) are included.
  • +
  • The year contains four digits, such that the year must be between 0 and 9999.
  • +
  • The date uses the calendar format.
  • +
  • The time has precision to the second and nine decimal digits.
  • +
  • The UTC offset has precision to the minute.
  • +
+

If you need different behavior, use another associated constant. For full customization, use +Config::DEFAULT and Config’s methods to create a custom configuration.

+
§

impl Iso8601<time::::format_description::well_known::iso8601::{impl#8}::{constant#0}>

pub const PARSING: Iso8601<time::::format_description::well_known::iso8601::{impl#8}::{constant#0}> = Self

An Iso8601 that can only be used for parsing. Using this to format a value is +unspecified behavior.

+
§

impl Iso8601<time::::format_description::well_known::iso8601::{impl#9}::{constant#0}>

pub const DATE: Iso8601<time::::format_description::well_known::iso8601::{impl#9}::{constant#0}> = Self

An Iso8601 that handles only the date, but is otherwise the same as Config::DEFAULT.

+
§

impl Iso8601<time::::format_description::well_known::iso8601::{impl#10}::{constant#0}>

pub const TIME: Iso8601<time::::format_description::well_known::iso8601::{impl#10}::{constant#0}> = Self

An Iso8601 that handles only the time, but is otherwise the same as Config::DEFAULT.

+
§

impl Iso8601<time::::format_description::well_known::iso8601::{impl#11}::{constant#0}>

pub const OFFSET: Iso8601<time::::format_description::well_known::iso8601::{impl#11}::{constant#0}> = Self

An Iso8601 that handles only the UTC offset, but is otherwise the same as +Config::DEFAULT.

+
§

impl Iso8601<time::::format_description::well_known::iso8601::{impl#12}::{constant#0}>

pub const DATE_TIME: Iso8601<time::::format_description::well_known::iso8601::{impl#12}::{constant#0}> = Self

An Iso8601 that handles the date and time, but is otherwise the same as +Config::DEFAULT.

+
§

impl Iso8601<time::::format_description::well_known::iso8601::{impl#13}::{constant#0}>

pub const DATE_TIME_OFFSET: Iso8601<time::::format_description::well_known::iso8601::{impl#13}::{constant#0}> = Self

An Iso8601 that handles the date, time, and UTC offset. This is the same as +Config::DEFAULT.

+
§

impl Iso8601<time::::format_description::well_known::iso8601::{impl#14}::{constant#0}>

pub const TIME_OFFSET: Iso8601<time::::format_description::well_known::iso8601::{impl#14}::{constant#0}> = Self

An Iso8601 that handles the time and UTC offset, but is otherwise the same as +Config::DEFAULT.

+

Trait Implementations§

§

impl<const CONFIG: u128> Clone for Iso8601<CONFIG>

§

fn clone(&self) -> Iso8601<CONFIG>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl<const CONFIG: u128> Debug for Iso8601<CONFIG>

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<const CONFIG: u128> PartialEq for Iso8601<CONFIG>

§

fn eq(&self, other: &Iso8601<CONFIG>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<const CONFIG: u128> Copy for Iso8601<CONFIG>

§

impl<const CONFIG: u128> Eq for Iso8601<CONFIG>

§

impl<const CONFIG: u128> Formattable for Iso8601<CONFIG>

§

impl<const CONFIG: u128> Parsable for Iso8601<CONFIG>

§

impl<const CONFIG: u128> StructuralPartialEq for Iso8601<CONFIG>

Auto Trait Implementations§

§

impl<const CONFIG: u128> Freeze for Iso8601<CONFIG>

§

impl<const CONFIG: u128> RefUnwindSafe for Iso8601<CONFIG>

§

impl<const CONFIG: u128> Send for Iso8601<CONFIG>

§

impl<const CONFIG: u128> Sync for Iso8601<CONFIG>

§

impl<const CONFIG: u128> Unpin for Iso8601<CONFIG>

§

impl<const CONFIG: u128> UnwindSafe for Iso8601<CONFIG>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/well_known/struct.Rfc2822.html b/actix_web/cookie/time/format_description/well_known/struct.Rfc2822.html new file mode 100644 index 000000000..c28486e49 --- /dev/null +++ b/actix_web/cookie/time/format_description/well_known/struct.Rfc2822.html @@ -0,0 +1,37 @@ +Rfc2822 in actix_web::cookie::time::format_description::well_known - Rust

Struct actix_web::cookie::time::format_description::well_known::Rfc2822

pub struct Rfc2822;
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

The format described in RFC 2822.

+

Example: Fri, 21 Nov 1997 09:55:06 -0600

+

§Examples

+
use time_macros::datetime;
+assert_eq!(
+    OffsetDateTime::parse("Sat, 12 Jun 1993 13:25:19 GMT", &Rfc2822)?,
+    datetime!(1993-06-12 13:25:19 +00:00)
+);
+ +
assert_eq!(
+    datetime!(1997-11-21 09:55:06 -06:00).format(&Rfc2822)?,
+    "Fri, 21 Nov 1997 09:55:06 -0600"
+);
+

Trait Implementations§

§

impl Clone for Rfc2822

§

fn clone(&self) -> Rfc2822

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Rfc2822

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl PartialEq for Rfc2822

§

fn eq(&self, other: &Rfc2822) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for Rfc2822

§

impl Eq for Rfc2822

§

impl Formattable for Rfc2822

§

impl Parsable for Rfc2822

§

impl StructuralPartialEq for Rfc2822

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/format_description/well_known/struct.Rfc3339.html b/actix_web/cookie/time/format_description/well_known/struct.Rfc3339.html new file mode 100644 index 000000000..106440d72 --- /dev/null +++ b/actix_web/cookie/time/format_description/well_known/struct.Rfc3339.html @@ -0,0 +1,36 @@ +Rfc3339 in actix_web::cookie::time::format_description::well_known - Rust

Struct actix_web::cookie::time::format_description::well_known::Rfc3339

pub struct Rfc3339;
Available on crate feature cookies and (crate features formatting or parsing) only.
Expand description

The format described in RFC 3339.

+

Format example: 1985-04-12T23:20:50.52Z

+

§Examples

+
assert_eq!(
+    OffsetDateTime::parse("1985-04-12T23:20:50.52Z", &Rfc3339)?,
+    datetime!(1985-04-12 23:20:50.52 +00:00)
+);
+ +
assert_eq!(
+    datetime!(1985-04-12 23:20:50.52 +00:00).format(&Rfc3339)?,
+    "1985-04-12T23:20:50.52Z"
+);
+

Trait Implementations§

§

impl Clone for Rfc3339

§

fn clone(&self) -> Rfc3339

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Rfc3339

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl PartialEq for Rfc3339

§

fn eq(&self, other: &Rfc3339) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for Rfc3339

§

impl Eq for Rfc3339

§

impl Formattable for Rfc3339

§

impl Parsable for Rfc3339

§

impl StructuralPartialEq for Rfc3339

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/formatting/index.html b/actix_web/cookie/time/formatting/index.html new file mode 100644 index 000000000..cd5948b19 --- /dev/null +++ b/actix_web/cookie/time/formatting/index.html @@ -0,0 +1,2 @@ +actix_web::cookie::time::formatting - Rust

Module actix_web::cookie::time::formatting

Available on crate features cookies and formatting only.
Expand description

Formatting for various types.

+

Traits§

\ No newline at end of file diff --git a/actix_web/cookie/time/formatting/sidebar-items.js b/actix_web/cookie/time/formatting/sidebar-items.js new file mode 100644 index 000000000..898b8b406 --- /dev/null +++ b/actix_web/cookie/time/formatting/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"trait":["Formattable"]}; \ No newline at end of file diff --git a/actix_web/cookie/time/formatting/trait.Formattable.html b/actix_web/cookie/time/formatting/trait.Formattable.html new file mode 100644 index 000000000..19b29b6dc --- /dev/null +++ b/actix_web/cookie/time/formatting/trait.Formattable.html @@ -0,0 +1,7 @@ +Formattable in actix_web::cookie::time::formatting - Rust

Trait actix_web::cookie::time::formatting::Formattable

pub trait Formattable: Sealed { }
Available on crate features cookies and formatting only.
Expand description

A type that describes a format.

+

Implementors of Formattable are format descriptions.

+

Date::format and Time::format each use a format description to generate +a String from their data. See the respective methods for usage examples.

+

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

§

impl Formattable for [BorrowedFormatItem<'_>]

§

impl Formattable for [OwnedFormatItem]

Implementors§

§

impl Formattable for BorrowedFormatItem<'_>

§

impl Formattable for OwnedFormatItem

§

impl Formattable for Rfc2822

§

impl Formattable for Rfc3339

§

impl<T> Formattable for T
where + T: Deref, + <T as Deref>::Target: Formattable,

§

impl<const CONFIG: u128> Formattable for Iso8601<CONFIG>

\ No newline at end of file diff --git a/actix_web/cookie/time/index.html b/actix_web/cookie/time/index.html new file mode 100644 index 000000000..0a338f5bf --- /dev/null +++ b/actix_web/cookie/time/index.html @@ -0,0 +1,66 @@ +actix_web::cookie::time - Rust

Crate actix_web::cookie::time

Available on crate feature cookies only.
Expand description

§Feature flags

+

This crate exposes a number of features. These can be enabled or disabled as shown +in Cargo’s documentation. Features +are disabled by default unless otherwise noted.

+

Reliance on a given feature is always indicated alongside the item definition.

+
    +
  • +

    std (enabled by default, implicitly enables alloc)

    +

    This enables a number of features that depend on the standard library.

    +
  • +
  • +

    alloc (enabled by default via std)

    +

    Enables a number of features that require the ability to dynamically allocate memory.

    +
  • +
  • +

    macros

    +

    Enables macros that provide compile-time verification of values and intuitive syntax.

    +
  • +
  • +

    formatting (implicitly enables std)

    +

    Enables formatting of most structs.

    +
  • +
  • +

    parsing

    +

    Enables parsing of most structs.

    +
  • +
  • +

    local-offset (implicitly enables std)

    +

    This feature enables a number of methods that allow obtaining the system’s UTC offset.

    +
  • +
  • +

    large-dates

    +

    By default, only years within the ±9999 range (inclusive) are supported. If you need support +for years outside this range, consider enabling this feature; the supported range will be +increased to ±999,999.

    +

    Note that enabling this feature has some costs, as it means forgoing some optimizations. +Ambiguities may be introduced when parsing that would not otherwise exist.

    +
  • +
  • +

    serde

    +

    Enables serde support for all types except Instant.

    +
  • +
  • +

    serde-human-readable (implicitly enables serde, formatting, and parsing)

    +

    Allows serde representations to use a human-readable format. This is determined by the +serializer, not the user. If this feature is not enabled or if the serializer requests a +non-human-readable format, a format optimized for binary representation will be used.

    +

    Libraries should never enable this feature, as the decision of what format to use should be up +to the user.

    +
  • +
  • +

    rand

    +

    Enables rand support for all types.

    +
  • +
  • +

    quickcheck (implicitly enables alloc)

    +

    Enables quickcheck support for all types except Instant.

    +
  • +
  • +

    wasm-bindgen

    +

    Enables wasm-bindgen support for converting +JavaScript dates, as +well as obtaining the UTC offset from JavaScript.

    +
  • +
+

Modules§

  • Conversion between units of time.
  • Various error types returned by methods in the time crate.
  • Extension traits.
  • format_descriptionformatting or parsing
    Description of how types should be formatted and parsed.
  • formattingformatting
    Formatting for various types.
  • macrosmacros
    Macros to construct statically known values.
  • parsingparsing
    Parsing for various types.
  • Utility functions.

Structs§

Enums§

  • A unified error type for anything returned by a method in the time crate.
  • Months of the year.
  • Days of the week.

Type Aliases§

\ No newline at end of file diff --git a/actix_web/cookie/time/macros/index.html b/actix_web/cookie/time/macros/index.html new file mode 100644 index 000000000..20c210231 --- /dev/null +++ b/actix_web/cookie/time/macros/index.html @@ -0,0 +1,2 @@ +actix_web::cookie::time::macros - Rust

Module actix_web::cookie::time::macros

Available on crate features cookies and macros only.
Expand description

Macros to construct statically known values.

+

Macros§

\ No newline at end of file diff --git a/actix_web/cookie/time/macros/macro.date!.html b/actix_web/cookie/time/macros/macro.date!.html new file mode 100644 index 000000000..6c6d83726 --- /dev/null +++ b/actix_web/cookie/time/macros/macro.date!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.date.html...

+ + + \ No newline at end of file diff --git a/actix_web/cookie/time/macros/macro.date.html b/actix_web/cookie/time/macros/macro.date.html new file mode 100644 index 000000000..194f07f80 --- /dev/null +++ b/actix_web/cookie/time/macros/macro.date.html @@ -0,0 +1 @@ +date in actix_web::cookie::time::macros - Rust

Macro actix_web::cookie::time::macros::date

date!() { /* proc-macro */ }
Available on crate features cookies and macros only.
\ No newline at end of file diff --git a/actix_web/cookie/time/macros/macro.datetime!.html b/actix_web/cookie/time/macros/macro.datetime!.html new file mode 100644 index 000000000..c4036dd34 --- /dev/null +++ b/actix_web/cookie/time/macros/macro.datetime!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.datetime.html...

+ + + \ No newline at end of file diff --git a/actix_web/cookie/time/macros/macro.datetime.html b/actix_web/cookie/time/macros/macro.datetime.html new file mode 100644 index 000000000..14c9b5fc3 --- /dev/null +++ b/actix_web/cookie/time/macros/macro.datetime.html @@ -0,0 +1 @@ +datetime in actix_web::cookie::time::macros - Rust

Macro actix_web::cookie::time::macros::datetime

datetime!() { /* proc-macro */ }
Available on crate features cookies and macros only.
\ No newline at end of file diff --git a/actix_web/cookie/time/macros/macro.format_description!.html b/actix_web/cookie/time/macros/macro.format_description!.html new file mode 100644 index 000000000..f3a03056d --- /dev/null +++ b/actix_web/cookie/time/macros/macro.format_description!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.format_description.html...

+ + + \ No newline at end of file diff --git a/actix_web/cookie/time/macros/macro.format_description.html b/actix_web/cookie/time/macros/macro.format_description.html new file mode 100644 index 000000000..caa707da2 --- /dev/null +++ b/actix_web/cookie/time/macros/macro.format_description.html @@ -0,0 +1 @@ +format_description in actix_web::cookie::time::macros - Rust

Macro actix_web::cookie::time::macros::format_description

format_description!() { /* proc-macro */ }
Available on crate feature cookies and crate feature macros and (crate features formatting or parsing) only.
\ No newline at end of file diff --git a/actix_web/cookie/time/macros/macro.offset!.html b/actix_web/cookie/time/macros/macro.offset!.html new file mode 100644 index 000000000..502e589c9 --- /dev/null +++ b/actix_web/cookie/time/macros/macro.offset!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.offset.html...

+ + + \ No newline at end of file diff --git a/actix_web/cookie/time/macros/macro.offset.html b/actix_web/cookie/time/macros/macro.offset.html new file mode 100644 index 000000000..b3f9f7444 --- /dev/null +++ b/actix_web/cookie/time/macros/macro.offset.html @@ -0,0 +1 @@ +offset in actix_web::cookie::time::macros - Rust

Macro actix_web::cookie::time::macros::offset

offset!() { /* proc-macro */ }
Available on crate features cookies and macros only.
\ No newline at end of file diff --git a/actix_web/cookie/time/macros/macro.time!.html b/actix_web/cookie/time/macros/macro.time!.html new file mode 100644 index 000000000..2a1cec834 --- /dev/null +++ b/actix_web/cookie/time/macros/macro.time!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.time.html...

+ + + \ No newline at end of file diff --git a/actix_web/cookie/time/macros/macro.time.html b/actix_web/cookie/time/macros/macro.time.html new file mode 100644 index 000000000..06c7ea7ae --- /dev/null +++ b/actix_web/cookie/time/macros/macro.time.html @@ -0,0 +1 @@ +time in actix_web::cookie::time::macros - Rust

Macro actix_web::cookie::time::macros::time

time!() { /* proc-macro */ }
Available on crate features cookies and macros only.
\ No newline at end of file diff --git a/actix_web/cookie/time/macros/sidebar-items.js b/actix_web/cookie/time/macros/sidebar-items.js new file mode 100644 index 000000000..904b6893e --- /dev/null +++ b/actix_web/cookie/time/macros/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"macro":["date","datetime","format_description","offset","time"]}; \ No newline at end of file diff --git a/actix_web/cookie/time/parsing/index.html b/actix_web/cookie/time/parsing/index.html new file mode 100644 index 000000000..a5dc6ba5d --- /dev/null +++ b/actix_web/cookie/time/parsing/index.html @@ -0,0 +1,2 @@ +actix_web::cookie::time::parsing - Rust

Module actix_web::cookie::time::parsing

Available on crate features cookies and parsing only.
Expand description

Parsing for various types.

+

Structs§

Traits§

\ No newline at end of file diff --git a/actix_web/cookie/time/parsing/sidebar-items.js b/actix_web/cookie/time/parsing/sidebar-items.js new file mode 100644 index 000000000..42dfd93aa --- /dev/null +++ b/actix_web/cookie/time/parsing/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Parsed"],"trait":["Parsable"]}; \ No newline at end of file diff --git a/actix_web/cookie/time/parsing/struct.Parsed.html b/actix_web/cookie/time/parsing/struct.Parsed.html new file mode 100644 index 000000000..dddedc19e --- /dev/null +++ b/actix_web/cookie/time/parsing/struct.Parsed.html @@ -0,0 +1,125 @@ +Parsed in actix_web::cookie::time::parsing - Rust

Struct actix_web::cookie::time::parsing::Parsed

pub struct Parsed { /* private fields */ }
Available on crate features cookies and parsing only.
Expand description

All information parsed.

+

This information is directly used to construct the final values.

+

Most users will not need think about this struct in any way. It is public to allow for manual +control over values, in the instance that the default parser is insufficient.

+

Implementations§

§

impl Parsed

pub const fn new() -> Parsed

Create a new instance of Parsed with no information known.

+

pub fn parse_item<'a>( + &mut self, + input: &'a [u8], + item: &impl AnyFormatItem +) -> Result<&'a [u8], ParseFromDescription>

Parse a single BorrowedFormatItem or OwnedFormatItem, mutating the struct. The +remaining input is returned as the Ok value.

+

If a BorrowedFormatItem::Optional or OwnedFormatItem::Optional is passed, parsing +will not fail; the input will be returned as-is if the expected format is not present.

+

pub fn parse_items<'a>( + &mut self, + input: &'a [u8], + items: &[impl AnyFormatItem] +) -> Result<&'a [u8], ParseFromDescription>

Parse a sequence of BorrowedFormatItems or OwnedFormatItems, mutating the struct. +The remaining input is returned as the Ok value.

+

This method will fail if any of the contained BorrowedFormatItems or +OwnedFormatItems fail to parse. self will not be mutated in this instance.

+

pub fn parse_literal<'a>( + input: &'a [u8], + literal: &[u8] +) -> Result<&'a [u8], ParseFromDescription>

Parse a literal byte sequence. The remaining input is returned as the Ok value.

+

pub fn parse_component<'a>( + &mut self, + input: &'a [u8], + component: Component +) -> Result<&'a [u8], ParseFromDescription>

Parse a single component, mutating the struct. The remaining input is returned as the Ok +value.

+
§

impl Parsed

Getter methods

+

pub const fn year(&self) -> Option<i32>

Obtain the year component.

+

pub const fn year_last_two(&self) -> Option<u8>

Obtain the year_last_two component.

+

pub const fn iso_year(&self) -> Option<i32>

Obtain the iso_year component.

+

pub const fn iso_year_last_two(&self) -> Option<u8>

Obtain the iso_year_last_two component.

+

pub const fn month(&self) -> Option<Month>

Obtain the month component.

+

pub const fn sunday_week_number(&self) -> Option<u8>

Obtain the sunday_week_number component.

+

pub const fn monday_week_number(&self) -> Option<u8>

Obtain the monday_week_number component.

+

pub const fn iso_week_number(&self) -> Option<NonZero<u8>>

Obtain the iso_week_number component.

+

pub const fn weekday(&self) -> Option<Weekday>

Obtain the weekday component.

+

pub const fn ordinal(&self) -> Option<NonZero<u16>>

Obtain the ordinal component.

+

pub const fn day(&self) -> Option<NonZero<u8>>

Obtain the day component.

+

pub const fn hour_24(&self) -> Option<u8>

Obtain the hour_24 component.

+

pub const fn hour_12(&self) -> Option<NonZero<u8>>

Obtain the hour_12 component.

+

pub const fn hour_12_is_pm(&self) -> Option<bool>

Obtain the hour_12_is_pm component.

+

pub const fn minute(&self) -> Option<u8>

Obtain the minute component.

+

pub const fn second(&self) -> Option<u8>

Obtain the second component.

+

pub const fn subsecond(&self) -> Option<u32>

Obtain the subsecond component.

+

pub const fn offset_hour(&self) -> Option<i8>

Obtain the offset_hour component.

+

pub const fn offset_minute_signed(&self) -> Option<i8>

Obtain the offset_minute component.

+

pub const fn offset_second_signed(&self) -> Option<i8>

Obtain the offset_second component.

+

pub const fn unix_timestamp_nanos(&self) -> Option<i128>

Obtain the unix_timestamp_nanos component.

+
§

impl Parsed

Setter methods

+

All setters return Option<()>, which is Some if the value was set, and None if not. The +setters may fail if the value is invalid, though behavior is not guaranteed.

+

pub fn set_year(&mut self, value: i32) -> Option<()>

Set the set_year component.

+

pub fn set_year_last_two(&mut self, value: u8) -> Option<()>

Set the set_year_last_two component.

+

pub fn set_iso_year(&mut self, value: i32) -> Option<()>

Set the set_iso_year component.

+

pub fn set_iso_year_last_two(&mut self, value: u8) -> Option<()>

Set the set_iso_year_last_two component.

+

pub fn set_month(&mut self, value: Month) -> Option<()>

Set the set_month component.

+

pub fn set_sunday_week_number(&mut self, value: u8) -> Option<()>

Set the set_sunday_week_number component.

+

pub fn set_monday_week_number(&mut self, value: u8) -> Option<()>

Set the set_monday_week_number component.

+

pub fn set_iso_week_number(&mut self, value: NonZero<u8>) -> Option<()>

Set the set_iso_week_number component.

+

pub fn set_weekday(&mut self, value: Weekday) -> Option<()>

Set the set_weekday component.

+

pub fn set_ordinal(&mut self, value: NonZero<u16>) -> Option<()>

Set the set_ordinal component.

+

pub fn set_day(&mut self, value: NonZero<u8>) -> Option<()>

Set the set_day component.

+

pub fn set_hour_24(&mut self, value: u8) -> Option<()>

Set the set_hour_24 component.

+

pub fn set_hour_12(&mut self, value: NonZero<u8>) -> Option<()>

Set the set_hour_12 component.

+

pub fn set_hour_12_is_pm(&mut self, value: bool) -> Option<()>

Set the set_hour_12_is_pm component.

+

pub fn set_minute(&mut self, value: u8) -> Option<()>

Set the set_minute component.

+

pub fn set_second(&mut self, value: u8) -> Option<()>

Set the set_second component.

+

pub fn set_subsecond(&mut self, value: u32) -> Option<()>

Set the set_subsecond component.

+

pub fn set_offset_hour(&mut self, value: i8) -> Option<()>

Set the set_offset_hour component.

+

pub fn set_offset_minute_signed(&mut self, value: i8) -> Option<()>

Set the set_offset_minute_signed component.

+

pub fn set_offset_second_signed(&mut self, value: i8) -> Option<()>

Set the set_offset_second_signed component.

+

pub fn set_unix_timestamp_nanos(&mut self, value: i128) -> Option<()>

Set the set_unix_timestamp_nanos component.

+
§

impl Parsed

Builder methods

+

All builder methods return Option<Self>, which is Some if the value was set, and None if +not. The builder methods may fail if the value is invalid, though behavior is not guaranteed.

+

pub const fn with_year(self, value: i32) -> Option<Parsed>

Set the year component and return self.

+

pub const fn with_year_last_two(self, value: u8) -> Option<Parsed>

Set the year_last_two component and return self.

+

pub const fn with_iso_year(self, value: i32) -> Option<Parsed>

Set the iso_year component and return self.

+

pub const fn with_iso_year_last_two(self, value: u8) -> Option<Parsed>

Set the iso_year_last_two component and return self.

+

pub const fn with_month(self, value: Month) -> Option<Parsed>

Set the month component and return self.

+

pub const fn with_sunday_week_number(self, value: u8) -> Option<Parsed>

Set the sunday_week_number component and return self.

+

pub const fn with_monday_week_number(self, value: u8) -> Option<Parsed>

Set the monday_week_number component and return self.

+

pub const fn with_iso_week_number(self, value: NonZero<u8>) -> Option<Parsed>

Set the iso_week_number component and return self.

+

pub const fn with_weekday(self, value: Weekday) -> Option<Parsed>

Set the weekday component and return self.

+

pub const fn with_ordinal(self, value: NonZero<u16>) -> Option<Parsed>

Set the ordinal component and return self.

+

pub const fn with_day(self, value: NonZero<u8>) -> Option<Parsed>

Set the day component and return self.

+

pub const fn with_hour_24(self, value: u8) -> Option<Parsed>

Set the hour_24 component and return self.

+

pub const fn with_hour_12(self, value: NonZero<u8>) -> Option<Parsed>

Set the hour_12 component and return self.

+

pub const fn with_hour_12_is_pm(self, value: bool) -> Option<Parsed>

Set the hour_12_is_pm component and return self.

+

pub const fn with_minute(self, value: u8) -> Option<Parsed>

Set the minute component and return self.

+

pub const fn with_second(self, value: u8) -> Option<Parsed>

Set the second component and return self.

+

pub const fn with_subsecond(self, value: u32) -> Option<Parsed>

Set the subsecond component and return self.

+

pub const fn with_offset_hour(self, value: i8) -> Option<Parsed>

Set the offset_hour component and return self.

+

pub const fn with_offset_minute_signed(self, value: i8) -> Option<Parsed>

Set the offset_minute component and return self.

+

pub const fn with_offset_second_signed(self, value: i8) -> Option<Parsed>

Set the offset_second component and return self.

+

pub const fn with_unix_timestamp_nanos(self, value: i128) -> Option<Parsed>

Set the unix_timestamp_nanos component and return self.

+

Trait Implementations§

§

impl Clone for Parsed

§

fn clone(&self) -> Parsed

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Parsed

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for Parsed

§

fn default() -> Parsed

Returns the “default value” for a type. Read more
§

impl TryFrom<Parsed> for Date

§

type Error = TryFromParsed

The type returned in the event of a conversion error.
§

fn try_from(parsed: Parsed) -> Result<Date, <Date as TryFrom<Parsed>>::Error>

Performs the conversion.
§

impl TryFrom<Parsed> for OffsetDateTime

§

type Error = TryFromParsed

The type returned in the event of a conversion error.
§

fn try_from( + parsed: Parsed +) -> Result<OffsetDateTime, <OffsetDateTime as TryFrom<Parsed>>::Error>

Performs the conversion.
§

impl TryFrom<Parsed> for PrimitiveDateTime

§

type Error = TryFromParsed

The type returned in the event of a conversion error.
§

fn try_from( + parsed: Parsed +) -> Result<PrimitiveDateTime, <PrimitiveDateTime as TryFrom<Parsed>>::Error>

Performs the conversion.
§

impl TryFrom<Parsed> for Time

§

type Error = TryFromParsed

The type returned in the event of a conversion error.
§

fn try_from(parsed: Parsed) -> Result<Time, <Time as TryFrom<Parsed>>::Error>

Performs the conversion.
§

impl TryFrom<Parsed> for UtcOffset

§

type Error = TryFromParsed

The type returned in the event of a conversion error.
§

fn try_from( + parsed: Parsed +) -> Result<UtcOffset, <UtcOffset as TryFrom<Parsed>>::Error>

Performs the conversion.
§

impl Copy for Parsed

Auto Trait Implementations§

§

impl Freeze for Parsed

§

impl RefUnwindSafe for Parsed

§

impl Send for Parsed

§

impl Sync for Parsed

§

impl Unpin for Parsed

§

impl UnwindSafe for Parsed

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/parsing/trait.Parsable.html b/actix_web/cookie/time/parsing/trait.Parsable.html new file mode 100644 index 000000000..dade887b5 --- /dev/null +++ b/actix_web/cookie/time/parsing/trait.Parsable.html @@ -0,0 +1,4 @@ +Parsable in actix_web::cookie::time::parsing - Rust

Trait actix_web::cookie::time::parsing::Parsable

pub trait Parsable: Sealed { }
Available on crate features cookies and parsing only.
Expand description

A type that can be parsed.

+

Implementations on Foreign Types§

§

impl Parsable for [BorrowedFormatItem<'_>]

§

impl Parsable for [OwnedFormatItem]

Available on crate feature alloc only.

Implementors§

§

impl Parsable for BorrowedFormatItem<'_>

§

impl Parsable for OwnedFormatItem

Available on crate feature alloc only.
§

impl Parsable for Rfc2822

§

impl Parsable for Rfc3339

§

impl<T> Parsable for T
where + T: Deref, + <T as Deref>::Target: Parsable,

§

impl<const CONFIG: u128> Parsable for Iso8601<CONFIG>

\ No newline at end of file diff --git a/actix_web/cookie/time/sidebar-items.js b/actix_web/cookie/time/sidebar-items.js new file mode 100644 index 000000000..818855e26 --- /dev/null +++ b/actix_web/cookie/time/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Error","Month","Weekday"],"mod":["convert","error","ext","format_description","formatting","macros","parsing","util"],"struct":["Date","Duration","Instant","OffsetDateTime","PrimitiveDateTime","Time","UtcOffset"],"type":["Result"]}; \ No newline at end of file diff --git a/actix_web/cookie/time/struct.Date.html b/actix_web/cookie/time/struct.Date.html new file mode 100644 index 000000000..24df4ba1d --- /dev/null +++ b/actix_web/cookie/time/struct.Date.html @@ -0,0 +1,479 @@ +Date in actix_web::cookie::time - Rust

Struct actix_web::cookie::time::Date

pub struct Date { /* private fields */ }
Available on crate feature cookies only.
Expand description

Date in the proleptic Gregorian calendar.

+

By default, years between ±9999 inclusive are representable. This can be expanded to ±999,999 +inclusive by enabling the large-dates crate feature. Doing so has performance implications +and introduces some ambiguities when parsing.

+

Implementations§

§

impl Date

pub const MIN: Date = _

The minimum valid Date.

+

The value of this may vary depending on the feature flags enabled.

+

pub const MAX: Date = _

The maximum valid Date.

+

The value of this may vary depending on the feature flags enabled.

+

pub const fn from_calendar_date( + year: i32, + month: Month, + day: u8 +) -> Result<Date, ComponentRange>

Attempt to create a Date from the year, month, and day.

+ +
assert!(Date::from_calendar_date(2019, Month::January, 1).is_ok());
+assert!(Date::from_calendar_date(2019, Month::December, 31).is_ok());
+ +
assert!(Date::from_calendar_date(2019, Month::February, 29).is_err()); // 2019 isn't a leap year.
+

pub const fn from_ordinal_date( + year: i32, + ordinal: u16 +) -> Result<Date, ComponentRange>

Attempt to create a Date from the year and ordinal day number.

+ +
assert!(Date::from_ordinal_date(2019, 1).is_ok());
+assert!(Date::from_ordinal_date(2019, 365).is_ok());
+ +
assert!(Date::from_ordinal_date(2019, 366).is_err()); // 2019 isn't a leap year.
+

pub const fn from_iso_week_date( + year: i32, + week: u8, + weekday: Weekday +) -> Result<Date, ComponentRange>

Attempt to create a Date from the ISO year, week, and weekday.

+ +
assert!(Date::from_iso_week_date(2019, 1, Monday).is_ok());
+assert!(Date::from_iso_week_date(2019, 1, Tuesday).is_ok());
+assert!(Date::from_iso_week_date(2020, 53, Friday).is_ok());
+ +
assert!(Date::from_iso_week_date(2019, 53, Monday).is_err()); // 2019 doesn't have 53 weeks.
+

pub const fn from_julian_day(julian_day: i32) -> Result<Date, ComponentRange>

Create a Date from the Julian day.

+

The algorithm to perform this conversion is derived from one provided by Peter Baum; it is +freely available here.

+ +
assert_eq!(Date::from_julian_day(0), Ok(date!(-4713 - 11 - 24)));
+assert_eq!(Date::from_julian_day(2_451_545), Ok(date!(2000 - 01 - 01)));
+assert_eq!(Date::from_julian_day(2_458_485), Ok(date!(2019 - 01 - 01)));
+assert_eq!(Date::from_julian_day(2_458_849), Ok(date!(2019 - 12 - 31)));
+

pub const fn year(self) -> i32

Get the year of the date.

+ +
assert_eq!(date!(2019 - 01 - 01).year(), 2019);
+assert_eq!(date!(2019 - 12 - 31).year(), 2019);
+assert_eq!(date!(2020 - 01 - 01).year(), 2020);
+

pub const fn month(self) -> Month

Get the month.

+ +
assert_eq!(date!(2019 - 01 - 01).month(), Month::January);
+assert_eq!(date!(2019 - 12 - 31).month(), Month::December);
+

pub const fn day(self) -> u8

Get the day of the month.

+

The returned value will always be in the range 1..=31.

+ +
assert_eq!(date!(2019 - 01 - 01).day(), 1);
+assert_eq!(date!(2019 - 12 - 31).day(), 31);
+

pub const fn ordinal(self) -> u16

Get the day of the year.

+

The returned value will always be in the range 1..=366 (1..=365 for common years).

+ +
assert_eq!(date!(2019 - 01 - 01).ordinal(), 1);
+assert_eq!(date!(2019 - 12 - 31).ordinal(), 365);
+

pub const fn iso_week(self) -> u8

Get the ISO week number.

+

The returned value will always be in the range 1..=53.

+ +
assert_eq!(date!(2019 - 01 - 01).iso_week(), 1);
+assert_eq!(date!(2019 - 10 - 04).iso_week(), 40);
+assert_eq!(date!(2020 - 01 - 01).iso_week(), 1);
+assert_eq!(date!(2020 - 12 - 31).iso_week(), 53);
+assert_eq!(date!(2021 - 01 - 01).iso_week(), 53);
+

pub const fn sunday_based_week(self) -> u8

Get the week number where week 1 begins on the first Sunday.

+

The returned value will always be in the range 0..=53.

+ +
assert_eq!(date!(2019 - 01 - 01).sunday_based_week(), 0);
+assert_eq!(date!(2020 - 01 - 01).sunday_based_week(), 0);
+assert_eq!(date!(2020 - 12 - 31).sunday_based_week(), 52);
+assert_eq!(date!(2021 - 01 - 01).sunday_based_week(), 0);
+

pub const fn monday_based_week(self) -> u8

Get the week number where week 1 begins on the first Monday.

+

The returned value will always be in the range 0..=53.

+ +
assert_eq!(date!(2019 - 01 - 01).monday_based_week(), 0);
+assert_eq!(date!(2020 - 01 - 01).monday_based_week(), 0);
+assert_eq!(date!(2020 - 12 - 31).monday_based_week(), 52);
+assert_eq!(date!(2021 - 01 - 01).monday_based_week(), 0);
+

pub const fn to_calendar_date(self) -> (i32, Month, u8)

Get the year, month, and day.

+ +
assert_eq!(
+    date!(2019 - 01 - 01).to_calendar_date(),
+    (2019, Month::January, 1)
+);
+

pub const fn to_ordinal_date(self) -> (i32, u16)

Get the year and ordinal day number.

+ +
assert_eq!(date!(2019 - 01 - 01).to_ordinal_date(), (2019, 1));
+

pub const fn to_iso_week_date(self) -> (i32, u8, Weekday)

Get the ISO 8601 year, week number, and weekday.

+ +
assert_eq!(date!(2019 - 01 - 01).to_iso_week_date(), (2019, 1, Tuesday));
+assert_eq!(date!(2019 - 10 - 04).to_iso_week_date(), (2019, 40, Friday));
+assert_eq!(
+    date!(2020 - 01 - 01).to_iso_week_date(),
+    (2020, 1, Wednesday)
+);
+assert_eq!(
+    date!(2020 - 12 - 31).to_iso_week_date(),
+    (2020, 53, Thursday)
+);
+assert_eq!(date!(2021 - 01 - 01).to_iso_week_date(), (2020, 53, Friday));
+

pub const fn weekday(self) -> Weekday

Get the weekday.

+ +
assert_eq!(date!(2019 - 01 - 01).weekday(), Tuesday);
+assert_eq!(date!(2019 - 02 - 01).weekday(), Friday);
+assert_eq!(date!(2019 - 03 - 01).weekday(), Friday);
+assert_eq!(date!(2019 - 04 - 01).weekday(), Monday);
+assert_eq!(date!(2019 - 05 - 01).weekday(), Wednesday);
+assert_eq!(date!(2019 - 06 - 01).weekday(), Saturday);
+assert_eq!(date!(2019 - 07 - 01).weekday(), Monday);
+assert_eq!(date!(2019 - 08 - 01).weekday(), Thursday);
+assert_eq!(date!(2019 - 09 - 01).weekday(), Sunday);
+assert_eq!(date!(2019 - 10 - 01).weekday(), Tuesday);
+assert_eq!(date!(2019 - 11 - 01).weekday(), Friday);
+assert_eq!(date!(2019 - 12 - 01).weekday(), Sunday);
+

pub const fn next_day(self) -> Option<Date>

Get the next calendar date.

+ +
assert_eq!(
+    date!(2019 - 01 - 01).next_day(),
+    Some(date!(2019 - 01 - 02))
+);
+assert_eq!(
+    date!(2019 - 01 - 31).next_day(),
+    Some(date!(2019 - 02 - 01))
+);
+assert_eq!(
+    date!(2019 - 12 - 31).next_day(),
+    Some(date!(2020 - 01 - 01))
+);
+assert_eq!(Date::MAX.next_day(), None);
+

pub const fn previous_day(self) -> Option<Date>

Get the previous calendar date.

+ +
assert_eq!(
+    date!(2019 - 01 - 02).previous_day(),
+    Some(date!(2019 - 01 - 01))
+);
+assert_eq!(
+    date!(2019 - 02 - 01).previous_day(),
+    Some(date!(2019 - 01 - 31))
+);
+assert_eq!(
+    date!(2020 - 01 - 01).previous_day(),
+    Some(date!(2019 - 12 - 31))
+);
+assert_eq!(Date::MIN.previous_day(), None);
+

pub const fn next_occurrence(self, weekday: Weekday) -> Date

Calculates the first occurrence of a weekday that is strictly later than a given Date.

+
§Panics
+

Panics if an overflow occurred.

+
§Examples
+
assert_eq!(
+    date!(2023 - 06 - 28).next_occurrence(Weekday::Monday),
+    date!(2023 - 07 - 03)
+);
+assert_eq!(
+    date!(2023 - 06 - 19).next_occurrence(Weekday::Monday),
+    date!(2023 - 06 - 26)
+);
+

pub const fn prev_occurrence(self, weekday: Weekday) -> Date

Calculates the first occurrence of a weekday that is strictly earlier than a given Date.

+
§Panics
+

Panics if an overflow occurred.

+
§Examples
+
assert_eq!(
+    date!(2023 - 06 - 28).prev_occurrence(Weekday::Monday),
+    date!(2023 - 06 - 26)
+);
+assert_eq!(
+    date!(2023 - 06 - 19).prev_occurrence(Weekday::Monday),
+    date!(2023 - 06 - 12)
+);
+

pub const fn nth_next_occurrence(self, weekday: Weekday, n: u8) -> Date

Calculates the nth occurrence of a weekday that is strictly later than a given Date.

+
§Panics
+

Panics if an overflow occurred or if n == 0.

+
§Examples
+
assert_eq!(
+    date!(2023 - 06 - 25).nth_next_occurrence(Weekday::Monday, 5),
+    date!(2023 - 07 - 24)
+);
+assert_eq!(
+    date!(2023 - 06 - 26).nth_next_occurrence(Weekday::Monday, 5),
+    date!(2023 - 07 - 31)
+);
+

pub const fn nth_prev_occurrence(self, weekday: Weekday, n: u8) -> Date

Calculates the nth occurrence of a weekday that is strictly earlier than a given Date.

+
§Panics
+

Panics if an overflow occurred or if n == 0.

+
§Examples
+
assert_eq!(
+    date!(2023 - 06 - 27).nth_prev_occurrence(Weekday::Monday, 3),
+    date!(2023 - 06 - 12)
+);
+assert_eq!(
+    date!(2023 - 06 - 26).nth_prev_occurrence(Weekday::Monday, 3),
+    date!(2023 - 06 - 05)
+);
+

pub const fn to_julian_day(self) -> i32

Get the Julian day for the date.

+

The algorithm to perform this conversion is derived from one provided by Peter Baum; it is +freely available here.

+ +
assert_eq!(date!(-4713 - 11 - 24).to_julian_day(), 0);
+assert_eq!(date!(2000 - 01 - 01).to_julian_day(), 2_451_545);
+assert_eq!(date!(2019 - 01 - 01).to_julian_day(), 2_458_485);
+assert_eq!(date!(2019 - 12 - 31).to_julian_day(), 2_458_849);
+

pub const fn checked_add(self, duration: Duration) -> Option<Date>

Computes self + duration, returning None if an overflow occurred.

+ +
assert_eq!(Date::MAX.checked_add(1.days()), None);
+assert_eq!(Date::MIN.checked_add((-2).days()), None);
+assert_eq!(
+    date!(2020 - 12 - 31).checked_add(2.days()),
+    Some(date!(2021 - 01 - 02))
+);
+
§Note
+

This function only takes whole days into account.

+ +
assert_eq!(Date::MAX.checked_add(23.hours()), Some(Date::MAX));
+assert_eq!(Date::MIN.checked_add((-23).hours()), Some(Date::MIN));
+assert_eq!(
+    date!(2020 - 12 - 31).checked_add(23.hours()),
+    Some(date!(2020 - 12 - 31))
+);
+assert_eq!(
+    date!(2020 - 12 - 31).checked_add(47.hours()),
+    Some(date!(2021 - 01 - 01))
+);
+

pub const fn checked_add_std(self, duration: Duration) -> Option<Date>

Computes self + duration, returning None if an overflow occurred.

+ +
assert_eq!(Date::MAX.checked_add_std(1.std_days()), None);
+assert_eq!(
+    date!(2020 - 12 - 31).checked_add_std(2.std_days()),
+    Some(date!(2021 - 01 - 02))
+);
+
§Note
+

This function only takes whole days into account.

+ +
assert_eq!(Date::MAX.checked_add_std(23.std_hours()), Some(Date::MAX));
+assert_eq!(
+    date!(2020 - 12 - 31).checked_add_std(23.std_hours()),
+    Some(date!(2020 - 12 - 31))
+);
+assert_eq!(
+    date!(2020 - 12 - 31).checked_add_std(47.std_hours()),
+    Some(date!(2021 - 01 - 01))
+);
+

pub const fn checked_sub(self, duration: Duration) -> Option<Date>

Computes self - duration, returning None if an overflow occurred.

+ +
assert_eq!(Date::MAX.checked_sub((-2).days()), None);
+assert_eq!(Date::MIN.checked_sub(1.days()), None);
+assert_eq!(
+    date!(2020 - 12 - 31).checked_sub(2.days()),
+    Some(date!(2020 - 12 - 29))
+);
+
§Note
+

This function only takes whole days into account.

+ +
assert_eq!(Date::MAX.checked_sub((-23).hours()), Some(Date::MAX));
+assert_eq!(Date::MIN.checked_sub(23.hours()), Some(Date::MIN));
+assert_eq!(
+    date!(2020 - 12 - 31).checked_sub(23.hours()),
+    Some(date!(2020 - 12 - 31))
+);
+assert_eq!(
+    date!(2020 - 12 - 31).checked_sub(47.hours()),
+    Some(date!(2020 - 12 - 30))
+);
+

pub const fn checked_sub_std(self, duration: Duration) -> Option<Date>

Computes self - duration, returning None if an overflow occurred.

+ +
assert_eq!(Date::MIN.checked_sub_std(1.std_days()), None);
+assert_eq!(
+    date!(2020 - 12 - 31).checked_sub_std(2.std_days()),
+    Some(date!(2020 - 12 - 29))
+);
+
§Note
+

This function only takes whole days into account.

+ +
assert_eq!(Date::MIN.checked_sub_std(23.std_hours()), Some(Date::MIN));
+assert_eq!(
+    date!(2020 - 12 - 31).checked_sub_std(23.std_hours()),
+    Some(date!(2020 - 12 - 31))
+);
+assert_eq!(
+    date!(2020 - 12 - 31).checked_sub_std(47.std_hours()),
+    Some(date!(2020 - 12 - 30))
+);
+

pub const fn saturating_add(self, duration: Duration) -> Date

Computes self + duration, saturating value on overflow.

+ +
assert_eq!(Date::MAX.saturating_add(1.days()), Date::MAX);
+assert_eq!(Date::MIN.saturating_add((-2).days()), Date::MIN);
+assert_eq!(
+    date!(2020 - 12 - 31).saturating_add(2.days()),
+    date!(2021 - 01 - 02)
+);
+
§Note
+

This function only takes whole days into account.

+ +
assert_eq!(
+    date!(2020 - 12 - 31).saturating_add(23.hours()),
+    date!(2020 - 12 - 31)
+);
+assert_eq!(
+    date!(2020 - 12 - 31).saturating_add(47.hours()),
+    date!(2021 - 01 - 01)
+);
+

pub const fn saturating_sub(self, duration: Duration) -> Date

Computes self - duration, saturating value on overflow.

+ +
assert_eq!(Date::MAX.saturating_sub((-2).days()), Date::MAX);
+assert_eq!(Date::MIN.saturating_sub(1.days()), Date::MIN);
+assert_eq!(
+    date!(2020 - 12 - 31).saturating_sub(2.days()),
+    date!(2020 - 12 - 29)
+);
+
§Note
+

This function only takes whole days into account.

+ +
assert_eq!(
+    date!(2020 - 12 - 31).saturating_sub(23.hours()),
+    date!(2020 - 12 - 31)
+);
+assert_eq!(
+    date!(2020 - 12 - 31).saturating_sub(47.hours()),
+    date!(2020 - 12 - 30)
+);
+

pub const fn replace_year(self, year: i32) -> Result<Date, ComponentRange>

Replace the year. The month and day will be unchanged.

+ +
assert_eq!(
+    date!(2022 - 02 - 18).replace_year(2019),
+    Ok(date!(2019 - 02 - 18))
+);
+assert!(date!(2022 - 02 - 18).replace_year(-1_000_000_000).is_err()); // -1_000_000_000 isn't a valid year
+assert!(date!(2022 - 02 - 18).replace_year(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid year
+

pub const fn replace_month(self, month: Month) -> Result<Date, ComponentRange>

Replace the month of the year.

+ +
assert_eq!(
+    date!(2022 - 02 - 18).replace_month(Month::January),
+    Ok(date!(2022 - 01 - 18))
+);
+assert!(
+    date!(2022 - 01 - 30)
+        .replace_month(Month::February)
+        .is_err()
+); // 30 isn't a valid day in February
+

pub const fn replace_day(self, day: u8) -> Result<Date, ComponentRange>

Replace the day of the month.

+ +
assert_eq!(
+    date!(2022 - 02 - 18).replace_day(1),
+    Ok(date!(2022 - 02 - 01))
+);
+assert!(date!(2022 - 02 - 18).replace_day(0).is_err()); // 0 isn't a valid day
+assert!(date!(2022 - 02 - 18).replace_day(30).is_err()); // 30 isn't a valid day in February
+

pub const fn replace_ordinal(self, ordinal: u16) -> Result<Date, ComponentRange>

Replace the day of the year.

+ +
assert_eq!(date!(2022 - 049).replace_ordinal(1), Ok(date!(2022 - 001)));
+assert!(date!(2022 - 049).replace_ordinal(0).is_err()); // 0 isn't a valid ordinal
+assert!(date!(2022 - 049).replace_ordinal(366).is_err()); // 2022 isn't a leap year
+
§

impl Date

Methods to add a Time component, resulting in a PrimitiveDateTime.

+

pub const fn midnight(self) -> PrimitiveDateTime

Create a PrimitiveDateTime using the existing date. The Time component will be set +to midnight.

+ +
assert_eq!(date!(1970-01-01).midnight(), datetime!(1970-01-01 0:00));
+

pub const fn with_time(self, time: Time) -> PrimitiveDateTime

Create a PrimitiveDateTime using the existing date and the provided Time.

+ +
assert_eq!(
+    date!(1970-01-01).with_time(time!(0:00)),
+    datetime!(1970-01-01 0:00),
+);
+

pub const fn with_hms( + self, + hour: u8, + minute: u8, + second: u8 +) -> Result<PrimitiveDateTime, ComponentRange>

Attempt to create a PrimitiveDateTime using the existing date and the provided time.

+ +
assert!(date!(1970 - 01 - 01).with_hms(0, 0, 0).is_ok());
+assert!(date!(1970 - 01 - 01).with_hms(24, 0, 0).is_err());
+

pub const fn with_hms_milli( + self, + hour: u8, + minute: u8, + second: u8, + millisecond: u16 +) -> Result<PrimitiveDateTime, ComponentRange>

Attempt to create a PrimitiveDateTime using the existing date and the provided time.

+ +
assert!(date!(1970 - 01 - 01).with_hms_milli(0, 0, 0, 0).is_ok());
+assert!(date!(1970 - 01 - 01).with_hms_milli(24, 0, 0, 0).is_err());
+

pub const fn with_hms_micro( + self, + hour: u8, + minute: u8, + second: u8, + microsecond: u32 +) -> Result<PrimitiveDateTime, ComponentRange>

Attempt to create a PrimitiveDateTime using the existing date and the provided time.

+ +
assert!(date!(1970 - 01 - 01).with_hms_micro(0, 0, 0, 0).is_ok());
+assert!(date!(1970 - 01 - 01).with_hms_micro(24, 0, 0, 0).is_err());
+

pub const fn with_hms_nano( + self, + hour: u8, + minute: u8, + second: u8, + nanosecond: u32 +) -> Result<PrimitiveDateTime, ComponentRange>

Attempt to create a PrimitiveDateTime using the existing date and the provided time.

+ +
assert!(date!(1970 - 01 - 01).with_hms_nano(0, 0, 0, 0).is_ok());
+assert!(date!(1970 - 01 - 01).with_hms_nano(24, 0, 0, 0).is_err());
+
§

impl Date

pub fn format_into( + self, + output: &mut impl Write, + format: &(impl Formattable + ?Sized) +) -> Result<usize, Format>

Available on crate feature formatting only.

Format the Date using the provided format description.

+

pub fn format( + self, + format: &(impl Formattable + ?Sized) +) -> Result<String, Format>

Available on crate feature formatting only.

Format the Date using the provided format description.

+ +
let format = format_description::parse("[year]-[month]-[day]")?;
+assert_eq!(date!(2020 - 01 - 02).format(&format)?, "2020-01-02");
+
§

impl Date

pub fn parse( + input: &str, + description: &(impl Parsable + ?Sized) +) -> Result<Date, Parse>

Available on crate feature parsing only.

Parse a Date from the input using the provided format +description.

+ +
let format = format_description!("[year]-[month]-[day]");
+assert_eq!(Date::parse("2020-01-02", &format)?, date!(2020 - 01 - 02));
+

Trait Implementations§

§

impl Add<Duration> for Date

§

fn add(self, duration: Duration) -> <Date as Add<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = Date

The resulting type after applying the + operator.
§

impl Add<Duration> for Date

§

fn add(self, duration: Duration) -> <Date as Add<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = Date

The resulting type after applying the + operator.
§

impl AddAssign<Duration> for Date

§

fn add_assign(&mut self, rhs: Duration)

Performs the += operation. Read more
§

impl AddAssign<Duration> for Date

§

fn add_assign(&mut self, rhs: Duration)

Performs the += operation. Read more
§

impl Clone for Date

§

fn clone(&self) -> Date

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Date

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for Date

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Hash for Date

§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl Ord for Date

§

fn cmp(&self, other: &Date) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
§

impl PartialEq for Date

§

fn eq(&self, other: &Date) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialOrd for Date

§

fn partial_cmp(&self, other: &Date) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl SmartDisplay for Date

§

type Metadata = DateMetadata

User-provided metadata type.
§

fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Date>

Compute any information needed to format the value. This must, at a minimum, determine the +width of the value before any padding is added by the formatter. Read more
§

fn fmt_with_metadata( + &self, + f: &mut Formatter<'_>, + metadata: Metadata<'_, Date> +) -> Result<(), Error>

Format the value using the given formatter and metadata. The formatted output should have +the width indicated by the metadata. This is before any padding is added by the +formatter. Read more
§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Format the value using the given formatter. This is the same as Display::fmt. Read more
§

impl Sub<Duration> for Date

§

fn sub(self, duration: Duration) -> <Date as Sub<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = Date

The resulting type after applying the - operator.
§

impl Sub<Duration> for Date

§

fn sub(self, duration: Duration) -> <Date as Sub<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = Date

The resulting type after applying the - operator.
§

impl Sub for Date

§

type Output = Duration

The resulting type after applying the - operator.
§

fn sub(self, other: Date) -> <Date as Sub>::Output

Performs the - operation. Read more
§

impl SubAssign<Duration> for Date

§

fn sub_assign(&mut self, rhs: Duration)

Performs the -= operation. Read more
§

impl SubAssign<Duration> for Date

§

fn sub_assign(&mut self, rhs: Duration)

Performs the -= operation. Read more
§

impl TryFrom<Parsed> for Date

§

type Error = TryFromParsed

The type returned in the event of a conversion error.
§

fn try_from(parsed: Parsed) -> Result<Date, <Date as TryFrom<Parsed>>::Error>

Performs the conversion.
§

impl Copy for Date

§

impl Eq for Date

§

impl StructuralPartialEq for Date

Auto Trait Implementations§

§

impl Freeze for Date

§

impl RefUnwindSafe for Date

§

impl Send for Date

§

impl Sync for Date

§

impl Unpin for Date

§

impl UnwindSafe for Date

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/struct.Duration.html b/actix_web/cookie/time/struct.Duration.html new file mode 100644 index 000000000..fb9c7dc4b --- /dev/null +++ b/actix_web/cookie/time/struct.Duration.html @@ -0,0 +1,389 @@ +Duration in actix_web::cookie::time - Rust

Struct actix_web::cookie::time::Duration

pub struct Duration { /* private fields */ }
Available on crate feature cookies only.
Expand description

A span of time with nanosecond precision.

+

Each Duration is composed of a whole number of seconds and a fractional part represented in +nanoseconds.

+

This implementation allows for negative durations, unlike core::time::Duration.

+

Implementations§

§

impl Duration

pub const ZERO: Duration = _

Equivalent to 0.seconds().

+ +
assert_eq!(Duration::ZERO, 0.seconds());
+

pub const NANOSECOND: Duration = _

Equivalent to 1.nanoseconds().

+ +
assert_eq!(Duration::NANOSECOND, 1.nanoseconds());
+

pub const MICROSECOND: Duration = _

Equivalent to 1.microseconds().

+ +
assert_eq!(Duration::MICROSECOND, 1.microseconds());
+

pub const MILLISECOND: Duration = _

Equivalent to 1.milliseconds().

+ +
assert_eq!(Duration::MILLISECOND, 1.milliseconds());
+

pub const SECOND: Duration = _

Equivalent to 1.seconds().

+ +
assert_eq!(Duration::SECOND, 1.seconds());
+

pub const MINUTE: Duration = _

Equivalent to 1.minutes().

+ +
assert_eq!(Duration::MINUTE, 1.minutes());
+

pub const HOUR: Duration = _

Equivalent to 1.hours().

+ +
assert_eq!(Duration::HOUR, 1.hours());
+

pub const DAY: Duration = _

Equivalent to 1.days().

+ +
assert_eq!(Duration::DAY, 1.days());
+

pub const WEEK: Duration = _

Equivalent to 1.weeks().

+ +
assert_eq!(Duration::WEEK, 1.weeks());
+

pub const MIN: Duration = _

The minimum possible duration. Adding any negative duration to this will cause an overflow.

+

pub const MAX: Duration = _

The maximum possible duration. Adding any positive duration to this will cause an overflow.

+

pub const fn is_zero(self) -> bool

Check if a duration is exactly zero.

+ +
assert!(0.seconds().is_zero());
+assert!(!1.nanoseconds().is_zero());
+

pub const fn is_negative(self) -> bool

Check if a duration is negative.

+ +
assert!((-1).seconds().is_negative());
+assert!(!0.seconds().is_negative());
+assert!(!1.seconds().is_negative());
+

pub const fn is_positive(self) -> bool

Check if a duration is positive.

+ +
assert!(1.seconds().is_positive());
+assert!(!0.seconds().is_positive());
+assert!(!(-1).seconds().is_positive());
+

pub const fn abs(self) -> Duration

Get the absolute value of the duration.

+

This method saturates the returned value if it would otherwise overflow.

+ +
assert_eq!(1.seconds().abs(), 1.seconds());
+assert_eq!(0.seconds().abs(), 0.seconds());
+assert_eq!((-1).seconds().abs(), 1.seconds());
+

pub const fn unsigned_abs(self) -> Duration

Convert the existing Duration to a std::time::Duration and its sign. This returns a +std::time::Duration and does not saturate the returned value (unlike Duration::abs).

+ +
assert_eq!(1.seconds().unsigned_abs(), 1.std_seconds());
+assert_eq!(0.seconds().unsigned_abs(), 0.std_seconds());
+assert_eq!((-1).seconds().unsigned_abs(), 1.std_seconds());
+

pub const fn new(seconds: i64, nanoseconds: i32) -> Duration

Create a new Duration with the provided seconds and nanoseconds. If nanoseconds is at +least ±109, it will wrap to the number of seconds.

+ +
assert_eq!(Duration::new(1, 0), 1.seconds());
+assert_eq!(Duration::new(-1, 0), (-1).seconds());
+assert_eq!(Duration::new(1, 2_000_000_000), 3.seconds());
+
§Panics
+

This may panic if an overflow occurs.

+

pub const fn weeks(weeks: i64) -> Duration

Create a new Duration with the given number of weeks. Equivalent to +Duration::seconds(weeks * 604_800).

+ +
assert_eq!(Duration::weeks(1), 604_800.seconds());
+
§Panics
+

This may panic if an overflow occurs.

+

pub const fn days(days: i64) -> Duration

Create a new Duration with the given number of days. Equivalent to +Duration::seconds(days * 86_400).

+ +
assert_eq!(Duration::days(1), 86_400.seconds());
+
§Panics
+

This may panic if an overflow occurs.

+

pub const fn hours(hours: i64) -> Duration

Create a new Duration with the given number of hours. Equivalent to +Duration::seconds(hours * 3_600).

+ +
assert_eq!(Duration::hours(1), 3_600.seconds());
+
§Panics
+

This may panic if an overflow occurs.

+

pub const fn minutes(minutes: i64) -> Duration

Create a new Duration with the given number of minutes. Equivalent to +Duration::seconds(minutes * 60).

+ +
assert_eq!(Duration::minutes(1), 60.seconds());
+
§Panics
+

This may panic if an overflow occurs.

+

pub const fn seconds(seconds: i64) -> Duration

Create a new Duration with the given number of seconds.

+ +
assert_eq!(Duration::seconds(1), 1_000.milliseconds());
+

pub fn seconds_f64(seconds: f64) -> Duration

Creates a new Duration from the specified number of seconds represented as f64.

+ +
assert_eq!(Duration::seconds_f64(0.5), 0.5.seconds());
+assert_eq!(Duration::seconds_f64(-0.5), -0.5.seconds());
+

pub fn seconds_f32(seconds: f32) -> Duration

Creates a new Duration from the specified number of seconds represented as f32.

+ +
assert_eq!(Duration::seconds_f32(0.5), 0.5.seconds());
+assert_eq!(Duration::seconds_f32(-0.5), (-0.5).seconds());
+

pub fn saturating_seconds_f64(seconds: f64) -> Duration

Creates a new Duration from the specified number of seconds +represented as f64. Any values that are out of bounds are saturated at +the minimum or maximum respectively. NaN gets turned into a Duration +of 0 seconds.

+ +
assert_eq!(Duration::saturating_seconds_f64(0.5), 0.5.seconds());
+assert_eq!(Duration::saturating_seconds_f64(-0.5), -0.5.seconds());
+assert_eq!(
+    Duration::saturating_seconds_f64(f64::NAN),
+    Duration::new(0, 0),
+);
+assert_eq!(
+    Duration::saturating_seconds_f64(f64::NEG_INFINITY),
+    Duration::MIN,
+);
+assert_eq!(
+    Duration::saturating_seconds_f64(f64::INFINITY),
+    Duration::MAX,
+);
+

pub fn saturating_seconds_f32(seconds: f32) -> Duration

Creates a new Duration from the specified number of seconds +represented as f32. Any values that are out of bounds are saturated at +the minimum or maximum respectively. NaN gets turned into a Duration +of 0 seconds.

+ +
assert_eq!(Duration::saturating_seconds_f32(0.5), 0.5.seconds());
+assert_eq!(Duration::saturating_seconds_f32(-0.5), (-0.5).seconds());
+assert_eq!(
+    Duration::saturating_seconds_f32(f32::NAN),
+    Duration::new(0, 0),
+);
+assert_eq!(
+    Duration::saturating_seconds_f32(f32::NEG_INFINITY),
+    Duration::MIN,
+);
+assert_eq!(
+    Duration::saturating_seconds_f32(f32::INFINITY),
+    Duration::MAX,
+);
+

pub fn checked_seconds_f64(seconds: f64) -> Option<Duration>

Creates a new Duration from the specified number of seconds +represented as f64. Returns None if the Duration can’t be +represented.

+ +
assert_eq!(Duration::checked_seconds_f64(0.5), Some(0.5.seconds()));
+assert_eq!(Duration::checked_seconds_f64(-0.5), Some(-0.5.seconds()));
+assert_eq!(Duration::checked_seconds_f64(f64::NAN), None);
+assert_eq!(Duration::checked_seconds_f64(f64::NEG_INFINITY), None);
+assert_eq!(Duration::checked_seconds_f64(f64::INFINITY), None);
+

pub fn checked_seconds_f32(seconds: f32) -> Option<Duration>

Creates a new Duration from the specified number of seconds +represented as f32. Returns None if the Duration can’t be +represented.

+ +
assert_eq!(Duration::checked_seconds_f32(0.5), Some(0.5.seconds()));
+assert_eq!(Duration::checked_seconds_f32(-0.5), Some(-0.5.seconds()));
+assert_eq!(Duration::checked_seconds_f32(f32::NAN), None);
+assert_eq!(Duration::checked_seconds_f32(f32::NEG_INFINITY), None);
+assert_eq!(Duration::checked_seconds_f32(f32::INFINITY), None);
+

pub const fn milliseconds(milliseconds: i64) -> Duration

Create a new Duration with the given number of milliseconds.

+ +
assert_eq!(Duration::milliseconds(1), 1_000.microseconds());
+assert_eq!(Duration::milliseconds(-1), (-1_000).microseconds());
+

pub const fn microseconds(microseconds: i64) -> Duration

Create a new Duration with the given number of microseconds.

+ +
assert_eq!(Duration::microseconds(1), 1_000.nanoseconds());
+assert_eq!(Duration::microseconds(-1), (-1_000).nanoseconds());
+

pub const fn nanoseconds(nanoseconds: i64) -> Duration

Create a new Duration with the given number of nanoseconds.

+ +
assert_eq!(Duration::nanoseconds(1), 1.microseconds() / 1_000);
+assert_eq!(Duration::nanoseconds(-1), (-1).microseconds() / 1_000);
+

pub const fn whole_weeks(self) -> i64

Get the number of whole weeks in the duration.

+ +
assert_eq!(1.weeks().whole_weeks(), 1);
+assert_eq!((-1).weeks().whole_weeks(), -1);
+assert_eq!(6.days().whole_weeks(), 0);
+assert_eq!((-6).days().whole_weeks(), 0);
+

pub const fn whole_days(self) -> i64

Get the number of whole days in the duration.

+ +
assert_eq!(1.days().whole_days(), 1);
+assert_eq!((-1).days().whole_days(), -1);
+assert_eq!(23.hours().whole_days(), 0);
+assert_eq!((-23).hours().whole_days(), 0);
+

pub const fn whole_hours(self) -> i64

Get the number of whole hours in the duration.

+ +
assert_eq!(1.hours().whole_hours(), 1);
+assert_eq!((-1).hours().whole_hours(), -1);
+assert_eq!(59.minutes().whole_hours(), 0);
+assert_eq!((-59).minutes().whole_hours(), 0);
+

pub const fn whole_minutes(self) -> i64

Get the number of whole minutes in the duration.

+ +
assert_eq!(1.minutes().whole_minutes(), 1);
+assert_eq!((-1).minutes().whole_minutes(), -1);
+assert_eq!(59.seconds().whole_minutes(), 0);
+assert_eq!((-59).seconds().whole_minutes(), 0);
+

pub const fn whole_seconds(self) -> i64

Get the number of whole seconds in the duration.

+ +
assert_eq!(1.seconds().whole_seconds(), 1);
+assert_eq!((-1).seconds().whole_seconds(), -1);
+assert_eq!(1.minutes().whole_seconds(), 60);
+assert_eq!((-1).minutes().whole_seconds(), -60);
+

pub fn as_seconds_f64(self) -> f64

Get the number of fractional seconds in the duration.

+ +
assert_eq!(1.5.seconds().as_seconds_f64(), 1.5);
+assert_eq!((-1.5).seconds().as_seconds_f64(), -1.5);
+

pub fn as_seconds_f32(self) -> f32

Get the number of fractional seconds in the duration.

+ +
assert_eq!(1.5.seconds().as_seconds_f32(), 1.5);
+assert_eq!((-1.5).seconds().as_seconds_f32(), -1.5);
+

pub const fn whole_milliseconds(self) -> i128

Get the number of whole milliseconds in the duration.

+ +
assert_eq!(1.seconds().whole_milliseconds(), 1_000);
+assert_eq!((-1).seconds().whole_milliseconds(), -1_000);
+assert_eq!(1.milliseconds().whole_milliseconds(), 1);
+assert_eq!((-1).milliseconds().whole_milliseconds(), -1);
+

pub const fn subsec_milliseconds(self) -> i16

Get the number of milliseconds past the number of whole seconds.

+

Always in the range -999..=999.

+ +
assert_eq!(1.4.seconds().subsec_milliseconds(), 400);
+assert_eq!((-1.4).seconds().subsec_milliseconds(), -400);
+

pub const fn whole_microseconds(self) -> i128

Get the number of whole microseconds in the duration.

+ +
assert_eq!(1.milliseconds().whole_microseconds(), 1_000);
+assert_eq!((-1).milliseconds().whole_microseconds(), -1_000);
+assert_eq!(1.microseconds().whole_microseconds(), 1);
+assert_eq!((-1).microseconds().whole_microseconds(), -1);
+

pub const fn subsec_microseconds(self) -> i32

Get the number of microseconds past the number of whole seconds.

+

Always in the range -999_999..=999_999.

+ +
assert_eq!(1.0004.seconds().subsec_microseconds(), 400);
+assert_eq!((-1.0004).seconds().subsec_microseconds(), -400);
+

pub const fn whole_nanoseconds(self) -> i128

Get the number of nanoseconds in the duration.

+ +
assert_eq!(1.microseconds().whole_nanoseconds(), 1_000);
+assert_eq!((-1).microseconds().whole_nanoseconds(), -1_000);
+assert_eq!(1.nanoseconds().whole_nanoseconds(), 1);
+assert_eq!((-1).nanoseconds().whole_nanoseconds(), -1);
+

pub const fn subsec_nanoseconds(self) -> i32

Get the number of nanoseconds past the number of whole seconds.

+

The returned value will always be in the range -999_999_999..=999_999_999.

+ +
assert_eq!(1.000_000_400.seconds().subsec_nanoseconds(), 400);
+assert_eq!((-1.000_000_400).seconds().subsec_nanoseconds(), -400);
+

pub const fn checked_add(self, rhs: Duration) -> Option<Duration>

Computes self + rhs, returning None if an overflow occurred.

+ +
assert_eq!(5.seconds().checked_add(5.seconds()), Some(10.seconds()));
+assert_eq!(Duration::MAX.checked_add(1.nanoseconds()), None);
+assert_eq!((-5).seconds().checked_add(5.seconds()), Some(0.seconds()));
+

pub const fn checked_sub(self, rhs: Duration) -> Option<Duration>

Computes self - rhs, returning None if an overflow occurred.

+ +
assert_eq!(5.seconds().checked_sub(5.seconds()), Some(Duration::ZERO));
+assert_eq!(Duration::MIN.checked_sub(1.nanoseconds()), None);
+assert_eq!(5.seconds().checked_sub(10.seconds()), Some((-5).seconds()));
+

pub const fn checked_mul(self, rhs: i32) -> Option<Duration>

Computes self * rhs, returning None if an overflow occurred.

+ +
assert_eq!(5.seconds().checked_mul(2), Some(10.seconds()));
+assert_eq!(5.seconds().checked_mul(-2), Some((-10).seconds()));
+assert_eq!(5.seconds().checked_mul(0), Some(0.seconds()));
+assert_eq!(Duration::MAX.checked_mul(2), None);
+assert_eq!(Duration::MIN.checked_mul(2), None);
+

pub const fn checked_div(self, rhs: i32) -> Option<Duration>

Computes self / rhs, returning None if rhs == 0 or if the result would overflow.

+ +
assert_eq!(10.seconds().checked_div(2), Some(5.seconds()));
+assert_eq!(10.seconds().checked_div(-2), Some((-5).seconds()));
+assert_eq!(1.seconds().checked_div(0), None);
+

pub const fn checked_neg(self) -> Option<Duration>

Computes -self, returning None if the result would overflow.

+ +
assert_eq!(5.seconds().checked_neg(), Some((-5).seconds()));
+assert_eq!(Duration::MIN.checked_neg(), None);
+

pub const fn saturating_add(self, rhs: Duration) -> Duration

Computes self + rhs, saturating if an overflow occurred.

+ +
assert_eq!(5.seconds().saturating_add(5.seconds()), 10.seconds());
+assert_eq!(Duration::MAX.saturating_add(1.nanoseconds()), Duration::MAX);
+assert_eq!(
+    Duration::MIN.saturating_add((-1).nanoseconds()),
+    Duration::MIN
+);
+assert_eq!((-5).seconds().saturating_add(5.seconds()), Duration::ZERO);
+

pub const fn saturating_sub(self, rhs: Duration) -> Duration

Computes self - rhs, saturating if an overflow occurred.

+ +
assert_eq!(5.seconds().saturating_sub(5.seconds()), Duration::ZERO);
+assert_eq!(Duration::MIN.saturating_sub(1.nanoseconds()), Duration::MIN);
+assert_eq!(
+    Duration::MAX.saturating_sub((-1).nanoseconds()),
+    Duration::MAX
+);
+assert_eq!(5.seconds().saturating_sub(10.seconds()), (-5).seconds());
+

pub const fn saturating_mul(self, rhs: i32) -> Duration

Computes self * rhs, saturating if an overflow occurred.

+ +
assert_eq!(5.seconds().saturating_mul(2), 10.seconds());
+assert_eq!(5.seconds().saturating_mul(-2), (-10).seconds());
+assert_eq!(5.seconds().saturating_mul(0), Duration::ZERO);
+assert_eq!(Duration::MAX.saturating_mul(2), Duration::MAX);
+assert_eq!(Duration::MIN.saturating_mul(2), Duration::MIN);
+assert_eq!(Duration::MAX.saturating_mul(-2), Duration::MIN);
+assert_eq!(Duration::MIN.saturating_mul(-2), Duration::MAX);
+

pub fn time_fn<T>(f: impl FnOnce() -> T) -> (Duration, T)

👎Deprecated since 0.3.32: extremely limited use case, not intended for benchmarking
Available on crate feature std only.

Runs a closure, returning the duration of time it took to run. The return value of the +closure is provided in the second part of the tuple.

+

Trait Implementations§

§

impl Add<Duration> for Date

§

fn add(self, duration: Duration) -> <Date as Add<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = Date

The resulting type after applying the + operator.
§

impl Add<Duration> for Duration

§

fn add(self, std_duration: Duration) -> <Duration as Add<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = Duration

The resulting type after applying the + operator.
§

impl Add<Duration> for Instant

§

fn add(self, duration: Duration) -> <Instant as Add<Duration>>::Output

§Panics
+

This function may panic if the resulting point in time cannot be represented by the +underlying data structure.

+
§

type Output = Instant

The resulting type after applying the + operator.
§

impl Add<Duration> for OffsetDateTime

§

fn add(self, duration: Duration) -> <OffsetDateTime as Add<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = OffsetDateTime

The resulting type after applying the + operator.
§

impl Add<Duration> for PrimitiveDateTime

§

fn add(self, duration: Duration) -> <PrimitiveDateTime as Add<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = PrimitiveDateTime

The resulting type after applying the + operator.
§

impl Add<Duration> for Time

§

fn add(self, duration: Duration) -> <Time as Add<Duration>>::Output

Add the sub-day time of the Duration to the Time. Wraps on overflow.

+ +
assert_eq!(time!(12:00) + 2.hours(), time!(14:00));
+assert_eq!(time!(0:00:01) + (-2).seconds(), time!(23:59:59));
+
§

type Output = Time

The resulting type after applying the + operator.
§

impl Add for Duration

§

fn add(self, rhs: Duration) -> <Duration as Add>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = Duration

The resulting type after applying the + operator.
§

impl AddAssign<Duration> for Date

§

fn add_assign(&mut self, rhs: Duration)

Performs the += operation. Read more
§

impl AddAssign<Duration> for Duration

§

fn add_assign(&mut self, rhs: Duration)

Performs the += operation. Read more
§

impl AddAssign<Duration> for Instant

§

fn add_assign(&mut self, rhs: Duration)

Performs the += operation. Read more
§

impl AddAssign<Duration> for OffsetDateTime

§

fn add_assign(&mut self, rhs: Duration)

§Panics
+

This may panic if an overflow occurs.

+
§

impl AddAssign<Duration> for PrimitiveDateTime

§

fn add_assign(&mut self, duration: Duration)

§Panics
+

This may panic if an overflow occurs.

+
§

impl AddAssign<Duration> for Time

§

fn add_assign(&mut self, rhs: Duration)

Performs the += operation. Read more
§

impl AddAssign for Duration

§

fn add_assign(&mut self, rhs: Duration)

Performs the += operation. Read more
§

impl Clone for Duration

§

fn clone(&self) -> Duration

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Duration

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for Duration

§

fn default() -> Duration

Returns the “default value” for a type. Read more
§

impl Display for Duration

The format returned by this implementation is not stable and must not be relied upon.

+

By default this produces an exact, full-precision printout of the duration. +For a concise, rounded printout instead, you can use the .N format specifier:

+ +
let duration = Duration::new(123456, 789011223);
+println!("{duration:.3}");
+

For the purposes of this implementation, a day is exactly 24 hours and a minute is exactly 60 +seconds.

+
§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Div<Duration> for Duration

§

type Output = f64

The resulting type after applying the / operator.
§

fn div(self, rhs: Duration) -> <Duration as Div<Duration>>::Output

Performs the / operation. Read more
§

impl Div<f32> for Duration

§

type Output = Duration

The resulting type after applying the / operator.
§

fn div(self, rhs: f32) -> <Duration as Div<f32>>::Output

Performs the / operation. Read more
§

impl Div<f64> for Duration

§

type Output = Duration

The resulting type after applying the / operator.
§

fn div(self, rhs: f64) -> <Duration as Div<f64>>::Output

Performs the / operation. Read more
§

impl Div<i16> for Duration

§

type Output = Duration

The resulting type after applying the / operator.
§

fn div(self, rhs: i16) -> <Duration as Div<i16>>::Output

Performs the / operation. Read more
§

impl Div<i32> for Duration

§

type Output = Duration

The resulting type after applying the / operator.
§

fn div(self, rhs: i32) -> <Duration as Div<i32>>::Output

Performs the / operation. Read more
§

impl Div<i8> for Duration

§

type Output = Duration

The resulting type after applying the / operator.
§

fn div(self, rhs: i8) -> <Duration as Div<i8>>::Output

Performs the / operation. Read more
§

impl Div<u16> for Duration

§

type Output = Duration

The resulting type after applying the / operator.
§

fn div(self, rhs: u16) -> <Duration as Div<u16>>::Output

Performs the / operation. Read more
§

impl Div<u32> for Duration

§

type Output = Duration

The resulting type after applying the / operator.
§

fn div(self, rhs: u32) -> <Duration as Div<u32>>::Output

Performs the / operation. Read more
§

impl Div<u8> for Duration

§

type Output = Duration

The resulting type after applying the / operator.
§

fn div(self, rhs: u8) -> <Duration as Div<u8>>::Output

Performs the / operation. Read more
§

impl Div for Duration

§

type Output = f64

The resulting type after applying the / operator.
§

fn div(self, rhs: Duration) -> <Duration as Div>::Output

Performs the / operation. Read more
§

impl DivAssign<f32> for Duration

§

fn div_assign(&mut self, rhs: f32)

Performs the /= operation. Read more
§

impl DivAssign<f64> for Duration

§

fn div_assign(&mut self, rhs: f64)

Performs the /= operation. Read more
§

impl DivAssign<i16> for Duration

§

fn div_assign(&mut self, rhs: i16)

Performs the /= operation. Read more
§

impl DivAssign<i32> for Duration

§

fn div_assign(&mut self, rhs: i32)

Performs the /= operation. Read more
§

impl DivAssign<i8> for Duration

§

fn div_assign(&mut self, rhs: i8)

Performs the /= operation. Read more
§

impl DivAssign<u16> for Duration

§

fn div_assign(&mut self, rhs: u16)

Performs the /= operation. Read more
§

impl DivAssign<u32> for Duration

§

fn div_assign(&mut self, rhs: u32)

Performs the /= operation. Read more
§

impl DivAssign<u8> for Duration

§

fn div_assign(&mut self, rhs: u8)

Performs the /= operation. Read more
§

impl Hash for Duration

§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl Mul<f32> for Duration

§

type Output = Duration

The resulting type after applying the * operator.
§

fn mul(self, rhs: f32) -> <Duration as Mul<f32>>::Output

Performs the * operation. Read more
§

impl Mul<f64> for Duration

§

type Output = Duration

The resulting type after applying the * operator.
§

fn mul(self, rhs: f64) -> <Duration as Mul<f64>>::Output

Performs the * operation. Read more
§

impl Mul<i16> for Duration

§

type Output = Duration

The resulting type after applying the * operator.
§

fn mul(self, rhs: i16) -> <Duration as Mul<i16>>::Output

Performs the * operation. Read more
§

impl Mul<i32> for Duration

§

type Output = Duration

The resulting type after applying the * operator.
§

fn mul(self, rhs: i32) -> <Duration as Mul<i32>>::Output

Performs the * operation. Read more
§

impl Mul<i8> for Duration

§

type Output = Duration

The resulting type after applying the * operator.
§

fn mul(self, rhs: i8) -> <Duration as Mul<i8>>::Output

Performs the * operation. Read more
§

impl Mul<u16> for Duration

§

type Output = Duration

The resulting type after applying the * operator.
§

fn mul(self, rhs: u16) -> <Duration as Mul<u16>>::Output

Performs the * operation. Read more
§

impl Mul<u32> for Duration

§

type Output = Duration

The resulting type after applying the * operator.
§

fn mul(self, rhs: u32) -> <Duration as Mul<u32>>::Output

Performs the * operation. Read more
§

impl Mul<u8> for Duration

§

type Output = Duration

The resulting type after applying the * operator.
§

fn mul(self, rhs: u8) -> <Duration as Mul<u8>>::Output

Performs the * operation. Read more
§

impl MulAssign<f32> for Duration

§

fn mul_assign(&mut self, rhs: f32)

Performs the *= operation. Read more
§

impl MulAssign<f64> for Duration

§

fn mul_assign(&mut self, rhs: f64)

Performs the *= operation. Read more
§

impl MulAssign<i16> for Duration

§

fn mul_assign(&mut self, rhs: i16)

Performs the *= operation. Read more
§

impl MulAssign<i32> for Duration

§

fn mul_assign(&mut self, rhs: i32)

Performs the *= operation. Read more
§

impl MulAssign<i8> for Duration

§

fn mul_assign(&mut self, rhs: i8)

Performs the *= operation. Read more
§

impl MulAssign<u16> for Duration

§

fn mul_assign(&mut self, rhs: u16)

Performs the *= operation. Read more
§

impl MulAssign<u32> for Duration

§

fn mul_assign(&mut self, rhs: u32)

Performs the *= operation. Read more
§

impl MulAssign<u8> for Duration

§

fn mul_assign(&mut self, rhs: u8)

Performs the *= operation. Read more
§

impl Neg for Duration

§

type Output = Duration

The resulting type after applying the - operator.
§

fn neg(self) -> <Duration as Neg>::Output

Performs the unary - operation. Read more
§

impl Ord for Duration

§

fn cmp(&self, other: &Duration) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
§

impl PartialEq<Duration> for Duration

§

fn eq(&self, rhs: &Duration) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq for Duration

§

fn eq(&self, other: &Duration) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialOrd<Duration> for Duration

§

fn partial_cmp(&self, rhs: &Duration) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd for Duration

§

fn partial_cmp(&self, other: &Duration) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl Sub<Duration> for Date

§

fn sub(self, duration: Duration) -> <Date as Sub<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = Date

The resulting type after applying the - operator.
§

impl Sub<Duration> for Duration

§

fn sub(self, rhs: Duration) -> <Duration as Sub<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = Duration

The resulting type after applying the - operator.
§

impl Sub<Duration> for Instant

§

fn sub(self, duration: Duration) -> <Instant as Sub<Duration>>::Output

§Panics
+

This function may panic if the resulting point in time cannot be represented by the +underlying data structure.

+
§

type Output = Instant

The resulting type after applying the - operator.
§

impl Sub<Duration> for OffsetDateTime

§

fn sub(self, rhs: Duration) -> <OffsetDateTime as Sub<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = OffsetDateTime

The resulting type after applying the - operator.
§

impl Sub<Duration> for PrimitiveDateTime

§

fn sub(self, duration: Duration) -> <PrimitiveDateTime as Sub<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = PrimitiveDateTime

The resulting type after applying the - operator.
§

impl Sub<Duration> for Time

§

fn sub(self, duration: Duration) -> <Time as Sub<Duration>>::Output

Subtract the sub-day time of the Duration from the Time. Wraps on overflow.

+ +
assert_eq!(time!(14:00) - 2.hours(), time!(12:00));
+assert_eq!(time!(23:59:59) - (-2).seconds(), time!(0:00:01));
+
§

type Output = Time

The resulting type after applying the - operator.
§

impl Sub for Duration

§

fn sub(self, rhs: Duration) -> <Duration as Sub>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = Duration

The resulting type after applying the - operator.
§

impl SubAssign<Duration> for Date

§

fn sub_assign(&mut self, rhs: Duration)

Performs the -= operation. Read more
§

impl SubAssign<Duration> for Duration

§

fn sub_assign(&mut self, rhs: Duration)

Performs the -= operation. Read more
§

impl SubAssign<Duration> for Instant

§

fn sub_assign(&mut self, rhs: Duration)

Performs the -= operation. Read more
§

impl SubAssign<Duration> for OffsetDateTime

§

fn sub_assign(&mut self, rhs: Duration)

§Panics
+

This may panic if an overflow occurs.

+
§

impl SubAssign<Duration> for PrimitiveDateTime

§

fn sub_assign(&mut self, duration: Duration)

§Panics
+

This may panic if an overflow occurs.

+
§

impl SubAssign<Duration> for Time

§

fn sub_assign(&mut self, rhs: Duration)

Performs the -= operation. Read more
§

impl SubAssign for Duration

§

fn sub_assign(&mut self, rhs: Duration)

Performs the -= operation. Read more
§

impl<'a> Sum<&'a Duration> for Duration

§

fn sum<I>(iter: I) -> Duration
where + I: Iterator<Item = &'a Duration>,

Method which takes an iterator and generates Self from the elements by +“summing up” the items.
§

impl Sum for Duration

§

fn sum<I>(iter: I) -> Duration
where + I: Iterator<Item = Duration>,

Method which takes an iterator and generates Self from the elements by +“summing up” the items.
§

impl TryFrom<Duration> for Duration

§

type Error = ConversionRange

The type returned in the event of a conversion error.
§

fn try_from(original: Duration) -> Result<Duration, ConversionRange>

Performs the conversion.
§

impl Copy for Duration

§

impl Eq for Duration

§

impl StructuralPartialEq for Duration

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/struct.Instant.html b/actix_web/cookie/time/struct.Instant.html new file mode 100644 index 000000000..adc73c396 --- /dev/null +++ b/actix_web/cookie/time/struct.Instant.html @@ -0,0 +1,89 @@ +Instant in actix_web::cookie::time - Rust

Struct actix_web::cookie::time::Instant

#[repr(transparent)]
pub struct Instant(pub Instant);
👎Deprecated since 0.3.35: import time::ext::InstantExt instead
Available on crate feature cookies only.
Expand description

A measurement of a monotonically non-decreasing clock. Opaque and useful only with Duration.

+

Instants are always guaranteed to be no less than any previously measured instant when created, +and are often useful for tasks such as measuring benchmarks or timing how long an operation +takes.

+

Note, however, that instants are not guaranteed to be steady. In other words, each tick of +the underlying clock may not be the same length (e.g. some seconds may be longer than others). +An instant may jump forwards or experience time dilation (slow down or speed up), but it will +never go backwards.

+

Instants are opaque types that can only be compared to one another. There is no method to get +“the number of seconds” from an instant. Instead, it only allows measuring the duration between +two instants (or comparing two instants).

+

This implementation allows for operations with signed Durations, but is otherwise identical +to std::time::Instant.

+

Tuple Fields§

§0: Instant
👎Deprecated since 0.3.35: import time::ext::InstantExt instead

Implementations§

§

impl Instant

pub fn now() -> Instant

Returns an Instant corresponding to “now”.

+ +
println!("{:?}", Instant::now());
+

pub fn elapsed(self) -> Duration

Returns the amount of time elapsed since this instant was created. The duration will always +be nonnegative if the instant is not synthetically created.

+ +
let instant = Instant::now();
+thread::sleep(1.std_milliseconds());
+assert!(instant.elapsed() >= 1.milliseconds());
+

pub fn checked_add(self, duration: Duration) -> Option<Instant>

Returns Some(t) where t is the time self + duration if t can be represented as +Instant (which means it’s inside the bounds of the underlying data structure), None +otherwise.

+ +
let now = Instant::now();
+assert_eq!(now.checked_add(5.seconds()), Some(now + 5.seconds()));
+assert_eq!(now.checked_add((-5).seconds()), Some(now + (-5).seconds()));
+

pub fn checked_sub(self, duration: Duration) -> Option<Instant>

Returns Some(t) where t is the time self - duration if t can be represented as +Instant (which means it’s inside the bounds of the underlying data structure), None +otherwise.

+ +
let now = Instant::now();
+assert_eq!(now.checked_sub(5.seconds()), Some(now - 5.seconds()));
+assert_eq!(now.checked_sub((-5).seconds()), Some(now - (-5).seconds()));
+

pub const fn into_inner(self) -> Instant

Obtain the inner std::time::Instant.

+ +
let now = Instant::now();
+assert_eq!(now.into_inner(), now.0);
+

Trait Implementations§

§

impl Add<Duration> for Instant

§

fn add(self, duration: Duration) -> <Instant as Add<Duration>>::Output

§Panics
+

This function may panic if the resulting point in time cannot be represented by the +underlying data structure.

+
§

type Output = Instant

The resulting type after applying the + operator.
§

impl Add<Duration> for Instant

§

type Output = Instant

The resulting type after applying the + operator.
§

fn add(self, duration: Duration) -> <Instant as Add<Duration>>::Output

Performs the + operation. Read more
§

impl AddAssign<Duration> for Instant

§

fn add_assign(&mut self, rhs: Duration)

Performs the += operation. Read more
§

impl AddAssign<Duration> for Instant

§

fn add_assign(&mut self, rhs: Duration)

Performs the += operation. Read more
§

impl AsRef<Instant> for Instant

§

fn as_ref(&self) -> &Instant

Converts this type into a shared reference of the (usually inferred) input type.
§

impl Borrow<Instant> for Instant

§

fn borrow(&self) -> &Instant

Immutably borrows from an owned value. Read more
§

impl Clone for Instant

§

fn clone(&self) -> Instant

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Instant

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl From<Instant> for Instant

§

fn from(instant: Instant) -> Instant

Converts to this type from the input type.
§

impl Hash for Instant

§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl Ord for Instant

§

fn cmp(&self, other: &Instant) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
§

impl PartialEq<Instant> for Instant

§

fn eq(&self, rhs: &Instant) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq for Instant

§

fn eq(&self, other: &Instant) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialOrd<Instant> for Instant

§

fn partial_cmp(&self, rhs: &Instant) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd for Instant

§

fn partial_cmp(&self, other: &Instant) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl Sub<Duration> for Instant

§

fn sub(self, duration: Duration) -> <Instant as Sub<Duration>>::Output

§Panics
+

This function may panic if the resulting point in time cannot be represented by the +underlying data structure.

+
§

type Output = Instant

The resulting type after applying the - operator.
§

impl Sub<Duration> for Instant

§

fn sub(self, duration: Duration) -> <Instant as Sub<Duration>>::Output

§Panics
+

This function may panic if the resulting point in time cannot be represented by the +underlying data structure.

+
§

type Output = Instant

The resulting type after applying the - operator.
§

impl Sub<Instant> for Instant

§

type Output = Duration

The resulting type after applying the - operator.
§

fn sub(self, other: Instant) -> <Instant as Sub<Instant>>::Output

Performs the - operation. Read more
§

impl Sub for Instant

§

fn sub(self, other: Instant) -> <Instant as Sub>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = Duration

The resulting type after applying the - operator.
§

impl SubAssign<Duration> for Instant

§

fn sub_assign(&mut self, rhs: Duration)

Performs the -= operation. Read more
§

impl SubAssign<Duration> for Instant

§

fn sub_assign(&mut self, rhs: Duration)

Performs the -= operation. Read more
§

impl Copy for Instant

§

impl Eq for Instant

§

impl StructuralPartialEq for Instant

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/struct.OffsetDateTime.html b/actix_web/cookie/time/struct.OffsetDateTime.html new file mode 100644 index 000000000..499068a16 --- /dev/null +++ b/actix_web/cookie/time/struct.OffsetDateTime.html @@ -0,0 +1,632 @@ +OffsetDateTime in actix_web::cookie::time - Rust

Struct actix_web::cookie::time::OffsetDateTime

pub struct OffsetDateTime { /* private fields */ }
Available on crate feature cookies only.
Expand description

A PrimitiveDateTime with a UtcOffset.

+

All comparisons are performed using the UTC time.

+

Implementations§

§

impl OffsetDateTime

pub const UNIX_EPOCH: OffsetDateTime = _

Midnight, 1 January, 1970 (UTC).

+ +
assert_eq!(OffsetDateTime::UNIX_EPOCH, datetime!(1970-01-01 0:00 UTC),);
+

pub fn now_utc() -> OffsetDateTime

Available on crate feature std only.

Create a new OffsetDateTime with the current date and time in UTC.

+ +
assert!(OffsetDateTime::now_utc().year() >= 2019);
+assert_eq!(OffsetDateTime::now_utc().offset(), offset!(UTC));
+

pub const fn new_in_offset( + date: Date, + time: Time, + offset: UtcOffset +) -> OffsetDateTime

Create a new OffsetDateTime with the given Date, Time, and UtcOffset.

+ +
let dt = OffsetDateTime::new_in_offset(
+    Date::from_calendar_date(2024, Month::January, 1)?,
+    Time::from_hms_nano(12, 59, 59, 500_000_000)?,
+    UtcOffset::from_hms(-5, 0, 0)?,
+);
+assert_eq!(dt, datetime!(2024-01-01 12:59:59.5 -5));
+

pub const fn new_utc(date: Date, time: Time) -> OffsetDateTime

Create a new OffsetDateTime with the given Date and Time in the UTC timezone.

+ +
let dt = OffsetDateTime::new_utc(
+    Date::from_calendar_date(2024, Month::January, 1)?,
+    Time::from_hms_nano(12, 59, 59, 500_000_000)?,
+);
+assert_eq!(dt, datetime!(2024-01-01 12:59:59.5 UTC));
+

pub const fn to_offset(self, offset: UtcOffset) -> OffsetDateTime

Convert the OffsetDateTime from the current UtcOffset to the provided UtcOffset.

+ +
assert_eq!(
+    datetime!(2000-01-01 0:00 UTC)
+        .to_offset(offset!(-1))
+        .year(),
+    1999,
+);
+
+// Let's see what time Sydney's new year's celebration is in New York and Los Angeles.
+
+// Construct midnight on new year's in Sydney.
+let sydney = datetime!(2000-01-01 0:00 +11);
+let new_york = sydney.to_offset(offset!(-5));
+let los_angeles = sydney.to_offset(offset!(-8));
+assert_eq!(sydney.hour(), 0);
+assert_eq!(new_york.hour(), 8);
+assert_eq!(los_angeles.hour(), 5);
+
§Panics
+

This method panics if the local date-time in the new offset is outside the supported range.

+

pub const fn checked_to_offset( + self, + offset: UtcOffset +) -> Option<OffsetDateTime>

Convert the OffsetDateTime from the current UtcOffset to the provided UtcOffset, +returning None if the date-time in the resulting offset is invalid.

+ +
assert_eq!(
+    datetime!(2000-01-01 0:00 UTC)
+        .checked_to_offset(offset!(-1))
+        .unwrap()
+        .year(),
+    1999,
+);
+assert_eq!(
+    PrimitiveDateTime::MAX
+        .assume_utc()
+        .checked_to_offset(offset!(+1)),
+    None,
+);
+

pub const fn from_unix_timestamp( + timestamp: i64 +) -> Result<OffsetDateTime, ComponentRange>

Create an OffsetDateTime from the provided Unix timestamp. Calling .offset() on the +resulting value is guaranteed to return UTC.

+ +
assert_eq!(
+    OffsetDateTime::from_unix_timestamp(0),
+    Ok(OffsetDateTime::UNIX_EPOCH),
+);
+assert_eq!(
+    OffsetDateTime::from_unix_timestamp(1_546_300_800),
+    Ok(datetime!(2019-01-01 0:00 UTC)),
+);
+

If you have a timestamp-nanosecond pair, you can use something along the lines of the +following:

+ +
let (timestamp, nanos) = (1, 500_000_000);
+assert_eq!(
+    OffsetDateTime::from_unix_timestamp(timestamp)? + Duration::nanoseconds(nanos),
+    OffsetDateTime::UNIX_EPOCH + 1.5.seconds()
+);
+

pub const fn from_unix_timestamp_nanos( + timestamp: i128 +) -> Result<OffsetDateTime, ComponentRange>

Construct an OffsetDateTime from the provided Unix timestamp (in nanoseconds). Calling +.offset() on the resulting value is guaranteed to return UTC.

+ +
assert_eq!(
+    OffsetDateTime::from_unix_timestamp_nanos(0),
+    Ok(OffsetDateTime::UNIX_EPOCH),
+);
+assert_eq!(
+    OffsetDateTime::from_unix_timestamp_nanos(1_546_300_800_000_000_000),
+    Ok(datetime!(2019-01-01 0:00 UTC)),
+);
+

pub const fn offset(self) -> UtcOffset

Get the UtcOffset.

+ +
assert_eq!(datetime!(2019-01-01 0:00 UTC).offset(), offset!(UTC));
+assert_eq!(datetime!(2019-01-01 0:00 +1).offset(), offset!(+1));
+

pub const fn unix_timestamp(self) -> i64

Get the Unix timestamp.

+ +
assert_eq!(datetime!(1970-01-01 0:00 UTC).unix_timestamp(), 0);
+assert_eq!(datetime!(1970-01-01 0:00 -1).unix_timestamp(), 3_600);
+

pub const fn unix_timestamp_nanos(self) -> i128

Get the Unix timestamp in nanoseconds.

+ +
use time_macros::datetime;
+assert_eq!(datetime!(1970-01-01 0:00 UTC).unix_timestamp_nanos(), 0);
+assert_eq!(
+    datetime!(1970-01-01 0:00 -1).unix_timestamp_nanos(),
+    3_600_000_000_000,
+);
+

pub const fn date(self) -> Date

Get the Date in the stored offset.

+ +
assert_eq!(datetime!(2019-01-01 0:00 UTC).date(), date!(2019-01-01));
+assert_eq!(
+    datetime!(2019-01-01 0:00 UTC)
+        .to_offset(offset!(-1))
+        .date(),
+    date!(2018-12-31),
+);
+

pub const fn time(self) -> Time

Get the Time in the stored offset.

+ +
assert_eq!(datetime!(2019-01-01 0:00 UTC).time(), time!(0:00));
+assert_eq!(
+    datetime!(2019-01-01 0:00 UTC)
+        .to_offset(offset!(-1))
+        .time(),
+    time!(23:00)
+);
+

pub const fn year(self) -> i32

Get the year of the date in the stored offset.

+ +
assert_eq!(datetime!(2019-01-01 0:00 UTC).year(), 2019);
+assert_eq!(
+    datetime!(2019-12-31 23:00 UTC)
+        .to_offset(offset!(+1))
+        .year(),
+    2020,
+);
+assert_eq!(datetime!(2020-01-01 0:00 UTC).year(), 2020);
+

pub const fn month(self) -> Month

Get the month of the date in the stored offset.

+ +
assert_eq!(datetime!(2019-01-01 0:00 UTC).month(), Month::January);
+assert_eq!(
+    datetime!(2019-12-31 23:00 UTC)
+        .to_offset(offset!(+1))
+        .month(),
+    Month::January,
+);
+

pub const fn day(self) -> u8

Get the day of the date in the stored offset.

+

The returned value will always be in the range 1..=31.

+ +
assert_eq!(datetime!(2019-01-01 0:00 UTC).day(), 1);
+assert_eq!(
+    datetime!(2019-12-31 23:00 UTC)
+        .to_offset(offset!(+1))
+        .day(),
+    1,
+);
+

pub const fn ordinal(self) -> u16

Get the day of the year of the date in the stored offset.

+

The returned value will always be in the range 1..=366.

+ +
assert_eq!(datetime!(2019-01-01 0:00 UTC).ordinal(), 1);
+assert_eq!(
+    datetime!(2019-12-31 23:00 UTC)
+        .to_offset(offset!(+1))
+        .ordinal(),
+    1,
+);
+

pub const fn iso_week(self) -> u8

Get the ISO week number of the date in the stored offset.

+

The returned value will always be in the range 1..=53.

+ +
assert_eq!(datetime!(2019-01-01 0:00 UTC).iso_week(), 1);
+assert_eq!(datetime!(2020-01-01 0:00 UTC).iso_week(), 1);
+assert_eq!(datetime!(2020-12-31 0:00 UTC).iso_week(), 53);
+assert_eq!(datetime!(2021-01-01 0:00 UTC).iso_week(), 53);
+

pub const fn sunday_based_week(self) -> u8

Get the week number where week 1 begins on the first Sunday.

+

The returned value will always be in the range 0..=53.

+ +
assert_eq!(datetime!(2019-01-01 0:00 UTC).sunday_based_week(), 0);
+assert_eq!(datetime!(2020-01-01 0:00 UTC).sunday_based_week(), 0);
+assert_eq!(datetime!(2020-12-31 0:00 UTC).sunday_based_week(), 52);
+assert_eq!(datetime!(2021-01-01 0:00 UTC).sunday_based_week(), 0);
+

pub const fn monday_based_week(self) -> u8

Get the week number where week 1 begins on the first Monday.

+

The returned value will always be in the range 0..=53.

+ +
assert_eq!(datetime!(2019-01-01 0:00 UTC).monday_based_week(), 0);
+assert_eq!(datetime!(2020-01-01 0:00 UTC).monday_based_week(), 0);
+assert_eq!(datetime!(2020-12-31 0:00 UTC).monday_based_week(), 52);
+assert_eq!(datetime!(2021-01-01 0:00 UTC).monday_based_week(), 0);
+

pub const fn to_calendar_date(self) -> (i32, Month, u8)

Get the year, month, and day.

+ +
assert_eq!(
+    datetime!(2019-01-01 0:00 UTC).to_calendar_date(),
+    (2019, Month::January, 1)
+);
+

pub const fn to_ordinal_date(self) -> (i32, u16)

Get the year and ordinal day number.

+ +
assert_eq!(
+    datetime!(2019-01-01 0:00 UTC).to_ordinal_date(),
+    (2019, 1)
+);
+

pub const fn to_iso_week_date(self) -> (i32, u8, Weekday)

Get the ISO 8601 year, week number, and weekday.

+ +
assert_eq!(
+    datetime!(2019-01-01 0:00 UTC).to_iso_week_date(),
+    (2019, 1, Tuesday)
+);
+assert_eq!(
+    datetime!(2019-10-04 0:00 UTC).to_iso_week_date(),
+    (2019, 40, Friday)
+);
+assert_eq!(
+    datetime!(2020-01-01 0:00 UTC).to_iso_week_date(),
+    (2020, 1, Wednesday)
+);
+assert_eq!(
+    datetime!(2020-12-31 0:00 UTC).to_iso_week_date(),
+    (2020, 53, Thursday)
+);
+assert_eq!(
+    datetime!(2021-01-01 0:00 UTC).to_iso_week_date(),
+    (2020, 53, Friday)
+);
+

pub const fn weekday(self) -> Weekday

Get the weekday of the date in the stored offset.

+ +
assert_eq!(datetime!(2019-01-01 0:00 UTC).weekday(), Tuesday);
+assert_eq!(datetime!(2019-02-01 0:00 UTC).weekday(), Friday);
+assert_eq!(datetime!(2019-03-01 0:00 UTC).weekday(), Friday);
+

pub const fn to_julian_day(self) -> i32

Get the Julian day for the date. The time is not taken into account for this calculation.

+

The algorithm to perform this conversion is derived from one provided by Peter Baum; it is +freely available here.

+ +
assert_eq!(datetime!(-4713-11-24 0:00 UTC).to_julian_day(), 0);
+assert_eq!(datetime!(2000-01-01 0:00 UTC).to_julian_day(), 2_451_545);
+assert_eq!(datetime!(2019-01-01 0:00 UTC).to_julian_day(), 2_458_485);
+assert_eq!(datetime!(2019-12-31 0:00 UTC).to_julian_day(), 2_458_849);
+

pub const fn to_hms(self) -> (u8, u8, u8)

Get the clock hour, minute, and second.

+ +
assert_eq!(datetime!(2020-01-01 0:00:00 UTC).to_hms(), (0, 0, 0));
+assert_eq!(datetime!(2020-01-01 23:59:59 UTC).to_hms(), (23, 59, 59));
+

pub const fn to_hms_milli(self) -> (u8, u8, u8, u16)

Get the clock hour, minute, second, and millisecond.

+ +
assert_eq!(
+    datetime!(2020-01-01 0:00:00 UTC).to_hms_milli(),
+    (0, 0, 0, 0)
+);
+assert_eq!(
+    datetime!(2020-01-01 23:59:59.999 UTC).to_hms_milli(),
+    (23, 59, 59, 999)
+);
+

pub const fn to_hms_micro(self) -> (u8, u8, u8, u32)

Get the clock hour, minute, second, and microsecond.

+ +
assert_eq!(
+    datetime!(2020-01-01 0:00:00 UTC).to_hms_micro(),
+    (0, 0, 0, 0)
+);
+assert_eq!(
+    datetime!(2020-01-01 23:59:59.999_999 UTC).to_hms_micro(),
+    (23, 59, 59, 999_999)
+);
+

pub const fn to_hms_nano(self) -> (u8, u8, u8, u32)

Get the clock hour, minute, second, and nanosecond.

+ +
assert_eq!(
+    datetime!(2020-01-01 0:00:00 UTC).to_hms_nano(),
+    (0, 0, 0, 0)
+);
+assert_eq!(
+    datetime!(2020-01-01 23:59:59.999_999_999 UTC).to_hms_nano(),
+    (23, 59, 59, 999_999_999)
+);
+

pub const fn hour(self) -> u8

Get the clock hour in the stored offset.

+

The returned value will always be in the range 0..24.

+ +
assert_eq!(datetime!(2019-01-01 0:00 UTC).hour(), 0);
+assert_eq!(
+    datetime!(2019-01-01 23:59:59 UTC)
+        .to_offset(offset!(-2))
+        .hour(),
+    21,
+);
+

pub const fn minute(self) -> u8

Get the minute within the hour in the stored offset.

+

The returned value will always be in the range 0..60.

+ +
assert_eq!(datetime!(2019-01-01 0:00 UTC).minute(), 0);
+assert_eq!(
+    datetime!(2019-01-01 23:59:59 UTC)
+        .to_offset(offset!(+0:30))
+        .minute(),
+    29,
+);
+

pub const fn second(self) -> u8

Get the second within the minute in the stored offset.

+

The returned value will always be in the range 0..60.

+ +
assert_eq!(datetime!(2019-01-01 0:00 UTC).second(), 0);
+assert_eq!(
+    datetime!(2019-01-01 23:59:59 UTC)
+        .to_offset(offset!(+0:00:30))
+        .second(),
+    29,
+);
+

pub const fn millisecond(self) -> u16

Get the milliseconds within the second in the stored offset.

+

The returned value will always be in the range 0..1_000.

+ +
assert_eq!(datetime!(2019-01-01 0:00 UTC).millisecond(), 0);
+assert_eq!(datetime!(2019-01-01 23:59:59.999 UTC).millisecond(), 999);
+

pub const fn microsecond(self) -> u32

Get the microseconds within the second in the stored offset.

+

The returned value will always be in the range 0..1_000_000.

+ +
assert_eq!(datetime!(2019-01-01 0:00 UTC).microsecond(), 0);
+assert_eq!(
+    datetime!(2019-01-01 23:59:59.999_999 UTC).microsecond(),
+    999_999,
+);
+

pub const fn nanosecond(self) -> u32

Get the nanoseconds within the second in the stored offset.

+

The returned value will always be in the range 0..1_000_000_000.

+ +
assert_eq!(datetime!(2019-01-01 0:00 UTC).nanosecond(), 0);
+assert_eq!(
+    datetime!(2019-01-01 23:59:59.999_999_999 UTC).nanosecond(),
+    999_999_999,
+);
+

pub const fn checked_add(self, duration: Duration) -> Option<OffsetDateTime>

Computes self + duration, returning None if an overflow occurred.

+ +
let datetime = Date::MIN.midnight().assume_offset(offset!(+10));
+assert_eq!(datetime.checked_add((-2).days()), None);
+
+let datetime = Date::MAX.midnight().assume_offset(offset!(+10));
+assert_eq!(datetime.checked_add(2.days()), None);
+
+assert_eq!(
+    datetime!(2019 - 11 - 25 15:30 +10).checked_add(27.hours()),
+    Some(datetime!(2019 - 11 - 26 18:30 +10))
+);
+

pub const fn checked_sub(self, duration: Duration) -> Option<OffsetDateTime>

Computes self - duration, returning None if an overflow occurred.

+ +
let datetime = Date::MIN.midnight().assume_offset(offset!(+10));
+assert_eq!(datetime.checked_sub(2.days()), None);
+
+let datetime = Date::MAX.midnight().assume_offset(offset!(+10));
+assert_eq!(datetime.checked_sub((-2).days()), None);
+
+assert_eq!(
+    datetime!(2019 - 11 - 25 15:30 +10).checked_sub(27.hours()),
+    Some(datetime!(2019 - 11 - 24 12:30 +10))
+);
+

pub const fn saturating_add(self, duration: Duration) -> OffsetDateTime

Computes self + duration, saturating value on overflow.

+ +
assert_eq!(
+    datetime!(-9999-01-01 0:00 +10).saturating_add((-2).days()),
+    datetime!(-9999-01-01 0:00 +10)
+);
+
+assert_eq!(
+    datetime!(+9999-12-31 23:59:59.999_999_999 +10).saturating_add(2.days()),
+    datetime!(+9999-12-31 23:59:59.999_999_999 +10)
+);
+
+assert_eq!(
+    datetime!(2019 - 11 - 25 15:30 +10).saturating_add(27.hours()),
+    datetime!(2019 - 11 - 26 18:30 +10)
+);
+

pub const fn saturating_sub(self, duration: Duration) -> OffsetDateTime

Computes self - duration, saturating value on overflow.

+ +
assert_eq!(
+    datetime!(-9999-01-01 0:00 +10).saturating_sub(2.days()),
+    datetime!(-9999-01-01 0:00 +10)
+);
+
+assert_eq!(
+    datetime!(+9999-12-31 23:59:59.999_999_999 +10).saturating_sub((-2).days()),
+    datetime!(+9999-12-31 23:59:59.999_999_999 +10)
+);
+
+assert_eq!(
+    datetime!(2019 - 11 - 25 15:30 +10).saturating_sub(27.hours()),
+    datetime!(2019 - 11 - 24 12:30 +10)
+);
+
§

impl OffsetDateTime

Methods that replace part of the OffsetDateTime.

+

pub const fn replace_time(self, time: Time) -> OffsetDateTime

Replace the time, which is assumed to be in the stored offset. The date and offset +components are unchanged.

+ +
assert_eq!(
+    datetime!(2020-01-01 5:00 UTC).replace_time(time!(12:00)),
+    datetime!(2020-01-01 12:00 UTC)
+);
+assert_eq!(
+    datetime!(2020-01-01 12:00 -5).replace_time(time!(7:00)),
+    datetime!(2020-01-01 7:00 -5)
+);
+assert_eq!(
+    datetime!(2020-01-01 0:00 +1).replace_time(time!(12:00)),
+    datetime!(2020-01-01 12:00 +1)
+);
+

pub const fn replace_date(self, date: Date) -> OffsetDateTime

Replace the date, which is assumed to be in the stored offset. The time and offset +components are unchanged.

+ +
assert_eq!(
+    datetime!(2020-01-01 12:00 UTC).replace_date(date!(2020-01-30)),
+    datetime!(2020-01-30 12:00 UTC)
+);
+assert_eq!(
+    datetime!(2020-01-01 0:00 +1).replace_date(date!(2020-01-30)),
+    datetime!(2020-01-30 0:00 +1)
+);
+

pub const fn replace_date_time( + self, + date_time: PrimitiveDateTime +) -> OffsetDateTime

Replace the date and time, which are assumed to be in the stored offset. The offset +component remains unchanged.

+ +
assert_eq!(
+    datetime!(2020-01-01 12:00 UTC).replace_date_time(datetime!(2020-01-30 16:00)),
+    datetime!(2020-01-30 16:00 UTC)
+);
+assert_eq!(
+    datetime!(2020-01-01 12:00 +1).replace_date_time(datetime!(2020-01-30 0:00)),
+    datetime!(2020-01-30 0:00 +1)
+);
+

pub const fn replace_offset(self, offset: UtcOffset) -> OffsetDateTime

Replace the offset. The date and time components remain unchanged.

+ +
assert_eq!(
+    datetime!(2020-01-01 0:00 UTC).replace_offset(offset!(-5)),
+    datetime!(2020-01-01 0:00 -5)
+);
+

pub const fn replace_year( + self, + year: i32 +) -> Result<OffsetDateTime, ComponentRange>

Replace the year. The month and day will be unchanged.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 12:00 +01).replace_year(2019),
+    Ok(datetime!(2019 - 02 - 18 12:00 +01))
+);
+assert!(datetime!(2022 - 02 - 18 12:00 +01).replace_year(-1_000_000_000).is_err()); // -1_000_000_000 isn't a valid year
+assert!(datetime!(2022 - 02 - 18 12:00 +01).replace_year(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid year
+

pub const fn replace_month( + self, + month: Month +) -> Result<OffsetDateTime, ComponentRange>

Replace the month of the year.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 12:00 +01).replace_month(Month::January),
+    Ok(datetime!(2022 - 01 - 18 12:00 +01))
+);
+assert!(datetime!(2022 - 01 - 30 12:00 +01).replace_month(Month::February).is_err()); // 30 isn't a valid day in February
+

pub const fn replace_day( + self, + day: u8 +) -> Result<OffsetDateTime, ComponentRange>

Replace the day of the month.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 12:00 +01).replace_day(1),
+    Ok(datetime!(2022 - 02 - 01 12:00 +01))
+);
+assert!(datetime!(2022 - 02 - 18 12:00 +01).replace_day(0).is_err()); // 00 isn't a valid day
+assert!(datetime!(2022 - 02 - 18 12:00 +01).replace_day(30).is_err()); // 30 isn't a valid day in February
+

pub const fn replace_ordinal( + self, + ordinal: u16 +) -> Result<OffsetDateTime, ComponentRange>

Replace the day of the year.

+ +
assert_eq!(datetime!(2022-049 12:00 +01).replace_ordinal(1), Ok(datetime!(2022-001 12:00 +01)));
+assert!(datetime!(2022-049 12:00 +01).replace_ordinal(0).is_err()); // 0 isn't a valid ordinal
+assert!(datetime!(2022-049 12:00 +01).replace_ordinal(366).is_err()); // 2022 isn't a leap year
+

pub const fn replace_hour( + self, + hour: u8 +) -> Result<OffsetDateTime, ComponentRange>

Replace the clock hour.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_hour(7),
+    Ok(datetime!(2022 - 02 - 18 07:02:03.004_005_006 +01))
+);
+assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_hour(24).is_err()); // 24 isn't a valid hour
+

pub const fn replace_minute( + self, + minute: u8 +) -> Result<OffsetDateTime, ComponentRange>

Replace the minutes within the hour.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_minute(7),
+    Ok(datetime!(2022 - 02 - 18 01:07:03.004_005_006 +01))
+);
+assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_minute(60).is_err()); // 60 isn't a valid minute
+

pub const fn replace_second( + self, + second: u8 +) -> Result<OffsetDateTime, ComponentRange>

Replace the seconds within the minute.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_second(7),
+    Ok(datetime!(2022 - 02 - 18 01:02:07.004_005_006 +01))
+);
+assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_second(60).is_err()); // 60 isn't a valid second
+

pub const fn replace_millisecond( + self, + millisecond: u16 +) -> Result<OffsetDateTime, ComponentRange>

Replace the milliseconds within the second.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_millisecond(7),
+    Ok(datetime!(2022 - 02 - 18 01:02:03.007 +01))
+);
+assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_millisecond(1_000).is_err()); // 1_000 isn't a valid millisecond
+

pub const fn replace_microsecond( + self, + microsecond: u32 +) -> Result<OffsetDateTime, ComponentRange>

Replace the microseconds within the second.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_microsecond(7_008),
+    Ok(datetime!(2022 - 02 - 18 01:02:03.007_008 +01))
+);
+assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_microsecond(1_000_000).is_err()); // 1_000_000 isn't a valid microsecond
+

pub const fn replace_nanosecond( + self, + nanosecond: u32 +) -> Result<OffsetDateTime, ComponentRange>

Replace the nanoseconds within the second.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_nanosecond(7_008_009),
+    Ok(datetime!(2022 - 02 - 18 01:02:03.007_008_009 +01))
+);
+assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006 +01).replace_nanosecond(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid nanosecond
+
§

impl OffsetDateTime

pub fn format_into( + self, + output: &mut impl Write, + format: &(impl Formattable + ?Sized) +) -> Result<usize, Format>

Available on crate feature formatting only.

Format the OffsetDateTime using the provided format +description.

+

pub fn format( + self, + format: &(impl Formattable + ?Sized) +) -> Result<String, Format>

Available on crate feature formatting only.

Format the OffsetDateTime using the provided format +description.

+ +
let format = format_description::parse(
+    "[year]-[month]-[day] [hour]:[minute]:[second] [offset_hour \
+         sign:mandatory]:[offset_minute]:[offset_second]",
+)?;
+assert_eq!(
+    datetime!(2020-01-02 03:04:05 +06:07:08).format(&format)?,
+    "2020-01-02 03:04:05 +06:07:08"
+);
+
§

impl OffsetDateTime

pub fn parse( + input: &str, + description: &(impl Parsable + ?Sized) +) -> Result<OffsetDateTime, Parse>

Available on crate feature parsing only.

Parse an OffsetDateTime from the input using the provided format +description.

+ +
let format = format_description!(
+    "[year]-[month]-[day] [hour]:[minute]:[second] [offset_hour \
+         sign:mandatory]:[offset_minute]:[offset_second]"
+);
+assert_eq!(
+    OffsetDateTime::parse("2020-01-02 03:04:05 +06:07:08", &format)?,
+    datetime!(2020-01-02 03:04:05 +06:07:08)
+);
+

Trait Implementations§

§

impl Add<Duration> for OffsetDateTime

§

fn add(self, duration: Duration) -> <OffsetDateTime as Add<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = OffsetDateTime

The resulting type after applying the + operator.
§

impl Add<Duration> for OffsetDateTime

§

fn add(self, duration: Duration) -> <OffsetDateTime as Add<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = OffsetDateTime

The resulting type after applying the + operator.
§

impl AddAssign<Duration> for OffsetDateTime

§

fn add_assign(&mut self, rhs: Duration)

§Panics
+

This may panic if an overflow occurs.

+
§

impl AddAssign<Duration> for OffsetDateTime

§

fn add_assign(&mut self, rhs: Duration)

§Panics
+

This may panic if an overflow occurs.

+
§

impl Clone for OffsetDateTime

§

fn clone(&self) -> OffsetDateTime

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for OffsetDateTime

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for OffsetDateTime

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl From<SystemTime> for OffsetDateTime

Available on crate feature std only.
§

fn from(system_time: SystemTime) -> OffsetDateTime

Converts to this type from the input type.
§

impl Hash for OffsetDateTime

§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl Ord for OffsetDateTime

§

fn cmp(&self, other: &OffsetDateTime) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
§

impl PartialEq<SystemTime> for OffsetDateTime

Available on crate feature std only.
§

fn eq(&self, rhs: &SystemTime) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq for OffsetDateTime

§

fn eq(&self, other: &OffsetDateTime) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialOrd<SystemTime> for OffsetDateTime

Available on crate feature std only.
§

fn partial_cmp(&self, other: &SystemTime) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd for OffsetDateTime

§

fn partial_cmp(&self, other: &OffsetDateTime) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl SmartDisplay for OffsetDateTime

§

type Metadata = ()

User-provided metadata type.
§

fn metadata(&self, _: FormatterOptions) -> Metadata<'_, OffsetDateTime>

Compute any information needed to format the value. This must, at a minimum, determine the +width of the value before any padding is added by the formatter. Read more
§

fn fmt_with_metadata( + &self, + f: &mut Formatter<'_>, + metadata: Metadata<'_, OffsetDateTime> +) -> Result<(), Error>

Format the value using the given formatter and metadata. The formatted output should have +the width indicated by the metadata. This is before any padding is added by the +formatter. Read more
§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Format the value using the given formatter. This is the same as Display::fmt. Read more
§

impl Sub<Duration> for OffsetDateTime

§

fn sub(self, duration: Duration) -> <OffsetDateTime as Sub<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = OffsetDateTime

The resulting type after applying the - operator.
§

impl Sub<Duration> for OffsetDateTime

§

fn sub(self, rhs: Duration) -> <OffsetDateTime as Sub<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = OffsetDateTime

The resulting type after applying the - operator.
§

impl Sub<SystemTime> for OffsetDateTime

Available on crate feature std only.
§

fn sub(self, rhs: SystemTime) -> <OffsetDateTime as Sub<SystemTime>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = Duration

The resulting type after applying the - operator.
§

impl Sub for OffsetDateTime

§

fn sub(self, rhs: OffsetDateTime) -> <OffsetDateTime as Sub>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = Duration

The resulting type after applying the - operator.
§

impl SubAssign<Duration> for OffsetDateTime

§

fn sub_assign(&mut self, rhs: Duration)

§Panics
+

This may panic if an overflow occurs.

+
§

impl SubAssign<Duration> for OffsetDateTime

§

fn sub_assign(&mut self, rhs: Duration)

§Panics
+

This may panic if an overflow occurs.

+
§

impl TryFrom<Parsed> for OffsetDateTime

§

type Error = TryFromParsed

The type returned in the event of a conversion error.
§

fn try_from( + parsed: Parsed +) -> Result<OffsetDateTime, <OffsetDateTime as TryFrom<Parsed>>::Error>

Performs the conversion.
§

impl Copy for OffsetDateTime

§

impl Eq for OffsetDateTime

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/struct.PrimitiveDateTime.html b/actix_web/cookie/time/struct.PrimitiveDateTime.html new file mode 100644 index 000000000..cbd56944e --- /dev/null +++ b/actix_web/cookie/time/struct.PrimitiveDateTime.html @@ -0,0 +1,467 @@ +PrimitiveDateTime in actix_web::cookie::time - Rust

Struct actix_web::cookie::time::PrimitiveDateTime

pub struct PrimitiveDateTime { /* private fields */ }
Available on crate feature cookies only.
Expand description

Combined date and time.

+

Implementations§

§

impl PrimitiveDateTime

pub const MIN: PrimitiveDateTime = _

The smallest value that can be represented by PrimitiveDateTime.

+

Depending on large-dates feature flag, value of this constant may vary.

+
    +
  1. With large-dates disabled it is equal to -9999-01-01 00:00:00.0
  2. +
  3. With large-dates enabled it is equal to -999999-01-01 00:00:00.0
  4. +
+ +
// Assuming `large-dates` feature is disabled.
+assert_eq!(PrimitiveDateTime::MIN, datetime!(-9999-01-01 0:00));
+

pub const MAX: PrimitiveDateTime = _

The largest value that can be represented by PrimitiveDateTime.

+

Depending on large-dates feature flag, value of this constant may vary.

+
    +
  1. With large-dates disabled it is equal to 9999-12-31 23:59:59.999_999_999
  2. +
  3. With large-dates enabled it is equal to 999999-12-31 23:59:59.999_999_999
  4. +
+ +
// Assuming `large-dates` feature is disabled.
+assert_eq!(PrimitiveDateTime::MAX, datetime!(+9999-12-31 23:59:59.999_999_999));
+

pub const fn new(date: Date, time: Time) -> PrimitiveDateTime

Create a new PrimitiveDateTime from the provided Date and Time.

+ +
assert_eq!(
+    PrimitiveDateTime::new(date!(2019-01-01), time!(0:00)),
+    datetime!(2019-01-01 0:00),
+);
+

pub const fn date(self) -> Date

Get the Date component of the PrimitiveDateTime.

+ +
assert_eq!(datetime!(2019-01-01 0:00).date(), date!(2019-01-01));
+

pub const fn time(self) -> Time

Get the Time component of the PrimitiveDateTime.

+ +
assert_eq!(datetime!(2019-01-01 0:00).time(), time!(0:00));
+

pub const fn year(self) -> i32

Get the year of the date.

+ +
assert_eq!(datetime!(2019-01-01 0:00).year(), 2019);
+assert_eq!(datetime!(2019-12-31 0:00).year(), 2019);
+assert_eq!(datetime!(2020-01-01 0:00).year(), 2020);
+

pub const fn month(self) -> Month

Get the month of the date.

+ +
assert_eq!(datetime!(2019-01-01 0:00).month(), Month::January);
+assert_eq!(datetime!(2019-12-31 0:00).month(), Month::December);
+

pub const fn day(self) -> u8

Get the day of the date.

+

The returned value will always be in the range 1..=31.

+ +
assert_eq!(datetime!(2019-01-01 0:00).day(), 1);
+assert_eq!(datetime!(2019-12-31 0:00).day(), 31);
+

pub const fn ordinal(self) -> u16

Get the day of the year.

+

The returned value will always be in the range 1..=366 (1..=365 for common years).

+ +
assert_eq!(datetime!(2019-01-01 0:00).ordinal(), 1);
+assert_eq!(datetime!(2019-12-31 0:00).ordinal(), 365);
+

pub const fn iso_week(self) -> u8

Get the ISO week number.

+

The returned value will always be in the range 1..=53.

+ +
assert_eq!(datetime!(2019-01-01 0:00).iso_week(), 1);
+assert_eq!(datetime!(2019-10-04 0:00).iso_week(), 40);
+assert_eq!(datetime!(2020-01-01 0:00).iso_week(), 1);
+assert_eq!(datetime!(2020-12-31 0:00).iso_week(), 53);
+assert_eq!(datetime!(2021-01-01 0:00).iso_week(), 53);
+

pub const fn sunday_based_week(self) -> u8

Get the week number where week 1 begins on the first Sunday.

+

The returned value will always be in the range 0..=53.

+ +
assert_eq!(datetime!(2019-01-01 0:00).sunday_based_week(), 0);
+assert_eq!(datetime!(2020-01-01 0:00).sunday_based_week(), 0);
+assert_eq!(datetime!(2020-12-31 0:00).sunday_based_week(), 52);
+assert_eq!(datetime!(2021-01-01 0:00).sunday_based_week(), 0);
+

pub const fn monday_based_week(self) -> u8

Get the week number where week 1 begins on the first Monday.

+

The returned value will always be in the range 0..=53.

+ +
assert_eq!(datetime!(2019-01-01 0:00).monday_based_week(), 0);
+assert_eq!(datetime!(2020-01-01 0:00).monday_based_week(), 0);
+assert_eq!(datetime!(2020-12-31 0:00).monday_based_week(), 52);
+assert_eq!(datetime!(2021-01-01 0:00).monday_based_week(), 0);
+

pub const fn to_calendar_date(self) -> (i32, Month, u8)

Get the year, month, and day.

+ +
assert_eq!(
+    datetime!(2019-01-01 0:00).to_calendar_date(),
+    (2019, Month::January, 1)
+);
+

pub const fn to_ordinal_date(self) -> (i32, u16)

Get the year and ordinal day number.

+ +
assert_eq!(datetime!(2019-01-01 0:00).to_ordinal_date(), (2019, 1));
+

pub const fn to_iso_week_date(self) -> (i32, u8, Weekday)

Get the ISO 8601 year, week number, and weekday.

+ +
assert_eq!(
+    datetime!(2019-01-01 0:00).to_iso_week_date(),
+    (2019, 1, Tuesday)
+);
+assert_eq!(
+    datetime!(2019-10-04 0:00).to_iso_week_date(),
+    (2019, 40, Friday)
+);
+assert_eq!(
+    datetime!(2020-01-01 0:00).to_iso_week_date(),
+    (2020, 1, Wednesday)
+);
+assert_eq!(
+    datetime!(2020-12-31 0:00).to_iso_week_date(),
+    (2020, 53, Thursday)
+);
+assert_eq!(
+    datetime!(2021-01-01 0:00).to_iso_week_date(),
+    (2020, 53, Friday)
+);
+

pub const fn weekday(self) -> Weekday

Get the weekday.

+ +
assert_eq!(datetime!(2019-01-01 0:00).weekday(), Tuesday);
+assert_eq!(datetime!(2019-02-01 0:00).weekday(), Friday);
+assert_eq!(datetime!(2019-03-01 0:00).weekday(), Friday);
+assert_eq!(datetime!(2019-04-01 0:00).weekday(), Monday);
+assert_eq!(datetime!(2019-05-01 0:00).weekday(), Wednesday);
+assert_eq!(datetime!(2019-06-01 0:00).weekday(), Saturday);
+assert_eq!(datetime!(2019-07-01 0:00).weekday(), Monday);
+assert_eq!(datetime!(2019-08-01 0:00).weekday(), Thursday);
+assert_eq!(datetime!(2019-09-01 0:00).weekday(), Sunday);
+assert_eq!(datetime!(2019-10-01 0:00).weekday(), Tuesday);
+assert_eq!(datetime!(2019-11-01 0:00).weekday(), Friday);
+assert_eq!(datetime!(2019-12-01 0:00).weekday(), Sunday);
+

pub const fn to_julian_day(self) -> i32

Get the Julian day for the date. The time is not taken into account for this calculation.

+

The algorithm to perform this conversion is derived from one provided by Peter Baum; it is +freely available here.

+ +
assert_eq!(datetime!(-4713-11-24 0:00).to_julian_day(), 0);
+assert_eq!(datetime!(2000-01-01 0:00).to_julian_day(), 2_451_545);
+assert_eq!(datetime!(2019-01-01 0:00).to_julian_day(), 2_458_485);
+assert_eq!(datetime!(2019-12-31 0:00).to_julian_day(), 2_458_849);
+

pub const fn as_hms(self) -> (u8, u8, u8)

Get the clock hour, minute, and second.

+ +
assert_eq!(datetime!(2020-01-01 0:00:00).as_hms(), (0, 0, 0));
+assert_eq!(datetime!(2020-01-01 23:59:59).as_hms(), (23, 59, 59));
+

pub const fn as_hms_milli(self) -> (u8, u8, u8, u16)

Get the clock hour, minute, second, and millisecond.

+ +
assert_eq!(datetime!(2020-01-01 0:00:00).as_hms_milli(), (0, 0, 0, 0));
+assert_eq!(
+    datetime!(2020-01-01 23:59:59.999).as_hms_milli(),
+    (23, 59, 59, 999)
+);
+

pub const fn as_hms_micro(self) -> (u8, u8, u8, u32)

Get the clock hour, minute, second, and microsecond.

+ +
assert_eq!(datetime!(2020-01-01 0:00:00).as_hms_micro(), (0, 0, 0, 0));
+assert_eq!(
+    datetime!(2020-01-01 23:59:59.999_999).as_hms_micro(),
+    (23, 59, 59, 999_999)
+);
+

pub const fn as_hms_nano(self) -> (u8, u8, u8, u32)

Get the clock hour, minute, second, and nanosecond.

+ +
assert_eq!(datetime!(2020-01-01 0:00:00).as_hms_nano(), (0, 0, 0, 0));
+assert_eq!(
+    datetime!(2020-01-01 23:59:59.999_999_999).as_hms_nano(),
+    (23, 59, 59, 999_999_999)
+);
+

pub const fn hour(self) -> u8

Get the clock hour.

+

The returned value will always be in the range 0..24.

+ +
assert_eq!(datetime!(2019-01-01 0:00).hour(), 0);
+assert_eq!(datetime!(2019-01-01 23:59:59).hour(), 23);
+

pub const fn minute(self) -> u8

Get the minute within the hour.

+

The returned value will always be in the range 0..60.

+ +
assert_eq!(datetime!(2019-01-01 0:00).minute(), 0);
+assert_eq!(datetime!(2019-01-01 23:59:59).minute(), 59);
+

pub const fn second(self) -> u8

Get the second within the minute.

+

The returned value will always be in the range 0..60.

+ +
assert_eq!(datetime!(2019-01-01 0:00).second(), 0);
+assert_eq!(datetime!(2019-01-01 23:59:59).second(), 59);
+

pub const fn millisecond(self) -> u16

Get the milliseconds within the second.

+

The returned value will always be in the range 0..1_000.

+ +
assert_eq!(datetime!(2019-01-01 0:00).millisecond(), 0);
+assert_eq!(datetime!(2019-01-01 23:59:59.999).millisecond(), 999);
+

pub const fn microsecond(self) -> u32

Get the microseconds within the second.

+

The returned value will always be in the range 0..1_000_000.

+ +
assert_eq!(datetime!(2019-01-01 0:00).microsecond(), 0);
+assert_eq!(
+    datetime!(2019-01-01 23:59:59.999_999).microsecond(),
+    999_999
+);
+

pub const fn nanosecond(self) -> u32

Get the nanoseconds within the second.

+

The returned value will always be in the range 0..1_000_000_000.

+ +
assert_eq!(datetime!(2019-01-01 0:00).nanosecond(), 0);
+assert_eq!(
+    datetime!(2019-01-01 23:59:59.999_999_999).nanosecond(),
+    999_999_999,
+);
+

pub const fn assume_offset(self, offset: UtcOffset) -> OffsetDateTime

Assuming that the existing PrimitiveDateTime represents a moment in the provided +UtcOffset, return an OffsetDateTime.

+ +
assert_eq!(
+    datetime!(2019-01-01 0:00)
+        .assume_offset(offset!(UTC))
+        .unix_timestamp(),
+    1_546_300_800,
+);
+assert_eq!(
+    datetime!(2019-01-01 0:00)
+        .assume_offset(offset!(-1))
+        .unix_timestamp(),
+    1_546_304_400,
+);
+

pub const fn assume_utc(self) -> OffsetDateTime

Assuming that the existing PrimitiveDateTime represents a moment in UTC, return an +OffsetDateTime.

+ +
assert_eq!(
+    datetime!(2019-01-01 0:00).assume_utc().unix_timestamp(),
+    1_546_300_800,
+);
+

pub const fn checked_add(self, duration: Duration) -> Option<PrimitiveDateTime>

Computes self + duration, returning None if an overflow occurred.

+ +
let datetime = Date::MIN.midnight();
+assert_eq!(datetime.checked_add((-2).days()), None);
+
+let datetime = Date::MAX.midnight();
+assert_eq!(datetime.checked_add(1.days()), None);
+
+assert_eq!(
+    datetime!(2019 - 11 - 25 15:30).checked_add(27.hours()),
+    Some(datetime!(2019 - 11 - 26 18:30))
+);
+

pub const fn checked_sub(self, duration: Duration) -> Option<PrimitiveDateTime>

Computes self - duration, returning None if an overflow occurred.

+ +
let datetime = Date::MIN.midnight();
+assert_eq!(datetime.checked_sub(2.days()), None);
+
+let datetime = Date::MAX.midnight();
+assert_eq!(datetime.checked_sub((-1).days()), None);
+
+assert_eq!(
+    datetime!(2019 - 11 - 25 15:30).checked_sub(27.hours()),
+    Some(datetime!(2019 - 11 - 24 12:30))
+);
+

pub const fn saturating_add(self, duration: Duration) -> PrimitiveDateTime

Computes self + duration, saturating value on overflow.

+ +
assert_eq!(
+    PrimitiveDateTime::MIN.saturating_add((-2).days()),
+    PrimitiveDateTime::MIN
+);
+
+assert_eq!(
+    PrimitiveDateTime::MAX.saturating_add(2.days()),
+    PrimitiveDateTime::MAX
+);
+
+assert_eq!(
+    datetime!(2019 - 11 - 25 15:30).saturating_add(27.hours()),
+    datetime!(2019 - 11 - 26 18:30)
+);
+

pub const fn saturating_sub(self, duration: Duration) -> PrimitiveDateTime

Computes self - duration, saturating value on overflow.

+ +
assert_eq!(
+    PrimitiveDateTime::MIN.saturating_sub(2.days()),
+    PrimitiveDateTime::MIN
+);
+
+assert_eq!(
+    PrimitiveDateTime::MAX.saturating_sub((-2).days()),
+    PrimitiveDateTime::MAX
+);
+
+assert_eq!(
+    datetime!(2019 - 11 - 25 15:30).saturating_sub(27.hours()),
+    datetime!(2019 - 11 - 24 12:30)
+);
+
§

impl PrimitiveDateTime

Methods that replace part of the PrimitiveDateTime.

+

pub const fn replace_time(self, time: Time) -> PrimitiveDateTime

Replace the time, preserving the date.

+ +
assert_eq!(
+    datetime!(2020-01-01 17:00).replace_time(time!(5:00)),
+    datetime!(2020-01-01 5:00)
+);
+

pub const fn replace_date(self, date: Date) -> PrimitiveDateTime

Replace the date, preserving the time.

+ +
assert_eq!(
+    datetime!(2020-01-01 12:00).replace_date(date!(2020-01-30)),
+    datetime!(2020-01-30 12:00)
+);
+

pub const fn replace_year( + self, + year: i32 +) -> Result<PrimitiveDateTime, ComponentRange>

Replace the year. The month and day will be unchanged.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 12:00).replace_year(2019),
+    Ok(datetime!(2019 - 02 - 18 12:00))
+);
+assert!(datetime!(2022 - 02 - 18 12:00).replace_year(-1_000_000_000).is_err()); // -1_000_000_000 isn't a valid year
+assert!(datetime!(2022 - 02 - 18 12:00).replace_year(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid year
+

pub const fn replace_month( + self, + month: Month +) -> Result<PrimitiveDateTime, ComponentRange>

Replace the month of the year.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 12:00).replace_month(Month::January),
+    Ok(datetime!(2022 - 01 - 18 12:00))
+);
+assert!(datetime!(2022 - 01 - 30 12:00).replace_month(Month::February).is_err()); // 30 isn't a valid day in February
+

pub const fn replace_day( + self, + day: u8 +) -> Result<PrimitiveDateTime, ComponentRange>

Replace the day of the month.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 12:00).replace_day(1),
+    Ok(datetime!(2022 - 02 - 01 12:00))
+);
+assert!(datetime!(2022 - 02 - 18 12:00).replace_day(0).is_err()); // 00 isn't a valid day
+assert!(datetime!(2022 - 02 - 18 12:00).replace_day(30).is_err()); // 30 isn't a valid day in February
+

pub const fn replace_ordinal( + self, + ordinal: u16 +) -> Result<PrimitiveDateTime, ComponentRange>

Replace the day of the year.

+ +
assert_eq!(datetime!(2022-049 12:00).replace_ordinal(1), Ok(datetime!(2022-001 12:00)));
+assert!(datetime!(2022-049 12:00).replace_ordinal(0).is_err()); // 0 isn't a valid ordinal
+assert!(datetime!(2022-049 12:00).replace_ordinal(366).is_err()); // 2022 isn't a leap year
+

pub const fn replace_hour( + self, + hour: u8 +) -> Result<PrimitiveDateTime, ComponentRange>

Replace the clock hour.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_hour(7),
+    Ok(datetime!(2022 - 02 - 18 07:02:03.004_005_006))
+);
+assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_hour(24).is_err()); // 24 isn't a valid hour
+

pub const fn replace_minute( + self, + minute: u8 +) -> Result<PrimitiveDateTime, ComponentRange>

Replace the minutes within the hour.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_minute(7),
+    Ok(datetime!(2022 - 02 - 18 01:07:03.004_005_006))
+);
+assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_minute(60).is_err()); // 60 isn't a valid minute
+

pub const fn replace_second( + self, + second: u8 +) -> Result<PrimitiveDateTime, ComponentRange>

Replace the seconds within the minute.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_second(7),
+    Ok(datetime!(2022 - 02 - 18 01:02:07.004_005_006))
+);
+assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_second(60).is_err()); // 60 isn't a valid second
+

pub const fn replace_millisecond( + self, + millisecond: u16 +) -> Result<PrimitiveDateTime, ComponentRange>

Replace the milliseconds within the second.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_millisecond(7),
+    Ok(datetime!(2022 - 02 - 18 01:02:03.007))
+);
+assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_millisecond(1_000).is_err()); // 1_000 isn't a valid millisecond
+

pub const fn replace_microsecond( + self, + microsecond: u32 +) -> Result<PrimitiveDateTime, ComponentRange>

Replace the microseconds within the second.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_microsecond(7_008),
+    Ok(datetime!(2022 - 02 - 18 01:02:03.007_008))
+);
+assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_microsecond(1_000_000).is_err()); // 1_000_000 isn't a valid microsecond
+

pub const fn replace_nanosecond( + self, + nanosecond: u32 +) -> Result<PrimitiveDateTime, ComponentRange>

Replace the nanoseconds within the second.

+ +
assert_eq!(
+    datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_nanosecond(7_008_009),
+    Ok(datetime!(2022 - 02 - 18 01:02:03.007_008_009))
+);
+assert!(datetime!(2022 - 02 - 18 01:02:03.004_005_006).replace_nanosecond(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid nanosecond
+
§

impl PrimitiveDateTime

pub fn format_into( + self, + output: &mut impl Write, + format: &(impl Formattable + ?Sized) +) -> Result<usize, Format>

Available on crate feature formatting only.

Format the PrimitiveDateTime using the provided format +description.

+

pub fn format( + self, + format: &(impl Formattable + ?Sized) +) -> Result<String, Format>

Available on crate feature formatting only.

Format the PrimitiveDateTime using the provided format +description.

+ +
let format = format_description::parse("[year]-[month]-[day] [hour]:[minute]:[second]")?;
+assert_eq!(
+    datetime!(2020-01-02 03:04:05).format(&format)?,
+    "2020-01-02 03:04:05"
+);
+
§

impl PrimitiveDateTime

pub fn parse( + input: &str, + description: &(impl Parsable + ?Sized) +) -> Result<PrimitiveDateTime, Parse>

Available on crate feature parsing only.

Parse a PrimitiveDateTime from the input using the provided format +description.

+ +
let format = format_description!("[year]-[month]-[day] [hour]:[minute]:[second]");
+assert_eq!(
+    PrimitiveDateTime::parse("2020-01-02 03:04:05", &format)?,
+    datetime!(2020-01-02 03:04:05)
+);
+

Trait Implementations§

§

impl Add<Duration> for PrimitiveDateTime

§

fn add(self, duration: Duration) -> <PrimitiveDateTime as Add<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = PrimitiveDateTime

The resulting type after applying the + operator.
§

impl Add<Duration> for PrimitiveDateTime

§

fn add(self, duration: Duration) -> <PrimitiveDateTime as Add<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = PrimitiveDateTime

The resulting type after applying the + operator.
§

impl AddAssign<Duration> for PrimitiveDateTime

§

fn add_assign(&mut self, duration: Duration)

§Panics
+

This may panic if an overflow occurs.

+
§

impl AddAssign<Duration> for PrimitiveDateTime

§

fn add_assign(&mut self, duration: Duration)

§Panics
+

This may panic if an overflow occurs.

+
§

impl Clone for PrimitiveDateTime

§

fn clone(&self) -> PrimitiveDateTime

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for PrimitiveDateTime

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for PrimitiveDateTime

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Hash for PrimitiveDateTime

§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl Ord for PrimitiveDateTime

§

fn cmp(&self, other: &PrimitiveDateTime) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
§

impl PartialEq for PrimitiveDateTime

§

fn eq(&self, other: &PrimitiveDateTime) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialOrd for PrimitiveDateTime

§

fn partial_cmp(&self, other: &PrimitiveDateTime) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl SmartDisplay for PrimitiveDateTime

§

type Metadata = ()

User-provided metadata type.
§

fn metadata(&self, _: FormatterOptions) -> Metadata<'_, PrimitiveDateTime>

Compute any information needed to format the value. This must, at a minimum, determine the +width of the value before any padding is added by the formatter. Read more
§

fn fmt_with_metadata( + &self, + f: &mut Formatter<'_>, + metadata: Metadata<'_, PrimitiveDateTime> +) -> Result<(), Error>

Format the value using the given formatter and metadata. The formatted output should have +the width indicated by the metadata. This is before any padding is added by the +formatter. Read more
§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Format the value using the given formatter. This is the same as Display::fmt. Read more
§

impl Sub<Duration> for PrimitiveDateTime

§

fn sub(self, duration: Duration) -> <PrimitiveDateTime as Sub<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = PrimitiveDateTime

The resulting type after applying the - operator.
§

impl Sub<Duration> for PrimitiveDateTime

§

fn sub(self, duration: Duration) -> <PrimitiveDateTime as Sub<Duration>>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = PrimitiveDateTime

The resulting type after applying the - operator.
§

impl Sub for PrimitiveDateTime

§

fn sub(self, rhs: PrimitiveDateTime) -> <PrimitiveDateTime as Sub>::Output

§Panics
+

This may panic if an overflow occurs.

+
§

type Output = Duration

The resulting type after applying the - operator.
§

impl SubAssign<Duration> for PrimitiveDateTime

§

fn sub_assign(&mut self, duration: Duration)

§Panics
+

This may panic if an overflow occurs.

+
§

impl SubAssign<Duration> for PrimitiveDateTime

§

fn sub_assign(&mut self, duration: Duration)

§Panics
+

This may panic if an overflow occurs.

+
§

impl TryFrom<Parsed> for PrimitiveDateTime

§

type Error = TryFromParsed

The type returned in the event of a conversion error.
§

fn try_from( + parsed: Parsed +) -> Result<PrimitiveDateTime, <PrimitiveDateTime as TryFrom<Parsed>>::Error>

Performs the conversion.
§

impl Copy for PrimitiveDateTime

§

impl Eq for PrimitiveDateTime

§

impl StructuralPartialEq for PrimitiveDateTime

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/struct.Time.html b/actix_web/cookie/time/struct.Time.html new file mode 100644 index 000000000..b8fd8d519 --- /dev/null +++ b/actix_web/cookie/time/struct.Time.html @@ -0,0 +1,245 @@ +Time in actix_web::cookie::time - Rust

Struct actix_web::cookie::time::Time

#[repr(C)]
pub struct Time { /* private fields */ }
Available on crate feature cookies only.
Expand description

The clock time within a given date. Nanosecond precision.

+

All minutes are assumed to have exactly 60 seconds; no attempt is made to handle leap seconds +(either positive or negative).

+

When comparing two Times, they are assumed to be in the same calendar date.

+

Implementations§

§

impl Time

pub const MIDNIGHT: Time = Self::MIN

Create a Time that is exactly midnight.

+ +
assert_eq!(Time::MIDNIGHT, time!(0:00));
+

pub const fn from_hms( + hour: u8, + minute: u8, + second: u8 +) -> Result<Time, ComponentRange>

Attempt to create a Time from the hour, minute, and second.

+ +
assert!(Time::from_hms(1, 2, 3).is_ok());
+ +
assert!(Time::from_hms(24, 0, 0).is_err()); // 24 isn't a valid hour.
+assert!(Time::from_hms(0, 60, 0).is_err()); // 60 isn't a valid minute.
+assert!(Time::from_hms(0, 0, 60).is_err()); // 60 isn't a valid second.
+

pub const fn from_hms_milli( + hour: u8, + minute: u8, + second: u8, + millisecond: u16 +) -> Result<Time, ComponentRange>

Attempt to create a Time from the hour, minute, second, and millisecond.

+ +
assert!(Time::from_hms_milli(1, 2, 3, 4).is_ok());
+ +
assert!(Time::from_hms_milli(24, 0, 0, 0).is_err()); // 24 isn't a valid hour.
+assert!(Time::from_hms_milli(0, 60, 0, 0).is_err()); // 60 isn't a valid minute.
+assert!(Time::from_hms_milli(0, 0, 60, 0).is_err()); // 60 isn't a valid second.
+assert!(Time::from_hms_milli(0, 0, 0, 1_000).is_err()); // 1_000 isn't a valid millisecond.
+

pub const fn from_hms_micro( + hour: u8, + minute: u8, + second: u8, + microsecond: u32 +) -> Result<Time, ComponentRange>

Attempt to create a Time from the hour, minute, second, and microsecond.

+ +
assert!(Time::from_hms_micro(1, 2, 3, 4).is_ok());
+ +
assert!(Time::from_hms_micro(24, 0, 0, 0).is_err()); // 24 isn't a valid hour.
+assert!(Time::from_hms_micro(0, 60, 0, 0).is_err()); // 60 isn't a valid minute.
+assert!(Time::from_hms_micro(0, 0, 60, 0).is_err()); // 60 isn't a valid second.
+assert!(Time::from_hms_micro(0, 0, 0, 1_000_000).is_err()); // 1_000_000 isn't a valid microsecond.
+

pub const fn from_hms_nano( + hour: u8, + minute: u8, + second: u8, + nanosecond: u32 +) -> Result<Time, ComponentRange>

Attempt to create a Time from the hour, minute, second, and nanosecond.

+ +
assert!(Time::from_hms_nano(1, 2, 3, 4).is_ok());
+ +
assert!(Time::from_hms_nano(24, 0, 0, 0).is_err()); // 24 isn't a valid hour.
+assert!(Time::from_hms_nano(0, 60, 0, 0).is_err()); // 60 isn't a valid minute.
+assert!(Time::from_hms_nano(0, 0, 60, 0).is_err()); // 60 isn't a valid second.
+assert!(Time::from_hms_nano(0, 0, 0, 1_000_000_000).is_err()); // 1_000_000_000 isn't a valid nanosecond.
+

pub const fn as_hms(self) -> (u8, u8, u8)

Get the clock hour, minute, and second.

+ +
assert_eq!(time!(0:00:00).as_hms(), (0, 0, 0));
+assert_eq!(time!(23:59:59).as_hms(), (23, 59, 59));
+

pub const fn as_hms_milli(self) -> (u8, u8, u8, u16)

Get the clock hour, minute, second, and millisecond.

+ +
assert_eq!(time!(0:00:00).as_hms_milli(), (0, 0, 0, 0));
+assert_eq!(time!(23:59:59.999).as_hms_milli(), (23, 59, 59, 999));
+

pub const fn as_hms_micro(self) -> (u8, u8, u8, u32)

Get the clock hour, minute, second, and microsecond.

+ +
assert_eq!(time!(0:00:00).as_hms_micro(), (0, 0, 0, 0));
+assert_eq!(
+    time!(23:59:59.999_999).as_hms_micro(),
+    (23, 59, 59, 999_999)
+);
+

pub const fn as_hms_nano(self) -> (u8, u8, u8, u32)

Get the clock hour, minute, second, and nanosecond.

+ +
assert_eq!(time!(0:00:00).as_hms_nano(), (0, 0, 0, 0));
+assert_eq!(
+    time!(23:59:59.999_999_999).as_hms_nano(),
+    (23, 59, 59, 999_999_999)
+);
+

pub const fn hour(self) -> u8

Get the clock hour.

+

The returned value will always be in the range 0..24.

+ +
assert_eq!(time!(0:00:00).hour(), 0);
+assert_eq!(time!(23:59:59).hour(), 23);
+

pub const fn minute(self) -> u8

Get the minute within the hour.

+

The returned value will always be in the range 0..60.

+ +
assert_eq!(time!(0:00:00).minute(), 0);
+assert_eq!(time!(23:59:59).minute(), 59);
+

pub const fn second(self) -> u8

Get the second within the minute.

+

The returned value will always be in the range 0..60.

+ +
assert_eq!(time!(0:00:00).second(), 0);
+assert_eq!(time!(23:59:59).second(), 59);
+

pub const fn millisecond(self) -> u16

Get the milliseconds within the second.

+

The returned value will always be in the range 0..1_000.

+ +
assert_eq!(time!(0:00).millisecond(), 0);
+assert_eq!(time!(23:59:59.999).millisecond(), 999);
+

pub const fn microsecond(self) -> u32

Get the microseconds within the second.

+

The returned value will always be in the range 0..1_000_000.

+ +
assert_eq!(time!(0:00).microsecond(), 0);
+assert_eq!(time!(23:59:59.999_999).microsecond(), 999_999);
+

pub const fn nanosecond(self) -> u32

Get the nanoseconds within the second.

+

The returned value will always be in the range 0..1_000_000_000.

+ +
assert_eq!(time!(0:00).nanosecond(), 0);
+assert_eq!(time!(23:59:59.999_999_999).nanosecond(), 999_999_999);
+

pub const fn replace_hour(self, hour: u8) -> Result<Time, ComponentRange>

Replace the clock hour.

+ +
assert_eq!(
+    time!(01:02:03.004_005_006).replace_hour(7),
+    Ok(time!(07:02:03.004_005_006))
+);
+assert!(time!(01:02:03.004_005_006).replace_hour(24).is_err()); // 24 isn't a valid hour
+

pub const fn replace_minute(self, minute: u8) -> Result<Time, ComponentRange>

Replace the minutes within the hour.

+ +
assert_eq!(
+    time!(01:02:03.004_005_006).replace_minute(7),
+    Ok(time!(01:07:03.004_005_006))
+);
+assert!(time!(01:02:03.004_005_006).replace_minute(60).is_err()); // 60 isn't a valid minute
+

pub const fn replace_second(self, second: u8) -> Result<Time, ComponentRange>

Replace the seconds within the minute.

+ +
assert_eq!(
+    time!(01:02:03.004_005_006).replace_second(7),
+    Ok(time!(01:02:07.004_005_006))
+);
+assert!(time!(01:02:03.004_005_006).replace_second(60).is_err()); // 60 isn't a valid second
+

pub const fn replace_millisecond( + self, + millisecond: u16 +) -> Result<Time, ComponentRange>

Replace the milliseconds within the second.

+ +
assert_eq!(
+    time!(01:02:03.004_005_006).replace_millisecond(7),
+    Ok(time!(01:02:03.007))
+);
+assert!(time!(01:02:03.004_005_006).replace_millisecond(1_000).is_err()); // 1_000 isn't a valid millisecond
+

pub const fn replace_microsecond( + self, + microsecond: u32 +) -> Result<Time, ComponentRange>

Replace the microseconds within the second.

+ +
assert_eq!(
+    time!(01:02:03.004_005_006).replace_microsecond(7_008),
+    Ok(time!(01:02:03.007_008))
+);
+assert!(time!(01:02:03.004_005_006).replace_microsecond(1_000_000).is_err()); // 1_000_000 isn't a valid microsecond
+

pub const fn replace_nanosecond( + self, + nanosecond: u32 +) -> Result<Time, ComponentRange>

Replace the nanoseconds within the second.

+ +
assert_eq!(
+    time!(01:02:03.004_005_006).replace_nanosecond(7_008_009),
+    Ok(time!(01:02:03.007_008_009))
+);
+assert!(time!(01:02:03.004_005_006).replace_nanosecond(1_000_000_000).is_err()); // 1_000_000_000 isn't a valid nanosecond
+
§

impl Time

pub fn format_into( + self, + output: &mut impl Write, + format: &(impl Formattable + ?Sized) +) -> Result<usize, Format>

Available on crate feature formatting only.

Format the Time using the provided format description.

+

pub fn format( + self, + format: &(impl Formattable + ?Sized) +) -> Result<String, Format>

Available on crate feature formatting only.

Format the Time using the provided format description.

+ +
let format = format_description::parse("[hour]:[minute]:[second]")?;
+assert_eq!(time!(12:00).format(&format)?, "12:00:00");
+
§

impl Time

pub fn parse( + input: &str, + description: &(impl Parsable + ?Sized) +) -> Result<Time, Parse>

Available on crate feature parsing only.

Parse a Time from the input using the provided format +description.

+ +
let format = format_description!("[hour]:[minute]:[second]");
+assert_eq!(Time::parse("12:00:00", &format)?, time!(12:00));
+

Trait Implementations§

§

impl Add<Duration> for Time

§

fn add(self, duration: Duration) -> <Time as Add<Duration>>::Output

Add the sub-day time of the Duration to the Time. Wraps on overflow.

+ +
assert_eq!(time!(12:00) + 2.hours(), time!(14:00));
+assert_eq!(time!(0:00:01) + (-2).seconds(), time!(23:59:59));
+
§

type Output = Time

The resulting type after applying the + operator.
§

impl Add<Duration> for Time

§

fn add(self, duration: Duration) -> <Time as Add<Duration>>::Output

Add the sub-day time of the std::time::Duration to the Time. Wraps on overflow.

+ +
assert_eq!(time!(12:00) + 2.std_hours(), time!(14:00));
+assert_eq!(time!(23:59:59) + 2.std_seconds(), time!(0:00:01));
+
§

type Output = Time

The resulting type after applying the + operator.
§

impl AddAssign<Duration> for Time

§

fn add_assign(&mut self, rhs: Duration)

Performs the += operation. Read more
§

impl AddAssign<Duration> for Time

§

fn add_assign(&mut self, rhs: Duration)

Performs the += operation. Read more
§

impl Clone for Time

§

fn clone(&self) -> Time

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Time

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for Time

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Hash for Time

§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl Ord for Time

§

fn cmp(&self, other: &Time) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
§

impl PartialEq for Time

§

fn eq(&self, other: &Time) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialOrd for Time

§

fn partial_cmp(&self, other: &Time) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl SmartDisplay for Time

§

type Metadata = TimeMetadata

User-provided metadata type.
§

fn metadata(&self, _: FormatterOptions) -> Metadata<'_, Time>

Compute any information needed to format the value. This must, at a minimum, determine the +width of the value before any padding is added by the formatter. Read more
§

fn fmt_with_metadata( + &self, + f: &mut Formatter<'_>, + metadata: Metadata<'_, Time> +) -> Result<(), Error>

Format the value using the given formatter and metadata. The formatted output should have +the width indicated by the metadata. This is before any padding is added by the +formatter. Read more
§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Format the value using the given formatter. This is the same as Display::fmt. Read more
§

impl Sub<Duration> for Time

§

fn sub(self, duration: Duration) -> <Time as Sub<Duration>>::Output

Subtract the sub-day time of the std::time::Duration from the Time. Wraps on overflow.

+ +
assert_eq!(time!(14:00) - 2.std_hours(), time!(12:00));
+assert_eq!(time!(0:00:01) - 2.std_seconds(), time!(23:59:59));
+
§

type Output = Time

The resulting type after applying the - operator.
§

impl Sub<Duration> for Time

§

fn sub(self, duration: Duration) -> <Time as Sub<Duration>>::Output

Subtract the sub-day time of the Duration from the Time. Wraps on overflow.

+ +
assert_eq!(time!(14:00) - 2.hours(), time!(12:00));
+assert_eq!(time!(23:59:59) - (-2).seconds(), time!(0:00:01));
+
§

type Output = Time

The resulting type after applying the - operator.
§

impl Sub for Time

§

fn sub(self, rhs: Time) -> <Time as Sub>::Output

Subtract two Times, returning the Duration between. This assumes both Times are in +the same calendar day.

+ +
assert_eq!(time!(0:00) - time!(0:00), 0.seconds());
+assert_eq!(time!(1:00) - time!(0:00), 1.hours());
+assert_eq!(time!(0:00) - time!(1:00), (-1).hours());
+assert_eq!(time!(0:00) - time!(23:00), (-23).hours());
+
§

type Output = Duration

The resulting type after applying the - operator.
§

impl SubAssign<Duration> for Time

§

fn sub_assign(&mut self, rhs: Duration)

Performs the -= operation. Read more
§

impl SubAssign<Duration> for Time

§

fn sub_assign(&mut self, rhs: Duration)

Performs the -= operation. Read more
§

impl TryFrom<Parsed> for Time

§

type Error = TryFromParsed

The type returned in the event of a conversion error.
§

fn try_from(parsed: Parsed) -> Result<Time, <Time as TryFrom<Parsed>>::Error>

Performs the conversion.
§

impl Copy for Time

§

impl Eq for Time

Auto Trait Implementations§

§

impl Freeze for Time

§

impl RefUnwindSafe for Time

§

impl Send for Time

§

impl Sync for Time

§

impl Unpin for Time

§

impl UnwindSafe for Time

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/struct.UtcOffset.html b/actix_web/cookie/time/struct.UtcOffset.html new file mode 100644 index 000000000..8d832ac29 --- /dev/null +++ b/actix_web/cookie/time/struct.UtcOffset.html @@ -0,0 +1,131 @@ +UtcOffset in actix_web::cookie::time - Rust

Struct actix_web::cookie::time::UtcOffset

pub struct UtcOffset { /* private fields */ }
Available on crate feature cookies only.
Expand description

An offset from UTC.

+

This struct can store values up to ±25:59:59. If you need support outside this range, please +file an issue with your use case.

+

Implementations§

§

impl UtcOffset

pub const UTC: UtcOffset = _

A UtcOffset that is UTC.

+ +
assert_eq!(UtcOffset::UTC, offset!(UTC));
+

pub const fn from_hms( + hours: i8, + minutes: i8, + seconds: i8 +) -> Result<UtcOffset, ComponentRange>

Create a UtcOffset representing an offset by the number of hours, minutes, and seconds +provided.

+

The sign of all three components should match. If they do not, all smaller components will +have their signs flipped.

+ +
assert_eq!(UtcOffset::from_hms(1, 2, 3)?.as_hms(), (1, 2, 3));
+assert_eq!(UtcOffset::from_hms(1, -2, -3)?.as_hms(), (1, 2, 3));
+

pub const fn from_whole_seconds( + seconds: i32 +) -> Result<UtcOffset, ComponentRange>

Create a UtcOffset representing an offset by the number of seconds provided.

+ +
assert_eq!(UtcOffset::from_whole_seconds(3_723)?.as_hms(), (1, 2, 3));
+

pub const fn as_hms(self) -> (i8, i8, i8)

Obtain the UTC offset as its hours, minutes, and seconds. The sign of all three components +will always match. A positive value indicates an offset to the east; a negative to the west.

+ +
assert_eq!(offset!(+1:02:03).as_hms(), (1, 2, 3));
+assert_eq!(offset!(-1:02:03).as_hms(), (-1, -2, -3));
+

pub const fn whole_hours(self) -> i8

Obtain the number of whole hours the offset is from UTC. A positive value indicates an +offset to the east; a negative to the west.

+ +
assert_eq!(offset!(+1:02:03).whole_hours(), 1);
+assert_eq!(offset!(-1:02:03).whole_hours(), -1);
+

pub const fn whole_minutes(self) -> i16

Obtain the number of whole minutes the offset is from UTC. A positive value indicates an +offset to the east; a negative to the west.

+ +
assert_eq!(offset!(+1:02:03).whole_minutes(), 62);
+assert_eq!(offset!(-1:02:03).whole_minutes(), -62);
+

pub const fn minutes_past_hour(self) -> i8

Obtain the number of minutes past the hour the offset is from UTC. A positive value +indicates an offset to the east; a negative to the west.

+ +
assert_eq!(offset!(+1:02:03).minutes_past_hour(), 2);
+assert_eq!(offset!(-1:02:03).minutes_past_hour(), -2);
+

pub const fn whole_seconds(self) -> i32

Obtain the number of whole seconds the offset is from UTC. A positive value indicates an +offset to the east; a negative to the west.

+ +
assert_eq!(offset!(+1:02:03).whole_seconds(), 3723);
+assert_eq!(offset!(-1:02:03).whole_seconds(), -3723);
+

pub const fn seconds_past_minute(self) -> i8

Obtain the number of seconds past the minute the offset is from UTC. A positive value +indicates an offset to the east; a negative to the west.

+ +
assert_eq!(offset!(+1:02:03).seconds_past_minute(), 3);
+assert_eq!(offset!(-1:02:03).seconds_past_minute(), -3);
+

pub const fn is_utc(self) -> bool

Check if the offset is exactly UTC.

+ +
assert!(!offset!(+1:02:03).is_utc());
+assert!(!offset!(-1:02:03).is_utc());
+assert!(offset!(UTC).is_utc());
+

pub const fn is_positive(self) -> bool

Check if the offset is positive, or east of UTC.

+ +
assert!(offset!(+1:02:03).is_positive());
+assert!(!offset!(-1:02:03).is_positive());
+assert!(!offset!(UTC).is_positive());
+

pub const fn is_negative(self) -> bool

Check if the offset is negative, or west of UTC.

+ +
assert!(!offset!(+1:02:03).is_negative());
+assert!(offset!(-1:02:03).is_negative());
+assert!(!offset!(UTC).is_negative());
+
§

impl UtcOffset

pub fn format_into( + self, + output: &mut impl Write, + format: &(impl Formattable + ?Sized) +) -> Result<usize, Format>

Available on crate feature formatting only.

Format the UtcOffset using the provided format description.

+

pub fn format( + self, + format: &(impl Formattable + ?Sized) +) -> Result<String, Format>

Available on crate feature formatting only.

Format the UtcOffset using the provided format description.

+ +
let format = format_description::parse("[offset_hour sign:mandatory]:[offset_minute]")?;
+assert_eq!(offset!(+1).format(&format)?, "+01:00");
+
§

impl UtcOffset

pub fn parse( + input: &str, + description: &(impl Parsable + ?Sized) +) -> Result<UtcOffset, Parse>

Available on crate feature parsing only.

Parse a UtcOffset from the input using the provided format +description.

+ +
let format = format_description!("[offset_hour]:[offset_minute]");
+assert_eq!(UtcOffset::parse("-03:42", &format)?, offset!(-3:42));
+

Trait Implementations§

§

impl Clone for UtcOffset

§

fn clone(&self) -> UtcOffset

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for UtcOffset

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for UtcOffset

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Hash for UtcOffset

§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl Neg for UtcOffset

§

type Output = UtcOffset

The resulting type after applying the - operator.
§

fn neg(self) -> <UtcOffset as Neg>::Output

Performs the unary - operation. Read more
§

impl Ord for UtcOffset

§

fn cmp(&self, other: &UtcOffset) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
§

impl PartialEq for UtcOffset

§

fn eq(&self, other: &UtcOffset) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialOrd for UtcOffset

§

fn partial_cmp(&self, other: &UtcOffset) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl SmartDisplay for UtcOffset

§

type Metadata = UtcOffsetMetadata

User-provided metadata type.
§

fn metadata(&self, _: FormatterOptions) -> Metadata<'_, UtcOffset>

Compute any information needed to format the value. This must, at a minimum, determine the +width of the value before any padding is added by the formatter. Read more
§

fn fmt_with_metadata( + &self, + f: &mut Formatter<'_>, + metadata: Metadata<'_, UtcOffset> +) -> Result<(), Error>

Format the value using the given formatter and metadata. The formatted output should have +the width indicated by the metadata. This is before any padding is added by the +formatter. Read more
§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Format the value using the given formatter. This is the same as Display::fmt. Read more
§

impl TryFrom<Parsed> for UtcOffset

§

type Error = TryFromParsed

The type returned in the event of a conversion error.
§

fn try_from( + parsed: Parsed +) -> Result<UtcOffset, <UtcOffset as TryFrom<Parsed>>::Error>

Performs the conversion.
§

impl Copy for UtcOffset

§

impl Eq for UtcOffset

§

impl StructuralPartialEq for UtcOffset

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/cookie/time/type.Result.html b/actix_web/cookie/time/type.Result.html new file mode 100644 index 000000000..a1a442cd3 --- /dev/null +++ b/actix_web/cookie/time/type.Result.html @@ -0,0 +1,7 @@ +Result in actix_web::cookie::time - Rust

Type Alias actix_web::cookie::time::Result

pub type Result<T> = Result<T, Error>;
Available on crate feature cookies only.
Expand description

An alias for std::result::Result with a generic error from the time crate.

+

Aliased Type§

enum Result<T> {
+    Ok(T),
+    Err(Error),
+}

Variants§

§1.0.0

Ok(T)

Contains the success value

+
§1.0.0

Err(Error)

Contains the error value

+
\ No newline at end of file diff --git a/actix_web/cookie/time/util/fn.days_in_year.html b/actix_web/cookie/time/util/fn.days_in_year.html new file mode 100644 index 000000000..7721b570f --- /dev/null +++ b/actix_web/cookie/time/util/fn.days_in_year.html @@ -0,0 +1,9 @@ +days_in_year in actix_web::cookie::time::util - Rust

Function actix_web::cookie::time::util::days_in_year

pub const fn days_in_year(year: i32) -> u16
Available on crate feature cookies only.
Expand description

Get the number of calendar days in a given year.

+

The returned value will always be either 365 or 366.

+ +
assert_eq!(days_in_year(1900), 365);
+assert_eq!(days_in_year(2000), 366);
+assert_eq!(days_in_year(2004), 366);
+assert_eq!(days_in_year(2005), 365);
+assert_eq!(days_in_year(2100), 365);
+
\ No newline at end of file diff --git a/actix_web/cookie/time/util/fn.days_in_year_month.html b/actix_web/cookie/time/util/fn.days_in_year_month.html new file mode 100644 index 000000000..bbd26de8a --- /dev/null +++ b/actix_web/cookie/time/util/fn.days_in_year_month.html @@ -0,0 +1,4 @@ +days_in_year_month in actix_web::cookie::time::util - Rust

Function actix_web::cookie::time::util::days_in_year_month

pub const fn days_in_year_month(year: i32, month: Month) -> u8
Available on crate feature cookies only.
Expand description

Get the number of days in the month of a given year.

+ +
assert_eq!(util::days_in_year_month(2020, Month::February), 29);
+
\ No newline at end of file diff --git a/actix_web/cookie/time/util/fn.is_leap_year.html b/actix_web/cookie/time/util/fn.is_leap_year.html new file mode 100644 index 000000000..f0995a344 --- /dev/null +++ b/actix_web/cookie/time/util/fn.is_leap_year.html @@ -0,0 +1,9 @@ +is_leap_year in actix_web::cookie::time::util - Rust

Function actix_web::cookie::time::util::is_leap_year

pub const fn is_leap_year(year: i32) -> bool
Available on crate feature cookies only.
Expand description

Returns if the provided year is a leap year in the proleptic Gregorian calendar. Uses +astronomical year numbering.

+ +
assert!(!is_leap_year(1900));
+assert!(is_leap_year(2000));
+assert!(is_leap_year(2004));
+assert!(!is_leap_year(2005));
+assert!(!is_leap_year(2100));
+
\ No newline at end of file diff --git a/actix_web/cookie/time/util/fn.weeks_in_year.html b/actix_web/cookie/time/util/fn.weeks_in_year.html new file mode 100644 index 000000000..b5e0a11f3 --- /dev/null +++ b/actix_web/cookie/time/util/fn.weeks_in_year.html @@ -0,0 +1,6 @@ +weeks_in_year in actix_web::cookie::time::util - Rust

Function actix_web::cookie::time::util::weeks_in_year

pub const fn weeks_in_year(year: i32) -> u8
Available on crate feature cookies only.
Expand description

Get the number of weeks in the ISO year.

+

The returned value will always be either 52 or 53.

+ +
assert_eq!(weeks_in_year(2019), 52);
+assert_eq!(weeks_in_year(2020), 53);
+
\ No newline at end of file diff --git a/actix_web/cookie/time/util/index.html b/actix_web/cookie/time/util/index.html new file mode 100644 index 000000000..44ead17e0 --- /dev/null +++ b/actix_web/cookie/time/util/index.html @@ -0,0 +1,3 @@ +actix_web::cookie::time::util - Rust

Module actix_web::cookie::time::util

Available on crate feature cookies only.
Expand description

Utility functions.

+

Functions§

\ No newline at end of file diff --git a/actix_web/cookie/time/util/sidebar-items.js b/actix_web/cookie/time/util/sidebar-items.js new file mode 100644 index 000000000..5b188d269 --- /dev/null +++ b/actix_web/cookie/time/util/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["days_in_year","days_in_year_month","is_leap_year","weeks_in_year"]}; \ No newline at end of file diff --git a/actix_web/data/struct.Data.html b/actix_web/data/struct.Data.html new file mode 100644 index 000000000..9ad2a2465 --- /dev/null +++ b/actix_web/data/struct.Data.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/web/struct.Data.html...

+ + + \ No newline at end of file diff --git a/actix_web/dev/enum.JsonBody.html b/actix_web/dev/enum.JsonBody.html new file mode 100644 index 000000000..6a95a0204 --- /dev/null +++ b/actix_web/dev/enum.JsonBody.html @@ -0,0 +1,137 @@ +JsonBody in actix_web::dev - Rust

Enum actix_web::dev::JsonBody

source ·
pub enum JsonBody<T> {
+    Error(Option<JsonPayloadError>),
+    Body {
+        limit: usize,
+        length: Option<usize>,
+        payload: Decompress<Payload>,
+        buf: BytesMut,
+        _res: PhantomData<T>,
+    },
+}
Expand description

Future that resolves to some T when parsed from a JSON payload.

+

Can deserialize any type T that implements Deserialize.

+

Returns error if:

+
    +
  • Content-Type is not application/json when ctype_required (passed to new) +is true.
  • +
  • Content-Length is greater than limit.
  • +
  • The payload, when consumed, is not valid JSON.
  • +
+

Variants§

§

Error(Option<JsonPayloadError>)

§

Body

Fields

§limit: usize
§length: Option<usize>

Length as reported by Content-Length header, if present.

+
§payload: Decompress<Payload>
Available on crate feature __compress only.
§_res: PhantomData<T>

Implementations§

source§

impl<T: DeserializeOwned> JsonBody<T>

source

pub fn new( + req: &HttpRequest, + payload: &mut Payload, + ctype_fn: Option<&(dyn Fn(Mime) -> bool + Send + Sync)>, + ctype_required: bool +) -> Self

Create a new future to decode a JSON request payload.

+
source

pub fn limit(self, limit: usize) -> Self

Set maximum accepted payload size. The default limit is 2MB.

+

Trait Implementations§

source§

impl<T: DeserializeOwned> Future for JsonBody<T>

§

type Output = Result<T, JsonPayloadError>

The type of value produced on completion.
source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
source§

impl<T> Unpin for JsonBody<T>

Auto Trait Implementations§

§

impl<T> !Freeze for JsonBody<T>

§

impl<T> !RefUnwindSafe for JsonBody<T>

§

impl<T> !Send for JsonBody<T>

§

impl<T> !Sync for JsonBody<T>

§

impl<T> !UnwindSafe for JsonBody<T>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> FutureExt for T
where + T: Future + ?Sized,

§

fn map<U, F>(self, f: F) -> Map<Self, F>
where + F: FnOnce(Self::Output) -> U, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn map_into<U>(self) -> MapInto<Self, U>
where + Self::Output: Into<U>, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnOnce(Self::Output) -> Fut, + Fut: Future, + Self: Sized,

Chain on a computation for when a future finished, passing the result of +the future to the provided closure f. Read more
§

fn left_future<B>(self) -> Either<Self, B>
where + B: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the left-hand variant +of that Either. Read more
§

fn right_future<A>(self) -> Either<A, Self>
where + A: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the right-hand variant +of that Either. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Convert this future into a single element stream. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Output: Future, + Self: Sized,

Flatten the execution of this future when the output of this +future is itself another future. Read more
§

fn flatten_stream(self) -> FlattenStream<Self>
where + Self::Output: Stream, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a future such that poll will never again be called once it has +completed. This method can be used to turn any Future into a +FusedFuture. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnOnce(&Self::Output), + Self: Sized,

Do something with the output of a future before passing it on. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the future. Read more
§

fn shared(self) -> Shared<Self>
where + Self: Sized, + Self::Output: Clone,

Available on crate feature std only.
Create a cloneable handle to this future where all handles will resolve +to the same result. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn unit_error(self) -> UnitError<Self>
where + Self: Sized,

§

fn never_error(self) -> NeverError<Self>
where + Self: Sized,

§

fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where + Self: Unpin,

A convenience for calling Future::poll on Unpin future types.
§

fn now_or_never(self) -> Option<Self::Output>
where + Self: Sized,

Evaluates and consumes the future, returning the resulting output if +the future is ready after the first call to Future::poll. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<F> IntoFuture for F
where + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

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
§

fn try_poll( + self: Pin<&mut F>, + cx: &mut Context<'_> +) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
§

impl<Fut> TryFutureExt for Fut
where + Fut: TryFuture + ?Sized,

§

fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>
where + Self::Ok: Sink<Item, Error = Self::Error>, + Self: Sized,

Available on crate feature sink only.
Flattens the execution of this future when the successful result of this +future is a [Sink]. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + F: FnOnce(Self::Ok) -> T, + Self: Sized,

Maps this future’s success value to a different value. Read more
§

fn map_ok_or_else<T, E, F>(self, e: E, f: F) -> MapOkOrElse<Self, F, E>
where + F: FnOnce(Self::Ok) -> T, + E: FnOnce(Self::Error) -> T, + Self: Sized,

Maps this future’s success value to a different value, and permits for error handling resulting in the same type. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + F: FnOnce(Self::Error) -> E, + Self: Sized,

Maps this future’s error value to a different value. Read more
§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Maps this future’s Error to a new error type +using the Into trait. Read more
§

fn ok_into<U>(self) -> OkInto<Self, U>
where + Self: Sized, + Self::Ok: Into<U>,

Maps this future’s Ok to a new type +using the Into trait.
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnOnce(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Executes another future after this one resolves successfully. The +success value is passed to a closure to create this subsequent future. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnOnce(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Executes another future if this one resolves to an error. The +error value is passed to a closure to create this subsequent future. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnOnce(&Self::Ok), + Self: Sized,

Do something with the success value of a future before passing it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnOnce(&Self::Error), + Self: Sized,

Do something with the error value of a future before passing it on. Read more
§

fn try_flatten(self) -> TryFlatten<Self, Self::Ok>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is another future. Read more
§

fn try_flatten_stream(self) -> TryFlattenStream<Self>
where + Self::Ok: TryStream<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F>
where + Self: Sized, + F: FnOnce(Self::Error) -> Self::Ok,

Unwraps this future’s output, producing a future with this future’s +Ok type as its +Output type. Read more
§

fn into_future(self) -> IntoFuture<Self>
where + Self: Sized,

Wraps a [TryFuture] into a type that implements +Future. Read more
§

fn try_poll_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Result<Self::Ok, Self::Error>>
where + Self: Unpin,

A convenience method for calling [TryFuture::try_poll] on Unpin +future types.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/enum.Payload.html b/actix_web/dev/enum.Payload.html new file mode 100644 index 000000000..e19b828cb --- /dev/null +++ b/actix_web/dev/enum.Payload.html @@ -0,0 +1,270 @@ +Payload in actix_web::dev - Rust

Enum actix_web::dev::Payload

source ·
pub enum Payload<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> {
+    None,
+    H1 {
+        payload: Payload,
+    },
+    H2 {
+        payload: Payload,
+    },
+    Stream {
+        payload: S,
+    },
+}
Expand description

A streaming payload.

+

Variants§

§

None

§

H1

Fields

§payload: Payload
§

H2

Fields

§payload: Payload
§

Stream

Fields

§payload: S

Implementations§

source§

impl<S> Payload<S>

source

pub fn take(&mut self) -> Payload<S>

Takes current payload and replaces it with None value

+

Trait Implementations§

source§

impl<S> From<Payload> for Payload<S>

Available on crate feature http2 only.
source§

fn from(payload: Payload) -> Payload<S>

Converts to this type from the input type.
source§

impl<S> From<Payload> for Payload<S>

source§

fn from(payload: Payload) -> Payload<S>

Converts to this type from the input type.
source§

impl From<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> for Payload

source§

fn from( + payload: Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>> +) -> Payload

Converts to this type from the input type.
source§

impl<S> From<RecvStream> for Payload<S>

Available on crate feature http2 only.
source§

fn from(stream: RecvStream) -> Payload<S>

Converts to this type from the input type.
source§

impl<S> Stream for Payload<S>
where + S: Stream<Item = Result<Bytes, PayloadError>>,

§

type Item = Result<Bytes, PayloadError>

Values yielded by the stream.
source§

fn poll_next( + self: Pin<&mut Payload<S>>, + cx: &mut Context<'_> +) -> Poll<Option<<Payload<S> as Stream>::Item>>

Attempt to pull out the next value of this stream, registering the +current task for wakeup if the value is not yet available, and returning +None if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more
source§

impl<'__pin, S> Unpin for Payload<S>
where + __Origin<'__pin, S>: Unpin,

Auto Trait Implementations§

§

impl<S> Freeze for Payload<S>
where + S: Freeze,

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !RefUnwindSafe for Payload<S>

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Send for Payload<S>

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Sync for Payload<S>

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !UnwindSafe for Payload<S>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<T> StreamExt for T
where + T: Stream + ?Sized,

§

fn next(&mut self) -> Next<'_, Self>
where + Self: Unpin,

Creates a future that resolves to the next item in the stream. Read more
§

fn into_future(self) -> StreamFuture<Self>
where + Self: Sized + Unpin,

Converts this stream into a future of (next_item, tail_of_stream). +If the stream terminates, then the next item is None. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + F: FnMut(Self::Item) -> T, + Self: Sized,

Maps this stream’s items to a different type, returning a new stream of +the resulting type. Read more
§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates a stream which gives the current iteration count as well as +the next value. Read more
§

fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Filters the values produced by this stream according to the provided +asynchronous predicate. Read more
§

fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = Option<T>>, + Self: Sized,

Filters the values produced by this stream while simultaneously mapping +them to a different type according to the provided asynchronous closure. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized,

Computes from this stream’s items new items of a different type using +an asynchronous closure. Read more
§

fn collect<C>(self) -> Collect<Self, C>
where + C: Default + Extend<Self::Item>, + Self: Sized,

Transforms a stream into a collection, returning a +future representing the result of that computation. Read more
§

fn unzip<A, B, FromA, FromB>(self) -> Unzip<Self, FromA, FromB>
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Stream<Item = (A, B)>,

Converts a stream of pairs into a future, which +resolves to pair of containers. Read more
§

fn concat(self) -> Concat<Self>
where + Self: Sized, + Self::Item: Extend<<Self::Item as IntoIterator>::Item> + IntoIterator + Default,

Concatenate all items of a stream into a single extendable +destination, returning a future representing the end result. Read more
§

fn count(self) -> Count<Self>
where + Self: Sized,

Drives the stream to completion, counting the number of items. Read more
§

fn cycle(self) -> Cycle<Self>
where + Self: Sized + Clone,

Repeats a stream endlessly. Read more
§

fn fold<T, Fut, F>(self, init: T, f: F) -> Fold<Self, Fut, T, F>
where + F: FnMut(T, Self::Item) -> Fut, + Fut: Future<Output = T>, + Self: Sized,

Execute an accumulating asynchronous computation over a stream, +collecting all the values into one final result. Read more
§

fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if any element in stream satisfied a predicate. Read more
§

fn all<Fut, F>(self, f: F) -> All<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if all element in stream satisfied a predicate. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Item: Stream, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> FlattenUnorderedWithFlowController<Self, ()>
where + Self::Item: Stream + Unpin, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Polls +inner streams produced by the base stream concurrently. Read more
§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + F: FnMut(Self::Item) -> U, + U: Stream, + Self: Sized,

Maps a stream like [StreamExt::map] but flattens nested Streams. Read more
§

fn flat_map_unordered<U, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> FlatMapUnordered<Self, U, F>
where + U: Stream + Unpin, + F: FnMut(Self::Item) -> U, + Self: Sized,

Available on crate feature alloc only.
Maps a stream like [StreamExt::map] but flattens nested Streams +and polls them concurrently, yielding items in any order, as they made +available. Read more
§

fn scan<S, B, Fut, F>(self, initial_state: S, f: F) -> Scan<Self, S, Fut, F>
where + F: FnMut(&mut S, Self::Item) -> Fut, + Fut: Future<Output = Option<B>>, + Self: Sized,

Combinator similar to [StreamExt::fold] that holds internal state +and produces a new stream. Read more
§

fn skip_while<Fut, F>(self, f: F) -> SkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_while<Fut, F>(self, f: F) -> TakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Take elements from this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_until<Fut>(self, fut: Fut) -> TakeUntil<Self, Fut>
where + Fut: Future, + Self: Sized,

Take elements from this stream until the provided future resolves. Read more
§

fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream. Read more
§

fn for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> ForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Available on crate feature alloc only.
Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates a new stream of at most n items of the underlying stream. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates a new stream which skips n items of the underlying stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a stream such that poll_next will never +again be called once it has finished. This method can be used to turn +any Stream into a FusedStream. Read more
§

fn by_ref(&mut self) -> &mut Self

Borrows a stream, rather than consuming it. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the stream. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn buffered(self, n: usize) -> Buffered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures. Read more
§

fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures (unordered). Read more
§

fn zip<St>(self, other: St) -> Zip<Self, St>
where + St: Stream, + Self: Sized,

An adapter for zipping two streams together. Read more
§

fn chain<St>(self, other: St) -> Chain<Self, St>
where + St: Stream<Item = Self::Item>, + Self: Sized,

Adapter for chaining two streams. Read more
§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates a new stream which exposes a peek method. Read more
§

fn chunks(self, capacity: usize) -> Chunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up items of the stream inside a vector. Read more
§

fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up ready items of the stream inside a vector. Read more
§

fn forward<S>(self, sink: S) -> Forward<Self, S>
where + S: Sink<Self::Ok, Error = Self::Error>, + Self: Sized + TryStream,

Available on crate feature sink only.
A future that completes after the given stream has been fully processed +into the sink and the sink has been flushed and closed. Read more
§

fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
where + Self: Sized + Sink<Item>,

Available on crate features sink and alloc only.
Splits this Stream + Sink object into separate Sink and Stream +objects. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnMut(&Self::Item), + Self: Sized,

Do something with each item of this stream, afterwards passing it on. Read more
§

fn left_stream<B>(self) -> Either<Self, B>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the left-hand variant +of that Either. Read more
§

fn right_stream<B>(self) -> Either<B, Self>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the right-hand variant +of that Either. Read more
§

fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>
where + Self: Unpin,

A convenience method for calling [Stream::poll_next] on Unpin +stream types.
§

fn select_next_some(&mut self) -> SelectNextSome<'_, Self>
where + Self: Unpin + FusedStream,

Returns a Future that resolves when the next item in this stream is +ready. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<S, T, E> TryStream for S
where + S: Stream<Item = 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
§

fn try_poll_next( + self: Pin<&mut S>, + cx: &mut Context<'_> +) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>>

Poll this TryStream as if it were a Stream. Read more
§

impl<S> TryStreamExt for S
where + S: TryStream + ?Sized,

§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Wraps the current stream in a new stream which converts the error type +into the one provided. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> T,

Wraps the current stream in a new stream which maps the success value +using the provided closure. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + Self: Sized, + F: FnMut(Self::Error) -> E,

Wraps the current stream in a new stream which maps the error value +using the provided closure. Read more
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Chain on a computation for when a value is ready, passing the successful +results to the provided closure f. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnMut(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Chain on a computation for when an error happens, passing the +erroneous result to the provided closure f. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnMut(&Self::Ok), + Self: Sized,

Do something with the success value of this stream, afterwards passing +it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnMut(&Self::Error), + Self: Sized,

Do something with the error value of this stream, afterwards passing it on. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Wraps a [TryStream] into a type that implements +Stream Read more
§

fn try_next(&mut self) -> TryNext<'_, Self>
where + Self: Unpin,

Creates a future that attempts to resolve the next item in the stream. +If an error is encountered before the next item, the error is returned +instead. Read more
§

fn try_for_each<Fut, F>(self, f: F) -> TryForEach<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Ok = (), Error = Self::Error>, + Self: Sized,

Attempts to run this stream to completion, executing the provided +asynchronous closure for each element on the stream. Read more
§

fn try_skip_while<Fut, F>(self, f: F) -> TrySkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_take_while<Fut, F>(self, f: F) -> TryTakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Take elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> TryForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = Result<(), Self::Error>>, + Self: Sized,

Available on crate feature alloc only.
Attempts to run this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available, exiting as soon as an error occurs. Read more
§

fn try_collect<C>(self) -> TryCollect<Self, C>
where + C: Default + Extend<Self::Ok>, + Self: Sized,

Attempt to transform a stream into a collection, +returning a future representing the result of that computation. Read more
§

fn try_chunks(self, capacity: usize) -> TryChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful items of the stream inside a vector. Read more
§

fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful, ready items of the stream inside a vector. Read more
§

fn try_filter<Fut, F>(self, f: F) -> TryFilter<Self, Fut, F>
where + Fut: Future<Output = bool>, + F: FnMut(&Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream according to the +provided asynchronous closure. Read more
§

fn try_filter_map<Fut, F, T>(self, f: F) -> TryFilterMap<Self, Fut, F>
where + Fut: TryFuture<Ok = Option<T>, Error = Self::Error>, + F: FnMut(Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream while +simultaneously mapping them to a different type according to the +provided asynchronous closure. Read more
§

fn try_flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> TryFlattenUnordered<Self>
where + Self::Ok: TryStream + Unpin, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Produced streams +will be polled concurrently and any errors will be passed through without looking at them. +If the underlying base stream returns an error, it will be immediately propagated. Read more
§

fn try_flatten(self) -> TryFlatten<Self>
where + Self::Ok: TryStream, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn try_fold<T, Fut, F>(self, init: T, f: F) -> TryFold<Self, Fut, T, F>
where + F: FnMut(T, Self::Ok) -> Fut, + Fut: TryFuture<Ok = T, Error = Self::Error>, + Self: Sized,

Attempt to execute an accumulating asynchronous computation over a +stream, collecting all the values into one final result. Read more
§

fn try_concat(self) -> TryConcat<Self>
where + Self: Sized, + Self::Ok: Extend<<Self::Ok as IntoIterator>::Item> + IntoIterator + Default,

Attempt to concatenate all items of a stream into a single +extendable destination, returning a future representing the end result. Read more
§

fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently (unordered). Read more
§

fn try_buffered(self, n: usize) -> TryBuffered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently. Read more
§

fn try_poll_next_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Option<Result<Self::Ok, Self::Error>>>
where + Self: Unpin,

A convenience method for calling [TryStream::try_poll_next] on Unpin +stream types.
§

fn try_all<Fut, F>(self, f: F) -> TryAll<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if all items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that does not satisfy the predicate. Read more
§

fn try_any<Fut, F>(self, f: F) -> TryAny<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if any items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that satisfies the predicate. Read more
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/fn.fn_factory.html b/actix_web/dev/fn.fn_factory.html new file mode 100644 index 000000000..f2d51b023 --- /dev/null +++ b/actix_web/dev/fn.fn_factory.html @@ -0,0 +1,38 @@ +fn_factory in actix_web::dev - Rust

Function actix_web::dev::fn_factory

pub fn fn_factory<F, Cfg, Srv, Req, Fut, Err>(
+    f: F
+) -> FnServiceNoConfig<F, Cfg, Srv, Req, Fut, Err>
where + F: Fn() -> Fut, + Fut: Future<Output = Result<Srv, Err>>, + Srv: Service<Req>,
Expand description

Create ServiceFactory for function that can produce services

+

§Examples

+
use std::io;
+use actix_service::{fn_factory, fn_service, Service, ServiceFactory};
+use futures_util::future::ok;
+
+/// Service that divides two usize values.
+async fn div((x, y): (usize, usize)) -> Result<usize, io::Error> {
+    if y == 0 {
+        Err(io::Error::new(io::ErrorKind::Other, "divide by zero"))
+    } else {
+        Ok(x / y)
+    }
+}
+
+#[actix_rt::main]
+async fn main() -> io::Result<()> {
+    // Create service factory that produces `div` services
+    let factory = fn_factory(|| {
+        ok::<_, io::Error>(fn_service(div))
+    });
+
+    // construct new service
+    let srv = factory.new_service(()).await?;
+
+    // now we can use `div` service
+    let result = srv.call((10, 20)).await?;
+
+    println!("10 / 20 = {}", result);
+
+    Ok(())
+}
+
\ No newline at end of file diff --git a/actix_web/dev/fn.fn_service.html b/actix_web/dev/fn.fn_service.html new file mode 100644 index 000000000..27afcc5cc --- /dev/null +++ b/actix_web/dev/fn.fn_service.html @@ -0,0 +1,6 @@ +fn_service in actix_web::dev - Rust

Function actix_web::dev::fn_service

pub fn fn_service<F, Fut, Req, Res, Err, Cfg>(
+    f: F
+) -> FnServiceFactory<F, Fut, Req, Res, Err, Cfg>
where + F: Fn(Req) -> Fut + Clone, + Fut: Future<Output = Result<Res, Err>>,
Expand description

Create ServiceFactory for function that can act as a Service

+
\ No newline at end of file diff --git a/actix_web/dev/index.html b/actix_web/dev/index.html new file mode 100644 index 000000000..cf04d21d8 --- /dev/null +++ b/actix_web/dev/index.html @@ -0,0 +1,10 @@ +actix_web::dev - Rust

Module actix_web::dev

source ·
Expand description

Lower-level types and re-exports.

+

Most users will not have to interact with the types in this module, but it is useful for those +writing extractors, middleware, libraries, or interacting with the service API directly.

+

§Request Extractors

+ +

Macros§

Structs§

Enums§

  • Future that resolves to some T when parsed from a JSON payload.
  • A streaming payload.

Traits§

Functions§

  • Create ServiceFactory for function that can produce services
  • Create ServiceFactory for function that can act as a Service
\ No newline at end of file diff --git a/actix_web/dev/macro.always_ready!.html b/actix_web/dev/macro.always_ready!.html new file mode 100644 index 000000000..115b940a3 --- /dev/null +++ b/actix_web/dev/macro.always_ready!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.always_ready.html...

+ + + \ No newline at end of file diff --git a/actix_web/dev/macro.always_ready.html b/actix_web/dev/macro.always_ready.html new file mode 100644 index 000000000..33f8b730c --- /dev/null +++ b/actix_web/dev/macro.always_ready.html @@ -0,0 +1,24 @@ +always_ready in actix_web::dev - Rust

Macro actix_web::dev::always_ready

macro_rules! always_ready {
+    () => { ... };
+}
Expand description

An implementation of poll_ready that always signals readiness.

+

This should only be used for basic leaf services that have no concept of un-readiness. +For wrapper or other service types, use [forward_ready!] for simple cases or write a bespoke +poll_ready implementation.

+

§Examples

+
use actix_service::Service;
+use futures_util::future::{ready, Ready};
+
+struct IdentityService;
+
+impl Service<u32> for IdentityService {
+    type Response = u32;
+    type Error = ();
+    type Future = Ready<Result<Self::Response, Self::Error>>;
+
+    actix_service::always_ready!();
+
+    fn call(&self, req: u32) -> Self::Future {
+        ready(Ok(req))
+    }
+}
+
\ No newline at end of file diff --git a/actix_web/dev/macro.forward_ready!.html b/actix_web/dev/macro.forward_ready!.html new file mode 100644 index 000000000..e4ff6141d --- /dev/null +++ b/actix_web/dev/macro.forward_ready!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.forward_ready.html...

+ + + \ No newline at end of file diff --git a/actix_web/dev/macro.forward_ready.html b/actix_web/dev/macro.forward_ready.html new file mode 100644 index 000000000..4516d21b2 --- /dev/null +++ b/actix_web/dev/macro.forward_ready.html @@ -0,0 +1,28 @@ +forward_ready in actix_web::dev - Rust

Macro actix_web::dev::forward_ready

macro_rules! forward_ready {
+    ($field:ident) => { ... };
+}
Expand description

An implementation of poll_ready that forwards readiness checks to a +named struct field.

+

Tuple structs are not supported.

+

§Examples

+
use actix_service::Service;
+use futures_util::future::{ready, Ready};
+
+struct WrapperService<S> {
+    inner: S,
+}
+
+impl<S> Service<()> for WrapperService<S>
+where
+    S: Service<()>,
+{
+    type Response = S::Response;
+    type Error = S::Error;
+    type Future = S::Future;
+
+    actix_service::forward_ready!(inner);
+
+    fn call(&self, req: ()) -> Self::Future {
+        self.inner.call(req)
+    }
+}
+
\ No newline at end of file diff --git a/actix_web/dev/sidebar-items.js b/actix_web/dev/sidebar-items.js new file mode 100644 index 000000000..559c2c207 --- /dev/null +++ b/actix_web/dev/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["JsonBody","Payload"],"fn":["fn_factory","fn_service"],"macro":["always_ready","forward_ready"],"struct":["AppConfig","AppService","ConnectionInfo","Decompress","Extensions","Path","PeerAddr","Readlines","RequestHead","ResourceDef","ResourceMap","Response","ResponseHead","Server","ServerHandle","ServiceRequest","ServiceResponse","Url","UrlEncoded","WebService"],"trait":["HttpServiceFactory","ResourcePath","Service","ServiceFactory","Transform"]}; \ No newline at end of file diff --git a/actix_web/dev/struct.AppConfig.html b/actix_web/dev/struct.AppConfig.html new file mode 100644 index 000000000..cf86e7c91 --- /dev/null +++ b/actix_web/dev/struct.AppConfig.html @@ -0,0 +1,34 @@ +AppConfig in actix_web::dev - Rust

Struct actix_web::dev::AppConfig

source ·
pub struct AppConfig { /* private fields */ }
Expand description

Application connection config.

+

Implementations§

source§

impl AppConfig

source

pub fn host(&self) -> &str

Server host name.

+

Host name is used by application router as a hostname for URL generation. +Check ConnectionInfo +documentation for more information.

+

By default host name is set to a “localhost” value.

+
source

pub fn secure(&self) -> bool

Returns true if connection is secure (i.e., running over https:).

+
source

pub fn local_addr(&self) -> SocketAddr

Returns the socket address of the local half of this TCP connection.

+

Trait Implementations§

source§

impl Clone for AppConfig

source§

fn clone(&self) -> AppConfig

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for AppConfig

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for AppConfig

source§

fn default() -> Self

Returns the default AppConfig. +Note: The included socket address is “127.0.0.1”.

+

127.0.0.1: non-routable meta address that denotes an unknown, invalid or non-applicable target. +If you need a service only accessed by itself, use a loopback address. +A loopback address for IPv4 is any loopback address that begins with “127”. +Loopback addresses should be only used to test your application locally. +The default configuration provides a loopback address.

+

0.0.0.0: if configured to use this special address, the application will listen to any IP address configured on the machine.

+

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.AppService.html b/actix_web/dev/struct.AppService.html new file mode 100644 index 000000000..3d0b40ccc --- /dev/null +++ b/actix_web/dev/struct.AppService.html @@ -0,0 +1,32 @@ +AppService in actix_web::dev - Rust

Struct actix_web::dev::AppService

source ·
pub struct AppService { /* private fields */ }
Expand description

Application configuration

+

Implementations§

source§

impl AppService

source

pub fn is_root(&self) -> bool

Check if root is being configured

+
source

pub fn config(&self) -> &AppConfig

Returns reference to configuration.

+
source

pub fn default_service( + &self +) -> Rc<BoxServiceFactory<(), ServiceRequest, ServiceResponse<BoxBody>, Error, ()>>

Returns default handler factory.

+
source

pub fn register_service<F, S>( + &mut self, + rdef: ResourceDef, + guards: Option<Vec<Box<dyn Guard>>>, + factory: F, + nested: Option<Rc<ResourceMap>> +)
where + F: IntoServiceFactory<S, ServiceRequest>, + S: ServiceFactory<ServiceRequest, Response = ServiceResponse, Error = Error, Config = (), InitError = ()> + 'static,

Register HTTP service.

+

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.ConnectionInfo.html b/actix_web/dev/struct.ConnectionInfo.html new file mode 100644 index 000000000..b9bc38022 --- /dev/null +++ b/actix_web/dev/struct.ConnectionInfo.html @@ -0,0 +1,66 @@ +ConnectionInfo in actix_web::dev - Rust

Struct actix_web::dev::ConnectionInfo

source ·
pub struct ConnectionInfo { /* private fields */ }
Expand description

HTTP connection information.

+

ConnectionInfo implements FromRequest and can be extracted in handlers.

+

§Examples

+
use actix_web::dev::ConnectionInfo;
+
+async fn handler(conn: ConnectionInfo) -> impl Responder {
+    match conn.host() {
+        "actix.rs" => HttpResponse::Ok().body("Welcome!"),
+        "admin.actix.rs" => HttpResponse::Ok().body("Admin portal."),
+        _ => HttpResponse::NotFound().finish()
+    }
+}
+

§Implementation Notes

+

Parses Forwarded header information according to RFC 7239 but does not try to +interpret the values for each property. As such, the getter methods on ConnectionInfo return +strings instead of IP addresses or other types to acknowledge that they may be +obfuscated or unknown.

+

If the older, related headers are also present (eg. X-Forwarded-For), then Forwarded +is preferred.

+

Implementations§

source§

impl ConnectionInfo

source

pub fn realip_remote_addr(&self) -> Option<&str>

Real IP (remote address) of client that initiated request.

+

The address is resolved through the following, in order:

+
    +
  • Forwarded header
  • +
  • X-Forwarded-For header
  • +
  • peer address of opened socket (same as remote_addr)
  • +
+
§Security
+

Do not use this function for security purposes unless you can be sure that the Forwarded +and X-Forwarded-For headers cannot be spoofed by the client. If you are running without a +proxy then obtaining the peer address would be more appropriate.

+
source

pub fn peer_addr(&self) -> Option<&str>

Returns serialized IP address of the peer connection.

+

See HttpRequest::peer_addr for more details.

+
source

pub fn host(&self) -> &str

Hostname of the request.

+

Hostname is resolved through the following, in order:

+
    +
  • Forwarded header
  • +
  • X-Forwarded-Host header
  • +
  • Host header
  • +
  • request target / URI
  • +
  • configured server hostname
  • +
+
source

pub fn scheme(&self) -> &str

Scheme of the request.

+

Scheme is resolved through the following, in order:

+
    +
  • Forwarded header
  • +
  • X-Forwarded-Proto header
  • +
  • request target / URI
  • +
+

Trait Implementations§

source§

impl Clone for ConnectionInfo

source§

fn clone(&self) -> ConnectionInfo

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ConnectionInfo

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for ConnectionInfo

source§

fn default() -> ConnectionInfo

Returns the “default value” for a type. Read more
source§

impl FromRequest for ConnectionInfo

§

type Error = Infallible

The associated error which can be returned.
§

type Future = Ready<Result<ConnectionInfo, <ConnectionInfo as FromRequest>::Error>>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.Decompress.html b/actix_web/dev/struct.Decompress.html new file mode 100644 index 000000000..a11d2a609 --- /dev/null +++ b/actix_web/dev/struct.Decompress.html @@ -0,0 +1,260 @@ +Decompress in actix_web::dev - Rust

Struct actix_web::dev::Decompress

source ·
pub struct Decompress<S> { /* private fields */ }
Available on crate feature __compress only.

Implementations§

source§

impl<S> Decoder<S>
where + S: Stream<Item = Result<Bytes, PayloadError>>,

source

pub fn new(stream: S, encoding: ContentEncoding) -> Decoder<S>

Construct a decoder.

+
source

pub fn from_headers(stream: S, headers: &HeaderMap) -> Decoder<S>

Construct decoder based on headers.

+

Trait Implementations§

source§

impl<S> Stream for Decoder<S>
where + S: Stream<Item = Result<Bytes, PayloadError>>,

§

type Item = Result<Bytes, PayloadError>

Values yielded by the stream.
source§

fn poll_next( + self: Pin<&mut Decoder<S>>, + cx: &mut Context<'_> +) -> Poll<Option<<Decoder<S> as Stream>::Item>>

Attempt to pull out the next value of this stream, registering the +current task for wakeup if the value is not yet available, and returning +None if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more
source§

impl<'__pin, S> Unpin for Decoder<S>
where + __Origin<'__pin, S>: Unpin,

Auto Trait Implementations§

§

impl<S> Freeze for Decoder<S>
where + S: Freeze,

§

impl<S> !RefUnwindSafe for Decoder<S>

§

impl<S> Send for Decoder<S>
where + S: Send,

§

impl<S> Sync for Decoder<S>
where + S: Sync,

§

impl<S> !UnwindSafe for Decoder<S>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<T> StreamExt for T
where + T: Stream + ?Sized,

§

fn next(&mut self) -> Next<'_, Self>
where + Self: Unpin,

Creates a future that resolves to the next item in the stream. Read more
§

fn into_future(self) -> StreamFuture<Self>
where + Self: Sized + Unpin,

Converts this stream into a future of (next_item, tail_of_stream). +If the stream terminates, then the next item is None. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + F: FnMut(Self::Item) -> T, + Self: Sized,

Maps this stream’s items to a different type, returning a new stream of +the resulting type. Read more
§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates a stream which gives the current iteration count as well as +the next value. Read more
§

fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Filters the values produced by this stream according to the provided +asynchronous predicate. Read more
§

fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = Option<T>>, + Self: Sized,

Filters the values produced by this stream while simultaneously mapping +them to a different type according to the provided asynchronous closure. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized,

Computes from this stream’s items new items of a different type using +an asynchronous closure. Read more
§

fn collect<C>(self) -> Collect<Self, C>
where + C: Default + Extend<Self::Item>, + Self: Sized,

Transforms a stream into a collection, returning a +future representing the result of that computation. Read more
§

fn unzip<A, B, FromA, FromB>(self) -> Unzip<Self, FromA, FromB>
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Stream<Item = (A, B)>,

Converts a stream of pairs into a future, which +resolves to pair of containers. Read more
§

fn concat(self) -> Concat<Self>
where + Self: Sized, + Self::Item: Extend<<Self::Item as IntoIterator>::Item> + IntoIterator + Default,

Concatenate all items of a stream into a single extendable +destination, returning a future representing the end result. Read more
§

fn count(self) -> Count<Self>
where + Self: Sized,

Drives the stream to completion, counting the number of items. Read more
§

fn cycle(self) -> Cycle<Self>
where + Self: Sized + Clone,

Repeats a stream endlessly. Read more
§

fn fold<T, Fut, F>(self, init: T, f: F) -> Fold<Self, Fut, T, F>
where + F: FnMut(T, Self::Item) -> Fut, + Fut: Future<Output = T>, + Self: Sized,

Execute an accumulating asynchronous computation over a stream, +collecting all the values into one final result. Read more
§

fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if any element in stream satisfied a predicate. Read more
§

fn all<Fut, F>(self, f: F) -> All<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if all element in stream satisfied a predicate. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Item: Stream, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> FlattenUnorderedWithFlowController<Self, ()>
where + Self::Item: Stream + Unpin, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Polls +inner streams produced by the base stream concurrently. Read more
§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + F: FnMut(Self::Item) -> U, + U: Stream, + Self: Sized,

Maps a stream like [StreamExt::map] but flattens nested Streams. Read more
§

fn flat_map_unordered<U, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> FlatMapUnordered<Self, U, F>
where + U: Stream + Unpin, + F: FnMut(Self::Item) -> U, + Self: Sized,

Available on crate feature alloc only.
Maps a stream like [StreamExt::map] but flattens nested Streams +and polls them concurrently, yielding items in any order, as they made +available. Read more
§

fn scan<S, B, Fut, F>(self, initial_state: S, f: F) -> Scan<Self, S, Fut, F>
where + F: FnMut(&mut S, Self::Item) -> Fut, + Fut: Future<Output = Option<B>>, + Self: Sized,

Combinator similar to [StreamExt::fold] that holds internal state +and produces a new stream. Read more
§

fn skip_while<Fut, F>(self, f: F) -> SkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_while<Fut, F>(self, f: F) -> TakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Take elements from this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_until<Fut>(self, fut: Fut) -> TakeUntil<Self, Fut>
where + Fut: Future, + Self: Sized,

Take elements from this stream until the provided future resolves. Read more
§

fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream. Read more
§

fn for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> ForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Available on crate feature alloc only.
Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates a new stream of at most n items of the underlying stream. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates a new stream which skips n items of the underlying stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a stream such that poll_next will never +again be called once it has finished. This method can be used to turn +any Stream into a FusedStream. Read more
§

fn by_ref(&mut self) -> &mut Self

Borrows a stream, rather than consuming it. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the stream. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn buffered(self, n: usize) -> Buffered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures. Read more
§

fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures (unordered). Read more
§

fn zip<St>(self, other: St) -> Zip<Self, St>
where + St: Stream, + Self: Sized,

An adapter for zipping two streams together. Read more
§

fn chain<St>(self, other: St) -> Chain<Self, St>
where + St: Stream<Item = Self::Item>, + Self: Sized,

Adapter for chaining two streams. Read more
§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates a new stream which exposes a peek method. Read more
§

fn chunks(self, capacity: usize) -> Chunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up items of the stream inside a vector. Read more
§

fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up ready items of the stream inside a vector. Read more
§

fn forward<S>(self, sink: S) -> Forward<Self, S>
where + S: Sink<Self::Ok, Error = Self::Error>, + Self: Sized + TryStream,

Available on crate feature sink only.
A future that completes after the given stream has been fully processed +into the sink and the sink has been flushed and closed. Read more
§

fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
where + Self: Sized + Sink<Item>,

Available on crate features sink and alloc only.
Splits this Stream + Sink object into separate Sink and Stream +objects. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnMut(&Self::Item), + Self: Sized,

Do something with each item of this stream, afterwards passing it on. Read more
§

fn left_stream<B>(self) -> Either<Self, B>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the left-hand variant +of that Either. Read more
§

fn right_stream<B>(self) -> Either<B, Self>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the right-hand variant +of that Either. Read more
§

fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>
where + Self: Unpin,

A convenience method for calling [Stream::poll_next] on Unpin +stream types.
§

fn select_next_some(&mut self) -> SelectNextSome<'_, Self>
where + Self: Unpin + FusedStream,

Returns a Future that resolves when the next item in this stream is +ready. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<S, T, E> TryStream for S
where + S: Stream<Item = 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
§

fn try_poll_next( + self: Pin<&mut S>, + cx: &mut Context<'_> +) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>>

Poll this TryStream as if it were a Stream. Read more
§

impl<S> TryStreamExt for S
where + S: TryStream + ?Sized,

§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Wraps the current stream in a new stream which converts the error type +into the one provided. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> T,

Wraps the current stream in a new stream which maps the success value +using the provided closure. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + Self: Sized, + F: FnMut(Self::Error) -> E,

Wraps the current stream in a new stream which maps the error value +using the provided closure. Read more
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Chain on a computation for when a value is ready, passing the successful +results to the provided closure f. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnMut(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Chain on a computation for when an error happens, passing the +erroneous result to the provided closure f. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnMut(&Self::Ok), + Self: Sized,

Do something with the success value of this stream, afterwards passing +it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnMut(&Self::Error), + Self: Sized,

Do something with the error value of this stream, afterwards passing it on. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Wraps a [TryStream] into a type that implements +Stream Read more
§

fn try_next(&mut self) -> TryNext<'_, Self>
where + Self: Unpin,

Creates a future that attempts to resolve the next item in the stream. +If an error is encountered before the next item, the error is returned +instead. Read more
§

fn try_for_each<Fut, F>(self, f: F) -> TryForEach<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Ok = (), Error = Self::Error>, + Self: Sized,

Attempts to run this stream to completion, executing the provided +asynchronous closure for each element on the stream. Read more
§

fn try_skip_while<Fut, F>(self, f: F) -> TrySkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_take_while<Fut, F>(self, f: F) -> TryTakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Take elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> TryForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = Result<(), Self::Error>>, + Self: Sized,

Available on crate feature alloc only.
Attempts to run this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available, exiting as soon as an error occurs. Read more
§

fn try_collect<C>(self) -> TryCollect<Self, C>
where + C: Default + Extend<Self::Ok>, + Self: Sized,

Attempt to transform a stream into a collection, +returning a future representing the result of that computation. Read more
§

fn try_chunks(self, capacity: usize) -> TryChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful items of the stream inside a vector. Read more
§

fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful, ready items of the stream inside a vector. Read more
§

fn try_filter<Fut, F>(self, f: F) -> TryFilter<Self, Fut, F>
where + Fut: Future<Output = bool>, + F: FnMut(&Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream according to the +provided asynchronous closure. Read more
§

fn try_filter_map<Fut, F, T>(self, f: F) -> TryFilterMap<Self, Fut, F>
where + Fut: TryFuture<Ok = Option<T>, Error = Self::Error>, + F: FnMut(Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream while +simultaneously mapping them to a different type according to the +provided asynchronous closure. Read more
§

fn try_flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> TryFlattenUnordered<Self>
where + Self::Ok: TryStream + Unpin, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Produced streams +will be polled concurrently and any errors will be passed through without looking at them. +If the underlying base stream returns an error, it will be immediately propagated. Read more
§

fn try_flatten(self) -> TryFlatten<Self>
where + Self::Ok: TryStream, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn try_fold<T, Fut, F>(self, init: T, f: F) -> TryFold<Self, Fut, T, F>
where + F: FnMut(T, Self::Ok) -> Fut, + Fut: TryFuture<Ok = T, Error = Self::Error>, + Self: Sized,

Attempt to execute an accumulating asynchronous computation over a +stream, collecting all the values into one final result. Read more
§

fn try_concat(self) -> TryConcat<Self>
where + Self: Sized, + Self::Ok: Extend<<Self::Ok as IntoIterator>::Item> + IntoIterator + Default,

Attempt to concatenate all items of a stream into a single +extendable destination, returning a future representing the end result. Read more
§

fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently (unordered). Read more
§

fn try_buffered(self, n: usize) -> TryBuffered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently. Read more
§

fn try_poll_next_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Option<Result<Self::Ok, Self::Error>>>
where + Self: Unpin,

A convenience method for calling [TryStream::try_poll_next] on Unpin +stream types.
§

fn try_all<Fut, F>(self, f: F) -> TryAll<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if all items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that does not satisfy the predicate. Read more
§

fn try_any<Fut, F>(self, f: F) -> TryAny<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if any items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that satisfies the predicate. Read more
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.Extensions.html b/actix_web/dev/struct.Extensions.html new file mode 100644 index 000000000..756fd1c60 --- /dev/null +++ b/actix_web/dev/struct.Extensions.html @@ -0,0 +1,70 @@ +Extensions in actix_web::dev - Rust

Struct actix_web::dev::Extensions

source ·
pub struct Extensions { /* private fields */ }
Expand description

A type map for request extensions.

+

All entries into this map must be owned types (or static references).

+

Implementations§

source§

impl Extensions

source

pub fn new() -> Extensions

Creates an empty Extensions.

+
source

pub fn insert<T>(&mut self, val: T) -> Option<T>
where + T: 'static,

Insert an item into the map.

+

If an item of this type was already stored, it will be replaced and returned.

+ +
let mut map = Extensions::new();
+assert_eq!(map.insert(""), None);
+assert_eq!(map.insert(1u32), None);
+assert_eq!(map.insert(2u32), Some(1u32));
+assert_eq!(*map.get::<u32>().unwrap(), 2u32);
+
source

pub fn contains<T>(&self) -> bool
where + T: 'static,

Check if map contains an item of a given type.

+ +
let mut map = Extensions::new();
+assert!(!map.contains::<u32>());
+
+assert_eq!(map.insert(1u32), None);
+assert!(map.contains::<u32>());
+
source

pub fn get<T>(&self) -> Option<&T>
where + T: 'static,

Get a reference to an item of a given type.

+ +
let mut map = Extensions::new();
+map.insert(1u32);
+assert_eq!(map.get::<u32>(), Some(&1u32));
+
source

pub fn get_mut<T>(&mut self) -> Option<&mut T>
where + T: 'static,

Get a mutable reference to an item of a given type.

+ +
let mut map = Extensions::new();
+map.insert(1u32);
+assert_eq!(map.get_mut::<u32>(), Some(&mut 1u32));
+
source

pub fn remove<T>(&mut self) -> Option<T>
where + T: 'static,

Remove an item from the map of a given type.

+

If an item of this type was already stored, it will be returned.

+ +
let mut map = Extensions::new();
+
+map.insert(1u32);
+assert_eq!(map.get::<u32>(), Some(&1u32));
+
+assert_eq!(map.remove::<u32>(), Some(1u32));
+assert!(!map.contains::<u32>());
+
source

pub fn clear(&mut self)

Clear the Extensions of all inserted extensions.

+ +
let mut map = Extensions::new();
+
+map.insert(1u32);
+assert!(map.contains::<u32>());
+
+map.clear();
+assert!(!map.contains::<u32>());
+
source

pub fn extend(&mut self, other: Extensions)

Extends self with the items from another Extensions.

+

Trait Implementations§

source§

impl Debug for Extensions

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Extensions

source§

fn default() -> Extensions

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.Path.html b/actix_web/dev/struct.Path.html new file mode 100644 index 000000000..04144f008 --- /dev/null +++ b/actix_web/dev/struct.Path.html @@ -0,0 +1,51 @@ +Path in actix_web::dev - Rust

Struct actix_web::dev::Path

source ·
pub struct Path<T> { /* private fields */ }
Expand description

Resource path match information.

+

If resource path contains variable patterns, Path stores them.

+

Implementations§

source§

impl<T> Path<T>
where + T: ResourcePath,

source

pub fn new(path: T) -> Path<T>

source

pub fn get_ref(&self) -> &T

Returns reference to inner path instance.

+
source

pub fn get_mut(&mut self) -> &mut T

Returns mutable reference to inner path instance.

+
source

pub fn as_str(&self) -> &str

Returns full path as a string.

+
source

pub fn unprocessed(&self) -> &str

Returns unprocessed part of the path.

+

Returns empty string if no more is to be processed.

+
source

pub fn set(&mut self, path: T)

Set new path.

+
source

pub fn reset(&mut self)

Reset state.

+
source

pub fn skip(&mut self, n: u16)

Skip first n chars in path.

+
source

pub fn is_empty(&self) -> bool

Check if there are any matched patterns.

+
source

pub fn segment_count(&self) -> usize

Returns number of interpolated segments.

+
source

pub fn get(&self, name: &str) -> Option<&str>

Get matched parameter by name without type conversion

+
source

pub fn query(&self, key: &str) -> &str

Returns matched parameter by name.

+

If keyed parameter is not available empty string is used as default value.

+
source

pub fn iter(&self) -> PathIter<'_, T>

Return iterator to items in parameter container.

+
source

pub fn load<'de, U>(&'de self) -> Result<U, Error>
where + U: Deserialize<'de>,

Deserializes matching parameters to a specified type U.

+
§Errors
+

Returns error when dynamic path segments cannot be deserialized into a U type.

+

Trait Implementations§

source§

impl<T> Clone for Path<T>
where + T: Clone,

source§

fn clone(&self) -> Path<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T> Debug for Path<T>
where + T: Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<T> Default for Path<T>
where + T: Default,

source§

fn default() -> Path<T>

Returns the “default value” for a type. Read more
source§

impl<'a, T> Index<&'a str> for Path<T>
where + T: ResourcePath,

§

type Output = str

The returned type after indexing.
source§

fn index(&self, name: &'a str) -> &str

Performs the indexing (container[index]) operation. Read more
source§

impl<T> Index<usize> for Path<T>
where + T: ResourcePath,

§

type Output = str

The returned type after indexing.
source§

fn index(&self, idx: usize) -> &str

Performs the indexing (container[index]) operation. Read more
source§

impl<T> Resource for Path<T>
where + T: ResourcePath,

§

type Path = T

Type of resource’s path returned in resource_path.
source§

fn resource_path(&mut self) -> &mut Path<<Path<T> as Resource>::Path>

Auto Trait Implementations§

§

impl<T> Freeze for Path<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for Path<T>
where + T: RefUnwindSafe,

§

impl<T> Send for Path<T>
where + T: Send,

§

impl<T> Sync for Path<T>
where + T: Sync,

§

impl<T> Unpin for Path<T>
where + T: Unpin,

§

impl<T> UnwindSafe for Path<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.PeerAddr.html b/actix_web/dev/struct.PeerAddr.html new file mode 100644 index 000000000..6ac6129f1 --- /dev/null +++ b/actix_web/dev/struct.PeerAddr.html @@ -0,0 +1,44 @@ +PeerAddr in actix_web::dev - Rust

Struct actix_web::dev::PeerAddr

source ·
pub struct PeerAddr(pub SocketAddr);
Expand description

Extractor for peer’s socket address.

+

Also see HttpRequest::peer_addr and ConnectionInfo::peer_addr.

+

§Examples

+
use actix_web::dev::PeerAddr;
+
+async fn handler(peer_addr: PeerAddr) -> impl Responder {
+    let socket_addr = peer_addr.0;
+    socket_addr.to_string()
+}
+

Tuple Fields§

§0: SocketAddr

Implementations§

source§

impl PeerAddr

source

pub fn into_inner(self) -> SocketAddr

Unwrap into inner SocketAddr value.

+

Trait Implementations§

source§

impl Clone for PeerAddr

source§

fn clone(&self) -> PeerAddr

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for PeerAddr

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for PeerAddr

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl FromRequest for PeerAddr

§

type Error = MissingPeerAddr

The associated error which can be returned.
§

type Future = Ready<Result<PeerAddr, <PeerAddr as FromRequest>::Error>>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more
source§

impl Hash for PeerAddr

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for PeerAddr

source§

fn cmp(&self, other: &PeerAddr) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq for PeerAddr

source§

fn eq(&self, other: &PeerAddr) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for PeerAddr

source§

fn partial_cmp(&self, other: &PeerAddr) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl Copy for PeerAddr

source§

impl Eq for PeerAddr

source§

impl StructuralPartialEq for PeerAddr

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.Readlines.html b/actix_web/dev/struct.Readlines.html new file mode 100644 index 000000000..98fcd40e4 --- /dev/null +++ b/actix_web/dev/struct.Readlines.html @@ -0,0 +1,260 @@ +Readlines in actix_web::dev - Rust

Struct actix_web::dev::Readlines

source ·
pub struct Readlines<T: HttpMessage> { /* private fields */ }
Expand description

Stream that reads request line by line.

+

Implementations§

source§

impl<T> Readlines<T>
where + T: HttpMessage, + T::Stream: Stream<Item = Result<Bytes, PayloadError>> + Unpin,

source

pub fn new(req: &mut T) -> Self

Create a new stream to read request line by line.

+
source

pub fn limit(self, limit: usize) -> Self

Set maximum accepted payload size. The default limit is 256kB.

+

Trait Implementations§

source§

impl<T> Stream for Readlines<T>
where + T: HttpMessage, + T::Stream: Stream<Item = Result<Bytes, PayloadError>> + Unpin,

§

type Item = Result<String, ReadlinesError>

Values yielded by the stream.
source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Self::Item>>

Attempt to pull out the next value of this stream, registering the +current task for wakeup if the value is not yet available, and returning +None if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more

Auto Trait Implementations§

§

impl<T> !Freeze for Readlines<T>

§

impl<T> !RefUnwindSafe for Readlines<T>

§

impl<T> !Send for Readlines<T>

§

impl<T> !Sync for Readlines<T>

§

impl<T> Unpin for Readlines<T>
where + <T as HttpMessage>::Stream: Unpin,

§

impl<T> !UnwindSafe for Readlines<T>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<T> StreamExt for T
where + T: Stream + ?Sized,

§

fn next(&mut self) -> Next<'_, Self>
where + Self: Unpin,

Creates a future that resolves to the next item in the stream. Read more
§

fn into_future(self) -> StreamFuture<Self>
where + Self: Sized + Unpin,

Converts this stream into a future of (next_item, tail_of_stream). +If the stream terminates, then the next item is None. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + F: FnMut(Self::Item) -> T, + Self: Sized,

Maps this stream’s items to a different type, returning a new stream of +the resulting type. Read more
§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates a stream which gives the current iteration count as well as +the next value. Read more
§

fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Filters the values produced by this stream according to the provided +asynchronous predicate. Read more
§

fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = Option<T>>, + Self: Sized,

Filters the values produced by this stream while simultaneously mapping +them to a different type according to the provided asynchronous closure. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized,

Computes from this stream’s items new items of a different type using +an asynchronous closure. Read more
§

fn collect<C>(self) -> Collect<Self, C>
where + C: Default + Extend<Self::Item>, + Self: Sized,

Transforms a stream into a collection, returning a +future representing the result of that computation. Read more
§

fn unzip<A, B, FromA, FromB>(self) -> Unzip<Self, FromA, FromB>
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Stream<Item = (A, B)>,

Converts a stream of pairs into a future, which +resolves to pair of containers. Read more
§

fn concat(self) -> Concat<Self>
where + Self: Sized, + Self::Item: Extend<<Self::Item as IntoIterator>::Item> + IntoIterator + Default,

Concatenate all items of a stream into a single extendable +destination, returning a future representing the end result. Read more
§

fn count(self) -> Count<Self>
where + Self: Sized,

Drives the stream to completion, counting the number of items. Read more
§

fn cycle(self) -> Cycle<Self>
where + Self: Sized + Clone,

Repeats a stream endlessly. Read more
§

fn fold<T, Fut, F>(self, init: T, f: F) -> Fold<Self, Fut, T, F>
where + F: FnMut(T, Self::Item) -> Fut, + Fut: Future<Output = T>, + Self: Sized,

Execute an accumulating asynchronous computation over a stream, +collecting all the values into one final result. Read more
§

fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if any element in stream satisfied a predicate. Read more
§

fn all<Fut, F>(self, f: F) -> All<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if all element in stream satisfied a predicate. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Item: Stream, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> FlattenUnorderedWithFlowController<Self, ()>
where + Self::Item: Stream + Unpin, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Polls +inner streams produced by the base stream concurrently. Read more
§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + F: FnMut(Self::Item) -> U, + U: Stream, + Self: Sized,

Maps a stream like [StreamExt::map] but flattens nested Streams. Read more
§

fn flat_map_unordered<U, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> FlatMapUnordered<Self, U, F>
where + U: Stream + Unpin, + F: FnMut(Self::Item) -> U, + Self: Sized,

Available on crate feature alloc only.
Maps a stream like [StreamExt::map] but flattens nested Streams +and polls them concurrently, yielding items in any order, as they made +available. Read more
§

fn scan<S, B, Fut, F>(self, initial_state: S, f: F) -> Scan<Self, S, Fut, F>
where + F: FnMut(&mut S, Self::Item) -> Fut, + Fut: Future<Output = Option<B>>, + Self: Sized,

Combinator similar to [StreamExt::fold] that holds internal state +and produces a new stream. Read more
§

fn skip_while<Fut, F>(self, f: F) -> SkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_while<Fut, F>(self, f: F) -> TakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Take elements from this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_until<Fut>(self, fut: Fut) -> TakeUntil<Self, Fut>
where + Fut: Future, + Self: Sized,

Take elements from this stream until the provided future resolves. Read more
§

fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream. Read more
§

fn for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> ForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Available on crate feature alloc only.
Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates a new stream of at most n items of the underlying stream. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates a new stream which skips n items of the underlying stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a stream such that poll_next will never +again be called once it has finished. This method can be used to turn +any Stream into a FusedStream. Read more
§

fn by_ref(&mut self) -> &mut Self

Borrows a stream, rather than consuming it. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the stream. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn buffered(self, n: usize) -> Buffered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures. Read more
§

fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures (unordered). Read more
§

fn zip<St>(self, other: St) -> Zip<Self, St>
where + St: Stream, + Self: Sized,

An adapter for zipping two streams together. Read more
§

fn chain<St>(self, other: St) -> Chain<Self, St>
where + St: Stream<Item = Self::Item>, + Self: Sized,

Adapter for chaining two streams. Read more
§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates a new stream which exposes a peek method. Read more
§

fn chunks(self, capacity: usize) -> Chunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up items of the stream inside a vector. Read more
§

fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up ready items of the stream inside a vector. Read more
§

fn forward<S>(self, sink: S) -> Forward<Self, S>
where + S: Sink<Self::Ok, Error = Self::Error>, + Self: Sized + TryStream,

Available on crate feature sink only.
A future that completes after the given stream has been fully processed +into the sink and the sink has been flushed and closed. Read more
§

fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
where + Self: Sized + Sink<Item>,

Available on crate features sink and alloc only.
Splits this Stream + Sink object into separate Sink and Stream +objects. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnMut(&Self::Item), + Self: Sized,

Do something with each item of this stream, afterwards passing it on. Read more
§

fn left_stream<B>(self) -> Either<Self, B>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the left-hand variant +of that Either. Read more
§

fn right_stream<B>(self) -> Either<B, Self>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the right-hand variant +of that Either. Read more
§

fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>
where + Self: Unpin,

A convenience method for calling [Stream::poll_next] on Unpin +stream types.
§

fn select_next_some(&mut self) -> SelectNextSome<'_, Self>
where + Self: Unpin + FusedStream,

Returns a Future that resolves when the next item in this stream is +ready. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<S, T, E> TryStream for S
where + S: Stream<Item = 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
§

fn try_poll_next( + self: Pin<&mut S>, + cx: &mut Context<'_> +) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>>

Poll this TryStream as if it were a Stream. Read more
§

impl<S> TryStreamExt for S
where + S: TryStream + ?Sized,

§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Wraps the current stream in a new stream which converts the error type +into the one provided. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> T,

Wraps the current stream in a new stream which maps the success value +using the provided closure. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + Self: Sized, + F: FnMut(Self::Error) -> E,

Wraps the current stream in a new stream which maps the error value +using the provided closure. Read more
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Chain on a computation for when a value is ready, passing the successful +results to the provided closure f. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnMut(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Chain on a computation for when an error happens, passing the +erroneous result to the provided closure f. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnMut(&Self::Ok), + Self: Sized,

Do something with the success value of this stream, afterwards passing +it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnMut(&Self::Error), + Self: Sized,

Do something with the error value of this stream, afterwards passing it on. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Wraps a [TryStream] into a type that implements +Stream Read more
§

fn try_next(&mut self) -> TryNext<'_, Self>
where + Self: Unpin,

Creates a future that attempts to resolve the next item in the stream. +If an error is encountered before the next item, the error is returned +instead. Read more
§

fn try_for_each<Fut, F>(self, f: F) -> TryForEach<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Ok = (), Error = Self::Error>, + Self: Sized,

Attempts to run this stream to completion, executing the provided +asynchronous closure for each element on the stream. Read more
§

fn try_skip_while<Fut, F>(self, f: F) -> TrySkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_take_while<Fut, F>(self, f: F) -> TryTakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Take elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> TryForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = Result<(), Self::Error>>, + Self: Sized,

Available on crate feature alloc only.
Attempts to run this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available, exiting as soon as an error occurs. Read more
§

fn try_collect<C>(self) -> TryCollect<Self, C>
where + C: Default + Extend<Self::Ok>, + Self: Sized,

Attempt to transform a stream into a collection, +returning a future representing the result of that computation. Read more
§

fn try_chunks(self, capacity: usize) -> TryChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful items of the stream inside a vector. Read more
§

fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful, ready items of the stream inside a vector. Read more
§

fn try_filter<Fut, F>(self, f: F) -> TryFilter<Self, Fut, F>
where + Fut: Future<Output = bool>, + F: FnMut(&Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream according to the +provided asynchronous closure. Read more
§

fn try_filter_map<Fut, F, T>(self, f: F) -> TryFilterMap<Self, Fut, F>
where + Fut: TryFuture<Ok = Option<T>, Error = Self::Error>, + F: FnMut(Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream while +simultaneously mapping them to a different type according to the +provided asynchronous closure. Read more
§

fn try_flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> TryFlattenUnordered<Self>
where + Self::Ok: TryStream + Unpin, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Produced streams +will be polled concurrently and any errors will be passed through without looking at them. +If the underlying base stream returns an error, it will be immediately propagated. Read more
§

fn try_flatten(self) -> TryFlatten<Self>
where + Self::Ok: TryStream, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn try_fold<T, Fut, F>(self, init: T, f: F) -> TryFold<Self, Fut, T, F>
where + F: FnMut(T, Self::Ok) -> Fut, + Fut: TryFuture<Ok = T, Error = Self::Error>, + Self: Sized,

Attempt to execute an accumulating asynchronous computation over a +stream, collecting all the values into one final result. Read more
§

fn try_concat(self) -> TryConcat<Self>
where + Self: Sized, + Self::Ok: Extend<<Self::Ok as IntoIterator>::Item> + IntoIterator + Default,

Attempt to concatenate all items of a stream into a single +extendable destination, returning a future representing the end result. Read more
§

fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently (unordered). Read more
§

fn try_buffered(self, n: usize) -> TryBuffered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently. Read more
§

fn try_poll_next_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Option<Result<Self::Ok, Self::Error>>>
where + Self: Unpin,

A convenience method for calling [TryStream::try_poll_next] on Unpin +stream types.
§

fn try_all<Fut, F>(self, f: F) -> TryAll<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if all items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that does not satisfy the predicate. Read more
§

fn try_any<Fut, F>(self, f: F) -> TryAny<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if any items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that satisfies the predicate. Read more
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.RequestHead.html b/actix_web/dev/struct.RequestHead.html new file mode 100644 index 000000000..0123de8a2 --- /dev/null +++ b/actix_web/dev/struct.RequestHead.html @@ -0,0 +1,36 @@ +RequestHead in actix_web::dev - Rust

Struct actix_web::dev::RequestHead

source ·
pub struct RequestHead {
+    pub method: Method,
+    pub uri: Uri,
+    pub version: Version,
+    pub headers: HeaderMap,
+    pub peer_addr: Option<SocketAddr>,
+    /* private fields */
+}

Fields§

§method: Method§uri: Uri§version: Version§headers: HeaderMap§peer_addr: Option<SocketAddr>

Will only be None when called in unit tests unless set manually.

+

Implementations§

source§

impl RequestHead

source

pub fn headers(&self) -> &HeaderMap

Read the message headers.

+
source

pub fn headers_mut(&mut self) -> &mut HeaderMap

Mutable reference to the message headers.

+
source

pub fn camel_case_headers(&self) -> bool

Is to uppercase headers with Camel-Case. +Default is false

+
source

pub fn set_camel_case_headers(&mut self, val: bool)

Set true to send headers which are formatted as Camel-Case.

+
source

pub fn set_connection_type(&mut self, ctype: ConnectionType)

Set connection type of the message

+
source

pub fn connection_type(&self) -> ConnectionType

Connection type

+
source

pub fn upgrade(&self) -> bool

Connection upgrade status

+
source

pub fn chunked(&self) -> bool

Get response body chunking state

+
source

pub fn no_chunking(&mut self, val: bool)

source

pub fn expect(&self) -> bool

Request contains EXPECT header.

+

Trait Implementations§

source§

impl Clone for RequestHead

source§

fn clone(&self) -> RequestHead

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for RequestHead

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for RequestHead

source§

fn default() -> RequestHead

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.ResourceDef.html b/actix_web/dev/struct.ResourceDef.html new file mode 100644 index 000000000..84c18834b --- /dev/null +++ b/actix_web/dev/struct.ResourceDef.html @@ -0,0 +1,412 @@ +ResourceDef in actix_web::dev - Rust

Struct actix_web::dev::ResourceDef

source ·
pub struct ResourceDef { /* private fields */ }
Expand description

Describes the set of paths that match to a resource.

+

ResourceDefs are effectively a way to transform the a custom resource pattern syntax into +suitable regular expressions from which to check matches with paths and capture portions of a +matched path into variables. Common cases are on a fast path that avoids going through the +regex engine.

+

§Pattern Format and Matching Behavior

+

Resource pattern is defined as a string of zero or more segments where each segment is +preceded by a slash /.

+

This means that pattern string must either be empty or begin with a slash (/). This also +implies that a trailing slash in pattern defines an empty segment. For example, the pattern +"/user/" has two segments: ["user", ""]

+

A key point to understand is that ResourceDef matches segments, not strings. Segments are +matched individually. For example, the pattern /user/ is not considered a prefix for the path +/user/123/456, because the second segment doesn’t match: ["user", ""] +vs ["user", "123", "456"].

+

This definition is consistent with the definition of absolute URL path in +RFC 3986 §3.3

+

§Static Resources

+

A static resource is the most basic type of definition. Pass a pattern to new. +Conforming paths must match the pattern exactly.

+

§Examples

+
let resource = ResourceDef::new("/home");
+
+assert!(resource.is_match("/home"));
+
+assert!(!resource.is_match("/home/"));
+assert!(!resource.is_match("/home/new"));
+assert!(!resource.is_match("/homes"));
+assert!(!resource.is_match("/search"));
+

§Dynamic Segments

+

Also known as “path parameters”. Resources can define sections of a pattern that be extracted +from a conforming path, if it conforms to (one of) the resource pattern(s).

+

The marker for a dynamic segment is curly braces wrapping an identifier. For example, +/user/{id} would match paths like /user/123 or /user/james and be able to extract the user +IDs “123” and “james”, respectively.

+

However, this resource pattern (/user/{id}) would, not cover /user/123/stars (unless +constructed as a prefix; see next section) since the default pattern for segments matches all +characters until it finds a / character (or the end of the path). Custom segment patterns are +covered further down.

+

Dynamic segments do not need to be delimited by / characters, they can be defined within a +path segment. For example, /rust-is-{opinion} can match the paths /rust-is-cool and +/rust-is-hard.

+

For information on capturing segment values from paths or other custom resource types, +see capture_match_info +and capture_match_info_fn.

+

A resource definition can contain at most 16 dynamic segments.

+

§Examples

+
use actix_router::{Path, ResourceDef};
+
+let resource = ResourceDef::prefix("/user/{id}");
+
+assert!(resource.is_match("/user/123"));
+assert!(!resource.is_match("/user"));
+assert!(!resource.is_match("/user/"));
+
+let mut path = Path::new("/user/123");
+resource.capture_match_info(&mut path);
+assert_eq!(path.get("id").unwrap(), "123");
+

§Prefix Resources

+

A prefix resource is defined as pattern that can match just the start of a path, up to a +segment boundary.

+

Prefix patterns with a trailing slash may have an unexpected, though correct, behavior. +They define and therefore require an empty segment in order to match. It is easier to understand +this behavior after reading the matching behavior section. Examples are given below.

+

The empty pattern (""), as a prefix, matches any path.

+

Prefix resources can contain dynamic segments.

+

§Examples

+
let resource = ResourceDef::prefix("/home");
+assert!(resource.is_match("/home"));
+assert!(resource.is_match("/home/new"));
+assert!(!resource.is_match("/homes"));
+
+// prefix pattern with a trailing slash
+let resource = ResourceDef::prefix("/user/{id}/");
+assert!(resource.is_match("/user/123/"));
+assert!(resource.is_match("/user/123//stars"));
+assert!(!resource.is_match("/user/123/stars"));
+assert!(!resource.is_match("/user/123"));
+

§Custom Regex Segments

+

Dynamic segments can be customised to only match a specific regular expression. It can be +helpful to do this if resource definitions would otherwise conflict and cause one to +be inaccessible.

+

The regex used when capturing segment values can be specified explicitly using this syntax: +{name:regex}. For example, /user/{id:\d+} will only match paths where the user ID +is numeric.

+

The regex could potentially match multiple segments. If this is not wanted, then care must be +taken to avoid matching a slash /. It is guaranteed, however, that the match ends at a +segment boundary; the pattern r"(/|$) is always appended to the regex.

+

By default, dynamic segments use this regex: [^/]+. This shows why it is the case, as shown in +the earlier section, that segments capture a slice of the path up to the next / character.

+

Custom regex segments can be used in static and prefix resource definition variants.

+

§Examples

+
let resource = ResourceDef::new(r"/user/{id:\d+}");
+assert!(resource.is_match("/user/123"));
+assert!(resource.is_match("/user/314159"));
+assert!(!resource.is_match("/user/abc"));
+

§Tail Segments

+

As a shortcut to defining a custom regex for matching all remaining characters (not just those +up until a / character), there is a special pattern to match (and capture) the remaining +path portion.

+

To do this, use the segment pattern: {name}*. Since a tail segment also has a name, values are +extracted in the same way as non-tail dynamic segments.

+

§Examples

+
let resource = ResourceDef::new("/blob/{tail}*");
+assert!(resource.is_match("/blob/HEAD/Cargo.toml"));
+assert!(resource.is_match("/blob/HEAD/README.md"));
+
+let mut path = Path::new("/blob/main/LICENSE");
+resource.capture_match_info(&mut path);
+assert_eq!(path.get("tail").unwrap(), "main/LICENSE");
+

§Multi-Pattern Resources

+

For resources that can map to multiple distinct paths, it may be suitable to use +multi-pattern resources by passing an array/vec to new. They will be combined +into a regex set which is usually quicker to check matches on than checking each +pattern individually.

+

Multi-pattern resources can contain dynamic segments just like single pattern ones. +However, take care to use consistent and semantically-equivalent segment names; it could affect +expectations in the router using these definitions and cause runtime panics.

+

§Examples

+
let resource = ResourceDef::new(["/home", "/index"]);
+assert!(resource.is_match("/home"));
+assert!(resource.is_match("/index"));
+

§Trailing Slashes

+

It should be noted that this library takes no steps to normalize intra-path or trailing slashes. +As such, all resource definitions implicitly expect a pre-processing step to normalize paths if +you wish to accommodate “recoverable” path errors. Below are several examples of resource-path +pairs that would not be compatible.

+

§Examples

+
assert!(!ResourceDef::new("/root").is_match("/root/"));
+assert!(!ResourceDef::new("/root/").is_match("/root"));
+assert!(!ResourceDef::prefix("/root/").is_match("/root"));
+

Implementations§

source§

impl ResourceDef

source

pub fn new<T>(paths: T) -> ResourceDef
where + T: IntoPatterns,

Constructs a new resource definition from patterns.

+

Multi-pattern resources can be constructed by providing a slice (or vec) of patterns.

+
§Panics
+

Panics if any path patterns are malformed.

+
§Examples
+
use actix_router::ResourceDef;
+
+let resource = ResourceDef::new("/user/{id}");
+assert!(resource.is_match("/user/123"));
+assert!(!resource.is_match("/user/123/stars"));
+assert!(!resource.is_match("user/1234"));
+assert!(!resource.is_match("/foo"));
+
+let resource = ResourceDef::new(["/profile", "/user/{id}"]);
+assert!(resource.is_match("/profile"));
+assert!(resource.is_match("/user/123"));
+assert!(!resource.is_match("user/123"));
+assert!(!resource.is_match("/foo"));
+
source

pub fn prefix<T>(paths: T) -> ResourceDef
where + T: IntoPatterns,

Constructs a new resource definition using a pattern that performs prefix matching.

+

More specifically, the regular expressions generated for matching are different when using +this method vs using new; they will not be appended with the $ meta-character that +matches the end of an input.

+

Although it will compile and run correctly, it is meaningless to construct a prefix +resource definition with a tail segment; use new in this case.

+
§Panics
+

Panics if path pattern is malformed.

+
§Examples
+
use actix_router::ResourceDef;
+
+let resource = ResourceDef::prefix("/user/{id}");
+assert!(resource.is_match("/user/123"));
+assert!(resource.is_match("/user/123/stars"));
+assert!(!resource.is_match("user/123"));
+assert!(!resource.is_match("user/123/stars"));
+assert!(!resource.is_match("/foo"));
+
source

pub fn root_prefix(path: &str) -> ResourceDef

Constructs a new resource definition using a string pattern that performs prefix matching, +ensuring a leading / if pattern is not empty.

+
§Panics
+

Panics if path pattern is malformed.

+
§Examples
+
use actix_router::ResourceDef;
+
+let resource = ResourceDef::root_prefix("user/{id}");
+
+assert_eq!(&resource, &ResourceDef::prefix("/user/{id}"));
+assert_eq!(&resource, &ResourceDef::root_prefix("/user/{id}"));
+assert_ne!(&resource, &ResourceDef::new("user/{id}"));
+assert_ne!(&resource, &ResourceDef::new("/user/{id}"));
+
+assert!(resource.is_match("/user/123"));
+assert!(!resource.is_match("user/123"));
+
source

pub fn id(&self) -> u16

Returns a numeric resource ID.

+

If not explicitly set using set_id, this will return 0.

+
§Examples
+
let mut resource = ResourceDef::new("/root");
+assert_eq!(resource.id(), 0);
+
+resource.set_id(42);
+assert_eq!(resource.id(), 42);
+
source

pub fn set_id(&mut self, id: u16)

Set numeric resource ID.

+
§Examples
+
let mut resource = ResourceDef::new("/root");
+resource.set_id(42);
+assert_eq!(resource.id(), 42);
+
source

pub fn name(&self) -> Option<&str>

Returns resource definition name, if set.

+
§Examples
+
let mut resource = ResourceDef::new("/root");
+assert!(resource.name().is_none());
+
+resource.set_name("root");
+assert_eq!(resource.name().unwrap(), "root");
+
source

pub fn set_name(&mut self, name: impl Into<String>)

Assigns a new name to the resource.

+
§Panics
+

Panics if name is an empty string.

+
§Examples
+
let mut resource = ResourceDef::new("/root");
+resource.set_name("root");
+assert_eq!(resource.name().unwrap(), "root");
+
source

pub fn is_prefix(&self) -> bool

Returns true if pattern type is prefix.

+
§Examples
+
assert!(ResourceDef::prefix("/user").is_prefix());
+assert!(!ResourceDef::new("/user").is_prefix());
+
source

pub fn pattern(&self) -> Option<&str>

Returns the pattern string that generated the resource definition.

+

If definition is constructed with multiple patterns, the first pattern is returned. To get +all patterns, use patterns_iter. If resource has 0 patterns, +returns None.

+
§Examples
+
let mut resource = ResourceDef::new("/user/{id}");
+assert_eq!(resource.pattern().unwrap(), "/user/{id}");
+
+let mut resource = ResourceDef::new(["/profile", "/user/{id}"]);
+assert_eq!(resource.pattern(), Some("/profile"));
+
source

pub fn pattern_iter(&self) -> impl Iterator<Item = &str>

Returns iterator of pattern strings that generated the resource definition.

+
§Examples
+
let mut resource = ResourceDef::new("/root");
+let mut iter = resource.pattern_iter();
+assert_eq!(iter.next().unwrap(), "/root");
+assert!(iter.next().is_none());
+
+let mut resource = ResourceDef::new(["/root", "/backup"]);
+let mut iter = resource.pattern_iter();
+assert_eq!(iter.next().unwrap(), "/root");
+assert_eq!(iter.next().unwrap(), "/backup");
+assert!(iter.next().is_none());
+
source

pub fn join(&self, other: &ResourceDef) -> ResourceDef

Joins two resources.

+

Resulting resource is prefix if other is prefix.

+
§Examples
+
let joined = ResourceDef::prefix("/root").join(&ResourceDef::prefix("/seg"));
+assert_eq!(joined, ResourceDef::prefix("/root/seg"));
+
source

pub fn is_match(&self, path: &str) -> bool

Returns true if path matches this resource.

+

The behavior of this method depends on how the ResourceDef was constructed. For example, +static resources will not be able to match as many paths as dynamic and prefix resources. +See ResourceDef struct docs for details on resource definition types.

+

This method will always agree with find_match on whether the path +matches or not.

+
§Examples
+
use actix_router::ResourceDef;
+
+// static resource
+let resource = ResourceDef::new("/user");
+assert!(resource.is_match("/user"));
+assert!(!resource.is_match("/users"));
+assert!(!resource.is_match("/user/123"));
+assert!(!resource.is_match("/foo"));
+
+// dynamic resource
+let resource = ResourceDef::new("/user/{user_id}");
+assert!(resource.is_match("/user/123"));
+assert!(!resource.is_match("/user/123/stars"));
+
+// prefix resource
+let resource = ResourceDef::prefix("/root");
+assert!(resource.is_match("/root"));
+assert!(resource.is_match("/root/leaf"));
+assert!(!resource.is_match("/roots"));
+
+// more examples are shown in the `ResourceDef` struct docs
+
source

pub fn find_match(&self, path: &str) -> Option<usize>

Tries to match path to this resource, returning the position in the path where the +match ends.

+

This method will always agree with is_match on whether the path matches +or not.

+
§Examples
+
use actix_router::ResourceDef;
+
+// static resource
+let resource = ResourceDef::new("/user");
+assert_eq!(resource.find_match("/user"), Some(5));
+assert!(resource.find_match("/user/").is_none());
+assert!(resource.find_match("/user/123").is_none());
+assert!(resource.find_match("/foo").is_none());
+
+// constant prefix resource
+let resource = ResourceDef::prefix("/user");
+assert_eq!(resource.find_match("/user"), Some(5));
+assert_eq!(resource.find_match("/user/"), Some(5));
+assert_eq!(resource.find_match("/user/123"), Some(5));
+
+// dynamic prefix resource
+let resource = ResourceDef::prefix("/user/{id}");
+assert_eq!(resource.find_match("/user/123"), Some(9));
+assert_eq!(resource.find_match("/user/1234/"), Some(10));
+assert_eq!(resource.find_match("/user/12345/stars"), Some(11));
+assert!(resource.find_match("/user/").is_none());
+
+// multi-pattern resource
+let resource = ResourceDef::new(["/user/{id}", "/profile/{id}"]);
+assert_eq!(resource.find_match("/user/123"), Some(9));
+assert_eq!(resource.find_match("/profile/1234"), Some(13));
+
source

pub fn capture_match_info<R>(&self, resource: &mut R) -> bool
where + R: Resource,

Collects dynamic segment values into resource.

+

Returns true if path matches this resource.

+
§Examples
+
use actix_router::{Path, ResourceDef};
+
+let resource = ResourceDef::prefix("/user/{id}");
+let mut path = Path::new("/user/123/stars");
+assert!(resource.capture_match_info(&mut path));
+assert_eq!(path.get("id").unwrap(), "123");
+assert_eq!(path.unprocessed(), "/stars");
+
+let resource = ResourceDef::new("/blob/{path}*");
+let mut path = Path::new("/blob/HEAD/Cargo.toml");
+assert!(resource.capture_match_info(&mut path));
+assert_eq!(path.get("path").unwrap(), "HEAD/Cargo.toml");
+assert_eq!(path.unprocessed(), "");
+
source

pub fn capture_match_info_fn<R, F>(&self, resource: &mut R, check_fn: F) -> bool
where + R: Resource, + F: FnOnce(&R) -> bool,

Collects dynamic segment values into resource after matching paths and executing +check function.

+

The check function is given a reference to the passed resource and optional arbitrary data. +This is useful if you want to conditionally match on some non-path related aspect of the +resource type.

+

Returns true if resource path matches this resource definition and satisfies the +given check function.

+
§Examples
+
use actix_router::{Path, ResourceDef};
+
+fn try_match(resource: &ResourceDef, path: &mut Path<&str>) -> bool {
+    let admin_allowed = std::env::var("ADMIN_ALLOWED").is_ok();
+
+    resource.capture_match_info_fn(
+        path,
+        // when env var is not set, reject when path contains "admin"
+        |path| !(!admin_allowed && path.as_str().contains("admin")),
+    )
+}
+
+let resource = ResourceDef::prefix("/user/{id}");
+
+// path matches; segment values are collected into path
+let mut path = Path::new("/user/james/stars");
+assert!(try_match(&resource, &mut path));
+assert_eq!(path.get("id").unwrap(), "james");
+assert_eq!(path.unprocessed(), "/stars");
+
+// path matches but fails check function; no segments are collected
+let mut path = Path::new("/user/admin/stars");
+assert!(!try_match(&resource, &mut path));
+assert_eq!(path.unprocessed(), "/user/admin/stars");
+
source

pub fn resource_path_from_iter<I>(&self, path: &mut String, values: I) -> bool
where + I: IntoIterator, + <I as IntoIterator>::Item: AsRef<str>,

Assembles full resource path from iterator of dynamic segment values.

+

Returns true on success.

+

For multi-pattern resources, the first pattern is used under the assumption that it would be +equivalent to any other choice.

+
§Examples
+
let mut s = String::new();
+let resource = ResourceDef::new("/user/{id}/post/{title}");
+
+assert!(resource.resource_path_from_iter(&mut s, &["123", "my-post"]));
+assert_eq!(s, "/user/123/post/my-post");
+
source

pub fn resource_path_from_map<K, V, S>( + &self, + path: &mut String, + values: &HashMap<K, V, S> +) -> bool
where + K: Borrow<str> + Eq + Hash, + V: AsRef<str>, + S: BuildHasher,

Assembles resource path from map of dynamic segment values.

+

Returns true on success.

+

For multi-pattern resources, the first pattern is used under the assumption that it would be +equivalent to any other choice.

+
§Examples
+
let mut s = String::new();
+let resource = ResourceDef::new("/user/{id}/post/{title}");
+
+let mut map = HashMap::new();
+map.insert("id", "123");
+map.insert("title", "my-post");
+
+assert!(resource.resource_path_from_map(&mut s, &map));
+assert_eq!(s, "/user/123/post/my-post");
+

Trait Implementations§

source§

impl Clone for ResourceDef

source§

fn clone(&self) -> ResourceDef

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ResourceDef

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a str> for ResourceDef

source§

fn from(path: &'a str) -> ResourceDef

Converts to this type from the input type.
source§

impl From<String> for ResourceDef

source§

fn from(path: String) -> ResourceDef

Converts to this type from the input type.
source§

impl Hash for ResourceDef

source§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq for ResourceDef

source§

fn eq(&self, other: &ResourceDef) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for ResourceDef

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.ResourceMap.html b/actix_web/dev/struct.ResourceMap.html new file mode 100644 index 000000000..be9a93c13 --- /dev/null +++ b/actix_web/dev/struct.ResourceMap.html @@ -0,0 +1,41 @@ +ResourceMap in actix_web::dev - Rust

Struct actix_web::dev::ResourceMap

source ·
pub struct ResourceMap { /* private fields */ }

Implementations§

source§

impl ResourceMap

source

pub fn new(root: ResourceDef) -> Self

Creates a container node in the ResourceMap tree.

+
source

pub fn add( + &mut self, + pattern: &mut ResourceDef, + nested: Option<Rc<ResourceMap>> +)

Adds a (possibly nested) resource.

+

To add a non-prefix pattern, nested must be None. +To add external resource, supply a pattern without a leading /. +The root pattern of nested, if present, should match pattern.

+
source

pub fn url_for<U, I>( + &self, + req: &HttpRequest, + name: &str, + elements: U +) -> Result<Url, UrlGenerationError>
where + U: IntoIterator<Item = I>, + I: AsRef<str>,

Generate URL for named resource.

+

Check HttpRequest::url_for for detailed information.

+
source

pub fn has_resource(&self, path: &str) -> bool

Returns true if there is a resource that would match path.

+
source

pub fn match_name(&self, path: &str) -> Option<&str>

Returns the name of the route that matches the given path or None if no full match +is possible or the matching resource is not named.

+
source

pub fn match_pattern(&self, path: &str) -> Option<String>

Returns the full resource pattern matched against a path or None if no full match +is possible.

+

Trait Implementations§

source§

impl Clone for ResourceMap

source§

fn clone(&self) -> ResourceMap

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ResourceMap

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.Response.html b/actix_web/dev/struct.Response.html new file mode 100644 index 000000000..a2ff6e8ac --- /dev/null +++ b/actix_web/dev/struct.Response.html @@ -0,0 +1,58 @@ +Response in actix_web::dev - Rust

Struct actix_web::dev::Response

source ·
pub struct Response<B> { /* private fields */ }
Expand description

An HTTP response.

+

Implementations§

source§

impl Response<BoxBody>

source

pub fn new(status: StatusCode) -> Response<BoxBody>

Constructs a new response with default body.

+
source

pub fn build(status: StatusCode) -> ResponseBuilder

Constructs a new response builder.

+
source

pub fn ok() -> Response<BoxBody>

Constructs a new response with status 200 OK.

+
source

pub fn bad_request() -> Response<BoxBody>

Constructs a new response with status 400 Bad Request.

+
source

pub fn not_found() -> Response<BoxBody>

Constructs a new response with status 404 Not Found.

+
source

pub fn internal_server_error() -> Response<BoxBody>

Constructs a new response with status 500 Internal Server Error.

+
source§

impl<B> Response<B>

source

pub fn with_body(status: StatusCode, body: B) -> Response<B>

Constructs a new response with given body.

+
source

pub fn head(&self) -> &ResponseHead

Returns a reference to the head of this response.

+
source

pub fn head_mut(&mut self) -> &mut ResponseHead

Returns a mutable reference to the head of this response.

+
source

pub fn status(&self) -> StatusCode

Returns the status code of this response.

+
source

pub fn status_mut(&mut self) -> &mut StatusCode

Returns a mutable reference the status code of this response.

+
source

pub fn headers(&self) -> &HeaderMap

Returns a reference to response headers.

+
source

pub fn headers_mut(&mut self) -> &mut HeaderMap

Returns a mutable reference to response headers.

+
source

pub fn upgrade(&self) -> bool

Returns true if connection upgrade is enabled.

+
source

pub fn keep_alive(&self) -> bool

Returns true if keep-alive is enabled.

+
source

pub fn extensions(&self) -> Ref<'_, Extensions>

Returns a reference to the request-local data/extensions container.

+
source

pub fn extensions_mut(&mut self) -> RefMut<'_, Extensions>

Returns a mutable reference to the request-local data/extensions container.

+
source

pub fn body(&self) -> &B

Returns a reference to the body of this response.

+
source

pub fn set_body<B2>(self, body: B2) -> Response<B2>

Sets new body.

+
source

pub fn drop_body(self) -> Response<()>

Drops body and returns new response.

+
source

pub fn into_parts(self) -> (Response<()>, B)

Returns split head and body.

+
§Implementation Notes
+

Due to internal performance optimizations, the first element of the returned tuple is a +Response as well but only contains the head of the response this was called on.

+
source

pub fn map_body<F, B2>(self, f: F) -> Response<B2>
where + F: FnOnce(&mut ResponseHead, B) -> B2,

Map the current body type to another using a closure, returning a new response.

+

Closure receives the response head and the current body type.

+
source

pub fn map_into_boxed_body(self) -> Response<BoxBody>
where + B: MessageBody + 'static,

Map the current body to a type-erased BoxBody.

+
source

pub fn into_body(self) -> B

Returns the response body, dropping all other parts.

+

Trait Implementations§

source§

impl<B> Debug for Response<B>
where + B: MessageBody,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<B> Default for Response<B>
where + B: Default,

source§

fn default() -> Response<B>

Returns the “default value” for a type. Read more
source§

impl From<&'static [u8]> for Response<&'static [u8]>

source§

fn from(val: &'static [u8]) -> Response<&'static [u8]>

Converts to this type from the input type.
source§

impl From<&HandshakeError> for Response<BoxBody>

source§

fn from(err: &HandshakeError) -> Response<BoxBody>

Converts to this type from the input type.
source§

impl From<&String> for Response<String>

source§

fn from(val: &String) -> Response<String>

Converts to this type from the input type.
source§

impl From<&Vec<u8>> for Response<Vec<u8>>

source§

fn from(val: &Vec<u8>) -> Response<Vec<u8>>

Converts to this type from the input type.
source§

impl From<&'static str> for Response<&'static str>

source§

fn from(val: &'static str) -> Response<&'static str>

Converts to this type from the input type.
source§

impl From<ByteString> for Response<ByteString>

source§

fn from(val: ByteString) -> Response<ByteString>

Converts to this type from the input type.
source§

impl From<Bytes> for Response<Bytes>

source§

fn from(val: Bytes) -> Response<Bytes>

Converts to this type from the input type.
source§

impl From<BytesMut> for Response<BytesMut>

source§

fn from(val: BytesMut) -> Response<BytesMut>

Converts to this type from the input type.
source§

impl<E, U, I> From<DispatcherError<E, U, I>> for Response<BoxBody>
where + E: Debug + Display, + U: Encoder<I> + Decoder, + <U as Encoder<I>>::Error: Debug, + <U as Decoder>::Error: Debug,

source§

fn from(err: DispatcherError<E, U, I>) -> Response<BoxBody>

Converts to this type from the input type.
source§

impl From<Error> for Response<BoxBody>

source§

fn from(err: Error) -> Response<BoxBody>

Converts to this type from the input type.
source§

impl From<Error> for Response<BoxBody>

source§

fn from(err: Error) -> Response<BoxBody>

Converts to this type from the input type.
source§

impl From<HandshakeError> for Response<BoxBody>

source§

fn from(err: HandshakeError) -> Response<BoxBody>

Converts to this type from the input type.
source§

impl<B> From<HttpResponse<B>> for Response<B>

source§

fn from(res: HttpResponse<B>) -> Self

Converts to this type from the input type.
source§

impl From<HttpResponseBuilder> for Response<BoxBody>

source§

fn from(builder: HttpResponseBuilder) -> Self

Converts to this type from the input type.
source§

impl From<Infallible> for Response<BoxBody>

source§

fn from(val: Infallible) -> Response<BoxBody>

Converts to this type from the input type.
source§

impl From<ParseError> for Response<BoxBody>

source§

fn from(err: ParseError) -> Response<BoxBody>

Converts to this type from the input type.
source§

impl<B> From<Response<B>> for HttpResponse<B>

source§

fn from(res: Response<B>) -> Self

Converts to this type from the input type.
source§

impl From<Response<BoxBody>> for DispatchError

source§

fn from(original: Response<BoxBody>) -> DispatchError

Converts to this type from the input type.
source§

impl From<ResponseBuilder> for Response<EitherBody<()>>

source§

fn from(builder: ResponseBuilder) -> Response<EitherBody<()>>

Converts to this type from the input type.
source§

impl<I, E> From<Result<I, E>> for Response<BoxBody>
where + I: Into<Response<BoxBody>>, + E: Into<Error>,

source§

fn from(res: Result<I, E>) -> Response<BoxBody>

Converts to this type from the input type.
source§

impl<B> From<ServiceResponse<B>> for Response<B>

source§

fn from(res: ServiceResponse<B>) -> Response<B>

Converts to this type from the input type.
source§

impl From<String> for Response<String>

source§

fn from(val: String) -> Response<String>

Converts to this type from the input type.
source§

impl From<Vec<u8>> for Response<Vec<u8>>

source§

fn from(val: Vec<u8>) -> Response<Vec<u8>>

Converts to this type from the input type.
source§

impl Responder for Response<BoxBody>

§

type Body = BoxBody

source§

fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body>

Convert self to HttpResponse.
source§

fn customize(self) -> CustomizeResponder<Self>
where + Self: Sized,

Wraps responder to allow alteration of its response. Read more

Auto Trait Implementations§

§

impl<B> !Freeze for Response<B>

§

impl<B> !RefUnwindSafe for Response<B>

§

impl<B> !Send for Response<B>

§

impl<B> !Sync for Response<B>

§

impl<B> Unpin for Response<B>
where + B: Unpin,

§

impl<B> !UnwindSafe for Response<B>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.ResponseHead.html b/actix_web/dev/struct.ResponseHead.html new file mode 100644 index 000000000..491b3805c --- /dev/null +++ b/actix_web/dev/struct.ResponseHead.html @@ -0,0 +1,35 @@ +ResponseHead in actix_web::dev - Rust

Struct actix_web::dev::ResponseHead

source ·
pub struct ResponseHead {
+    pub version: Version,
+    pub status: StatusCode,
+    pub headers: HeaderMap,
+    pub reason: Option<&'static str>,
+    /* private fields */
+}

Fields§

§version: Version§status: StatusCode§headers: HeaderMap§reason: Option<&'static str>

Implementations§

source§

impl ResponseHead

source

pub fn new(status: StatusCode) -> ResponseHead

Create new instance of ResponseHead type

+
source

pub fn headers(&self) -> &HeaderMap

Read the message headers.

+
source

pub fn headers_mut(&mut self) -> &mut HeaderMap

Mutable reference to the message headers.

+
source

pub fn set_camel_case_headers(&mut self, camel_case: bool)

Sets the flag that controls whether to send headers formatted as Camel-Case.

+

Only applicable to HTTP/1.x responses; HTTP/2 header names are always lowercase.

+
source

pub fn set_connection_type(&mut self, ctype: ConnectionType)

Set connection type of the message

+
source

pub fn connection_type(&self) -> ConnectionType

source

pub fn keep_alive(&self) -> bool

Check if keep-alive is enabled

+
source

pub fn upgrade(&self) -> bool

Check upgrade status of this message

+
source

pub fn reason(&self) -> &str

Get custom reason for the response

+
source

pub fn chunked(&self) -> bool

Get response body chunking state

+
source

pub fn no_chunking(&mut self, val: bool)

Set no chunking for payload

+

Trait Implementations§

source§

impl Clone for ResponseHead

source§

fn clone(&self) -> ResponseHead

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ResponseHead

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.Server.html b/actix_web/dev/struct.Server.html new file mode 100644 index 000000000..30ebc3f88 --- /dev/null +++ b/actix_web/dev/struct.Server.html @@ -0,0 +1,176 @@ +Server in actix_web::dev - Rust

Struct actix_web::dev::Server

pub struct Server { /* private fields */ }
Expand description

General purpose TCP server that runs services receiving Tokio TcpStreams.

+

Handles creating worker threads, restarting faulted workers, connection accepting, and +back-pressure logic.

+

Creates a worker per CPU core (or the number specified in [ServerBuilder::workers]) and +distributes connections with a round-robin strategy.

+

The Server must be awaited or polled in order to start running. It will resolve when the +server has fully shut down.

+

§Shutdown Signals

+

On UNIX systems, SIGTERM will start a graceful shutdown and SIGQUIT or SIGINT will start a +forced shutdown. On Windows, a Ctrl-C signal will start a forced shutdown.

+

A graceful shutdown will wait for all workers to stop first.

+

§Examples

+

The following is a TCP echo server. Test using telnet 127.0.0.1 8080.

+ +
use std::io;
+
+use actix_rt::net::TcpStream;
+use actix_server::Server;
+use actix_service::{fn_service, ServiceFactoryExt as _};
+use bytes::BytesMut;
+use tokio::io::{AsyncReadExt as _, AsyncWriteExt as _};
+
+#[actix_rt::main]
+async fn main() -> io::Result<()> {
+    let bind_addr = ("127.0.0.1", 8080);
+
+    Server::build()
+        .bind("echo", bind_addr, move || {
+            fn_service(move |mut stream: TcpStream| {
+                async move {
+                    let mut size = 0;
+                    let mut buf = BytesMut::new();
+
+                    loop {
+                        match stream.read_buf(&mut buf).await {
+                            // end of stream; bail from loop
+                            Ok(0) => break,
+
+                            // write bytes back to stream
+                            Ok(bytes_read) => {
+                                stream.write_all(&buf[size..]).await.unwrap();
+                                size += bytes_read;
+                            }
+
+                            Err(err) => {
+                                eprintln!("Stream Error: {:?}", err);
+                                return Err(());
+                            }
+                        }
+                    }
+
+                    Ok(())
+                }
+            })
+            .map_err(|err| eprintln!("Service Error: {:?}", err))
+        })?
+        .run()
+        .await
+}
+

Implementations§

§

impl Server

pub fn build() -> ServerBuilder

Create server build.

+

pub fn handle(&self) -> ServerHandle

Get a Server handle that can be used issue commands and change it’s state.

+

See ServerHandle for usage.

+

Trait Implementations§

§

impl Future for Server

§

type Output = Result<(), Error>

The type of value produced on completion.
§

fn poll( + self: Pin<&mut Server>, + cx: &mut Context<'_> +) -> Poll<<Server as Future>::Output>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more

Auto Trait Implementations§

§

impl Freeze for Server

§

impl !RefUnwindSafe for Server

§

impl Send for Server

§

impl !Sync for Server

§

impl Unpin for Server

§

impl !UnwindSafe for Server

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> FutureExt for T
where + T: Future + ?Sized,

§

fn map<U, F>(self, f: F) -> Map<Self, F>
where + F: FnOnce(Self::Output) -> U, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn map_into<U>(self) -> MapInto<Self, U>
where + Self::Output: Into<U>, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnOnce(Self::Output) -> Fut, + Fut: Future, + Self: Sized,

Chain on a computation for when a future finished, passing the result of +the future to the provided closure f. Read more
§

fn left_future<B>(self) -> Either<Self, B>
where + B: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the left-hand variant +of that Either. Read more
§

fn right_future<A>(self) -> Either<A, Self>
where + A: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the right-hand variant +of that Either. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Convert this future into a single element stream. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Output: Future, + Self: Sized,

Flatten the execution of this future when the output of this +future is itself another future. Read more
§

fn flatten_stream(self) -> FlattenStream<Self>
where + Self::Output: Stream, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a future such that poll will never again be called once it has +completed. This method can be used to turn any Future into a +FusedFuture. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnOnce(&Self::Output), + Self: Sized,

Do something with the output of a future before passing it on. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the future. Read more
§

fn shared(self) -> Shared<Self>
where + Self: Sized, + Self::Output: Clone,

Available on crate feature std only.
Create a cloneable handle to this future where all handles will resolve +to the same result. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn unit_error(self) -> UnitError<Self>
where + Self: Sized,

§

fn never_error(self) -> NeverError<Self>
where + Self: Sized,

§

fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where + Self: Unpin,

A convenience for calling Future::poll on Unpin future types.
§

fn now_or_never(self) -> Option<Self::Output>
where + Self: Sized,

Evaluates and consumes the future, returning the resulting output if +the future is ready after the first call to Future::poll. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<F> IntoFuture for F
where + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

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
§

fn try_poll( + self: Pin<&mut F>, + cx: &mut Context<'_> +) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
§

impl<Fut> TryFutureExt for Fut
where + Fut: TryFuture + ?Sized,

§

fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>
where + Self::Ok: Sink<Item, Error = Self::Error>, + Self: Sized,

Available on crate feature sink only.
Flattens the execution of this future when the successful result of this +future is a [Sink]. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + F: FnOnce(Self::Ok) -> T, + Self: Sized,

Maps this future’s success value to a different value. Read more
§

fn map_ok_or_else<T, E, F>(self, e: E, f: F) -> MapOkOrElse<Self, F, E>
where + F: FnOnce(Self::Ok) -> T, + E: FnOnce(Self::Error) -> T, + Self: Sized,

Maps this future’s success value to a different value, and permits for error handling resulting in the same type. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + F: FnOnce(Self::Error) -> E, + Self: Sized,

Maps this future’s error value to a different value. Read more
§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Maps this future’s Error to a new error type +using the Into trait. Read more
§

fn ok_into<U>(self) -> OkInto<Self, U>
where + Self: Sized, + Self::Ok: Into<U>,

Maps this future’s Ok to a new type +using the Into trait.
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnOnce(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Executes another future after this one resolves successfully. The +success value is passed to a closure to create this subsequent future. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnOnce(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Executes another future if this one resolves to an error. The +error value is passed to a closure to create this subsequent future. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnOnce(&Self::Ok), + Self: Sized,

Do something with the success value of a future before passing it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnOnce(&Self::Error), + Self: Sized,

Do something with the error value of a future before passing it on. Read more
§

fn try_flatten(self) -> TryFlatten<Self, Self::Ok>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is another future. Read more
§

fn try_flatten_stream(self) -> TryFlattenStream<Self>
where + Self::Ok: TryStream<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F>
where + Self: Sized, + F: FnOnce(Self::Error) -> Self::Ok,

Unwraps this future’s output, producing a future with this future’s +Ok type as its +Output type. Read more
§

fn into_future(self) -> IntoFuture<Self>
where + Self: Sized,

Wraps a [TryFuture] into a type that implements +Future. Read more
§

fn try_poll_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Result<Self::Ok, Self::Error>>
where + Self: Unpin,

A convenience method for calling [TryFuture::try_poll] on Unpin +future types.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.ServerHandle.html b/actix_web/dev/struct.ServerHandle.html new file mode 100644 index 000000000..76655ae73 --- /dev/null +++ b/actix_web/dev/struct.ServerHandle.html @@ -0,0 +1,23 @@ +ServerHandle in actix_web::dev - Rust

Struct actix_web::dev::ServerHandle

pub struct ServerHandle { /* private fields */ }
Expand description

Server handle.

+

Implementations§

§

impl ServerHandle

pub fn pause(&self) -> impl Future<Output = ()>

Pause accepting incoming connections.

+

May drop socket pending connection. All open connections remain active.

+

pub fn resume(&self) -> impl Future<Output = ()>

Resume accepting incoming connections.

+

pub fn stop(&self, graceful: bool) -> impl Future<Output = ()>

Stop incoming connection processing, stop all workers and exit.

+

Trait Implementations§

§

impl Clone for ServerHandle

§

fn clone(&self) -> ServerHandle

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for ServerHandle

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.ServiceRequest.html b/actix_web/dev/struct.ServiceRequest.html new file mode 100644 index 000000000..853904afd --- /dev/null +++ b/actix_web/dev/struct.ServiceRequest.html @@ -0,0 +1,84 @@ +ServiceRequest in actix_web::dev - Rust

Struct actix_web::dev::ServiceRequest

source ·
pub struct ServiceRequest { /* private fields */ }
Expand description

A service level request wrapper.

+

Allows mutable access to request’s internal structures.

+

Implementations§

source§

impl ServiceRequest

source

pub fn into_parts(self) -> (HttpRequest, Payload)

Deconstruct ServiceRequest into inner parts.

+
source

pub fn parts_mut(&mut self) -> (&mut HttpRequest, &mut Payload)

Returns mutable accessors to inner parts.

+
source

pub fn parts(&self) -> (&HttpRequest, &Payload)

Returns immutable accessors to inner parts.

+
source

pub fn request(&self) -> &HttpRequest

Returns immutable accessor to inner HttpRequest.

+
source

pub fn extract<T>(&mut self) -> <T as FromRequest>::Future
where + T: FromRequest,

Derives a type from this request using an extractor.

+

Returns the T extractor’s Future type which can be awaited. This is particularly handy +when you want to use an extractor in a middleware implementation.

+
§Examples
+
use actix_web::{
+    dev::{ServiceRequest, ServiceResponse},
+    web::Path, Error
+};
+
+async fn my_helper(mut srv_req: ServiceRequest) -> Result<ServiceResponse, Error> {
+    let path = srv_req.extract::<Path<(String, u32)>>().await?;
+    // [...]
+}
+
source

pub fn from_parts(req: HttpRequest, payload: Payload) -> Self

Construct request from parts.

+
source

pub fn from_request(req: HttpRequest) -> Self

Construct ServiceRequest with no payload from given HttpRequest.

+
source

pub fn into_response<B, R: Into<Response<B>>>( + self, + res: R +) -> ServiceResponse<B>

Create ServiceResponse from this request and given response.

+
source

pub fn error_response<E: Into<Error>>(self, err: E) -> ServiceResponse

Create ServiceResponse from this request and given error.

+
source

pub fn head(&self) -> &RequestHead

Returns a reference to the request head.

+
source

pub fn head_mut(&mut self) -> &mut RequestHead

Returns a mutable reference to the request head.

+
source

pub fn uri(&self) -> &Uri

Returns the request URI.

+
source

pub fn method(&self) -> &Method

Returns the request method.

+
source

pub fn version(&self) -> Version

Returns the request version.

+
source

pub fn headers(&self) -> &HeaderMap

Returns a reference to request headers.

+
source

pub fn headers_mut(&mut self) -> &mut HeaderMap

Returns a mutable reference to request headers.

+
source

pub fn path(&self) -> &str

Returns request path.

+
source

pub fn query_string(&self) -> &str

Counterpart to HttpRequest::query_string.

+
source

pub fn peer_addr(&self) -> Option<SocketAddr>

Returns peer’s socket address.

+

See HttpRequest::peer_addr for more details.

+
source

pub fn connection_info(&self) -> Ref<'_, ConnectionInfo>

Returns a reference to connection info.

+
source

pub fn match_info(&self) -> &Path<Url>

Counterpart to HttpRequest::match_info.

+
source

pub fn match_info_mut(&mut self) -> &mut Path<Url>

Returns a mutable reference to the path match information.

+
source

pub fn match_name(&self) -> Option<&str>

Counterpart to HttpRequest::match_name.

+
source

pub fn match_pattern(&self) -> Option<String>

Counterpart to HttpRequest::match_pattern.

+
source

pub fn resource_map(&self) -> &ResourceMap

Returns a reference to the application’s resource map. +Counterpart to HttpRequest::resource_map.

+
source

pub fn app_config(&self) -> &AppConfig

Counterpart to HttpRequest::app_config.

+
source

pub fn app_data<T: 'static>(&self) -> Option<&T>

Counterpart to HttpRequest::app_data.

+
source

pub fn conn_data<T: 'static>(&self) -> Option<&T>

Counterpart to HttpRequest::conn_data.

+
source

pub fn cookies(&self) -> Result<Ref<'_, Vec<Cookie<'static>>>, CookieParseError>

Available on crate feature cookies only.

Return request cookies.

+
source

pub fn cookie(&self, name: &str) -> Option<Cookie<'static>>

Available on crate feature cookies only.

Return request cookie.

+
source

pub fn set_payload(&mut self, payload: Payload)

Set request payload.

+
source

pub fn add_data_container(&mut self, extensions: Rc<Extensions>)

Add data container to request’s resolution set.

+

In middleware, prefer extensions_mut for request-local +data since it is assumed that the same app data is presented for every request.

+
source

pub fn guard_ctx(&self) -> GuardContext<'_>

Creates a context object for use with a routing guard.

+

Trait Implementations§

source§

impl Debug for ServiceRequest

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl HttpMessage for ServiceRequest

§

type Stream = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>

Type of message payload stream
source§

fn headers(&self) -> &HeaderMap

Read the message headers.
source§

fn extensions(&self) -> Ref<'_, Extensions>

Returns a reference to the request-local data/extensions container.
source§

fn extensions_mut(&self) -> RefMut<'_, Extensions>

Returns a mutable reference to the request-local data/extensions container.
source§

fn take_payload(&mut self) -> Payload<Self::Stream>

Message payload stream
source§

fn content_type(&self) -> &str

Read the request content type. If request did not contain a Content-Type header, an empty +string is returned.
source§

fn encoding(&self) -> Result<&'static Encoding, ContentTypeError>

Get content type encoding. Read more
source§

fn mime_type(&self) -> Result<Option<Mime>, ContentTypeError>

Convert the request content type to a known mime type.
source§

fn chunked(&self) -> Result<bool, ParseError>

Check if request has chunked transfer encoding.
source§

impl Resource for ServiceRequest

§

type Path = Url

Type of resource’s path returned in resource_path.
source§

fn resource_path(&mut self) -> &mut Path<Self::Path>

source§

impl ServiceFactory<ServiceRequest> for Route

§

type Response = ServiceResponse

Responses given by the created services.
§

type Error = Error

Errors produced by the created services.
§

type Config = ()

Service factory configuration.
§

type Service = RouteService

The kind of Service created by this factory.
§

type InitError = ()

Errors potentially raised while building a service.
§

type Future = Pin<Box<dyn Future<Output = Result<<Route as ServiceFactory<ServiceRequest>>::Service, <Route as ServiceFactory<ServiceRequest>>::InitError>>>>

The future of the Service instance.g
source§

fn new_service(&self, _: ()) -> Self::Future

Create and return a new service asynchronously.
source§

impl<S, B> Transform<S, ServiceRequest> for Compress
where + B: MessageBody, + S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,

Available on crate feature __compress only.
§

type Response = ServiceResponse<EitherBody<Encoder<B>>>

Responses produced by the service.
§

type Error = Error

Errors produced by the service.
§

type Transform = CompressMiddleware<S>

The TransformService value created by this factory
§

type InitError = ()

Errors produced while building a transform service.
§

type Future = Ready<Result<<Compress as Transform<S, ServiceRequest>>::Transform, <Compress as Transform<S, ServiceRequest>>::InitError>>

The future response value.
source§

fn new_transform(&self, service: S) -> Self::Future

Creates and returns a new Transform component, asynchronously
source§

impl<S, B> Transform<S, ServiceRequest> for DefaultHeaders
where + S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>, + S::Future: 'static,

§

type Response = ServiceResponse<B>

Responses produced by the service.
§

type Error = Error

Errors produced by the service.
§

type Transform = DefaultHeadersMiddleware<S>

The TransformService value created by this factory
§

type InitError = ()

Errors produced while building a transform service.
§

type Future = Ready<Result<<DefaultHeaders as Transform<S, ServiceRequest>>::Transform, <DefaultHeaders as Transform<S, ServiceRequest>>::InitError>>

The future response value.
source§

fn new_transform(&self, service: S) -> Self::Future

Creates and returns a new Transform component, asynchronously
source§

impl<S, B> Transform<S, ServiceRequest> for ErrorHandlers<B>
where + S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static, + S::Future: 'static, + B: 'static,

§

type Response = ServiceResponse<EitherBody<B>>

Responses produced by the service.
§

type Error = Error

Errors produced by the service.
§

type Transform = ErrorHandlersMiddleware<S, B>

The TransformService value created by this factory
§

type InitError = ()

Errors produced while building a transform service.
§

type Future = Pin<Box<dyn Future<Output = Result<<ErrorHandlers<B> as Transform<S, ServiceRequest>>::Transform, <ErrorHandlers<B> as Transform<S, ServiceRequest>>::InitError>>>>

The future response value.
source§

fn new_transform(&self, service: S) -> Self::Future

Creates and returns a new Transform component, asynchronously
source§

impl<S, B> Transform<S, ServiceRequest> for Logger
where + S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>, + B: MessageBody,

§

type Response = ServiceResponse<StreamLog<B>>

Responses produced by the service.
§

type Error = Error

Errors produced by the service.
§

type Transform = LoggerMiddleware<S>

The TransformService value created by this factory
§

type InitError = ()

Errors produced while building a transform service.
§

type Future = Ready<Result<<Logger as Transform<S, ServiceRequest>>::Transform, <Logger as Transform<S, ServiceRequest>>::InitError>>

The future response value.
source§

fn new_transform(&self, service: S) -> Self::Future

Creates and returns a new Transform component, asynchronously
source§

impl<S, B> Transform<S, ServiceRequest> for NormalizePath
where + S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>, + S::Future: 'static,

§

type Response = ServiceResponse<B>

Responses produced by the service.
§

type Error = Error

Errors produced by the service.
§

type Transform = NormalizePathNormalization<S>

The TransformService value created by this factory
§

type InitError = ()

Errors produced while building a transform service.
§

type Future = Ready<Result<<NormalizePath as Transform<S, ServiceRequest>>::Transform, <NormalizePath as Transform<S, ServiceRequest>>::InitError>>

The future response value.
source§

fn new_transform(&self, service: S) -> Self::Future

Creates and returns a new Transform component, asynchronously

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.ServiceResponse.html b/actix_web/dev/struct.ServiceResponse.html new file mode 100644 index 000000000..8eeabb8a5 --- /dev/null +++ b/actix_web/dev/struct.ServiceResponse.html @@ -0,0 +1,40 @@ +ServiceResponse in actix_web::dev - Rust

Struct actix_web::dev::ServiceResponse

source ·
pub struct ServiceResponse<B = BoxBody> { /* private fields */ }
Expand description

A service level response wrapper.

+

Implementations§

source§

impl ServiceResponse<BoxBody>

source

pub fn from_err<E: Into<Error>>(err: E, request: HttpRequest) -> Self

Create service response from the error

+
source§

impl<B> ServiceResponse<B>

source

pub fn new(request: HttpRequest, response: HttpResponse<B>) -> Self

Create service response instance

+
source

pub fn error_response<E: Into<Error>>(self, err: E) -> ServiceResponse

Create service response for error

+
source

pub fn into_response<B1>( + self, + response: HttpResponse<B1> +) -> ServiceResponse<B1>

Create service response

+
source

pub fn request(&self) -> &HttpRequest

Returns reference to original request.

+
source

pub fn response(&self) -> &HttpResponse<B>

Returns reference to response.

+
source

pub fn response_mut(&mut self) -> &mut HttpResponse<B>

Returns mutable reference to response.

+
source

pub fn status(&self) -> StatusCode

Returns response status code.

+
source

pub fn headers(&self) -> &HeaderMap

Returns response’s headers.

+
source

pub fn headers_mut(&mut self) -> &mut HeaderMap

Returns mutable response’s headers.

+
source

pub fn into_parts(self) -> (HttpRequest, HttpResponse<B>)

Destructures ServiceResponse into request and response components.

+
source

pub fn map_body<F, B2>(self, f: F) -> ServiceResponse<B2>
where + F: FnOnce(&mut ResponseHead, B) -> B2,

Map the current body type to another using a closure. Returns a new response.

+

Closure receives the response head and the current body type.

+
source

pub fn map_into_left_body<R>(self) -> ServiceResponse<EitherBody<B, R>>

source

pub fn map_into_right_body<L>(self) -> ServiceResponse<EitherBody<L, B>>

source

pub fn map_into_boxed_body(self) -> ServiceResponse<BoxBody>
where + B: MessageBody + 'static,

source

pub fn into_body(self) -> B

Consumes the response and returns its body.

+

Trait Implementations§

source§

impl<B> Debug for ServiceResponse<B>
where + B: MessageBody, + B::Error: Into<Error>,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<B> From<ServiceResponse<B>> for HttpResponse<B>

source§

fn from(res: ServiceResponse<B>) -> HttpResponse<B>

Converts to this type from the input type.
source§

impl<B> From<ServiceResponse<B>> for Response<B>

source§

fn from(res: ServiceResponse<B>) -> Response<B>

Converts to this type from the input type.

Auto Trait Implementations§

§

impl<B = BoxBody> !Freeze for ServiceResponse<B>

§

impl<B = BoxBody> !RefUnwindSafe for ServiceResponse<B>

§

impl<B = BoxBody> !Send for ServiceResponse<B>

§

impl<B = BoxBody> !Sync for ServiceResponse<B>

§

impl<B> Unpin for ServiceResponse<B>
where + B: Unpin,

§

impl<B = BoxBody> !UnwindSafe for ServiceResponse<B>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.Url.html b/actix_web/dev/struct.Url.html new file mode 100644 index 000000000..18b7ac363 --- /dev/null +++ b/actix_web/dev/struct.Url.html @@ -0,0 +1,20 @@ +Url in actix_web::dev - Rust

Struct actix_web::dev::Url

source ·
pub struct Url { /* private fields */ }

Implementations§

source§

impl Url

source

pub fn new(uri: Uri) -> Url

source

pub fn new_with_quoter(uri: Uri, quoter: &Quoter) -> Url

source

pub fn uri(&self) -> &Uri

Returns URI.

+
source

pub fn path(&self) -> &str

Returns path.

+
source

pub fn update(&mut self, uri: &Uri)

source

pub fn update_with_quoter(&mut self, uri: &Uri, quoter: &Quoter)

Trait Implementations§

source§

impl Clone for Url

source§

fn clone(&self) -> Url

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Url

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Url

source§

fn default() -> Url

Returns the “default value” for a type. Read more
source§

impl ResourcePath for Url

source§

fn path(&self) -> &str

Auto Trait Implementations§

§

impl !Freeze for Url

§

impl RefUnwindSafe for Url

§

impl Send for Url

§

impl Sync for Url

§

impl Unpin for Url

§

impl UnwindSafe for Url

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.UrlEncoded.html b/actix_web/dev/struct.UrlEncoded.html new file mode 100644 index 000000000..02f0358a6 --- /dev/null +++ b/actix_web/dev/struct.UrlEncoded.html @@ -0,0 +1,121 @@ +UrlEncoded in actix_web::dev - Rust

Struct actix_web::dev::UrlEncoded

source ·
pub struct UrlEncoded<T> { /* private fields */ }
Expand description

Future that resolves to some T when parsed from a URL encoded payload.

+

Form can be deserialized from any type T that implements serde::Deserialize.

+

Returns error if:

+
    +
  • content type is not application/x-www-form-urlencoded
  • +
  • content length is greater than limit
  • +
+

Implementations§

source§

impl<T> UrlEncoded<T>

source

pub fn new(req: &HttpRequest, payload: &mut Payload) -> Self

Create a new future to decode a URL encoded request payload.

+
source

pub fn limit(self, limit: usize) -> Self

Set maximum accepted payload size. The default limit is 256kB.

+

Trait Implementations§

source§

impl<T> Future for UrlEncoded<T>
where + T: DeserializeOwned + 'static,

§

type Output = Result<T, UrlencodedError>

The type of value produced on completion.
source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more

Auto Trait Implementations§

§

impl<T> !Freeze for UrlEncoded<T>

§

impl<T> !RefUnwindSafe for UrlEncoded<T>

§

impl<T> !Send for UrlEncoded<T>

§

impl<T> !Sync for UrlEncoded<T>

§

impl<T> Unpin for UrlEncoded<T>

§

impl<T> !UnwindSafe for UrlEncoded<T>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> FutureExt for T
where + T: Future + ?Sized,

§

fn map<U, F>(self, f: F) -> Map<Self, F>
where + F: FnOnce(Self::Output) -> U, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn map_into<U>(self) -> MapInto<Self, U>
where + Self::Output: Into<U>, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnOnce(Self::Output) -> Fut, + Fut: Future, + Self: Sized,

Chain on a computation for when a future finished, passing the result of +the future to the provided closure f. Read more
§

fn left_future<B>(self) -> Either<Self, B>
where + B: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the left-hand variant +of that Either. Read more
§

fn right_future<A>(self) -> Either<A, Self>
where + A: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the right-hand variant +of that Either. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Convert this future into a single element stream. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Output: Future, + Self: Sized,

Flatten the execution of this future when the output of this +future is itself another future. Read more
§

fn flatten_stream(self) -> FlattenStream<Self>
where + Self::Output: Stream, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a future such that poll will never again be called once it has +completed. This method can be used to turn any Future into a +FusedFuture. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnOnce(&Self::Output), + Self: Sized,

Do something with the output of a future before passing it on. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the future. Read more
§

fn shared(self) -> Shared<Self>
where + Self: Sized, + Self::Output: Clone,

Available on crate feature std only.
Create a cloneable handle to this future where all handles will resolve +to the same result. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn unit_error(self) -> UnitError<Self>
where + Self: Sized,

§

fn never_error(self) -> NeverError<Self>
where + Self: Sized,

§

fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where + Self: Unpin,

A convenience for calling Future::poll on Unpin future types.
§

fn now_or_never(self) -> Option<Self::Output>
where + Self: Sized,

Evaluates and consumes the future, returning the resulting output if +the future is ready after the first call to Future::poll. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<F> IntoFuture for F
where + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

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
§

fn try_poll( + self: Pin<&mut F>, + cx: &mut Context<'_> +) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
§

impl<Fut> TryFutureExt for Fut
where + Fut: TryFuture + ?Sized,

§

fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>
where + Self::Ok: Sink<Item, Error = Self::Error>, + Self: Sized,

Available on crate feature sink only.
Flattens the execution of this future when the successful result of this +future is a [Sink]. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + F: FnOnce(Self::Ok) -> T, + Self: Sized,

Maps this future’s success value to a different value. Read more
§

fn map_ok_or_else<T, E, F>(self, e: E, f: F) -> MapOkOrElse<Self, F, E>
where + F: FnOnce(Self::Ok) -> T, + E: FnOnce(Self::Error) -> T, + Self: Sized,

Maps this future’s success value to a different value, and permits for error handling resulting in the same type. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + F: FnOnce(Self::Error) -> E, + Self: Sized,

Maps this future’s error value to a different value. Read more
§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Maps this future’s Error to a new error type +using the Into trait. Read more
§

fn ok_into<U>(self) -> OkInto<Self, U>
where + Self: Sized, + Self::Ok: Into<U>,

Maps this future’s Ok to a new type +using the Into trait.
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnOnce(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Executes another future after this one resolves successfully. The +success value is passed to a closure to create this subsequent future. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnOnce(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Executes another future if this one resolves to an error. The +error value is passed to a closure to create this subsequent future. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnOnce(&Self::Ok), + Self: Sized,

Do something with the success value of a future before passing it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnOnce(&Self::Error), + Self: Sized,

Do something with the error value of a future before passing it on. Read more
§

fn try_flatten(self) -> TryFlatten<Self, Self::Ok>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is another future. Read more
§

fn try_flatten_stream(self) -> TryFlattenStream<Self>
where + Self::Ok: TryStream<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F>
where + Self: Sized, + F: FnOnce(Self::Error) -> Self::Ok,

Unwraps this future’s output, producing a future with this future’s +Ok type as its +Output type. Read more
§

fn into_future(self) -> IntoFuture<Self>
where + Self: Sized,

Wraps a [TryFuture] into a type that implements +Future. Read more
§

fn try_poll_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Result<Self::Ok, Self::Error>>
where + Self: Unpin,

A convenience method for calling [TryFuture::try_poll] on Unpin +future types.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/struct.WebService.html b/actix_web/dev/struct.WebService.html new file mode 100644 index 000000000..b85507000 --- /dev/null +++ b/actix_web/dev/struct.WebService.html @@ -0,0 +1,37 @@ +WebService in actix_web::dev - Rust

Struct actix_web::dev::WebService

source ·
pub struct WebService { /* private fields */ }

Implementations§

source§

impl WebService

source

pub fn new<T: IntoPatterns>(path: T) -> Self

Create new WebService instance.

+
source

pub fn name(self, name: &str) -> Self

Set service name.

+

Name is used for URL generation.

+
source

pub fn guard<G: Guard + 'static>(self, guard: G) -> Self

Add match guard to a web service.

+ +
use actix_web::{web, guard, dev, App, Error, HttpResponse};
+
+async fn index(req: dev::ServiceRequest) -> Result<dev::ServiceResponse, Error> {
+    Ok(req.into_response(HttpResponse::Ok().finish()))
+}
+
+let app = App::new()
+    .service(
+        web::service("/app")
+            .guard(guard::Header("content-type", "text/plain"))
+            .finish(index)
+    );
+
source

pub fn finish<T, F>(self, service: F) -> impl HttpServiceFactory
where + F: IntoServiceFactory<T, ServiceRequest>, + T: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error, InitError = ()> + 'static,

Set a service factory implementation and generate web service.

+

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/dev/trait.HttpServiceFactory.html b/actix_web/dev/trait.HttpServiceFactory.html new file mode 100644 index 000000000..4e0cc9504 --- /dev/null +++ b/actix_web/dev/trait.HttpServiceFactory.html @@ -0,0 +1,8 @@ +HttpServiceFactory in actix_web::dev - Rust

Trait actix_web::dev::HttpServiceFactory

source ·
pub trait HttpServiceFactory {
+    // Required method
+    fn register(self, config: &mut AppService);
+}

Required Methods§

source

fn register(self, config: &mut AppService)

Implementations on Foreign Types§

source§

impl<A: HttpServiceFactory> HttpServiceFactory for (A,)

source§

fn register(self, config: &mut AppService)

source§

impl<A: HttpServiceFactory, B: HttpServiceFactory> HttpServiceFactory for (A, B)

source§

fn register(self, config: &mut AppService)

source§

impl<A: HttpServiceFactory, B: HttpServiceFactory, C: HttpServiceFactory> HttpServiceFactory for (A, B, C)

source§

fn register(self, config: &mut AppService)

source§

impl<A: HttpServiceFactory, B: HttpServiceFactory, C: HttpServiceFactory, D: HttpServiceFactory> HttpServiceFactory for (A, B, C, D)

source§

fn register(self, config: &mut AppService)

source§

impl<A: HttpServiceFactory, B: HttpServiceFactory, C: HttpServiceFactory, D: HttpServiceFactory, E: HttpServiceFactory> HttpServiceFactory for (A, B, C, D, E)

source§

fn register(self, config: &mut AppService)

source§

impl<A: HttpServiceFactory, B: HttpServiceFactory, C: HttpServiceFactory, D: HttpServiceFactory, E: HttpServiceFactory, F: HttpServiceFactory> HttpServiceFactory for (A, B, C, D, E, F)

source§

fn register(self, config: &mut AppService)

source§

impl<A: HttpServiceFactory, B: HttpServiceFactory, C: HttpServiceFactory, D: HttpServiceFactory, E: HttpServiceFactory, F: HttpServiceFactory, G: HttpServiceFactory> HttpServiceFactory for (A, B, C, D, E, F, G)

source§

fn register(self, config: &mut AppService)

source§

impl<A: HttpServiceFactory, B: HttpServiceFactory, C: HttpServiceFactory, D: HttpServiceFactory, E: HttpServiceFactory, F: HttpServiceFactory, G: HttpServiceFactory, H: HttpServiceFactory> HttpServiceFactory for (A, B, C, D, E, F, G, H)

source§

fn register(self, config: &mut AppService)

source§

impl<A: HttpServiceFactory, B: HttpServiceFactory, C: HttpServiceFactory, D: HttpServiceFactory, E: HttpServiceFactory, F: HttpServiceFactory, G: HttpServiceFactory, H: HttpServiceFactory, I: HttpServiceFactory> HttpServiceFactory for (A, B, C, D, E, F, G, H, I)

source§

fn register(self, config: &mut AppService)

source§

impl<A: HttpServiceFactory, B: HttpServiceFactory, C: HttpServiceFactory, D: HttpServiceFactory, E: HttpServiceFactory, F: HttpServiceFactory, G: HttpServiceFactory, H: HttpServiceFactory, I: HttpServiceFactory, J: HttpServiceFactory> HttpServiceFactory for (A, B, C, D, E, F, G, H, I, J)

source§

fn register(self, config: &mut AppService)

source§

impl<A: HttpServiceFactory, B: HttpServiceFactory, C: HttpServiceFactory, D: HttpServiceFactory, E: HttpServiceFactory, F: HttpServiceFactory, G: HttpServiceFactory, H: HttpServiceFactory, I: HttpServiceFactory, J: HttpServiceFactory, K: HttpServiceFactory> HttpServiceFactory for (A, B, C, D, E, F, G, H, I, J, K)

source§

fn register(self, config: &mut AppService)

source§

impl<A: HttpServiceFactory, B: HttpServiceFactory, C: HttpServiceFactory, D: HttpServiceFactory, E: HttpServiceFactory, F: HttpServiceFactory, G: HttpServiceFactory, H: HttpServiceFactory, I: HttpServiceFactory, J: HttpServiceFactory, K: HttpServiceFactory, L: HttpServiceFactory> HttpServiceFactory for (A, B, C, D, E, F, G, H, I, J, K, L)

source§

fn register(self, config: &mut AppService)

source§

impl<T: HttpServiceFactory> HttpServiceFactory for Vec<T>

source§

fn register(self, config: &mut AppService)

Implementors§

source§

impl HttpServiceFactory for Redirect

source§

impl<T, B> HttpServiceFactory for Resource<T>
where + T: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B>, Error = Error, InitError = ()> + 'static, + B: MessageBody + 'static,

source§

impl<T, B> HttpServiceFactory for Scope<T>
where + T: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B>, Error = Error, InitError = ()> + 'static, + B: MessageBody + 'static,

\ No newline at end of file diff --git a/actix_web/dev/trait.ResourcePath.html b/actix_web/dev/trait.ResourcePath.html new file mode 100644 index 000000000..ca92191b2 --- /dev/null +++ b/actix_web/dev/trait.ResourcePath.html @@ -0,0 +1,4 @@ +ResourcePath in actix_web::dev - Rust

Trait actix_web::dev::ResourcePath

source ·
pub trait ResourcePath {
+    // Required method
+    fn path(&self) -> &str;
+}

Required Methods§

source

fn path(&self) -> &str

Implementations on Foreign Types§

source§

impl ResourcePath for String

source§

fn path(&self) -> &str

source§

impl ResourcePath for ByteString

source§

fn path(&self) -> &str

source§

impl<'a> ResourcePath for &'a str

source§

fn path(&self) -> &str

Implementors§

source§

impl ResourcePath for Uri

Available on crate feature http only.
source§

impl ResourcePath for Url

\ No newline at end of file diff --git a/actix_web/dev/trait.Service.html b/actix_web/dev/trait.Service.html new file mode 100644 index 000000000..6e91fc70a --- /dev/null +++ b/actix_web/dev/trait.Service.html @@ -0,0 +1,176 @@ +Service in actix_web::dev - Rust

Trait actix_web::dev::Service

pub trait Service<Req> {
+    type Response;
+    type Error;
+    type Future: Future<Output = Result<Self::Response, Self::Error>>;
+
+    // Required methods
+    fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>;
+    fn call(&self, req: Req) -> Self::Future;
+}
Expand description

An asynchronous operation from Request to a Response.

+

The Service trait models a request/response interaction, receiving requests and returning +replies. You can think about a service as a function with one argument that returns some result +asynchronously. Conceptually, the operation looks like this:

+ +
async fn(Request) -> Result<Response, Err>
+

The Service trait just generalizes this form. Requests are defined as a generic type parameter +and responses and other details are defined as associated types on the trait impl. Notice that +this design means that services can receive many request types and converge them to a single +response type.

+

Services can also have mutable state that influence computation by using a Cell, RefCell +or Mutex. Services intentionally do not take &mut self to reduce overhead in the +common cases.

+

Service provides a symmetric and uniform API; the same abstractions can be used to represent +both clients and servers. Services describe only transformation operations which encourage +simple API surfaces. This leads to simpler design of each service, improves test-ability and +makes composition easier.

+ +
struct MyService;
+
+impl Service<u8> for MyService {
+     type Response = u64;
+     type Error = MyError;
+     type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
+
+     fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { ... }
+
+     fn call(&self, req: u8) -> Self::Future { ... }
+}
+

Sometimes it is not necessary to implement the Service trait. For example, the above service +could be rewritten as a simple function and passed to fn_service.

+ +
async fn my_service(req: u8) -> Result<u64, MyError>;
+
+let svc = fn_service(my_service)
+svc.call(123)
+

Required Associated Types§

type Response

Responses given by the service.

+

type Error

Errors produced by the service when polling readiness or executing call.

+

type Future: Future<Output = Result<Self::Response, Self::Error>>

The future response value.

+

Required Methods§

fn poll_ready(&self, ctx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>

Returns Ready when the service is able to process requests.

+

If the service is at capacity, then Pending is returned and the task is notified when the +service becomes ready again. This function is expected to be called while on a task.

+

This is a best effort implementation. False positives are permitted. It is permitted for +the service to return Ready from a poll_ready call and the next invocation of call +results in an error.

+
§Notes
+
    +
  1. poll_ready might be called on a different task to call.
  2. +
  3. In cases of chained services, .poll_ready() is called for all services at once.
  4. +
+

fn call(&self, req: Req) -> Self::Future

Process the request and return the response asynchronously.

+

This function is expected to be callable off-task. As such, implementations of call should +take care to not call poll_ready. If the service is at capacity and the request is unable +to be handled, the returned Future should resolve to an error.

+

Invoking call without first invoking poll_ready is permitted. Implementations must be +resilient to this fact.

+

Implementations on Foreign Types§

source§

impl Service<Request> for ExpectHandler

§

impl<'a, S, Req> Service<Req> for &'a S
where + S: Service<Req> + 'a,

§

type Response = <S as Service<Req>>::Response

§

type Error = <S as Service<Req>>::Error

§

type Future = <S as Service<Req>>::Future

§

fn poll_ready( + &self, + ctx: &mut Context<'_> +) -> Poll<Result<(), <&'a S as Service<Req>>::Error>>

§

fn call(&self, request: Req) -> <S as Service<Req>>::Future

§

impl<'a, S, Req> Service<Req> for &'a mut S
where + S: Service<Req> + 'a,

§

type Response = <S as Service<Req>>::Response

§

type Error = <S as Service<Req>>::Error

§

type Future = <S as Service<Req>>::Future

§

fn poll_ready( + &self, + ctx: &mut Context<'_> +) -> Poll<Result<(), <&'a mut S as Service<Req>>::Error>>

§

fn call(&self, request: Req) -> <S as Service<Req>>::Future

§

impl<IO> Service<IO> for AcceptorService
where + IO: ActixStream,

§

type Response = TlsStream<IO>

§

type Error = TlsError<Error, Infallible>

§

type Future = AcceptFut<IO>

§

fn poll_ready( + &self, + ctx: &mut Context<'_> +) -> Poll<Result<(), <AcceptorService as Service<IO>>::Error>>

§

fn call(&self, io: IO) -> <AcceptorService as Service<IO>>::Future

§

impl<IO> Service<IO> for AcceptorService
where + IO: ActixStream,

§

type Response = TlsStream<IO>

§

type Error = TlsError<Error, Infallible>

§

type Future = AcceptFut<IO>

§

fn poll_ready( + &self, + cx: &mut Context<'_> +) -> Poll<Result<(), <AcceptorService as Service<IO>>::Error>>

§

fn call(&self, req: IO) -> <AcceptorService as Service<IO>>::Future

§

impl<IO> Service<IO> for AcceptorService
where + IO: ActixStream,

§

type Response = TlsStream<IO>

§

type Error = TlsError<Error, Infallible>

§

type Future = AcceptFut<IO>

§

fn poll_ready( + &self, + cx: &mut Context<'_> +) -> Poll<Result<(), <AcceptorService as Service<IO>>::Error>>

§

fn call(&self, req: IO) -> <AcceptorService as Service<IO>>::Future

§

impl<IO> Service<IO> for AcceptorService
where + IO: ActixStream,

§

type Response = TlsStream<IO>

§

type Error = TlsError<Error, Infallible>

§

type Future = AcceptFut<IO>

§

fn poll_ready( + &self, + cx: &mut Context<'_> +) -> Poll<Result<(), <AcceptorService as Service<IO>>::Error>>

§

fn call(&self, req: IO) -> <AcceptorService as Service<IO>>::Future

§

impl<IO> Service<IO> for AcceptorService
where + IO: ActixStream,

§

type Response = TlsStream<IO>

§

type Error = TlsError<Error, Infallible>

§

type Future = AcceptFut<IO>

§

fn poll_ready( + &self, + cx: &mut Context<'_> +) -> Poll<Result<(), <AcceptorService as Service<IO>>::Error>>

§

fn call(&self, req: IO) -> <AcceptorService as Service<IO>>::Future

§

impl<R> Service<ConnectInfo<R>> for ConnectorService
where + R: Host,

§

type Response = Connection<R, TcpStream>

§

type Error = ConnectError

§

type Future = ConnectServiceResponse<R>

§

fn poll_ready( + &self, + _: &mut Context<'_> +) -> Poll<Result<(), <ConnectorService as Service<ConnectInfo<R>>>::Error>>

§

fn call( + &self, + req: ConnectInfo<R> +) -> <ConnectorService as Service<ConnectInfo<R>>>::Future

§

impl<R> Service<ConnectInfo<R>> for ResolverService
where + R: Host,

§

type Response = ConnectInfo<R>

§

type Error = ConnectError

§

type Future = ResolverFut<R>

§

fn poll_ready( + &self, + _: &mut Context<'_> +) -> Poll<Result<(), <ResolverService as Service<ConnectInfo<R>>>::Error>>

§

fn call( + &self, + req: ConnectInfo<R> +) -> <ResolverService as Service<ConnectInfo<R>>>::Future

§

impl<R> Service<ConnectInfo<R>> for TcpConnectorService
where + R: Host,

§

type Response = Connection<R, TcpStream>

§

type Error = ConnectError

§

type Future = TcpConnectorFut<R>

§

fn poll_ready( + &self, + _: &mut Context<'_> +) -> Poll<Result<(), <TcpConnectorService as Service<ConnectInfo<R>>>::Error>>

§

fn call( + &self, + req: ConnectInfo<R> +) -> <TcpConnectorService as Service<ConnectInfo<R>>>::Future

§

impl<R, IO> Service<Connection<R, IO>> for TlsConnectorService
where + R: Host, + IO: ActixStream,

§

type Response = Connection<R, TlsStream<IO>>

§

type Error = Error

§

type Future = ConnectFut<R, IO>

§

fn poll_ready( + &self, + _: &mut Context<'_> +) -> Poll<Result<(), <TlsConnectorService as Service<Connection<R, IO>>>::Error>>

§

fn call( + &self, + connection: Connection<R, IO> +) -> <TlsConnectorService as Service<Connection<R, IO>>>::Future

§

impl<R, IO> Service<Connection<R, IO>> for TlsConnectorService
where + R: Host, + IO: ActixStream,

§

type Response = Connection<R, TlsStream<IO>>

§

type Error = Error

§

type Future = ConnectFut<R, IO>

§

fn poll_ready( + &self, + _: &mut Context<'_> +) -> Poll<Result<(), <TlsConnectorService as Service<Connection<R, IO>>>::Error>>

§

fn call( + &self, + connection: Connection<R, IO> +) -> <TlsConnectorService as Service<Connection<R, IO>>>::Future

§

impl<R, IO> Service<Connection<R, IO>> for TlsConnectorService
where + R: Host, + IO: ActixStream,

§

type Response = Connection<R, SslStream<IO>>

§

type Error = Error

§

type Future = ConnectFut<R, IO>

§

fn poll_ready( + &self, + _: &mut Context<'_> +) -> Poll<Result<(), <TlsConnectorService as Service<Connection<R, IO>>>::Error>>

§

fn call( + &self, + stream: Connection<R, IO> +) -> <TlsConnectorService as Service<Connection<R, IO>>>::Future

§

impl<R, IO> Service<Connection<R, IO>> for TlsConnectorService
where + R: Host, + IO: ActixStream,

§

type Response = Connection<R, TlsStream<IO>>

§

type Error = Error

§

type Future = ConnectFut<R, IO>

§

fn poll_ready( + &self, + _: &mut Context<'_> +) -> Poll<Result<(), <TlsConnectorService as Service<Connection<R, IO>>>::Error>>

§

fn call( + &self, + connection: Connection<R, IO> +) -> <TlsConnectorService as Service<Connection<R, IO>>>::Future

§

impl<R, IO> Service<Connection<R, IO>> for TlsConnectorService
where + R: Host, + IO: ActixStream,

§

type Response = Connection<R, TlsStream<IO>>

§

type Error = Error

§

type Future = ConnectFut<R, IO>

§

fn poll_ready( + &self, + _: &mut Context<'_> +) -> Poll<Result<(), <TlsConnectorService as Service<Connection<R, IO>>>::Error>>

§

fn call( + &self, + connection: Connection<R, IO> +) -> <TlsConnectorService as Service<Connection<R, IO>>>::Future

§

impl<S, Req> Service<Req> for Box<S>
where + S: Service<Req> + ?Sized,

§

type Response = <S as Service<Req>>::Response

§

type Error = <S as Service<Req>>::Error

§

type Future = <S as Service<Req>>::Future

§

fn poll_ready( + &self, + ctx: &mut Context<'_> +) -> Poll<Result<(), <S as Service<Req>>::Error>>

§

fn call(&self, request: Req) -> <S as Service<Req>>::Future

§

impl<S, Req> Service<Req> for Rc<S>
where + S: Service<Req> + ?Sized,

§

type Response = <S as Service<Req>>::Response

§

type Error = <S as Service<Req>>::Error

§

type Future = <S as Service<Req>>::Future

§

fn poll_ready( + &self, + ctx: &mut Context<'_> +) -> Poll<Result<(), <Rc<S> as Service<Req>>::Error>>

§

fn call(&self, request: Req) -> <S as Service<Req>>::Future

§

impl<S, Req> Service<Req> for RefCell<S>
where + S: Service<Req>,

This impl is deprecated since v2 because the Service trait now receives shared reference.

+
§

type Response = <S as Service<Req>>::Response

§

type Error = <S as Service<Req>>::Error

§

type Future = <S as Service<Req>>::Future

§

fn poll_ready( + &self, + ctx: &mut Context<'_> +) -> Poll<Result<(), <RefCell<S> as Service<Req>>::Error>>

§

fn call(&self, request: Req) -> <S as Service<Req>>::Future

source§

impl<T> Service<(Request, Framed<T, Codec>)> for UpgradeHandler

§

type Response = ()

§

type Error = Error

§

type Future = Pin<Box<dyn Future<Output = Result<<UpgradeHandler as Service<(Request, Framed<T, Codec>)>>::Response, <UpgradeHandler as Service<(Request, Framed<T, Codec>)>>::Error>>>>

source§

fn poll_ready( + &self, + _: &mut Context<'_> +) -> Poll<Result<(), <UpgradeHandler as Service<(Request, Framed<T, Codec>)>>::Error>>

source§

fn call( + &self, + _: (Request, Framed<T, Codec>) +) -> <UpgradeHandler as Service<(Request, Framed<T, Codec>)>>::Future

Implementors§

\ No newline at end of file diff --git a/actix_web/dev/trait.ServiceFactory.html b/actix_web/dev/trait.ServiceFactory.html new file mode 100644 index 000000000..8c5649840 --- /dev/null +++ b/actix_web/dev/trait.ServiceFactory.html @@ -0,0 +1,135 @@ +ServiceFactory in actix_web::dev - Rust

Trait actix_web::dev::ServiceFactory

pub trait ServiceFactory<Req> {
+    type Response;
+    type Error;
+    type Config;
+    type Service: Service<Req, Response = Self::Response, Error = Self::Error>;
+    type InitError;
+    type Future: Future<Output = Result<Self::Service, Self::InitError>>;
+
+    // Required method
+    fn new_service(&self, cfg: Self::Config) -> Self::Future;
+}
Expand description

Factory for creating Services.

+

This is useful for cases where new Services must be produced. One case is a TCP +server listener: a listener accepts new connections, constructs a new Service for each using +the ServiceFactory trait, and uses the new Service to process inbound requests on that new +connection.

+

Config is a service factory configuration type.

+

Simple factories may be able to use fn_factory or [fn_factory_with_config] to +reduce boilerplate.

+

Required Associated Types§

type Response

Responses given by the created services.

+

type Error

Errors produced by the created services.

+

type Config

Service factory configuration.

+

type Service: Service<Req, Response = Self::Response, Error = Self::Error>

The kind of Service created by this factory.

+

type InitError

Errors potentially raised while building a service.

+

type Future: Future<Output = Result<Self::Service, Self::InitError>>

The future of the Service instance.g

+

Required Methods§

fn new_service(&self, cfg: Self::Config) -> Self::Future

Create and return a new service asynchronously.

+

Implementations on Foreign Types§

source§

impl ServiceFactory<Request> for ExpectHandler

§

impl<IO> ServiceFactory<IO> for Acceptor
where + IO: ActixStream,

§

type Response = TlsStream<IO>

§

type Error = TlsError<Error, Infallible>

§

type Config = ()

§

type Service = AcceptorService

§

type InitError = ()

§

type Future = Ready<Result<<Acceptor as ServiceFactory<IO>>::Service, <Acceptor as ServiceFactory<IO>>::InitError>>

§

fn new_service(&self, _: ()) -> <Acceptor as ServiceFactory<IO>>::Future

§

impl<IO> ServiceFactory<IO> for Acceptor
where + IO: ActixStream,

§

type Response = TlsStream<IO>

§

type Error = TlsError<Error, Infallible>

§

type Config = ()

§

type Service = AcceptorService

§

type InitError = ()

§

type Future = Ready<Result<<Acceptor as ServiceFactory<IO>>::Service, <Acceptor as ServiceFactory<IO>>::InitError>>

§

fn new_service(&self, _: ()) -> <Acceptor as ServiceFactory<IO>>::Future

§

impl<IO> ServiceFactory<IO> for Acceptor
where + IO: ActixStream,

§

type Response = TlsStream<IO>

§

type Error = TlsError<Error, Infallible>

§

type Config = ()

§

type Service = AcceptorService

§

type InitError = ()

§

type Future = Ready<Result<<Acceptor as ServiceFactory<IO>>::Service, <Acceptor as ServiceFactory<IO>>::InitError>>

§

fn new_service(&self, _: ()) -> <Acceptor as ServiceFactory<IO>>::Future

§

impl<IO> ServiceFactory<IO> for Acceptor
where + IO: ActixStream,

§

type Response = TlsStream<IO>

§

type Error = TlsError<Error, Infallible>

§

type Config = ()

§

type Service = AcceptorService

§

type InitError = ()

§

type Future = Ready<Result<<Acceptor as ServiceFactory<IO>>::Service, <Acceptor as ServiceFactory<IO>>::InitError>>

§

fn new_service(&self, _: ()) -> <Acceptor as ServiceFactory<IO>>::Future

§

impl<IO> ServiceFactory<IO> for Acceptor
where + IO: ActixStream,

§

type Response = TlsStream<IO>

§

type Error = TlsError<Error, Infallible>

§

type Config = ()

§

type Service = AcceptorService

§

type InitError = ()

§

type Future = Ready<Result<<Acceptor as ServiceFactory<IO>>::Service, <Acceptor as ServiceFactory<IO>>::InitError>>

§

fn new_service(&self, _: ()) -> <Acceptor as ServiceFactory<IO>>::Future

§

impl<R> ServiceFactory<ConnectInfo<R>> for Connector
where + R: Host,

§

type Response = Connection<R, TcpStream>

§

type Error = ConnectError

§

type Config = ()

§

type Service = ConnectorService

§

type InitError = ()

§

type Future = Ready<Result<<Connector as ServiceFactory<ConnectInfo<R>>>::Service, <Connector as ServiceFactory<ConnectInfo<R>>>::InitError>>

§

fn new_service( + &self, + _: () +) -> <Connector as ServiceFactory<ConnectInfo<R>>>::Future

§

impl<R> ServiceFactory<ConnectInfo<R>> for Resolver
where + R: Host,

§

type Response = ConnectInfo<R>

§

type Error = ConnectError

§

type Config = ()

§

type Service = ResolverService

§

type InitError = ()

§

type Future = Ready<Result<<Resolver as ServiceFactory<ConnectInfo<R>>>::Service, <Resolver as ServiceFactory<ConnectInfo<R>>>::InitError>>

§

fn new_service( + &self, + _: () +) -> <Resolver as ServiceFactory<ConnectInfo<R>>>::Future

§

impl<R> ServiceFactory<ConnectInfo<R>> for TcpConnector
where + R: Host,

§

type Response = Connection<R, TcpStream>

§

type Error = ConnectError

§

type Config = ()

§

type Service = TcpConnectorService

§

type InitError = ()

§

type Future = Ready<Result<<TcpConnector as ServiceFactory<ConnectInfo<R>>>::Service, <TcpConnector as ServiceFactory<ConnectInfo<R>>>::InitError>>

§

fn new_service( + &self, + _: () +) -> <TcpConnector as ServiceFactory<ConnectInfo<R>>>::Future

§

impl<R, IO> ServiceFactory<Connection<R, IO>> for TlsConnector
where + R: Host, + IO: ActixStream + 'static,

§

type Response = Connection<R, TlsStream<IO>>

§

type Error = Error

§

type Config = ()

§

type Service = TlsConnectorService

§

type InitError = ()

§

type Future = Ready<Result<<TlsConnector as ServiceFactory<Connection<R, IO>>>::Service, <TlsConnector as ServiceFactory<Connection<R, IO>>>::InitError>>

§

fn new_service( + &self, + _: () +) -> <TlsConnector as ServiceFactory<Connection<R, IO>>>::Future

§

impl<R, IO> ServiceFactory<Connection<R, IO>> for TlsConnector
where + R: Host, + IO: ActixStream + 'static,

§

type Response = Connection<R, SslStream<IO>>

§

type Error = Error

§

type Config = ()

§

type Service = TlsConnectorService

§

type InitError = ()

§

type Future = Ready<Result<<TlsConnector as ServiceFactory<Connection<R, IO>>>::Service, <TlsConnector as ServiceFactory<Connection<R, IO>>>::InitError>>

§

fn new_service( + &self, + _: () +) -> <TlsConnector as ServiceFactory<Connection<R, IO>>>::Future

§

impl<R, IO> ServiceFactory<Connection<R, IO>> for TlsConnector
where + R: Host, + IO: ActixStream + 'static,

§

type Response = Connection<R, TlsStream<IO>>

§

type Error = Error

§

type Config = ()

§

type Service = TlsConnectorService

§

type InitError = ()

§

type Future = Ready<Result<<TlsConnector as ServiceFactory<Connection<R, IO>>>::Service, <TlsConnector as ServiceFactory<Connection<R, IO>>>::InitError>>

§

fn new_service( + &self, + _: () +) -> <TlsConnector as ServiceFactory<Connection<R, IO>>>::Future

§

impl<R, IO> ServiceFactory<Connection<R, IO>> for TlsConnector
where + R: Host, + IO: ActixStream + 'static,

§

type Response = Connection<R, TlsStream<IO>>

§

type Error = Error

§

type Config = ()

§

type Service = TlsConnectorService

§

type InitError = ()

§

type Future = Ready<Result<<TlsConnector as ServiceFactory<Connection<R, IO>>>::Service, <TlsConnector as ServiceFactory<Connection<R, IO>>>::InitError>>

§

fn new_service( + &self, + _: () +) -> <TlsConnector as ServiceFactory<Connection<R, IO>>>::Future

§

impl<R, IO> ServiceFactory<Connection<R, IO>> for TlsConnector
where + R: Host, + IO: ActixStream + 'static,

§

type Response = Connection<R, TlsStream<IO>>

§

type Error = Error

§

type Config = ()

§

type Service = TlsConnectorService

§

type InitError = ()

§

type Future = Ready<Result<<TlsConnector as ServiceFactory<Connection<R, IO>>>::Service, <TlsConnector as ServiceFactory<Connection<R, IO>>>::InitError>>

§

fn new_service( + &self, + _: () +) -> <TlsConnector as ServiceFactory<Connection<R, IO>>>::Future

§

impl<S, Req> ServiceFactory<Req> for Rc<S>
where + S: ServiceFactory<Req>,

§

type Response = <S as ServiceFactory<Req>>::Response

§

type Error = <S as ServiceFactory<Req>>::Error

§

type Config = <S as ServiceFactory<Req>>::Config

§

type Service = <S as ServiceFactory<Req>>::Service

§

type InitError = <S as ServiceFactory<Req>>::InitError

§

type Future = <S as ServiceFactory<Req>>::Future

§

fn new_service( + &self, + cfg: <S as ServiceFactory<Req>>::Config +) -> <S as ServiceFactory<Req>>::Future

§

impl<S, Req> ServiceFactory<Req> for Arc<S>
where + S: ServiceFactory<Req>,

§

type Response = <S as ServiceFactory<Req>>::Response

§

type Error = <S as ServiceFactory<Req>>::Error

§

type Config = <S as ServiceFactory<Req>>::Config

§

type Service = <S as ServiceFactory<Req>>::Service

§

type InitError = <S as ServiceFactory<Req>>::InitError

§

type Future = <S as ServiceFactory<Req>>::Future

§

fn new_service( + &self, + cfg: <S as ServiceFactory<Req>>::Config +) -> <S as ServiceFactory<Req>>::Future

source§

impl<T> ServiceFactory<(Request, Framed<T, Codec>)> for UpgradeHandler

source§

impl<T, S, B> ServiceFactory<(T, Option<SocketAddr>)> for H2Service<T, S, B>
where + T: AsyncRead + AsyncWrite + Unpin + 'static, + S: ServiceFactory<Request, Config = ()>, + <S as ServiceFactory<Request>>::Future: 'static, + <S as ServiceFactory<Request>>::Error: Into<Response<BoxBody>> + 'static, + <S as ServiceFactory<Request>>::Response: Into<Response<B>> + 'static, + <<S as ServiceFactory<Request>>::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static,

§

type Response = ()

§

type Error = DispatchError

§

type Config = ()

§

type Service = H2ServiceHandler<T, <S as ServiceFactory<Request>>::Service, B>

§

type InitError = <S as ServiceFactory<Request>>::InitError

§

type Future = Pin<Box<dyn Future<Output = Result<<H2Service<T, S, B> as ServiceFactory<(T, Option<SocketAddr>)>>::Service, <H2Service<T, S, B> as ServiceFactory<(T, Option<SocketAddr>)>>::InitError>>>>

source§

fn new_service( + &self, + _: () +) -> <H2Service<T, S, B> as ServiceFactory<(T, Option<SocketAddr>)>>::Future

source§

impl<T, S, B, X, U> ServiceFactory<(T, Protocol, Option<SocketAddr>)> for HttpService<T, S, B, X, U>
where + T: AsyncRead + AsyncWrite + Unpin + 'static, + S: ServiceFactory<Request, Config = ()>, + <S as ServiceFactory<Request>>::Future: 'static, + <S as ServiceFactory<Request>>::Error: Into<Response<BoxBody>> + 'static, + <S as ServiceFactory<Request>>::InitError: Debug, + <S as ServiceFactory<Request>>::Response: Into<Response<B>> + 'static, + <<S as ServiceFactory<Request>>::Service as Service<Request>>::Future: 'static, + B: MessageBody + 'static, + X: ServiceFactory<Request, Config = (), Response = Request>, + <X as ServiceFactory<Request>>::Future: 'static, + <X as ServiceFactory<Request>>::Error: Into<Response<BoxBody>>, + <X as ServiceFactory<Request>>::InitError: Debug, + U: ServiceFactory<(Request, Framed<T, Codec>), Config = (), Response = ()>, + <U as ServiceFactory<(Request, Framed<T, Codec>)>>::Future: 'static, + <U as ServiceFactory<(Request, Framed<T, Codec>)>>::Error: Display + Into<Response<BoxBody>>, + <U as ServiceFactory<(Request, Framed<T, Codec>)>>::InitError: Debug,

§

type Response = ()

§

type Error = DispatchError

§

type Config = ()

§

type Service = HttpServiceHandler<T, <S as ServiceFactory<Request>>::Service, B, <X as ServiceFactory<Request>>::Service, <U as ServiceFactory<(Request, Framed<T, Codec>)>>::Service>

§

type InitError = ()

§

type Future = Pin<Box<dyn Future<Output = Result<<HttpService<T, S, B, X, U> as ServiceFactory<(T, Protocol, Option<SocketAddr>)>>::Service, <HttpService<T, S, B, X, U> as ServiceFactory<(T, Protocol, Option<SocketAddr>)>>::InitError>>>>

source§

fn new_service( + &self, + _: () +) -> <HttpService<T, S, B, X, U> as ServiceFactory<(T, Protocol, Option<SocketAddr>)>>::Future

source§

impl<T, S, B, X, U> ServiceFactory<(T, Option<SocketAddr>)> for H1Service<T, S, B, X, U>
where + T: AsyncRead + AsyncWrite + Unpin + 'static, + S: ServiceFactory<Request, Config = ()>, + <S as ServiceFactory<Request>>::Future: 'static, + <S as ServiceFactory<Request>>::Error: Into<Response<BoxBody>>, + <S as ServiceFactory<Request>>::Response: Into<Response<B>>, + <S as ServiceFactory<Request>>::InitError: Debug, + B: MessageBody, + X: ServiceFactory<Request, Config = (), Response = Request>, + <X as ServiceFactory<Request>>::Future: 'static, + <X as ServiceFactory<Request>>::Error: Into<Response<BoxBody>>, + <X as ServiceFactory<Request>>::InitError: Debug, + U: ServiceFactory<(Request, Framed<T, Codec>), Config = (), Response = ()>, + <U as ServiceFactory<(Request, Framed<T, Codec>)>>::Future: 'static, + <U as ServiceFactory<(Request, Framed<T, Codec>)>>::Error: Display + Into<Response<BoxBody>>, + <U as ServiceFactory<(Request, Framed<T, Codec>)>>::InitError: Debug,

§

type Response = ()

§

type Error = DispatchError

§

type Config = ()

§

type Service = HttpServiceHandler<T, <S as ServiceFactory<Request>>::Service, B, <X as ServiceFactory<Request>>::Service, <U as ServiceFactory<(Request, Framed<T, Codec>)>>::Service>

§

type InitError = ()

§

type Future = Pin<Box<dyn Future<Output = Result<<H1Service<T, S, B, X, U> as ServiceFactory<(T, Option<SocketAddr>)>>::Service, <H1Service<T, S, B, X, U> as ServiceFactory<(T, Option<SocketAddr>)>>::InitError>>>>

source§

fn new_service( + &self, + _: () +) -> <H1Service<T, S, B, X, U> as ServiceFactory<(T, Option<SocketAddr>)>>::Future

Implementors§

source§

impl ServiceFactory<ServiceRequest> for Route

§

impl<C, Req, Res, Err, InitErr> ServiceFactory<Req> for BoxServiceFactory<C, Req, Res, Err, InitErr>
where + Req: 'static, + Res: 'static, + Err: 'static, + InitErr: 'static,

§

type Response = Res

§

type Error = Err

§

type Config = C

§

type Service = Box<dyn Service<Req, Future = Pin<Box<dyn Future<Output = Result<Res, Err>>>>, Response = Res, Error = Err>>

§

type InitError = InitErr

§

type Future = Pin<Box<dyn Future<Output = Result<<BoxServiceFactory<C, Req, Res, Err, InitErr> as ServiceFactory<Req>>::Service, InitErr>>>>

§

impl<T, S, Req> ServiceFactory<Req> for ApplyTransform<T, S, Req>
where + S: ServiceFactory<Req>, + T: Transform<<S as ServiceFactory<Req>>::Service, Req, InitError = <S as ServiceFactory<Req>>::InitError>,

§

type Response = <T as Transform<<S as ServiceFactory<Req>>::Service, Req>>::Response

§

type Error = <T as Transform<<S as ServiceFactory<Req>>::Service, Req>>::Error

§

type Config = <S as ServiceFactory<Req>>::Config

§

type Service = <T as Transform<<S as ServiceFactory<Req>>::Service, Req>>::Transform

§

type InitError = <T as Transform<<S as ServiceFactory<Req>>::Service, Req>>::InitError

§

type Future = ApplyTransformFuture<T, S, Req>

\ No newline at end of file diff --git a/actix_web/dev/trait.Transform.html b/actix_web/dev/trait.Transform.html new file mode 100644 index 000000000..e3c9148d0 --- /dev/null +++ b/actix_web/dev/trait.Transform.html @@ -0,0 +1,89 @@ +Transform in actix_web::dev - Rust

Trait actix_web::dev::Transform

pub trait Transform<S, Req> {
+    type Response;
+    type Error;
+    type Transform: Service<Req, Response = Self::Response, Error = Self::Error>;
+    type InitError;
+    type Future: Future<Output = Result<Self::Transform, Self::InitError>>;
+
+    // Required method
+    fn new_transform(&self, service: S) -> Self::Future;
+}
Expand description

Defines the interface of a service factory that wraps inner service during construction.

+

Transformers wrap an inner service and runs during inbound and/or outbound processing in the +service lifecycle. It may modify request and/or response.

+

For example, a timeout service wrapper:

+ +
pub struct Timeout<S> {
+    service: S,
+    timeout: Duration,
+}
+
+impl<S: Service<Req>, Req> Service<Req> for Timeout<S> {
+    type Response = S::Response;
+    type Error = TimeoutError<S::Error>;
+    type Future = TimeoutServiceResponse<S>;
+
+    actix_service::forward_ready!(service);
+
+    fn call(&self, req: Req) -> Self::Future {
+        TimeoutServiceResponse {
+            fut: self.service.call(req),
+            sleep: Sleep::new(clock::now() + self.timeout),
+        }
+    }
+}
+

This wrapper service is decoupled from the underlying service implementation and could be +applied to any service.

+

The Transform trait defines the interface of a service wrapper. Transform is often +implemented for middleware, defining how to construct a middleware Service. A Service that is +constructed by the factory takes the Service that follows it during execution as a parameter, +assuming ownership of the next Service.

+

A transform for the Timeout middleware could look like this:

+ +
pub struct TimeoutTransform {
+    timeout: Duration,
+}
+
+impl<S: Service<Req>, Req> Transform<S, Req> for TimeoutTransform {
+    type Response = S::Response;
+    type Error = TimeoutError<S::Error>;
+    type InitError = S::Error;
+    type Transform = Timeout<S>;
+    type Future = Ready<Result<Self::Transform, Self::InitError>>;
+
+    fn new_transform(&self, service: S) -> Self::Future {
+        ready(Ok(Timeout {
+            service,
+            timeout: self.timeout,
+        }))
+    }
+}
+

Required Associated Types§

type Response

Responses produced by the service.

+

type Error

Errors produced by the service.

+

type Transform: Service<Req, Response = Self::Response, Error = Self::Error>

The TransformService value created by this factory

+

type InitError

Errors produced while building a transform service.

+

type Future: Future<Output = Result<Self::Transform, Self::InitError>>

The future response value.

+

Required Methods§

fn new_transform(&self, service: S) -> Self::Future

Creates and returns a new Transform component, asynchronously

+

Implementations on Foreign Types§

§

impl<T, S, Req> Transform<S, Req> for Rc<T>
where + T: Transform<S, Req>,

§

type Response = <T as Transform<S, Req>>::Response

§

type Error = <T as Transform<S, Req>>::Error

§

type Transform = <T as Transform<S, Req>>::Transform

§

type InitError = <T as Transform<S, Req>>::InitError

§

type Future = <T as Transform<S, Req>>::Future

§

fn new_transform(&self, service: S) -> <T as Transform<S, Req>>::Future

§

impl<T, S, Req> Transform<S, Req> for Arc<T>
where + T: Transform<S, Req>,

§

type Response = <T as Transform<S, Req>>::Response

§

type Error = <T as Transform<S, Req>>::Error

§

type Transform = <T as Transform<S, Req>>::Transform

§

type InitError = <T as Transform<S, Req>>::InitError

§

type Future = <T as Transform<S, Req>>::Future

§

fn new_transform(&self, service: S) -> <T as Transform<S, Req>>::Future

Implementors§

source§

impl<S, B> Transform<S, ServiceRequest> for Compress
where + B: MessageBody, + S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,

Available on crate feature __compress only.
source§

impl<S, B> Transform<S, ServiceRequest> for DefaultHeaders
where + S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>, + S::Future: 'static,

source§

impl<S, B> Transform<S, ServiceRequest> for ErrorHandlers<B>
where + S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static, + S::Future: 'static, + B: 'static,

§

type Response = ServiceResponse<EitherBody<B>>

§

type Error = Error

§

type Transform = ErrorHandlersMiddleware<S, B>

§

type InitError = ()

§

type Future = Pin<Box<dyn Future<Output = Result<<ErrorHandlers<B> as Transform<S, ServiceRequest>>::Transform, <ErrorHandlers<B> as Transform<S, ServiceRequest>>::InitError>>>>

source§

impl<S, B> Transform<S, ServiceRequest> for Logger
where + S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>, + B: MessageBody,

§

type Response = ServiceResponse<StreamLog<B>>

§

type Error = Error

§

type Transform = LoggerMiddleware<S>

§

type InitError = ()

§

type Future = Ready<Result<<Logger as Transform<S, ServiceRequest>>::Transform, <Logger as Transform<S, ServiceRequest>>::InitError>>

source§

impl<S, B> Transform<S, ServiceRequest> for NormalizePath
where + S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>, + S::Future: 'static,

source§

impl<S, T, Req> Transform<S, Req> for Compat<T>
where + S: Service<Req>, + T: Transform<S, Req>, + T::Future: 'static, + T::Response: MapServiceResponseBody, + T::Error: Into<Error>,

§

type Response = ServiceResponse

§

type Error = Error

§

type Transform = CompatMiddleware<<T as Transform<S, Req>>::Transform>

§

type InitError = <T as Transform<S, Req>>::InitError

§

type Future = Pin<Box<dyn Future<Output = Result<<Compat<T> as Transform<S, Req>>::Transform, <Compat<T> as Transform<S, Req>>::InitError>>>>

source§

impl<S, T, Req, BE, BD, Err> Transform<S, Req> for Condition<T>
where + S: Service<Req, Response = ServiceResponse<BD>, Error = Err> + 'static, + T: Transform<S, Req, Response = ServiceResponse<BE>, Error = Err>, + T::Future: 'static, + T::InitError: 'static, + T::Transform: 'static,

§

type Response = ServiceResponse<EitherBody<BE, BD>>

§

type Error = Err

§

type Transform = ConditionMiddleware<<T as Transform<S, Req>>::Transform, S>

§

type InitError = <T as Transform<S, Req>>::InitError

§

type Future = Pin<Box<dyn Future<Output = Result<<Condition<T> as Transform<S, Req>>::Transform, <Condition<T> as Transform<S, Req>>::InitError>>>>

\ No newline at end of file diff --git a/actix_web/enum.Either.html b/actix_web/enum.Either.html new file mode 100644 index 000000000..e99986e7c --- /dev/null +++ b/actix_web/enum.Either.html @@ -0,0 +1,94 @@ +Either in actix_web - Rust

Enum actix_web::Either

source ·
pub enum Either<L, R> {
+    Left(L),
+    Right(R),
+}
Expand description

Combines two extractor or responder types into a single type.

+

§Extractor

+

Provides a mechanism for trying two extractors, a primary and a fallback. Useful for +“polymorphic payloads” where, for example, a form might be JSON or URL encoded.

+

It is important to note that this extractor, by necessity, buffers the entire request payload +as part of its implementation. Though, it does respect any PayloadConfig maximum size limits.

+ +
use actix_web::{post, web, Either};
+use serde::Deserialize;
+
+#[derive(Deserialize)]
+struct Info {
+    name: String,
+}
+
+// handler that accepts form as JSON or form-urlencoded.
+#[post("/")]
+async fn index(form: Either<web::Json<Info>, web::Form<Info>>) -> String {
+    let name: String = match form {
+        Either::Left(json) => json.name.to_owned(),
+        Either::Right(form) => form.name.to_owned(),
+    };
+
+    format!("Welcome {}!", name)
+}
+

§Responder

+

It may be desirable to use a concrete type for a response with multiple branches. As long as +both types implement Responder, so will the Either type, enabling it to be used as a +handler’s return type.

+

All properties of a response are determined by the Responder branch returned.

+ +
use actix_web::{get, Either, Error, HttpResponse};
+
+#[get("/")]
+async fn index() -> Either<&'static str, Result<HttpResponse, Error>> {
+    if 1 == 2 {
+        // respond with Left variant
+        Either::Left("Bad data")
+    } else {
+        // respond with Right variant
+        Either::Right(
+            Ok(HttpResponse::Ok()
+                .content_type(mime::TEXT_HTML)
+                .body("<p>Hello!</p>"))
+        )
+    }
+}
+

Variants§

§

Left(L)

A value of type L.

+
§

Right(R)

A value of type R.

+

Implementations§

source§

impl<T> Either<Form<T>, Json<T>>

source

pub fn into_inner(self) -> T

source§

impl<T> Either<Json<T>, Form<T>>

source

pub fn into_inner(self) -> T

Trait Implementations§

source§

impl<L: Debug, R: Debug> Debug for Either<L, R>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<L, R> FromRequest for Either<L, R>
where + L: FromRequest + 'static, + R: FromRequest + 'static,

See here for example of usage as an extractor.

+
§

type Error = EitherExtractError<<L as FromRequest>::Error, <R as FromRequest>::Error>

The associated error which can be returned.
§

type Future = EitherExtractFut<L, R>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more
source§

impl<L: PartialEq, R: PartialEq> PartialEq for Either<L, R>

source§

fn eq(&self, other: &Either<L, R>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<L, R> Responder for Either<L, R>
where + L: Responder, + R: Responder,

See here for example of usage as a handler return type.

+
§

type Body = EitherBody<<L as Responder>::Body, <R as Responder>::Body>

source§

fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body>

Convert self to HttpResponse.
source§

fn customize(self) -> CustomizeResponder<Self>
where + Self: Sized,

Wraps responder to allow alteration of its response. Read more
source§

impl<L: Eq, R: Eq> Eq for Either<L, R>

source§

impl<L, R> StructuralPartialEq for Either<L, R>

Auto Trait Implementations§

§

impl<L, R> Freeze for Either<L, R>
where + L: Freeze, + R: Freeze,

§

impl<L, R> RefUnwindSafe for Either<L, R>
where + L: RefUnwindSafe, + R: RefUnwindSafe,

§

impl<L, R> Send for Either<L, R>
where + L: Send, + R: Send,

§

impl<L, R> Sync for Either<L, R>
where + L: Sync, + R: Sync,

§

impl<L, R> Unpin for Either<L, R>
where + L: Unpin, + R: Unpin,

§

impl<L, R> UnwindSafe for Either<L, R>
where + L: UnwindSafe, + R: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/error/enum.ContentTypeError.html b/actix_web/error/enum.ContentTypeError.html new file mode 100644 index 000000000..45ca8455f --- /dev/null +++ b/actix_web/error/enum.ContentTypeError.html @@ -0,0 +1,27 @@ +ContentTypeError in actix_web::error - Rust

Enum actix_web::error::ContentTypeError

source ·
#[non_exhaustive]
pub enum ContentTypeError { + ParseError, + UnknownEncoding, +}
Expand description

A set of error that can occur during parsing content type.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

ParseError

Can not parse content type.

+
§

UnknownEncoding

Unknown content encoding.

+

Trait Implementations§

source§

impl Debug for ContentTypeError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for ContentTypeError

source§

fn fmt( + &self, + _derive_more_display_formatter: &mut Formatter<'_> +) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for ContentTypeError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<ContentTypeError> for ReadlinesError

source§

fn from(original: ContentTypeError) -> ReadlinesError

Converts to this type from the input type.
source§

impl ResponseError for ContentTypeError

source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
source§

fn error_response(&self) -> HttpResponse<BoxBody>

Creates full response for error. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/error/enum.DispatchError.html b/actix_web/error/enum.DispatchError.html new file mode 100644 index 000000000..bed8de059 --- /dev/null +++ b/actix_web/error/enum.DispatchError.html @@ -0,0 +1,43 @@ +DispatchError in actix_web::error - Rust

Enum actix_web::error::DispatchError

source ·
#[non_exhaustive]
pub enum DispatchError { + Service(Response<BoxBody>), + Body(Box<dyn Error>), + Upgrade, + Io(Error), + Parse(ParseError), + H2(Error), + SlowRequestTimeout, + DisconnectTimeout, + HandlerDroppedPayload, + InternalError, +}
Expand description

A set of errors that can occur during dispatching HTTP requests.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Service(Response<BoxBody>)

Service error.

+
§

Body(Box<dyn Error>)

Body streaming error.

+
§

Upgrade

Upgrade service error.

+
§

Io(Error)

An io::Error that occurred while trying to read or write to a network stream.

+
§

Parse(ParseError)

Request parse error.

+
§

H2(Error)

Available on crate feature http2 only.

HTTP/2 error.

+
§

SlowRequestTimeout

The first request did not complete within the specified timeout.

+
§

DisconnectTimeout

Disconnect timeout. Makes sense for TLS streams.

+
§

HandlerDroppedPayload

Handler dropped payload before reading EOF.

+
§

InternalError

Internal error.

+

Trait Implementations§

source§

impl Debug for DispatchError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for DispatchError

source§

fn fmt( + &self, + _derive_more_display_formatter: &mut Formatter<'_> +) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for DispatchError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<Box<dyn Error>> for DispatchError

source§

fn from(original: Box<dyn Error>) -> DispatchError

Converts to this type from the input type.
source§

impl From<Error> for DispatchError

source§

fn from(original: Error) -> DispatchError

Converts to this type from the input type.
source§

impl From<Error> for DispatchError

source§

fn from(original: Error) -> DispatchError

Converts to this type from the input type.
source§

impl From<ParseError> for DispatchError

source§

fn from(original: ParseError) -> DispatchError

Converts to this type from the input type.
source§

impl From<Response<BoxBody>> for DispatchError

source§

fn from(original: Response<BoxBody>) -> DispatchError

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/error/enum.JsonPayloadError.html b/actix_web/error/enum.JsonPayloadError.html new file mode 100644 index 000000000..29b1696cb --- /dev/null +++ b/actix_web/error/enum.JsonPayloadError.html @@ -0,0 +1,37 @@ +JsonPayloadError in actix_web::error - Rust

Enum actix_web::error::JsonPayloadError

source ·
#[non_exhaustive]
pub enum JsonPayloadError { + OverflowKnownLength { + length: usize, + limit: usize, + }, + Overflow { + limit: usize, + }, + ContentType, + Deserialize(Error), + Serialize(Error), + Payload(PayloadError), +}
Expand description

A set of errors that can occur during parsing json payloads

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

OverflowKnownLength

Payload size is bigger than allowed & content length header set. (default: 2MB)

+

Fields

§length: usize
§limit: usize
§

Overflow

Payload size is bigger than allowed but no content length header set. (default: 2MB)

+

Fields

§limit: usize
§

ContentType

Content type error

+
§

Deserialize(Error)

Deserialize error

+
§

Serialize(Error)

Serialize error

+
§

Payload(PayloadError)

Payload error

+

Trait Implementations§

source§

impl Debug for JsonPayloadError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for JsonPayloadError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for JsonPayloadError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<PayloadError> for JsonPayloadError

source§

fn from(err: PayloadError) -> Self

Converts to this type from the input type.
source§

impl ResponseError for JsonPayloadError

source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
source§

fn error_response(&self) -> HttpResponse<BoxBody>

Creates full response for error. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/error/enum.ParseError.html b/actix_web/error/enum.ParseError.html new file mode 100644 index 000000000..91c0ed479 --- /dev/null +++ b/actix_web/error/enum.ParseError.html @@ -0,0 +1,43 @@ +ParseError in actix_web::error - Rust

Enum actix_web::error::ParseError

source ·
#[non_exhaustive]
pub enum ParseError { + Method, + Uri(InvalidUri), + Version, + Header, + TooLarge, + Incomplete, + Status, + Timeout, + Io(Error), + Utf8(Utf8Error), +}
Expand description

A set of errors that can occur during parsing HTTP streams.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Method

An invalid Method, such as GE.T.

+
§

Uri(InvalidUri)

An invalid Uri, such as exam ple.domain.

+
§

Version

An invalid HttpVersion, such as HTP/1.1

+
§

Header

An invalid Header.

+
§

TooLarge

A message head is too large to be reasonable.

+
§

Incomplete

A message reached EOF, but is not complete.

+
§

Status

An invalid Status, such as 1337 ELITE.

+
§

Timeout

A timeout occurred waiting for an IO event.

+
§

Io(Error)

An I/O error that occurred while trying to read or write to a network stream.

+
§

Utf8(Utf8Error)

Parsing a field as string failed.

+

Trait Implementations§

source§

impl Debug for ParseError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for ParseError

source§

fn fmt( + &self, + _derive_more_display_formatter: &mut Formatter<'_> +) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for ParseError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<Error> for ParseError

source§

fn from(err: Error) -> ParseError

Converts to this type from the input type.
source§

impl From<Error> for ParseError

source§

fn from(err: Error) -> ParseError

Converts to this type from the input type.
source§

impl From<FromUtf8Error> for ParseError

source§

fn from(err: FromUtf8Error) -> ParseError

Converts to this type from the input type.
source§

impl From<InvalidUri> for ParseError

source§

fn from(err: InvalidUri) -> ParseError

Converts to this type from the input type.
source§

impl From<ParseError> for DispatchError

source§

fn from(original: ParseError) -> DispatchError

Converts to this type from the input type.
source§

impl From<ParseError> for Error

source§

fn from(err: ParseError) -> Error

Converts to this type from the input type.
source§

impl From<ParseError> for Response<BoxBody>

source§

fn from(err: ParseError) -> Response<BoxBody>

Converts to this type from the input type.
source§

impl From<Utf8Error> for ParseError

source§

fn from(err: Utf8Error) -> ParseError

Converts to this type from the input type.
source§

impl ResponseError for ParseError

source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
source§

fn error_response(&self) -> HttpResponse<BoxBody>

Creates full response for error. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/error/enum.PathError.html b/actix_web/error/enum.PathError.html new file mode 100644 index 000000000..bcf1f9722 --- /dev/null +++ b/actix_web/error/enum.PathError.html @@ -0,0 +1,23 @@ +PathError in actix_web::error - Rust

Enum actix_web::error::PathError

source ·
#[non_exhaustive]
pub enum PathError { + Deserialize(Error), +}
Expand description

A set of errors that can occur during parsing request paths

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Deserialize(Error)

Deserialize error

+

Trait Implementations§

source§

impl Debug for PathError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for PathError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for PathError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl ResponseError for PathError

Return BadRequest for PathError

+
source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
source§

fn error_response(&self) -> HttpResponse<BoxBody>

Creates full response for error. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/error/enum.PayloadError.html b/actix_web/error/enum.PayloadError.html new file mode 100644 index 000000000..40d705a9a --- /dev/null +++ b/actix_web/error/enum.PayloadError.html @@ -0,0 +1,35 @@ +PayloadError in actix_web::error - Rust

Enum actix_web::error::PayloadError

source ·
#[non_exhaustive]
pub enum PayloadError { + Incomplete(Option<Error>), + EncodingCorrupted, + Overflow, + UnknownLength, + Http2Payload(Error), + Io(Error), +}
Expand description

A set of errors that can occur during payload parsing.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Incomplete(Option<Error>)

A payload reached EOF, but is not complete.

+
§

EncodingCorrupted

Content encoding stream corruption.

+
§

Overflow

Payload reached size limit.

+
§

UnknownLength

Payload length is unknown.

+
§

Http2Payload(Error)

Available on crate feature http2 only.

HTTP/2 payload error.

+
§

Io(Error)

Generic I/O error.

+

Trait Implementations§

source§

impl Debug for PayloadError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for PayloadError

source§

fn fmt( + &self, + _derive_more_display_formatter: &mut Formatter<'_> +) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for PayloadError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<Error> for PayloadError

source§

fn from(err: Error) -> PayloadError

Converts to this type from the input type.
source§

impl From<Error> for PayloadError

Available on crate feature http2 only.
source§

fn from(err: Error) -> PayloadError

Converts to this type from the input type.
source§

impl From<Option<Error>> for PayloadError

source§

fn from(err: Option<Error>) -> PayloadError

Converts to this type from the input type.
source§

impl From<PayloadError> for Error

source§

fn from(err: PayloadError) -> Error

Converts to this type from the input type.
source§

impl From<PayloadError> for JsonPayloadError

source§

fn from(err: PayloadError) -> Self

Converts to this type from the input type.
source§

impl From<PayloadError> for ReadlinesError

source§

fn from(original: PayloadError) -> ReadlinesError

Converts to this type from the input type.
source§

impl From<PayloadError> for UrlencodedError

source§

fn from(original: PayloadError) -> UrlencodedError

Converts to this type from the input type.
source§

impl ResponseError for PayloadError

source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
source§

fn error_response(&self) -> HttpResponse<BoxBody>

Creates full response for error. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/error/enum.QueryPayloadError.html b/actix_web/error/enum.QueryPayloadError.html new file mode 100644 index 000000000..b96d09c5c --- /dev/null +++ b/actix_web/error/enum.QueryPayloadError.html @@ -0,0 +1,22 @@ +QueryPayloadError in actix_web::error - Rust

Enum actix_web::error::QueryPayloadError

source ·
#[non_exhaustive]
pub enum QueryPayloadError { + Deserialize(Error), +}
Expand description

A set of errors that can occur during parsing query strings.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Deserialize(Error)

Query deserialize error.

+

Trait Implementations§

source§

impl Debug for QueryPayloadError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for QueryPayloadError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for QueryPayloadError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<Error> for QueryPayloadError

source§

fn from(original: Error) -> QueryPayloadError

Converts to this type from the input type.
source§

impl ResponseError for QueryPayloadError

source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
source§

fn error_response(&self) -> HttpResponse<BoxBody>

Creates full response for error. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/error/enum.ReadlinesError.html b/actix_web/error/enum.ReadlinesError.html new file mode 100644 index 000000000..592a35696 --- /dev/null +++ b/actix_web/error/enum.ReadlinesError.html @@ -0,0 +1,28 @@ +ReadlinesError in actix_web::error - Rust

Enum actix_web::error::ReadlinesError

source ·
#[non_exhaustive]
pub enum ReadlinesError { + EncodingError, + Payload(PayloadError), + LimitOverflow, + ContentTypeError(ContentTypeError), +}
Expand description

Error type returned when reading body as lines.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

EncodingError

Payload size is bigger than allowed. (default: 256kB)

+
§

Payload(PayloadError)

Payload error.

+
§

LimitOverflow

Line limit exceeded.

+
§

ContentTypeError(ContentTypeError)

ContentType error.

+

Trait Implementations§

source§

impl Debug for ReadlinesError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for ReadlinesError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for ReadlinesError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<ContentTypeError> for ReadlinesError

source§

fn from(original: ContentTypeError) -> ReadlinesError

Converts to this type from the input type.
source§

impl From<PayloadError> for ReadlinesError

source§

fn from(original: PayloadError) -> ReadlinesError

Converts to this type from the input type.
source§

impl ResponseError for ReadlinesError

source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
source§

fn error_response(&self) -> HttpResponse<BoxBody>

Creates full response for error. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/error/enum.UrlGenerationError.html b/actix_web/error/enum.UrlGenerationError.html new file mode 100644 index 000000000..d71e88d05 --- /dev/null +++ b/actix_web/error/enum.UrlGenerationError.html @@ -0,0 +1,32 @@ +UrlGenerationError in actix_web::error - Rust

Enum actix_web::error::UrlGenerationError

source ·
#[non_exhaustive]
pub enum UrlGenerationError { + ResourceNotFound, + NotEnoughElements, + ParseError(ParseError), +}
Expand description

Errors which can occur when attempting to generate resource uri.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

ResourceNotFound

Resource not found.

+
§

NotEnoughElements

Not all URL parameters covered.

+
§

ParseError(ParseError)

URL parse error.

+

Trait Implementations§

source§

impl Debug for UrlGenerationError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for UrlGenerationError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for UrlGenerationError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<ParseError> for UrlGenerationError

source§

fn from(original: UrlParseError) -> UrlGenerationError

Converts to this type from the input type.
source§

impl PartialEq for UrlGenerationError

source§

fn eq(&self, other: &UrlGenerationError) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl ResponseError for UrlGenerationError

source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
source§

fn error_response(&self) -> HttpResponse<BoxBody>

Creates full response for error. Read more
source§

impl Eq for UrlGenerationError

source§

impl StructuralPartialEq for UrlGenerationError

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/error/enum.UrlencodedError.html b/actix_web/error/enum.UrlencodedError.html new file mode 100644 index 000000000..48253ed47 --- /dev/null +++ b/actix_web/error/enum.UrlencodedError.html @@ -0,0 +1,39 @@ +UrlencodedError in actix_web::error - Rust

Enum actix_web::error::UrlencodedError

source ·
#[non_exhaustive]
pub enum UrlencodedError { + Chunked, + Overflow { + size: usize, + limit: usize, + }, + UnknownLength, + ContentType, + Parse(Error), + Encoding, + Serialize(Error), + Payload(PayloadError), +}
Expand description

A set of errors that can occur during parsing urlencoded payloads

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Chunked

Can not decode chunked transfer encoding.

+
§

Overflow

Payload size is larger than allowed. (default limit: 256kB).

+

Fields

§size: usize
§limit: usize
§

UnknownLength

Payload size is now known.

+
§

ContentType

Content type error.

+
§

Parse(Error)

Parse error.

+
§

Encoding

Encoding error.

+
§

Serialize(Error)

Serialize error.

+
§

Payload(PayloadError)

Payload error.

+

Trait Implementations§

source§

impl Debug for UrlencodedError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for UrlencodedError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for UrlencodedError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<(usize, usize)> for UrlencodedError

source§

fn from(original: (usize, usize)) -> UrlencodedError

Converts to this type from the input type.
source§

impl From<Error> for UrlencodedError

source§

fn from(original: FormDeError) -> UrlencodedError

Converts to this type from the input type.
source§

impl From<Error> for UrlencodedError

source§

fn from(original: FormError) -> UrlencodedError

Converts to this type from the input type.
source§

impl From<PayloadError> for UrlencodedError

source§

fn from(original: PayloadError) -> UrlencodedError

Converts to this type from the input type.
source§

impl ResponseError for UrlencodedError

source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
source§

fn error_response(&self) -> HttpResponse<BoxBody>

Creates full response for error. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/error/error/struct.Error.html b/actix_web/error/error/struct.Error.html new file mode 100644 index 000000000..0a88e4842 --- /dev/null +++ b/actix_web/error/error/struct.Error.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/struct.Error.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/fn.ErrorBadGateway.html b/actix_web/error/fn.ErrorBadGateway.html new file mode 100644 index 000000000..5533fe735 --- /dev/null +++ b/actix_web/error/fn.ErrorBadGateway.html @@ -0,0 +1,3 @@ +ErrorBadGateway in actix_web::error - Rust

Function actix_web::error::ErrorBadGateway

source ·
pub fn ErrorBadGateway<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a BAD_GATEWAY response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorBadRequest.html b/actix_web/error/fn.ErrorBadRequest.html new file mode 100644 index 000000000..b380b45a3 --- /dev/null +++ b/actix_web/error/fn.ErrorBadRequest.html @@ -0,0 +1,3 @@ +ErrorBadRequest in actix_web::error - Rust

Function actix_web::error::ErrorBadRequest

source ·
pub fn ErrorBadRequest<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a BAD_REQUEST response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorConflict.html b/actix_web/error/fn.ErrorConflict.html new file mode 100644 index 000000000..a88408f2e --- /dev/null +++ b/actix_web/error/fn.ErrorConflict.html @@ -0,0 +1,3 @@ +ErrorConflict in actix_web::error - Rust

Function actix_web::error::ErrorConflict

source ·
pub fn ErrorConflict<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a CONFLICT response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorExpectationFailed.html b/actix_web/error/fn.ErrorExpectationFailed.html new file mode 100644 index 000000000..92aae2f18 --- /dev/null +++ b/actix_web/error/fn.ErrorExpectationFailed.html @@ -0,0 +1,3 @@ +ErrorExpectationFailed in actix_web::error - Rust

Function actix_web::error::ErrorExpectationFailed

source ·
pub fn ErrorExpectationFailed<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a EXPECTATION_FAILED response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorFailedDependency.html b/actix_web/error/fn.ErrorFailedDependency.html new file mode 100644 index 000000000..5b36fd834 --- /dev/null +++ b/actix_web/error/fn.ErrorFailedDependency.html @@ -0,0 +1,3 @@ +ErrorFailedDependency in actix_web::error - Rust

Function actix_web::error::ErrorFailedDependency

source ·
pub fn ErrorFailedDependency<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a FAILED_DEPENDENCY response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorForbidden.html b/actix_web/error/fn.ErrorForbidden.html new file mode 100644 index 000000000..0361c4157 --- /dev/null +++ b/actix_web/error/fn.ErrorForbidden.html @@ -0,0 +1,3 @@ +ErrorForbidden in actix_web::error - Rust

Function actix_web::error::ErrorForbidden

source ·
pub fn ErrorForbidden<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a FORBIDDEN response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorGatewayTimeout.html b/actix_web/error/fn.ErrorGatewayTimeout.html new file mode 100644 index 000000000..401ca715d --- /dev/null +++ b/actix_web/error/fn.ErrorGatewayTimeout.html @@ -0,0 +1,3 @@ +ErrorGatewayTimeout in actix_web::error - Rust

Function actix_web::error::ErrorGatewayTimeout

source ·
pub fn ErrorGatewayTimeout<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a GATEWAY_TIMEOUT response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorGone.html b/actix_web/error/fn.ErrorGone.html new file mode 100644 index 000000000..91f95450c --- /dev/null +++ b/actix_web/error/fn.ErrorGone.html @@ -0,0 +1,3 @@ +ErrorGone in actix_web::error - Rust

Function actix_web::error::ErrorGone

source ·
pub fn ErrorGone<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a GONE response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorHttpVersionNotSupported.html b/actix_web/error/fn.ErrorHttpVersionNotSupported.html new file mode 100644 index 000000000..48bc208ce --- /dev/null +++ b/actix_web/error/fn.ErrorHttpVersionNotSupported.html @@ -0,0 +1,3 @@ +ErrorHttpVersionNotSupported in actix_web::error - Rust

Function actix_web::error::ErrorHttpVersionNotSupported

source ·
pub fn ErrorHttpVersionNotSupported<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a HTTP_VERSION_NOT_SUPPORTED response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorImATeapot.html b/actix_web/error/fn.ErrorImATeapot.html new file mode 100644 index 000000000..a407b568e --- /dev/null +++ b/actix_web/error/fn.ErrorImATeapot.html @@ -0,0 +1,3 @@ +ErrorImATeapot in actix_web::error - Rust

Function actix_web::error::ErrorImATeapot

source ·
pub fn ErrorImATeapot<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a IM_A_TEAPOT response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorInsufficientStorage.html b/actix_web/error/fn.ErrorInsufficientStorage.html new file mode 100644 index 000000000..b24b1fbe0 --- /dev/null +++ b/actix_web/error/fn.ErrorInsufficientStorage.html @@ -0,0 +1,3 @@ +ErrorInsufficientStorage in actix_web::error - Rust

Function actix_web::error::ErrorInsufficientStorage

source ·
pub fn ErrorInsufficientStorage<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a INSUFFICIENT_STORAGE response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorInternalServerError.html b/actix_web/error/fn.ErrorInternalServerError.html new file mode 100644 index 000000000..6d53c844b --- /dev/null +++ b/actix_web/error/fn.ErrorInternalServerError.html @@ -0,0 +1,3 @@ +ErrorInternalServerError in actix_web::error - Rust

Function actix_web::error::ErrorInternalServerError

source ·
pub fn ErrorInternalServerError<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a INTERNAL_SERVER_ERROR response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorLengthRequired.html b/actix_web/error/fn.ErrorLengthRequired.html new file mode 100644 index 000000000..292c198ed --- /dev/null +++ b/actix_web/error/fn.ErrorLengthRequired.html @@ -0,0 +1,3 @@ +ErrorLengthRequired in actix_web::error - Rust

Function actix_web::error::ErrorLengthRequired

source ·
pub fn ErrorLengthRequired<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a LENGTH_REQUIRED response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorLocked.html b/actix_web/error/fn.ErrorLocked.html new file mode 100644 index 000000000..855a5a8cd --- /dev/null +++ b/actix_web/error/fn.ErrorLocked.html @@ -0,0 +1,3 @@ +ErrorLocked in actix_web::error - Rust

Function actix_web::error::ErrorLocked

source ·
pub fn ErrorLocked<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a LOCKED response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorLoopDetected.html b/actix_web/error/fn.ErrorLoopDetected.html new file mode 100644 index 000000000..e0c36e6bc --- /dev/null +++ b/actix_web/error/fn.ErrorLoopDetected.html @@ -0,0 +1,3 @@ +ErrorLoopDetected in actix_web::error - Rust

Function actix_web::error::ErrorLoopDetected

source ·
pub fn ErrorLoopDetected<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a LOOP_DETECTED response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorMethodNotAllowed.html b/actix_web/error/fn.ErrorMethodNotAllowed.html new file mode 100644 index 000000000..1903ea973 --- /dev/null +++ b/actix_web/error/fn.ErrorMethodNotAllowed.html @@ -0,0 +1,3 @@ +ErrorMethodNotAllowed in actix_web::error - Rust

Function actix_web::error::ErrorMethodNotAllowed

source ·
pub fn ErrorMethodNotAllowed<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a METHOD_NOT_ALLOWED response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorMisdirectedRequest.html b/actix_web/error/fn.ErrorMisdirectedRequest.html new file mode 100644 index 000000000..3dc3f2a33 --- /dev/null +++ b/actix_web/error/fn.ErrorMisdirectedRequest.html @@ -0,0 +1,3 @@ +ErrorMisdirectedRequest in actix_web::error - Rust

Function actix_web::error::ErrorMisdirectedRequest

source ·
pub fn ErrorMisdirectedRequest<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a MISDIRECTED_REQUEST response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorNetworkAuthenticationRequired.html b/actix_web/error/fn.ErrorNetworkAuthenticationRequired.html new file mode 100644 index 000000000..f6eed475b --- /dev/null +++ b/actix_web/error/fn.ErrorNetworkAuthenticationRequired.html @@ -0,0 +1,3 @@ +ErrorNetworkAuthenticationRequired in actix_web::error - Rust

Function actix_web::error::ErrorNetworkAuthenticationRequired

source ·
pub fn ErrorNetworkAuthenticationRequired<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a NETWORK_AUTHENTICATION_REQUIRED response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorNotAcceptable.html b/actix_web/error/fn.ErrorNotAcceptable.html new file mode 100644 index 000000000..442b2db25 --- /dev/null +++ b/actix_web/error/fn.ErrorNotAcceptable.html @@ -0,0 +1,3 @@ +ErrorNotAcceptable in actix_web::error - Rust

Function actix_web::error::ErrorNotAcceptable

source ·
pub fn ErrorNotAcceptable<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a NOT_ACCEPTABLE response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorNotExtended.html b/actix_web/error/fn.ErrorNotExtended.html new file mode 100644 index 000000000..fc39140a0 --- /dev/null +++ b/actix_web/error/fn.ErrorNotExtended.html @@ -0,0 +1,3 @@ +ErrorNotExtended in actix_web::error - Rust

Function actix_web::error::ErrorNotExtended

source ·
pub fn ErrorNotExtended<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a NOT_EXTENDED response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorNotFound.html b/actix_web/error/fn.ErrorNotFound.html new file mode 100644 index 000000000..cac7892ad --- /dev/null +++ b/actix_web/error/fn.ErrorNotFound.html @@ -0,0 +1,3 @@ +ErrorNotFound in actix_web::error - Rust

Function actix_web::error::ErrorNotFound

source ·
pub fn ErrorNotFound<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a NOT_FOUND response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorNotImplemented.html b/actix_web/error/fn.ErrorNotImplemented.html new file mode 100644 index 000000000..15cf93074 --- /dev/null +++ b/actix_web/error/fn.ErrorNotImplemented.html @@ -0,0 +1,3 @@ +ErrorNotImplemented in actix_web::error - Rust

Function actix_web::error::ErrorNotImplemented

source ·
pub fn ErrorNotImplemented<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a NOT_IMPLEMENTED response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorPayloadTooLarge.html b/actix_web/error/fn.ErrorPayloadTooLarge.html new file mode 100644 index 000000000..cb65fac70 --- /dev/null +++ b/actix_web/error/fn.ErrorPayloadTooLarge.html @@ -0,0 +1,3 @@ +ErrorPayloadTooLarge in actix_web::error - Rust

Function actix_web::error::ErrorPayloadTooLarge

source ·
pub fn ErrorPayloadTooLarge<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a PAYLOAD_TOO_LARGE response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorPaymentRequired.html b/actix_web/error/fn.ErrorPaymentRequired.html new file mode 100644 index 000000000..785dba635 --- /dev/null +++ b/actix_web/error/fn.ErrorPaymentRequired.html @@ -0,0 +1,3 @@ +ErrorPaymentRequired in actix_web::error - Rust

Function actix_web::error::ErrorPaymentRequired

source ·
pub fn ErrorPaymentRequired<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a PAYMENT_REQUIRED response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorPreconditionFailed.html b/actix_web/error/fn.ErrorPreconditionFailed.html new file mode 100644 index 000000000..fac28f284 --- /dev/null +++ b/actix_web/error/fn.ErrorPreconditionFailed.html @@ -0,0 +1,3 @@ +ErrorPreconditionFailed in actix_web::error - Rust

Function actix_web::error::ErrorPreconditionFailed

source ·
pub fn ErrorPreconditionFailed<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a PRECONDITION_FAILED response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorPreconditionRequired.html b/actix_web/error/fn.ErrorPreconditionRequired.html new file mode 100644 index 000000000..0d6a668f3 --- /dev/null +++ b/actix_web/error/fn.ErrorPreconditionRequired.html @@ -0,0 +1,3 @@ +ErrorPreconditionRequired in actix_web::error - Rust

Function actix_web::error::ErrorPreconditionRequired

source ·
pub fn ErrorPreconditionRequired<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a PRECONDITION_REQUIRED response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorProxyAuthenticationRequired.html b/actix_web/error/fn.ErrorProxyAuthenticationRequired.html new file mode 100644 index 000000000..5791dc7aa --- /dev/null +++ b/actix_web/error/fn.ErrorProxyAuthenticationRequired.html @@ -0,0 +1,3 @@ +ErrorProxyAuthenticationRequired in actix_web::error - Rust

Function actix_web::error::ErrorProxyAuthenticationRequired

source ·
pub fn ErrorProxyAuthenticationRequired<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a PROXY_AUTHENTICATION_REQUIRED response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorRangeNotSatisfiable.html b/actix_web/error/fn.ErrorRangeNotSatisfiable.html new file mode 100644 index 000000000..393cef6e1 --- /dev/null +++ b/actix_web/error/fn.ErrorRangeNotSatisfiable.html @@ -0,0 +1,3 @@ +ErrorRangeNotSatisfiable in actix_web::error - Rust

Function actix_web::error::ErrorRangeNotSatisfiable

source ·
pub fn ErrorRangeNotSatisfiable<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a RANGE_NOT_SATISFIABLE response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorRequestHeaderFieldsTooLarge.html b/actix_web/error/fn.ErrorRequestHeaderFieldsTooLarge.html new file mode 100644 index 000000000..fc0cbe43d --- /dev/null +++ b/actix_web/error/fn.ErrorRequestHeaderFieldsTooLarge.html @@ -0,0 +1,3 @@ +ErrorRequestHeaderFieldsTooLarge in actix_web::error - Rust

Function actix_web::error::ErrorRequestHeaderFieldsTooLarge

source ·
pub fn ErrorRequestHeaderFieldsTooLarge<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a REQUEST_HEADER_FIELDS_TOO_LARGE response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorRequestTimeout.html b/actix_web/error/fn.ErrorRequestTimeout.html new file mode 100644 index 000000000..6b504d059 --- /dev/null +++ b/actix_web/error/fn.ErrorRequestTimeout.html @@ -0,0 +1,3 @@ +ErrorRequestTimeout in actix_web::error - Rust

Function actix_web::error::ErrorRequestTimeout

source ·
pub fn ErrorRequestTimeout<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a REQUEST_TIMEOUT response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorServiceUnavailable.html b/actix_web/error/fn.ErrorServiceUnavailable.html new file mode 100644 index 000000000..1f27791c2 --- /dev/null +++ b/actix_web/error/fn.ErrorServiceUnavailable.html @@ -0,0 +1,3 @@ +ErrorServiceUnavailable in actix_web::error - Rust

Function actix_web::error::ErrorServiceUnavailable

source ·
pub fn ErrorServiceUnavailable<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a SERVICE_UNAVAILABLE response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorTooManyRequests.html b/actix_web/error/fn.ErrorTooManyRequests.html new file mode 100644 index 000000000..9dd3650b2 --- /dev/null +++ b/actix_web/error/fn.ErrorTooManyRequests.html @@ -0,0 +1,3 @@ +ErrorTooManyRequests in actix_web::error - Rust

Function actix_web::error::ErrorTooManyRequests

source ·
pub fn ErrorTooManyRequests<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a TOO_MANY_REQUESTS response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorUnauthorized.html b/actix_web/error/fn.ErrorUnauthorized.html new file mode 100644 index 000000000..a413dfb4b --- /dev/null +++ b/actix_web/error/fn.ErrorUnauthorized.html @@ -0,0 +1,3 @@ +ErrorUnauthorized in actix_web::error - Rust

Function actix_web::error::ErrorUnauthorized

source ·
pub fn ErrorUnauthorized<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a UNAUTHORIZED response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorUnavailableForLegalReasons.html b/actix_web/error/fn.ErrorUnavailableForLegalReasons.html new file mode 100644 index 000000000..5e5336ecd --- /dev/null +++ b/actix_web/error/fn.ErrorUnavailableForLegalReasons.html @@ -0,0 +1,3 @@ +ErrorUnavailableForLegalReasons in actix_web::error - Rust

Function actix_web::error::ErrorUnavailableForLegalReasons

source ·
pub fn ErrorUnavailableForLegalReasons<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a UNAVAILABLE_FOR_LEGAL_REASONS response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorUnprocessableEntity.html b/actix_web/error/fn.ErrorUnprocessableEntity.html new file mode 100644 index 000000000..f4f8afdd5 --- /dev/null +++ b/actix_web/error/fn.ErrorUnprocessableEntity.html @@ -0,0 +1,3 @@ +ErrorUnprocessableEntity in actix_web::error - Rust

Function actix_web::error::ErrorUnprocessableEntity

source ·
pub fn ErrorUnprocessableEntity<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a UNPROCESSABLE_ENTITY response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorUnsupportedMediaType.html b/actix_web/error/fn.ErrorUnsupportedMediaType.html new file mode 100644 index 000000000..f03884923 --- /dev/null +++ b/actix_web/error/fn.ErrorUnsupportedMediaType.html @@ -0,0 +1,3 @@ +ErrorUnsupportedMediaType in actix_web::error - Rust

Function actix_web::error::ErrorUnsupportedMediaType

source ·
pub fn ErrorUnsupportedMediaType<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a UNSUPPORTED_MEDIA_TYPE response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorUpgradeRequired.html b/actix_web/error/fn.ErrorUpgradeRequired.html new file mode 100644 index 000000000..8054a8693 --- /dev/null +++ b/actix_web/error/fn.ErrorUpgradeRequired.html @@ -0,0 +1,3 @@ +ErrorUpgradeRequired in actix_web::error - Rust

Function actix_web::error::ErrorUpgradeRequired

source ·
pub fn ErrorUpgradeRequired<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a UPGRADE_REQUIRED response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorUriTooLong.html b/actix_web/error/fn.ErrorUriTooLong.html new file mode 100644 index 000000000..ea152d2a2 --- /dev/null +++ b/actix_web/error/fn.ErrorUriTooLong.html @@ -0,0 +1,3 @@ +ErrorUriTooLong in actix_web::error - Rust

Function actix_web::error::ErrorUriTooLong

source ·
pub fn ErrorUriTooLong<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a URI_TOO_LONG response.

+
\ No newline at end of file diff --git a/actix_web/error/fn.ErrorVariantAlsoNegotiates.html b/actix_web/error/fn.ErrorVariantAlsoNegotiates.html new file mode 100644 index 000000000..02cd3461e --- /dev/null +++ b/actix_web/error/fn.ErrorVariantAlsoNegotiates.html @@ -0,0 +1,3 @@ +ErrorVariantAlsoNegotiates in actix_web::error - Rust

Function actix_web::error::ErrorVariantAlsoNegotiates

source ·
pub fn ErrorVariantAlsoNegotiates<T>(err: T) -> Error
where + T: Debug + Display + 'static,
Expand description

Helper function that wraps any error and generates a VARIANT_ALSO_NEGOTIATES response.

+
\ No newline at end of file diff --git a/actix_web/error/index.html b/actix_web/error/index.html new file mode 100644 index 000000000..730b7274d --- /dev/null +++ b/actix_web/error/index.html @@ -0,0 +1,2 @@ +actix_web::error - Rust

Module actix_web::error

source ·
Expand description

Error and Result module

+

Structs§

  • An error representing a problem running a blocking task on a thread pool.
  • General purpose Actix Web error.
  • A generic “error” for HTTP connections
  • Wraps errors to alter the generated response status code.

Enums§

  • A set of error that can occur during parsing content type.
  • A set of errors that can occur during dispatching HTTP requests.
  • A set of errors that can occur during parsing json payloads
  • A set of errors that can occur during parsing HTTP streams.
  • A set of errors that can occur during parsing request paths
  • A set of errors that can occur during payload parsing.
  • A set of errors that can occur during parsing query strings.
  • Error type returned when reading body as lines.
  • Errors which can occur when attempting to generate resource uri.
  • A set of errors that can occur during parsing urlencoded payloads

Traits§

Functions§

Type Aliases§

\ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorBadGateway.html b/actix_web/error/internal/fn.ErrorBadGateway.html new file mode 100644 index 000000000..3f919ceef --- /dev/null +++ b/actix_web/error/internal/fn.ErrorBadGateway.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorBadGateway.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorBadRequest.html b/actix_web/error/internal/fn.ErrorBadRequest.html new file mode 100644 index 000000000..864702748 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorBadRequest.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorBadRequest.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorConflict.html b/actix_web/error/internal/fn.ErrorConflict.html new file mode 100644 index 000000000..f4b3ef609 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorConflict.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorConflict.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorExpectationFailed.html b/actix_web/error/internal/fn.ErrorExpectationFailed.html new file mode 100644 index 000000000..5db33ee46 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorExpectationFailed.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorExpectationFailed.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorFailedDependency.html b/actix_web/error/internal/fn.ErrorFailedDependency.html new file mode 100644 index 000000000..db6373b17 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorFailedDependency.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorFailedDependency.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorForbidden.html b/actix_web/error/internal/fn.ErrorForbidden.html new file mode 100644 index 000000000..79243d12f --- /dev/null +++ b/actix_web/error/internal/fn.ErrorForbidden.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorForbidden.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorGatewayTimeout.html b/actix_web/error/internal/fn.ErrorGatewayTimeout.html new file mode 100644 index 000000000..96cc3efb6 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorGatewayTimeout.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorGatewayTimeout.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorGone.html b/actix_web/error/internal/fn.ErrorGone.html new file mode 100644 index 000000000..9ee46285c --- /dev/null +++ b/actix_web/error/internal/fn.ErrorGone.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorGone.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorHttpVersionNotSupported.html b/actix_web/error/internal/fn.ErrorHttpVersionNotSupported.html new file mode 100644 index 000000000..5b25b023e --- /dev/null +++ b/actix_web/error/internal/fn.ErrorHttpVersionNotSupported.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorHttpVersionNotSupported.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorImATeapot.html b/actix_web/error/internal/fn.ErrorImATeapot.html new file mode 100644 index 000000000..57c6ed6f9 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorImATeapot.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorImATeapot.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorInsufficientStorage.html b/actix_web/error/internal/fn.ErrorInsufficientStorage.html new file mode 100644 index 000000000..907370156 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorInsufficientStorage.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorInsufficientStorage.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorInternalServerError.html b/actix_web/error/internal/fn.ErrorInternalServerError.html new file mode 100644 index 000000000..d193f72c4 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorInternalServerError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorInternalServerError.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorLengthRequired.html b/actix_web/error/internal/fn.ErrorLengthRequired.html new file mode 100644 index 000000000..a9458f2db --- /dev/null +++ b/actix_web/error/internal/fn.ErrorLengthRequired.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorLengthRequired.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorLocked.html b/actix_web/error/internal/fn.ErrorLocked.html new file mode 100644 index 000000000..108c91d7b --- /dev/null +++ b/actix_web/error/internal/fn.ErrorLocked.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorLocked.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorLoopDetected.html b/actix_web/error/internal/fn.ErrorLoopDetected.html new file mode 100644 index 000000000..342613cee --- /dev/null +++ b/actix_web/error/internal/fn.ErrorLoopDetected.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorLoopDetected.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorMethodNotAllowed.html b/actix_web/error/internal/fn.ErrorMethodNotAllowed.html new file mode 100644 index 000000000..f7e5129a8 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorMethodNotAllowed.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorMethodNotAllowed.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorMisdirectedRequest.html b/actix_web/error/internal/fn.ErrorMisdirectedRequest.html new file mode 100644 index 000000000..2b2c16220 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorMisdirectedRequest.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorMisdirectedRequest.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorNetworkAuthenticationRequired.html b/actix_web/error/internal/fn.ErrorNetworkAuthenticationRequired.html new file mode 100644 index 000000000..eab4d675d --- /dev/null +++ b/actix_web/error/internal/fn.ErrorNetworkAuthenticationRequired.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorNetworkAuthenticationRequired.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorNotAcceptable.html b/actix_web/error/internal/fn.ErrorNotAcceptable.html new file mode 100644 index 000000000..916f974dc --- /dev/null +++ b/actix_web/error/internal/fn.ErrorNotAcceptable.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorNotAcceptable.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorNotExtended.html b/actix_web/error/internal/fn.ErrorNotExtended.html new file mode 100644 index 000000000..dfbd83776 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorNotExtended.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorNotExtended.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorNotFound.html b/actix_web/error/internal/fn.ErrorNotFound.html new file mode 100644 index 000000000..b78208cc9 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorNotFound.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorNotFound.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorNotImplemented.html b/actix_web/error/internal/fn.ErrorNotImplemented.html new file mode 100644 index 000000000..f03ea6170 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorNotImplemented.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorNotImplemented.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorPayloadTooLarge.html b/actix_web/error/internal/fn.ErrorPayloadTooLarge.html new file mode 100644 index 000000000..51cef46f4 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorPayloadTooLarge.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorPayloadTooLarge.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorPaymentRequired.html b/actix_web/error/internal/fn.ErrorPaymentRequired.html new file mode 100644 index 000000000..57ce77950 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorPaymentRequired.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorPaymentRequired.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorPreconditionFailed.html b/actix_web/error/internal/fn.ErrorPreconditionFailed.html new file mode 100644 index 000000000..d4be8ca5a --- /dev/null +++ b/actix_web/error/internal/fn.ErrorPreconditionFailed.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorPreconditionFailed.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorPreconditionRequired.html b/actix_web/error/internal/fn.ErrorPreconditionRequired.html new file mode 100644 index 000000000..cb334e678 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorPreconditionRequired.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorPreconditionRequired.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorProxyAuthenticationRequired.html b/actix_web/error/internal/fn.ErrorProxyAuthenticationRequired.html new file mode 100644 index 000000000..75c2fd862 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorProxyAuthenticationRequired.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorProxyAuthenticationRequired.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorRangeNotSatisfiable.html b/actix_web/error/internal/fn.ErrorRangeNotSatisfiable.html new file mode 100644 index 000000000..3953012e6 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorRangeNotSatisfiable.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorRangeNotSatisfiable.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorRequestHeaderFieldsTooLarge.html b/actix_web/error/internal/fn.ErrorRequestHeaderFieldsTooLarge.html new file mode 100644 index 000000000..68c567d26 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorRequestHeaderFieldsTooLarge.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorRequestHeaderFieldsTooLarge.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorRequestTimeout.html b/actix_web/error/internal/fn.ErrorRequestTimeout.html new file mode 100644 index 000000000..4aad7341d --- /dev/null +++ b/actix_web/error/internal/fn.ErrorRequestTimeout.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorRequestTimeout.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorServiceUnavailable.html b/actix_web/error/internal/fn.ErrorServiceUnavailable.html new file mode 100644 index 000000000..eff43ec77 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorServiceUnavailable.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorServiceUnavailable.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorTooManyRequests.html b/actix_web/error/internal/fn.ErrorTooManyRequests.html new file mode 100644 index 000000000..ed6a87912 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorTooManyRequests.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorTooManyRequests.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorUnauthorized.html b/actix_web/error/internal/fn.ErrorUnauthorized.html new file mode 100644 index 000000000..402c26d57 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorUnauthorized.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorUnauthorized.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorUnavailableForLegalReasons.html b/actix_web/error/internal/fn.ErrorUnavailableForLegalReasons.html new file mode 100644 index 000000000..5843ab2ab --- /dev/null +++ b/actix_web/error/internal/fn.ErrorUnavailableForLegalReasons.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorUnavailableForLegalReasons.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorUnprocessableEntity.html b/actix_web/error/internal/fn.ErrorUnprocessableEntity.html new file mode 100644 index 000000000..00bf0aaf3 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorUnprocessableEntity.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorUnprocessableEntity.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorUnsupportedMediaType.html b/actix_web/error/internal/fn.ErrorUnsupportedMediaType.html new file mode 100644 index 000000000..9bb337000 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorUnsupportedMediaType.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorUnsupportedMediaType.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorUpgradeRequired.html b/actix_web/error/internal/fn.ErrorUpgradeRequired.html new file mode 100644 index 000000000..95ba99ec1 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorUpgradeRequired.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorUpgradeRequired.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorUriTooLong.html b/actix_web/error/internal/fn.ErrorUriTooLong.html new file mode 100644 index 000000000..892f97110 --- /dev/null +++ b/actix_web/error/internal/fn.ErrorUriTooLong.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorUriTooLong.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/fn.ErrorVariantAlsoNegotiates.html b/actix_web/error/internal/fn.ErrorVariantAlsoNegotiates.html new file mode 100644 index 000000000..07810889b --- /dev/null +++ b/actix_web/error/internal/fn.ErrorVariantAlsoNegotiates.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/fn.ErrorVariantAlsoNegotiates.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/internal/struct.InternalError.html b/actix_web/error/internal/struct.InternalError.html new file mode 100644 index 000000000..fef62b98d --- /dev/null +++ b/actix_web/error/internal/struct.InternalError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/struct.InternalError.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/response_error/trait.ResponseError.html b/actix_web/error/response_error/trait.ResponseError.html new file mode 100644 index 000000000..48e6601ca --- /dev/null +++ b/actix_web/error/response_error/trait.ResponseError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/error/trait.ResponseError.html...

+ + + \ No newline at end of file diff --git a/actix_web/error/sidebar-items.js b/actix_web/error/sidebar-items.js new file mode 100644 index 000000000..29c171340 --- /dev/null +++ b/actix_web/error/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["ContentTypeError","DispatchError","JsonPayloadError","ParseError","PathError","PayloadError","QueryPayloadError","ReadlinesError","UrlGenerationError","UrlencodedError"],"fn":["ErrorBadGateway","ErrorBadRequest","ErrorConflict","ErrorExpectationFailed","ErrorFailedDependency","ErrorForbidden","ErrorGatewayTimeout","ErrorGone","ErrorHttpVersionNotSupported","ErrorImATeapot","ErrorInsufficientStorage","ErrorInternalServerError","ErrorLengthRequired","ErrorLocked","ErrorLoopDetected","ErrorMethodNotAllowed","ErrorMisdirectedRequest","ErrorNetworkAuthenticationRequired","ErrorNotAcceptable","ErrorNotExtended","ErrorNotFound","ErrorNotImplemented","ErrorPayloadTooLarge","ErrorPaymentRequired","ErrorPreconditionFailed","ErrorPreconditionRequired","ErrorProxyAuthenticationRequired","ErrorRangeNotSatisfiable","ErrorRequestHeaderFieldsTooLarge","ErrorRequestTimeout","ErrorServiceUnavailable","ErrorTooManyRequests","ErrorUnauthorized","ErrorUnavailableForLegalReasons","ErrorUnprocessableEntity","ErrorUnsupportedMediaType","ErrorUpgradeRequired","ErrorUriTooLong","ErrorVariantAlsoNegotiates"],"struct":["BlockingError","Error","HttpError","InternalError"],"trait":["ResponseError"],"type":["Result"]}; \ No newline at end of file diff --git a/actix_web/error/struct.BlockingError.html b/actix_web/error/struct.BlockingError.html new file mode 100644 index 000000000..fb86ed070 --- /dev/null +++ b/actix_web/error/struct.BlockingError.html @@ -0,0 +1,19 @@ +BlockingError in actix_web::error - Rust

Struct actix_web::error::BlockingError

source ·
#[non_exhaustive]
pub struct BlockingError;
Expand description

An error representing a problem running a blocking task on a thread pool.

+

Trait Implementations§

source§

impl Debug for BlockingError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for BlockingError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for BlockingError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl ResponseError for BlockingError

source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
source§

fn error_response(&self) -> HttpResponse<BoxBody>

Creates full response for error. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/error/struct.Error.html b/actix_web/error/struct.Error.html new file mode 100644 index 000000000..b3f0d87ac --- /dev/null +++ b/actix_web/error/struct.Error.html @@ -0,0 +1,28 @@ +Error in actix_web::error - Rust

Struct actix_web::error::Error

source ·
pub struct Error { /* private fields */ }
Expand description

General purpose Actix Web error.

+

An Actix Web error is used to carry errors from std::error through actix in a convenient way. +It can be created through converting errors with into().

+

Whenever it is created from an external object a response error is created for it that can be +used to create an HTTP response from it this means that if you have access to an actix Error +you can always get a ResponseError reference from it.

+

Implementations§

source§

impl Error

source

pub fn as_response_error(&self) -> &dyn ResponseError

Returns the reference to the underlying ResponseError.

+
source

pub fn as_error<T: ResponseError + 'static>(&self) -> Option<&T>

Similar to as_response_error but downcasts.

+
source

pub fn error_response(&self) -> HttpResponse

Shortcut for creating an HttpResponse.

+

Trait Implementations§

source§

impl Debug for Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for Error

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<Error> for HttpResponse

source§

fn from(err: Error) -> Self

Converts to this type from the input type.
source§

impl From<Error> for Response<BoxBody>

source§

fn from(err: Error) -> Response<BoxBody>

Converts to this type from the input type.
source§

impl<T: ResponseError + 'static> From<T> for Error

Error for any error that implements ResponseError

+
source§

fn from(err: T) -> Error

Converts to this type from the input type.

Auto Trait Implementations§

§

impl Freeze for Error

§

impl !RefUnwindSafe for Error

§

impl !Send for Error

§

impl !Sync for Error

§

impl Unpin for Error

§

impl !UnwindSafe for Error

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/error/struct.HttpError.html b/actix_web/error/struct.HttpError.html new file mode 100644 index 000000000..00e71669f --- /dev/null +++ b/actix_web/error/struct.HttpError.html @@ -0,0 +1,26 @@ +HttpError in actix_web::error - Rust

Struct actix_web::error::HttpError

source ·
pub struct HttpError { /* private fields */ }
Expand description

A generic “error” for HTTP connections

+

This error type is less specific than the error returned from other +functions in this crate, but all other errors can be converted to this +error. Consumers of this crate can typically consume and work with this form +of error for conversions with the ? operator.

+

Implementations§

source§

impl Error

source

pub fn is<T>(&self) -> bool
where + T: Error + 'static,

Return true if the underlying error has the same type as T.

+
source

pub fn get_ref(&self) -> &(dyn Error + 'static)

Return a reference to the lower level, inner error.

+

Trait Implementations§

source§

impl Debug for Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for Error

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<Error> for Error

source§

fn from(err: Error) -> Error

Converts to this type from the input type.
source§

impl From<Infallible> for Error

source§

fn from(err: Infallible) -> Error

Converts to this type from the input type.
source§

impl From<InvalidHeaderName> for Error

source§

fn from(err: InvalidHeaderName) -> Error

Converts to this type from the input type.
source§

impl From<InvalidHeaderPart> for Error

source§

fn from(part_err: InvalidHeaderPart) -> Error

Converts to this type from the input type.
source§

impl From<InvalidHeaderValue> for Error

source§

fn from(err: InvalidHeaderValue) -> Error

Converts to this type from the input type.
source§

impl From<InvalidMethod> for Error

source§

fn from(err: InvalidMethod) -> Error

Converts to this type from the input type.
source§

impl From<InvalidStatusCode> for Error

source§

fn from(err: InvalidStatusCode) -> Error

Converts to this type from the input type.
source§

impl From<InvalidUri> for Error

source§

fn from(err: InvalidUri) -> Error

Converts to this type from the input type.
source§

impl From<InvalidUriParts> for Error

source§

fn from(err: InvalidUriParts) -> Error

Converts to this type from the input type.
source§

impl From<MaxSizeReached> for Error

source§

fn from(err: MaxSizeReached) -> Error

Converts to this type from the input type.
source§

impl ResponseError for HttpError

source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
source§

fn error_response(&self) -> HttpResponse<BoxBody>

Creates full response for error. Read more

Auto Trait Implementations§

§

impl Freeze for Error

§

impl RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl UnwindSafe for Error

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/error/struct.InternalError.html b/actix_web/error/struct.InternalError.html new file mode 100644 index 000000000..77c05de65 --- /dev/null +++ b/actix_web/error/struct.InternalError.html @@ -0,0 +1,33 @@ +InternalError in actix_web::error - Rust

Struct actix_web::error::InternalError

source ·
pub struct InternalError<T> { /* private fields */ }
Expand description

Wraps errors to alter the generated response status code.

+

In following example, the io::Error is wrapped into ErrorBadRequest which will generate a +response with the 400 Bad Request status code instead of the usual status code generated by +an io::Error.

+

§Examples

+
async fn handler_error() -> Result<String, actix_web::Error> {
+    let err = io::Error::new(io::ErrorKind::Other, "error");
+    Err(error::ErrorBadRequest(err))
+}
+

Implementations§

source§

impl<T> InternalError<T>

source

pub fn new(cause: T, status: StatusCode) -> Self

Constructs an InternalError with given status code.

+
source

pub fn from_response(cause: T, response: HttpResponse) -> Self

Constructs an InternalError with pre-defined response.

+

Trait Implementations§

source§

impl<T: Debug> Debug for InternalError<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: Display> Display for InternalError<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> Responder for InternalError<T>
where + T: Debug + Display + 'static,

§

type Body = BoxBody

source§

fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body>

Convert self to HttpResponse.
source§

fn customize(self) -> CustomizeResponder<Self>
where + Self: Sized,

Wraps responder to allow alteration of its response. Read more
source§

impl<T> ResponseError for InternalError<T>
where + T: Debug + Display,

source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
source§

fn error_response(&self) -> HttpResponse

Creates full response for error. Read more

Auto Trait Implementations§

§

impl<T> !Freeze for InternalError<T>

§

impl<T> !RefUnwindSafe for InternalError<T>

§

impl<T> !Send for InternalError<T>

§

impl<T> !Sync for InternalError<T>

§

impl<T> Unpin for InternalError<T>
where + T: Unpin,

§

impl<T> !UnwindSafe for InternalError<T>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/error/trait.ResponseError.html b/actix_web/error/trait.ResponseError.html new file mode 100644 index 000000000..5a80bbad2 --- /dev/null +++ b/actix_web/error/trait.ResponseError.html @@ -0,0 +1,16 @@ +ResponseError in actix_web::error - Rust

Trait actix_web::error::ResponseError

source ·
pub trait ResponseError: Debug + Display {
+    // Provided methods
+    fn status_code(&self) -> StatusCode { ... }
+    fn error_response(&self) -> HttpResponse<BoxBody> { ... }
+}
Expand description

Errors that can generate responses.

+

Provided Methods§

source

fn status_code(&self) -> StatusCode

Returns appropriate status code for error.

+

A 500 Internal Server Error is used by default. If error_response is +also implemented and does not call self.status_code(), then this will not be used.

+
source

fn error_response(&self) -> HttpResponse<BoxBody>

Creates full response for error.

+

By default, the generated response uses a 500 Internal Server Error status code, a +Content-Type of text/plain, and the body is set to Self’s Display impl.

+

Implementations§

source§

impl dyn ResponseError + 'static

source

pub fn downcast_ref<T: ResponseError + 'static>(&self) -> Option<&T>

Downcasts generic body to a specific type.

+
source

pub fn downcast_mut<T: ResponseError + 'static>(&mut self) -> Option<&mut T>

Downcasts a generic body to a mutable specific type.

+

Implementations on Foreign Types§

source§

impl ResponseError for HandshakeError

source§

impl ResponseError for ProtocolError

source§

impl ResponseError for Infallible

source§

impl ResponseError for Box<dyn StdError + 'static>

source§

impl ResponseError for Utf8Error

source§

impl ResponseError for Error

source§

impl ResponseError for Error

Available on crate feature openssl only.
source§

impl ResponseError for Error

source§

impl ResponseError for Error

source§

impl ResponseError for Error

Implementors§

\ No newline at end of file diff --git a/actix_web/error/type.Result.html b/actix_web/error/type.Result.html new file mode 100644 index 000000000..0a5ecc0c4 --- /dev/null +++ b/actix_web/error/type.Result.html @@ -0,0 +1,8 @@ +Result in actix_web::error - Rust

Type Alias actix_web::error::Result

source ·
pub type Result<T, E = Error> = Result<T, E>;
Expand description

A convenience Result for Actix Web operations.

+

This type alias is generally used to avoid writing out actix_http::Error directly.

+

Aliased Type§

enum Result<T, E = Error> {
+    Ok(T),
+    Err(E),
+}

Variants§

§1.0.0

Ok(T)

Contains the success value

+
§1.0.0

Err(E)

Contains the error value

+
\ No newline at end of file diff --git a/actix_web/extract/trait.FromRequest.html b/actix_web/extract/trait.FromRequest.html new file mode 100644 index 000000000..f52308364 --- /dev/null +++ b/actix_web/extract/trait.FromRequest.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/trait.FromRequest.html...

+ + + \ No newline at end of file diff --git a/actix_web/guard/acceptable/struct.Acceptable.html b/actix_web/guard/acceptable/struct.Acceptable.html new file mode 100644 index 000000000..08b51e15f --- /dev/null +++ b/actix_web/guard/acceptable/struct.Acceptable.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/guard/struct.Acceptable.html...

+ + + \ No newline at end of file diff --git a/actix_web/guard/fn.All.html b/actix_web/guard/fn.All.html new file mode 100644 index 000000000..80d4a316d --- /dev/null +++ b/actix_web/guard/fn.All.html @@ -0,0 +1,14 @@ +All in actix_web::guard - Rust

Function actix_web::guard::All

source ·
pub fn All<F: Guard + 'static>(guard: F) -> AllGuard
Expand description

Creates a guard that matches if all added guards match.

+

§Examples

+

The handler below will only be called if the request method is GET and the specified +header name and value match exactly.

+ +
use actix_web::{guard, web, HttpResponse};
+
+web::route()
+    .guard(
+        guard::All(guard::Get())
+            .and(guard::Header("accept", "text/plain"))
+    )
+    .to(|| HttpResponse::Ok());
+
\ No newline at end of file diff --git a/actix_web/guard/fn.Any.html b/actix_web/guard/fn.Any.html new file mode 100644 index 000000000..4e3f5d826 --- /dev/null +++ b/actix_web/guard/fn.Any.html @@ -0,0 +1,12 @@ +Any in actix_web::guard - Rust

Function actix_web::guard::Any

source ·
pub fn Any<F: Guard + 'static>(guard: F) -> AnyGuard
Expand description

Creates a guard that matches if any added guards match.

+

§Examples

+

The handler below will be called for either request method GET or POST.

+ +
use actix_web::{web, guard, HttpResponse};
+
+web::route()
+    .guard(
+        guard::Any(guard::Get())
+            .or(guard::Post()))
+    .to(|| HttpResponse::Ok());
+
\ No newline at end of file diff --git a/actix_web/guard/fn.Connect.html b/actix_web/guard/fn.Connect.html new file mode 100644 index 000000000..12ed57b1e --- /dev/null +++ b/actix_web/guard/fn.Connect.html @@ -0,0 +1,10 @@ +Connect in actix_web::guard - Rust

Function actix_web::guard::Connect

source ·
pub fn Connect() -> impl Guard
Expand description

Creates a guard that matches the CONNECT request method.

+

§Examples

+

The route in this example will only respond to CONNECT requests.

+ +
use actix_web::{guard, web, HttpResponse};
+
+web::route()
+    .guard(guard::Connect())
+    .to(|| HttpResponse::Ok());
+
\ No newline at end of file diff --git a/actix_web/guard/fn.Delete.html b/actix_web/guard/fn.Delete.html new file mode 100644 index 000000000..3e2dcd248 --- /dev/null +++ b/actix_web/guard/fn.Delete.html @@ -0,0 +1,10 @@ +Delete in actix_web::guard - Rust

Function actix_web::guard::Delete

source ·
pub fn Delete() -> impl Guard
Expand description

Creates a guard that matches the DELETE request method.

+

§Examples

+

The route in this example will only respond to DELETE requests.

+ +
use actix_web::{guard, web, HttpResponse};
+
+web::route()
+    .guard(guard::Delete())
+    .to(|| HttpResponse::Ok());
+
\ No newline at end of file diff --git a/actix_web/guard/fn.Get.html b/actix_web/guard/fn.Get.html new file mode 100644 index 000000000..ebf8ace3d --- /dev/null +++ b/actix_web/guard/fn.Get.html @@ -0,0 +1,10 @@ +Get in actix_web::guard - Rust

Function actix_web::guard::Get

source ·
pub fn Get() -> impl Guard
Expand description

Creates a guard that matches the GET request method.

+

§Examples

+

The route in this example will only respond to GET requests.

+ +
use actix_web::{guard, web, HttpResponse};
+
+web::route()
+    .guard(guard::Get())
+    .to(|| HttpResponse::Ok());
+
\ No newline at end of file diff --git a/actix_web/guard/fn.Head.html b/actix_web/guard/fn.Head.html new file mode 100644 index 000000000..0ebefafa6 --- /dev/null +++ b/actix_web/guard/fn.Head.html @@ -0,0 +1,10 @@ +Head in actix_web::guard - Rust

Function actix_web::guard::Head

source ·
pub fn Head() -> impl Guard
Expand description

Creates a guard that matches the HEAD request method.

+

§Examples

+

The route in this example will only respond to HEAD requests.

+ +
use actix_web::{guard, web, HttpResponse};
+
+web::route()
+    .guard(guard::Head())
+    .to(|| HttpResponse::Ok());
+
\ No newline at end of file diff --git a/actix_web/guard/fn.Header.html b/actix_web/guard/fn.Header.html new file mode 100644 index 000000000..819f3f93f --- /dev/null +++ b/actix_web/guard/fn.Header.html @@ -0,0 +1,11 @@ +Header in actix_web::guard - Rust

Function actix_web::guard::Header

source ·
pub fn Header(name: &'static str, value: &'static str) -> impl Guard
Expand description

Creates a guard that matches if request contains given header name and value.

+

§Examples

+

The handler below will be called when the request contains an x-guarded header with value +equal to secret.

+ +
use actix_web::{guard, web, HttpResponse};
+
+web::route()
+    .guard(guard::Header("x-guarded", "secret"))
+    .to(|| HttpResponse::Ok());
+
\ No newline at end of file diff --git a/actix_web/guard/fn.Host.html b/actix_web/guard/fn.Host.html new file mode 100644 index 000000000..532b0a3f1 --- /dev/null +++ b/actix_web/guard/fn.Host.html @@ -0,0 +1,47 @@ +Host in actix_web::guard - Rust

Function actix_web::guard::Host

source ·
pub fn Host(host: impl AsRef<str>) -> HostGuard
Expand description

Creates a guard that matches requests targeting a specific host.

+

§Matching Host

+

This guard will:

+
    +
  • match against the Host header, if present;
  • +
  • fall-back to matching against the request target’s host, if present;
  • +
  • return false if host cannot be determined;
  • +
+

§Matching Scheme

+

Optionally, this guard can match against the host’s scheme. Set the scheme for matching using +Host(host).scheme(protocol). If the request’s scheme cannot be determined, it will not prevent +the guard from matching successfully.

+

§Examples

+

The Host guard can be used to set up a form of virtual hosting within a single app. +Overlapping scope prefixes are usually discouraged, but when combined with non-overlapping guard +definitions they become safe to use in this way. Without these host guards, only routes under +the first-to-be-defined scope would be accessible. You can test this locally using 127.0.0.1 +and localhost as the Host guards.

+ +
use actix_web::{web, http::Method, guard, App, HttpResponse};
+
+App::new()
+    .service(
+        web::scope("")
+            .guard(guard::Host("www.rust-lang.org"))
+            .default_service(web::to(|| async {
+                HttpResponse::Ok().body("marketing site")
+            })),
+    )
+    .service(
+        web::scope("")
+            .guard(guard::Host("play.rust-lang.org"))
+            .default_service(web::to(|| async {
+                HttpResponse::Ok().body("playground frontend")
+            })),
+    );
+

The example below additionally guards on the host URI’s scheme. This could allow routing to +different handlers for http: vs https: visitors; to redirect, for example.

+ +
use actix_web::{web, guard::Host, HttpResponse};
+
+web::scope("/admin")
+    .guard(Host("admin.rust-lang.org").scheme("https"))
+    .default_service(web::to(|| async {
+        HttpResponse::Ok().body("admin connection is secure")
+    }));
+
\ No newline at end of file diff --git a/actix_web/guard/fn.Method.html b/actix_web/guard/fn.Method.html new file mode 100644 index 000000000..59bd22b02 --- /dev/null +++ b/actix_web/guard/fn.Method.html @@ -0,0 +1,2 @@ +Method in actix_web::guard - Rust

Function actix_web::guard::Method

source ·
pub fn Method(method: Method) -> impl Guard
Expand description

Creates a guard that matches a specified HTTP method.

+
\ No newline at end of file diff --git a/actix_web/guard/fn.Options.html b/actix_web/guard/fn.Options.html new file mode 100644 index 000000000..56905d272 --- /dev/null +++ b/actix_web/guard/fn.Options.html @@ -0,0 +1,10 @@ +Options in actix_web::guard - Rust

Function actix_web::guard::Options

source ·
pub fn Options() -> impl Guard
Expand description

Creates a guard that matches the OPTIONS request method.

+

§Examples

+

The route in this example will only respond to OPTIONS requests.

+ +
use actix_web::{guard, web, HttpResponse};
+
+web::route()
+    .guard(guard::Options())
+    .to(|| HttpResponse::Ok());
+
\ No newline at end of file diff --git a/actix_web/guard/fn.Patch.html b/actix_web/guard/fn.Patch.html new file mode 100644 index 000000000..41adafd2c --- /dev/null +++ b/actix_web/guard/fn.Patch.html @@ -0,0 +1,10 @@ +Patch in actix_web::guard - Rust

Function actix_web::guard::Patch

source ·
pub fn Patch() -> impl Guard
Expand description

Creates a guard that matches the PATCH request method.

+

§Examples

+

The route in this example will only respond to PATCH requests.

+ +
use actix_web::{guard, web, HttpResponse};
+
+web::route()
+    .guard(guard::Patch())
+    .to(|| HttpResponse::Ok());
+
\ No newline at end of file diff --git a/actix_web/guard/fn.Post.html b/actix_web/guard/fn.Post.html new file mode 100644 index 000000000..8b0720e08 --- /dev/null +++ b/actix_web/guard/fn.Post.html @@ -0,0 +1,10 @@ +Post in actix_web::guard - Rust

Function actix_web::guard::Post

source ·
pub fn Post() -> impl Guard
Expand description

Creates a guard that matches the POST request method.

+

§Examples

+

The route in this example will only respond to POST requests.

+ +
use actix_web::{guard, web, HttpResponse};
+
+web::route()
+    .guard(guard::Post())
+    .to(|| HttpResponse::Ok());
+
\ No newline at end of file diff --git a/actix_web/guard/fn.Put.html b/actix_web/guard/fn.Put.html new file mode 100644 index 000000000..f738e1b6f --- /dev/null +++ b/actix_web/guard/fn.Put.html @@ -0,0 +1,10 @@ +Put in actix_web::guard - Rust

Function actix_web::guard::Put

source ·
pub fn Put() -> impl Guard
Expand description

Creates a guard that matches the PUT request method.

+

§Examples

+

The route in this example will only respond to PUT requests.

+ +
use actix_web::{guard, web, HttpResponse};
+
+web::route()
+    .guard(guard::Put())
+    .to(|| HttpResponse::Ok());
+
\ No newline at end of file diff --git a/actix_web/guard/fn.Trace.html b/actix_web/guard/fn.Trace.html new file mode 100644 index 000000000..d65554738 --- /dev/null +++ b/actix_web/guard/fn.Trace.html @@ -0,0 +1,10 @@ +Trace in actix_web::guard - Rust

Function actix_web::guard::Trace

source ·
pub fn Trace() -> impl Guard
Expand description

Creates a guard that matches the TRACE request method.

+

§Examples

+

The route in this example will only respond to TRACE requests.

+ +
use actix_web::{guard, web, HttpResponse};
+
+web::route()
+    .guard(guard::Trace())
+    .to(|| HttpResponse::Ok());
+
\ No newline at end of file diff --git a/actix_web/guard/fn.fn_guard.html b/actix_web/guard/fn.fn_guard.html new file mode 100644 index 000000000..496741ea7 --- /dev/null +++ b/actix_web/guard/fn.fn_guard.html @@ -0,0 +1,11 @@ +fn_guard in actix_web::guard - Rust

Function actix_web::guard::fn_guard

source ·
pub fn fn_guard<F>(f: F) -> impl Guard
where + F: Fn(&GuardContext<'_>) -> bool,
Expand description

Creates a guard using the given function.

+

§Examples

+
use actix_web::{guard, web, HttpResponse};
+
+web::route()
+    .guard(guard::fn_guard(|ctx| {
+        ctx.head().headers().contains_key("content-type")
+    }))
+    .to(|| HttpResponse::Ok());
+
\ No newline at end of file diff --git a/actix_web/guard/host/fn.Host.html b/actix_web/guard/host/fn.Host.html new file mode 100644 index 000000000..12827429e --- /dev/null +++ b/actix_web/guard/host/fn.Host.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/guard/fn.Host.html...

+ + + \ No newline at end of file diff --git a/actix_web/guard/index.html b/actix_web/guard/index.html new file mode 100644 index 000000000..43e10f26f --- /dev/null +++ b/actix_web/guard/index.html @@ -0,0 +1,37 @@ +actix_web::guard - Rust

Module actix_web::guard

source ·
Expand description

Route guards.

+

Guards are used during routing to help select a matching service or handler using some aspect of +the request; though guards should not be used for path matching since it is a built-in function +of the Actix Web router.

+

Guards can be used on Scopes, Resources, Routes, and other custom services.

+

Fundamentally, a guard is a predicate function that receives a reference to a request context +object and returns a boolean; true if the request should be handled by the guarded service +or handler. This interface is defined by the Guard trait.

+

Commonly-used guards are provided in this module as well as a way of creating a guard from a +closure (fn_guard). The Not, Any, and All guards are noteworthy, as they can be +used to compose other guards in a more flexible and semantic way than calling .guard(...) on +services multiple times (which might have different combining behavior than you want).

+

There are shortcuts for routes with method guards in the web module: +web::get(), web::post(), etc. The routes created by +the following calls are equivalent:

+
    +
  • web::get() (recommended form)
  • +
  • web::route().guard(guard::Get())
  • +
+

Guards can not modify anything about the request. However, it is possible to store extra +attributes in the request-local data container obtained with GuardContext::req_data_mut.

+

Guards can prevent resource definitions from overlapping which, when only considering paths, +would result in inaccessible routes. See the Host guard for an example of virtual hosting.

+

§Examples

+

In the following code, the /guarded resource has one defined route whose handler will only be +called if the request method is GET or POST and there is a x-guarded request header with value +equal to secret.

+ +
use actix_web::{web, http::Method, guard, HttpResponse};
+
+web::resource("/guarded").route(
+    web::route()
+        .guard(guard::Any(guard::Get()).or(guard::Post()))
+        .guard(guard::Header("x-guarded", "secret"))
+        .to(|| HttpResponse::Ok())
+);
+

Re-exports§

  • pub use self::host::HostGuard;

Structs§

  • A guard that verifies that an Accept header is present and it contains a compatible MIME type.
  • A collection of guards that match if the conjunction of their check outcomes is true.
  • A collection of guards that match if the disjunction of their check outcomes is true.
  • Provides access to request parts that are useful during routing.
  • Wraps a guard and inverts the outcome of its Guard implementation.

Traits§

  • Interface for routing guards.

Functions§

  • Creates a guard that matches if all added guards match.
  • Creates a guard that matches if any added guards match.
  • Creates a guard that matches the CONNECT request method.
  • Creates a guard that matches the DELETE request method.
  • Creates a guard that matches the GET request method.
  • Creates a guard that matches the HEAD request method.
  • Creates a guard that matches if request contains given header name and value.
  • Creates a guard that matches requests targeting a specific host.
  • Creates a guard that matches a specified HTTP method.
  • Creates a guard that matches the OPTIONS request method.
  • Creates a guard that matches the PATCH request method.
  • Creates a guard that matches the POST request method.
  • Creates a guard that matches the PUT request method.
  • Creates a guard that matches the TRACE request method.
  • Creates a guard using the given function.
\ No newline at end of file diff --git a/actix_web/guard/sidebar-items.js b/actix_web/guard/sidebar-items.js new file mode 100644 index 000000000..35f55ca96 --- /dev/null +++ b/actix_web/guard/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["All","Any","Connect","Delete","Get","Head","Header","Host","Method","Options","Patch","Post","Put","Trace","fn_guard"],"struct":["Acceptable","AllGuard","AnyGuard","GuardContext","Not"],"trait":["Guard"]}; \ No newline at end of file diff --git a/actix_web/guard/struct.Acceptable.html b/actix_web/guard/struct.Acceptable.html new file mode 100644 index 000000000..a6b5eb1e1 --- /dev/null +++ b/actix_web/guard/struct.Acceptable.html @@ -0,0 +1,31 @@ +Acceptable in actix_web::guard - Rust

Struct actix_web::guard::Acceptable

source ·
pub struct Acceptable { /* private fields */ }
Expand description

A guard that verifies that an Accept header is present and it contains a compatible MIME type.

+

An exception is that matching */* must be explicitly enabled because most browsers send this +as part of their Accept header for almost every request.

+

§Examples

+
use actix_web::{guard::Acceptable, web, HttpResponse};
+
+web::resource("/images")
+    .guard(Acceptable::new(mime::IMAGE_STAR))
+    .default_service(web::to(|| async {
+        HttpResponse::Ok().body("only called when images responses are acceptable")
+    }));
+

Implementations§

source§

impl Acceptable

source

pub fn new(mime: Mime) -> Self

Constructs new Acceptable guard with the given mime type/pattern.

+
source

pub fn match_star_star(self) -> Self

Allows */* in the Accept header to pass the guard check.

+

Trait Implementations§

source§

impl Clone for Acceptable

source§

fn clone(&self) -> Acceptable

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Acceptable

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Guard for Acceptable

source§

fn check(&self, ctx: &GuardContext<'_>) -> bool

Returns true if predicate condition is met for a given request.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/guard/struct.AllGuard.html b/actix_web/guard/struct.AllGuard.html new file mode 100644 index 000000000..8577014dd --- /dev/null +++ b/actix_web/guard/struct.AllGuard.html @@ -0,0 +1,21 @@ +AllGuard in actix_web::guard - Rust

Struct actix_web::guard::AllGuard

source ·
pub struct AllGuard { /* private fields */ }
Expand description

A collection of guards that match if the conjunction of their check outcomes is true.

+

That is, all contained guard needs to match in order for the aggregate guard to match.

+

Construct an AllGuard using All.

+

Implementations§

source§

impl AllGuard

source

pub fn and<F: Guard + 'static>(self, guard: F) -> Self

Adds new guard to the collection of guards to check.

+

Trait Implementations§

source§

impl Guard for AllGuard

source§

fn check(&self, ctx: &GuardContext<'_>) -> bool

Returns true if predicate condition is met for a given request.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/guard/struct.AnyGuard.html b/actix_web/guard/struct.AnyGuard.html new file mode 100644 index 000000000..b573014f4 --- /dev/null +++ b/actix_web/guard/struct.AnyGuard.html @@ -0,0 +1,21 @@ +AnyGuard in actix_web::guard - Rust

Struct actix_web::guard::AnyGuard

source ·
pub struct AnyGuard { /* private fields */ }
Expand description

A collection of guards that match if the disjunction of their check outcomes is true.

+

That is, only one contained guard needs to match in order for the aggregate guard to match.

+

Construct an AnyGuard using Any.

+

Implementations§

source§

impl AnyGuard

source

pub fn or<F: Guard + 'static>(self, guard: F) -> Self

Adds new guard to the collection of guards to check.

+

Trait Implementations§

source§

impl Guard for AnyGuard

source§

fn check(&self, ctx: &GuardContext<'_>) -> bool

Returns true if predicate condition is met for a given request.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/guard/struct.GuardContext.html b/actix_web/guard/struct.GuardContext.html new file mode 100644 index 000000000..7fa22ea81 --- /dev/null +++ b/actix_web/guard/struct.GuardContext.html @@ -0,0 +1,32 @@ +GuardContext in actix_web::guard - Rust

Struct actix_web::guard::GuardContext

source ·
pub struct GuardContext<'a> { /* private fields */ }
Expand description

Provides access to request parts that are useful during routing.

+

Implementations§

source§

impl<'a> GuardContext<'a>

source

pub fn head(&self) -> &RequestHead

Returns reference to the request head.

+
source

pub fn req_data(&self) -> Ref<'a, Extensions>

Returns reference to the request-local data/extensions container.

+
source

pub fn req_data_mut(&self) -> RefMut<'a, Extensions>

Returns mutable reference to the request-local data/extensions container.

+
source

pub fn header<H: Header>(&self) -> Option<H>

Extracts a typed header from the request.

+

Returns None if parsing H fails.

+
§Examples
+
use actix_web::{guard::fn_guard, http::header};
+
+let image_accept_guard = fn_guard(|ctx| {
+    match ctx.header::<header::Accept>() {
+        Some(hdr) => hdr.preference() == "image/*",
+        None => false,
+    }
+});
+

Trait Implementations§

source§

impl<'a> Debug for GuardContext<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> Freeze for GuardContext<'a>

§

impl<'a> !RefUnwindSafe for GuardContext<'a>

§

impl<'a> !Send for GuardContext<'a>

§

impl<'a> !Sync for GuardContext<'a>

§

impl<'a> Unpin for GuardContext<'a>

§

impl<'a> !UnwindSafe for GuardContext<'a>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/guard/struct.Not.html b/actix_web/guard/struct.Not.html new file mode 100644 index 000000000..889793769 --- /dev/null +++ b/actix_web/guard/struct.Not.html @@ -0,0 +1,32 @@ +Not in actix_web::guard - Rust

Struct actix_web::guard::Not

source ·
pub struct Not<G>(pub G);
Expand description

Wraps a guard and inverts the outcome of its Guard implementation.

+

§Examples

+

The handler below will be called for any request method apart from GET.

+ +
use actix_web::{guard, web, HttpResponse};
+
+web::route()
+    .guard(guard::Not(guard::Get()))
+    .to(|| HttpResponse::Ok());
+

Tuple Fields§

§0: G

Trait Implementations§

source§

impl<G: Guard> Guard for Not<G>

source§

fn check(&self, ctx: &GuardContext<'_>) -> bool

Returns true if predicate condition is met for a given request.

Auto Trait Implementations§

§

impl<G> Freeze for Not<G>
where + G: Freeze,

§

impl<G> RefUnwindSafe for Not<G>
where + G: RefUnwindSafe,

§

impl<G> Send for Not<G>
where + G: Send,

§

impl<G> Sync for Not<G>
where + G: Sync,

§

impl<G> Unpin for Not<G>
where + G: Unpin,

§

impl<G> UnwindSafe for Not<G>
where + G: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/guard/trait.Guard.html b/actix_web/guard/trait.Guard.html new file mode 100644 index 000000000..58bebd565 --- /dev/null +++ b/actix_web/guard/trait.Guard.html @@ -0,0 +1,8 @@ +Guard in actix_web::guard - Rust

Trait actix_web::guard::Guard

source ·
pub trait Guard {
+    // Required method
+    fn check(&self, ctx: &GuardContext<'_>) -> bool;
+}
Expand description

Interface for routing guards.

+

See module level documentation for more.

+

Required Methods§

source

fn check(&self, ctx: &GuardContext<'_>) -> bool

Returns true if predicate condition is met for a given request.

+

Implementations on Foreign Types§

source§

impl Guard for Rc<dyn Guard>

source§

fn check(&self, ctx: &GuardContext<'_>) -> bool

Implementors§

source§

impl Guard for Acceptable

source§

impl Guard for AllGuard

source§

impl Guard for AnyGuard

source§

impl<F> Guard for F
where + F: Fn(&GuardContext<'_>) -> bool,

source§

impl<G: Guard> Guard for Not<G>

\ No newline at end of file diff --git a/actix_web/handler/trait.Handler.html b/actix_web/handler/trait.Handler.html new file mode 100644 index 000000000..b7fb559bc --- /dev/null +++ b/actix_web/handler/trait.Handler.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/trait.Handler.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/enum.ConnectionType.html b/actix_web/http/enum.ConnectionType.html new file mode 100644 index 000000000..48eec22fc --- /dev/null +++ b/actix_web/http/enum.ConnectionType.html @@ -0,0 +1,32 @@ +ConnectionType in actix_web::http - Rust

Enum actix_web::http::ConnectionType

source ·
pub enum ConnectionType {
+    Close,
+    KeepAlive,
+    Upgrade,
+}
Expand description

Represents various types of connection

+

Variants§

§

Close

Close connection after response.

+
§

KeepAlive

Keep connection alive after response.

+
§

Upgrade

Connection is upgraded to different type.

+

Trait Implementations§

source§

impl Clone for ConnectionType

source§

fn clone(&self) -> ConnectionType

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ConnectionType

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl PartialEq for ConnectionType

source§

fn eq(&self, other: &ConnectionType) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for ConnectionType

source§

impl Eq for ConnectionType

source§

impl StructuralPartialEq for ConnectionType

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/enum.KeepAlive.html b/actix_web/http/enum.KeepAlive.html new file mode 100644 index 000000000..4b1b32f44 --- /dev/null +++ b/actix_web/http/enum.KeepAlive.html @@ -0,0 +1,35 @@ +KeepAlive in actix_web::http - Rust

Enum actix_web::http::KeepAlive

source ·
pub enum KeepAlive {
+    Timeout(Duration),
+    Os,
+    Disabled,
+}
Expand description

Connection keep-alive config.

+

Variants§

§

Timeout(Duration)

Keep-alive duration.

+

KeepAlive::Timeout(Duration::ZERO) is mapped to KeepAlive::Disabled.

+
§

Os

Rely on OS to shutdown TCP connection.

+

Some defaults can be very long, check your OS documentation.

+
§

Disabled

Keep-alive is disabled.

+

Connections will be closed immediately.

+

Trait Implementations§

source§

impl Clone for KeepAlive

source§

fn clone(&self) -> KeepAlive

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for KeepAlive

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for KeepAlive

source§

fn default() -> KeepAlive

Returns the “default value” for a type. Read more
source§

impl From<Duration> for KeepAlive

source§

fn from(dur: Duration) -> KeepAlive

Converts to this type from the input type.
source§

impl From<Option<Duration>> for KeepAlive

source§

fn from(ka_dur: Option<Duration>) -> KeepAlive

Converts to this type from the input type.
source§

impl PartialEq for KeepAlive

source§

fn eq(&self, other: &KeepAlive) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for KeepAlive

source§

impl Eq for KeepAlive

source§

impl StructuralPartialEq for KeepAlive

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/accept/struct.Accept.html b/actix_web/http/header/accept/struct.Accept.html new file mode 100644 index 000000000..4155f4222 --- /dev/null +++ b/actix_web/http/header/accept/struct.Accept.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.Accept.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/accept_charset/struct.AcceptCharset.html b/actix_web/http/header/accept_charset/struct.AcceptCharset.html new file mode 100644 index 000000000..9e4edc7cf --- /dev/null +++ b/actix_web/http/header/accept_charset/struct.AcceptCharset.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.AcceptCharset.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/accept_encoding/struct.AcceptEncoding.html b/actix_web/http/header/accept_encoding/struct.AcceptEncoding.html new file mode 100644 index 000000000..57c1b410e --- /dev/null +++ b/actix_web/http/header/accept_encoding/struct.AcceptEncoding.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.AcceptEncoding.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/accept_language/struct.AcceptLanguage.html b/actix_web/http/header/accept_language/struct.AcceptLanguage.html new file mode 100644 index 000000000..c4cf7550b --- /dev/null +++ b/actix_web/http/header/accept_language/struct.AcceptLanguage.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.AcceptLanguage.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/allow/struct.Allow.html b/actix_web/http/header/allow/struct.Allow.html new file mode 100644 index 000000000..dcfab3a83 --- /dev/null +++ b/actix_web/http/header/allow/struct.Allow.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.Allow.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/cache_control/enum.CacheDirective.html b/actix_web/http/header/cache_control/enum.CacheDirective.html new file mode 100644 index 000000000..92ec87b69 --- /dev/null +++ b/actix_web/http/header/cache_control/enum.CacheDirective.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/enum.CacheDirective.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/cache_control/struct.CacheControl.html b/actix_web/http/header/cache_control/struct.CacheControl.html new file mode 100644 index 000000000..6ff42c8df --- /dev/null +++ b/actix_web/http/header/cache_control/struct.CacheControl.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.CacheControl.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/constant.ACCEPT.html b/actix_web/http/header/constant.ACCEPT.html new file mode 100644 index 000000000..f3f7ecedf --- /dev/null +++ b/actix_web/http/header/constant.ACCEPT.html @@ -0,0 +1,10 @@ +ACCEPT in actix_web::http::header - Rust

Constant actix_web::http::header::ACCEPT

source ·
pub const ACCEPT: HeaderName;
Expand description

Advertises which content types the client is able to understand.

+

The Accept request HTTP header advertises which content types, expressed +as MIME types, the client is able to understand. Using content +negotiation, the server then selects one of the proposals, uses it and +informs the client of its choice with the Content-Type response header. +Browsers set adequate values for this header depending of the context +where the request is done: when fetching a CSS stylesheet a different +value is set for the request than when fetching an image, video or a +script.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.ACCEPT_CHARSET.html b/actix_web/http/header/constant.ACCEPT_CHARSET.html new file mode 100644 index 000000000..6efbde45f --- /dev/null +++ b/actix_web/http/header/constant.ACCEPT_CHARSET.html @@ -0,0 +1,12 @@ +ACCEPT_CHARSET in actix_web::http::header - Rust

Constant actix_web::http::header::ACCEPT_CHARSET

source ·
pub const ACCEPT_CHARSET: HeaderName;
Expand description

Advertises which character set the client is able to understand.

+

The Accept-Charset request HTTP header advertises which character set +the client is able to understand. Using content negotiation, the server +then selects one of the proposals, uses it and informs the client of its +choice within the Content-Type response header. Browsers usually don’t +set this header as the default value for each content type is usually +correct and transmitting it would allow easier fingerprinting.

+

If the server cannot serve any matching character set, it can +theoretically send back a 406 (Not Acceptable) error code. But, for a +better user experience, this is rarely done and the more common way is +to ignore the Accept-Charset header in this case.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.ACCEPT_ENCODING.html b/actix_web/http/header/constant.ACCEPT_ENCODING.html new file mode 100644 index 000000000..22ea2789b --- /dev/null +++ b/actix_web/http/header/constant.ACCEPT_ENCODING.html @@ -0,0 +1,28 @@ +ACCEPT_ENCODING in actix_web::http::header - Rust

Constant actix_web::http::header::ACCEPT_ENCODING

source ·
pub const ACCEPT_ENCODING: HeaderName;
Expand description

Advertises which content encoding the client is able to understand.

+

The Accept-Encoding request HTTP header advertises which content +encoding, usually a compression algorithm, the client is able to +understand. Using content negotiation, the server selects one of the +proposals, uses it and informs the client of its choice with the +Content-Encoding response header.

+

Even if both the client and the server supports the same compression +algorithms, the server may choose not to compress the body of a +response, if the identity value is also acceptable. Two common cases +lead to this:

+
    +
  • +

    The data to be sent is already compressed and a second compression +won’t lead to smaller data to be transmitted. This may the case with +some image formats;

    +
  • +
  • +

    The server is overloaded and cannot afford the computational overhead +induced by the compression requirement. Typically, Microsoft recommends +not to compress if a server use more than 80 % of its computational +power.

    +
  • +
+

As long as the identity value, meaning no encryption, is not explicitly +forbidden, by an identity;q=0 or a *;q=0 without another explicitly set +value for identity, the server must never send back a 406 Not Acceptable +error.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.ACCEPT_LANGUAGE.html b/actix_web/http/header/constant.ACCEPT_LANGUAGE.html new file mode 100644 index 000000000..5e5f7817c --- /dev/null +++ b/actix_web/http/header/constant.ACCEPT_LANGUAGE.html @@ -0,0 +1,21 @@ +ACCEPT_LANGUAGE in actix_web::http::header - Rust

Constant actix_web::http::header::ACCEPT_LANGUAGE

source ·
pub const ACCEPT_LANGUAGE: HeaderName;
Expand description

Advertises which languages the client is able to understand.

+

The Accept-Language request HTTP header advertises which languages the +client is able to understand, and which locale variant is preferred. +Using content negotiation, the server then selects one of the proposals, +uses it and informs the client of its choice with the Content-Language +response header. Browsers set adequate values for this header according +their user interface language and even if a user can change it, this +happens rarely (and is frown upon as it leads to fingerprinting).

+

This header is a hint to be used when the server has no way of +determining the language via another way, like a specific URL, that is +controlled by an explicit user decision. It is recommended that the +server never overrides an explicit decision. The content of the +Accept-Language is often out of the control of the user (like when +traveling and using an Internet Cafe in a different country); the user +may also want to visit a page in another language than the locale of +their user interface.

+

If the server cannot serve any matching language, it can theoretically +send back a 406 (Not Acceptable) error code. But, for a better user +experience, this is rarely done and more common way is to ignore the +Accept-Language header in this case.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.ACCEPT_RANGES.html b/actix_web/http/header/constant.ACCEPT_RANGES.html new file mode 100644 index 000000000..846f2be1f --- /dev/null +++ b/actix_web/http/header/constant.ACCEPT_RANGES.html @@ -0,0 +1,7 @@ +ACCEPT_RANGES in actix_web::http::header - Rust

Constant actix_web::http::header::ACCEPT_RANGES

source ·
pub const ACCEPT_RANGES: HeaderName;
Expand description

Marker used by the server to advertise partial request support.

+

The Accept-Ranges response HTTP header is a marker used by the server to +advertise its support of partial requests. The value of this field +indicates the unit that can be used to define a range.

+

In presence of an Accept-Ranges header, the browser may try to resume an +interrupted download, rather than to start it from the start again.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.ACCESS_CONTROL_ALLOW_CREDENTIALS.html b/actix_web/http/header/constant.ACCESS_CONTROL_ALLOW_CREDENTIALS.html new file mode 100644 index 000000000..790f3fcad --- /dev/null +++ b/actix_web/http/header/constant.ACCESS_CONTROL_ALLOW_CREDENTIALS.html @@ -0,0 +1,20 @@ +ACCESS_CONTROL_ALLOW_CREDENTIALS in actix_web::http::header - Rust

Constant actix_web::http::header::ACCESS_CONTROL_ALLOW_CREDENTIALS

source ·
pub const ACCESS_CONTROL_ALLOW_CREDENTIALS: HeaderName;
Expand description

Preflight response indicating if the response to the request can be +exposed to the page.

+

The Access-Control-Allow-Credentials response header indicates whether +or not the response to the request can be exposed to the page. It can be +exposed when the true value is returned; it can’t in other cases.

+

Credentials are cookies, authorization headers or TLS client +certificates.

+

When used as part of a response to a preflight request, this indicates +whether or not the actual request can be made using credentials. Note +that simple GET requests are not preflighted, and so if a request is +made for a resource with credentials, if this header is not returned +with the resource, the response is ignored by the browser and not +returned to web content.

+

The Access-Control-Allow-Credentials header works in conjunction with +the XMLHttpRequest.withCredentials property or with the credentials +option in the Request() constructor of the Fetch API. Credentials must +be set on both sides (the Access-Control-Allow-Credentials header and in +the XHR or Fetch request) in order for the CORS request with credentials +to succeed.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.ACCESS_CONTROL_ALLOW_HEADERS.html b/actix_web/http/header/constant.ACCESS_CONTROL_ALLOW_HEADERS.html new file mode 100644 index 000000000..b1b344b7b --- /dev/null +++ b/actix_web/http/header/constant.ACCESS_CONTROL_ALLOW_HEADERS.html @@ -0,0 +1,12 @@ +ACCESS_CONTROL_ALLOW_HEADERS in actix_web::http::header - Rust

Constant actix_web::http::header::ACCESS_CONTROL_ALLOW_HEADERS

source ·
pub const ACCESS_CONTROL_ALLOW_HEADERS: HeaderName;
Expand description

Preflight response indicating permitted HTTP headers.

+

The Access-Control-Allow-Headers response header is used in response to +a preflight request to indicate which HTTP headers will be available via +Access-Control-Expose-Headers when making the actual request.

+

The simple headers, Accept, Accept-Language, Content-Language, +Content-Type (but only with a MIME type of its parsed value (ignoring +parameters) of either application/x-www-form-urlencoded, +multipart/form-data, or text/plain), are always available and don’t need +to be listed by this header.

+

This header is required if the request has an +Access-Control-Request-Headers header.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.ACCESS_CONTROL_ALLOW_METHODS.html b/actix_web/http/header/constant.ACCESS_CONTROL_ALLOW_METHODS.html new file mode 100644 index 000000000..b4a32cf46 --- /dev/null +++ b/actix_web/http/header/constant.ACCESS_CONTROL_ALLOW_METHODS.html @@ -0,0 +1,5 @@ +ACCESS_CONTROL_ALLOW_METHODS in actix_web::http::header - Rust

Constant actix_web::http::header::ACCESS_CONTROL_ALLOW_METHODS

source ·
pub const ACCESS_CONTROL_ALLOW_METHODS: HeaderName;
Expand description

Preflight header response indicating permitted access methods.

+

The Access-Control-Allow-Methods response header specifies the method or +methods allowed when accessing the resource in response to a preflight +request.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.ACCESS_CONTROL_ALLOW_ORIGIN.html b/actix_web/http/header/constant.ACCESS_CONTROL_ALLOW_ORIGIN.html new file mode 100644 index 000000000..a3342b73d --- /dev/null +++ b/actix_web/http/header/constant.ACCESS_CONTROL_ALLOW_ORIGIN.html @@ -0,0 +1,3 @@ +ACCESS_CONTROL_ALLOW_ORIGIN in actix_web::http::header - Rust

Constant actix_web::http::header::ACCESS_CONTROL_ALLOW_ORIGIN

source ·
pub const ACCESS_CONTROL_ALLOW_ORIGIN: HeaderName;
Expand description

Indicates whether the response can be shared with resources with the +given origin.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.ACCESS_CONTROL_EXPOSE_HEADERS.html b/actix_web/http/header/constant.ACCESS_CONTROL_EXPOSE_HEADERS.html new file mode 100644 index 000000000..41bd8d44e --- /dev/null +++ b/actix_web/http/header/constant.ACCESS_CONTROL_EXPOSE_HEADERS.html @@ -0,0 +1,3 @@ +ACCESS_CONTROL_EXPOSE_HEADERS in actix_web::http::header - Rust

Constant actix_web::http::header::ACCESS_CONTROL_EXPOSE_HEADERS

source ·
pub const ACCESS_CONTROL_EXPOSE_HEADERS: HeaderName;
Expand description

Indicates which headers can be exposed as part of the response by +listing their names.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.ACCESS_CONTROL_MAX_AGE.html b/actix_web/http/header/constant.ACCESS_CONTROL_MAX_AGE.html new file mode 100644 index 000000000..8179b53f6 --- /dev/null +++ b/actix_web/http/header/constant.ACCESS_CONTROL_MAX_AGE.html @@ -0,0 +1,2 @@ +ACCESS_CONTROL_MAX_AGE in actix_web::http::header - Rust

Constant actix_web::http::header::ACCESS_CONTROL_MAX_AGE

source ·
pub const ACCESS_CONTROL_MAX_AGE: HeaderName;
Expand description

Indicates how long the results of a preflight request can be cached.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.ACCESS_CONTROL_REQUEST_HEADERS.html b/actix_web/http/header/constant.ACCESS_CONTROL_REQUEST_HEADERS.html new file mode 100644 index 000000000..1e1ba3835 --- /dev/null +++ b/actix_web/http/header/constant.ACCESS_CONTROL_REQUEST_HEADERS.html @@ -0,0 +1,3 @@ +ACCESS_CONTROL_REQUEST_HEADERS in actix_web::http::header - Rust

Constant actix_web::http::header::ACCESS_CONTROL_REQUEST_HEADERS

source ·
pub const ACCESS_CONTROL_REQUEST_HEADERS: HeaderName;
Expand description

Informs the server which HTTP headers will be used when an actual +request is made.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.ACCESS_CONTROL_REQUEST_METHOD.html b/actix_web/http/header/constant.ACCESS_CONTROL_REQUEST_METHOD.html new file mode 100644 index 000000000..cf4b335e8 --- /dev/null +++ b/actix_web/http/header/constant.ACCESS_CONTROL_REQUEST_METHOD.html @@ -0,0 +1,3 @@ +ACCESS_CONTROL_REQUEST_METHOD in actix_web::http::header - Rust

Constant actix_web::http::header::ACCESS_CONTROL_REQUEST_METHOD

source ·
pub const ACCESS_CONTROL_REQUEST_METHOD: HeaderName;
Expand description

Informs the server know which HTTP method will be used when the actual +request is made.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.AGE.html b/actix_web/http/header/constant.AGE.html new file mode 100644 index 000000000..5c62747b5 --- /dev/null +++ b/actix_web/http/header/constant.AGE.html @@ -0,0 +1,6 @@ +AGE in actix_web::http::header - Rust

Constant actix_web::http::header::AGE

source ·
pub const AGE: HeaderName;
Expand description

Indicates the time in seconds the object has been in a proxy cache.

+

The Age header is usually close to zero. If it is Age: 0, it was +probably just fetched from the origin server; otherwise It is usually +calculated as a difference between the proxy’s current date and the Date +general header included in the HTTP response.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.ALLOW.html b/actix_web/http/header/constant.ALLOW.html new file mode 100644 index 000000000..3afac93ec --- /dev/null +++ b/actix_web/http/header/constant.ALLOW.html @@ -0,0 +1,7 @@ +ALLOW in actix_web::http::header - Rust

Constant actix_web::http::header::ALLOW

source ·
pub const ALLOW: HeaderName;
Expand description

Lists the set of methods support by a resource.

+

This header must be sent if the server responds with a 405 Method Not +Allowed status code to indicate which request methods can be used. An +empty Allow header indicates that the resource allows no request +methods, which might occur temporarily for a given resource, for +example.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.ALT_SVC.html b/actix_web/http/header/constant.ALT_SVC.html new file mode 100644 index 000000000..6f170a7cd --- /dev/null +++ b/actix_web/http/header/constant.ALT_SVC.html @@ -0,0 +1,2 @@ +ALT_SVC in actix_web::http::header - Rust

Constant actix_web::http::header::ALT_SVC

source ·
pub const ALT_SVC: HeaderName;
Expand description

Advertises the availability of alternate services to clients.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.AUTHORIZATION.html b/actix_web/http/header/constant.AUTHORIZATION.html new file mode 100644 index 000000000..1597673e6 --- /dev/null +++ b/actix_web/http/header/constant.AUTHORIZATION.html @@ -0,0 +1,4 @@ +AUTHORIZATION in actix_web::http::header - Rust

Constant actix_web::http::header::AUTHORIZATION

source ·
pub const AUTHORIZATION: HeaderName;
Expand description

Contains the credentials to authenticate a user agent with a server.

+

Usually this header is included after the server has responded with a +401 Unauthorized status and the WWW-Authenticate header.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.CACHE_CONTROL.html b/actix_web/http/header/constant.CACHE_CONTROL.html new file mode 100644 index 000000000..4f0062192 --- /dev/null +++ b/actix_web/http/header/constant.CACHE_CONTROL.html @@ -0,0 +1,6 @@ +CACHE_CONTROL in actix_web::http::header - Rust

Constant actix_web::http::header::CACHE_CONTROL

source ·
pub const CACHE_CONTROL: HeaderName;
Expand description

Specifies directives for caching mechanisms in both requests and +responses.

+

Caching directives are unidirectional, meaning that a given directive in +a request is not implying that the same directive is to be given in the +response.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.CACHE_STATUS.html b/actix_web/http/header/constant.CACHE_STATUS.html new file mode 100644 index 000000000..ac76c4fab --- /dev/null +++ b/actix_web/http/header/constant.CACHE_STATUS.html @@ -0,0 +1,4 @@ +CACHE_STATUS in actix_web::http::header - Rust

Constant actix_web::http::header::CACHE_STATUS

source ·
pub const CACHE_STATUS: HeaderName;
Expand description

Response header field that indicates how caches have handled that response and its corresponding +request.

+

See RFC 9211 for full semantics.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.CDN_CACHE_CONTROL.html b/actix_web/http/header/constant.CDN_CACHE_CONTROL.html new file mode 100644 index 000000000..0db83ead3 --- /dev/null +++ b/actix_web/http/header/constant.CDN_CACHE_CONTROL.html @@ -0,0 +1,4 @@ +CDN_CACHE_CONTROL in actix_web::http::header - Rust

Constant actix_web::http::header::CDN_CACHE_CONTROL

source ·
pub const CDN_CACHE_CONTROL: HeaderName;
Expand description

Response header field that allows origin servers to control the behavior of CDN caches +interposed between them and clients separately from other caches that might handle the response.

+

See RFC 9213 for full semantics.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.CONNECTION.html b/actix_web/http/header/constant.CONNECTION.html new file mode 100644 index 000000000..365841b97 --- /dev/null +++ b/actix_web/http/header/constant.CONNECTION.html @@ -0,0 +1,12 @@ +CONNECTION in actix_web::http::header - Rust

Constant actix_web::http::header::CONNECTION

source ·
pub const CONNECTION: HeaderName;
Expand description

Controls whether or not the network connection stays open after the +current transaction finishes.

+

If the value sent is keep-alive, the connection is persistent and not +closed, allowing for subsequent requests to the same server to be done.

+

Except for the standard hop-by-hop headers (Keep-Alive, +Transfer-Encoding, TE, Connection, Trailer, Upgrade, Proxy-Authorization +and Proxy-Authenticate), any hop-by-hop headers used by the message must +be listed in the Connection header, so that the first proxy knows he has +to consume them and not to forward them further. Standard hop-by-hop +headers can be listed too (it is often the case of Keep-Alive, but this +is not mandatory.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.CONTENT_DISPOSITION.html b/actix_web/http/header/constant.CONTENT_DISPOSITION.html new file mode 100644 index 000000000..5b1b9447c --- /dev/null +++ b/actix_web/http/header/constant.CONTENT_DISPOSITION.html @@ -0,0 +1,16 @@ +CONTENT_DISPOSITION in actix_web::http::header - Rust

Constant actix_web::http::header::CONTENT_DISPOSITION

source ·
pub const CONTENT_DISPOSITION: HeaderName;
Expand description

Indicates if the content is expected to be displayed inline.

+

In a regular HTTP response, the Content-Disposition response header is a +header indicating if the content is expected to be displayed inline in +the browser, that is, as a Web page or as part of a Web page, or as an +attachment, that is downloaded and saved locally.

+

In a multipart/form-data body, the HTTP Content-Disposition general +header is a header that can be used on the subpart of a multipart body +to give information about the field it applies to. The subpart is +delimited by the boundary defined in the Content-Type header. Used on +the body itself, Content-Disposition has no effect.

+

The Content-Disposition header is defined in the larger context of MIME +messages for e-mail, but only a subset of the possible parameters apply +to HTTP forms and POST requests. Only the value form-data, as well as +the optional directive name and filename, can be used in the HTTP +context.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.CONTENT_ENCODING.html b/actix_web/http/header/constant.CONTENT_ENCODING.html new file mode 100644 index 000000000..c16edb0c1 --- /dev/null +++ b/actix_web/http/header/constant.CONTENT_ENCODING.html @@ -0,0 +1,9 @@ +CONTENT_ENCODING in actix_web::http::header - Rust

Constant actix_web::http::header::CONTENT_ENCODING

source ·
pub const CONTENT_ENCODING: HeaderName;
Expand description

Used to compress the media-type.

+

When present, its value indicates what additional content encoding has +been applied to the entity-body. It lets the client know, how to decode +in order to obtain the media-type referenced by the Content-Type header.

+

It is recommended to compress data as much as possible and therefore to +use this field, but some types of resources, like jpeg images, are +already compressed. Sometimes using additional compression doesn’t +reduce payload size and can even make the payload longer.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.CONTENT_LANGUAGE.html b/actix_web/http/header/constant.CONTENT_LANGUAGE.html new file mode 100644 index 000000000..6ce5eb672 --- /dev/null +++ b/actix_web/http/header/constant.CONTENT_LANGUAGE.html @@ -0,0 +1,12 @@ +CONTENT_LANGUAGE in actix_web::http::header - Rust

Constant actix_web::http::header::CONTENT_LANGUAGE

source ·
pub const CONTENT_LANGUAGE: HeaderName;
Expand description

Used to describe the languages intended for the audience.

+

This header allows a user to differentiate according to the users’ own +preferred language. For example, if “Content-Language: de-DE” is set, it +says that the document is intended for German language speakers +(however, it doesn’t indicate the document is written in German. For +example, it might be written in English as part of a language course for +German speakers).

+

If no Content-Language is specified, the default is that the content is +intended for all language audiences. Multiple language tags are also +possible, as well as applying the Content-Language header to various +media types and not only to textual documents.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.CONTENT_LENGTH.html b/actix_web/http/header/constant.CONTENT_LENGTH.html new file mode 100644 index 000000000..e89216ea9 --- /dev/null +++ b/actix_web/http/header/constant.CONTENT_LENGTH.html @@ -0,0 +1,4 @@ +CONTENT_LENGTH in actix_web::http::header - Rust

Constant actix_web::http::header::CONTENT_LENGTH

source ·
pub const CONTENT_LENGTH: HeaderName;
Expand description

Indicates the size of the entity-body.

+

The header value must be a decimal indicating the number of octets sent +to the recipient.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.CONTENT_LOCATION.html b/actix_web/http/header/constant.CONTENT_LOCATION.html new file mode 100644 index 000000000..4c6ed258b --- /dev/null +++ b/actix_web/http/header/constant.CONTENT_LOCATION.html @@ -0,0 +1,10 @@ +CONTENT_LOCATION in actix_web::http::header - Rust

Constant actix_web::http::header::CONTENT_LOCATION

source ·
pub const CONTENT_LOCATION: HeaderName;
Expand description

Indicates an alternate location for the returned data.

+

The principal use case is to indicate the URL of the resource +transmitted as the result of content negotiation.

+

Location and Content-Location are different: Location indicates the +target of a redirection (or the URL of a newly created document), while +Content-Location indicates the direct URL to use to access the resource, +without the need of further content negotiation. Location is a header +associated with the response, while Content-Location is associated with +the entity returned.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.CONTENT_RANGE.html b/actix_web/http/header/constant.CONTENT_RANGE.html new file mode 100644 index 000000000..03aaa3d8d --- /dev/null +++ b/actix_web/http/header/constant.CONTENT_RANGE.html @@ -0,0 +1,2 @@ +CONTENT_RANGE in actix_web::http::header - Rust

Constant actix_web::http::header::CONTENT_RANGE

source ·
pub const CONTENT_RANGE: HeaderName;
Expand description

Indicates where in a full body message a partial message belongs.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.CONTENT_SECURITY_POLICY.html b/actix_web/http/header/constant.CONTENT_SECURITY_POLICY.html new file mode 100644 index 000000000..dff686bd4 --- /dev/null +++ b/actix_web/http/header/constant.CONTENT_SECURITY_POLICY.html @@ -0,0 +1,6 @@ +CONTENT_SECURITY_POLICY in actix_web::http::header - Rust

Constant actix_web::http::header::CONTENT_SECURITY_POLICY

source ·
pub const CONTENT_SECURITY_POLICY: HeaderName;
Expand description

Allows controlling resources the user agent is allowed to load for a +given page.

+

With a few exceptions, policies mostly involve specifying server origins +and script endpoints. This helps guard against cross-site scripting +attacks (XSS).

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.CONTENT_SECURITY_POLICY_REPORT_ONLY.html b/actix_web/http/header/constant.CONTENT_SECURITY_POLICY_REPORT_ONLY.html new file mode 100644 index 000000000..5ff0a29b6 --- /dev/null +++ b/actix_web/http/header/constant.CONTENT_SECURITY_POLICY_REPORT_ONLY.html @@ -0,0 +1,6 @@ +CONTENT_SECURITY_POLICY_REPORT_ONLY in actix_web::http::header - Rust
pub const CONTENT_SECURITY_POLICY_REPORT_ONLY: HeaderName;
Expand description

Allows experimenting with policies by monitoring their effects.

+

The HTTP Content-Security-Policy-Report-Only response header allows web +developers to experiment with policies by monitoring (but not enforcing) +their effects. These violation reports consist of JSON documents sent +via an HTTP POST request to the specified URI.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.CONTENT_TYPE.html b/actix_web/http/header/constant.CONTENT_TYPE.html new file mode 100644 index 000000000..4ed133f48 --- /dev/null +++ b/actix_web/http/header/constant.CONTENT_TYPE.html @@ -0,0 +1,9 @@ +CONTENT_TYPE in actix_web::http::header - Rust

Constant actix_web::http::header::CONTENT_TYPE

source ·
pub const CONTENT_TYPE: HeaderName;
Expand description

Used to indicate the media type of the resource.

+

In responses, a Content-Type header tells the client what the content +type of the returned content actually is. Browsers will do MIME sniffing +in some cases and will not necessarily follow the value of this header; +to prevent this behavior, the header X-Content-Type-Options can be set +to nosniff.

+

In requests, (such as POST or PUT), the client tells the server what +type of data is actually sent.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.COOKIE.html b/actix_web/http/header/constant.COOKIE.html new file mode 100644 index 000000000..593221805 --- /dev/null +++ b/actix_web/http/header/constant.COOKIE.html @@ -0,0 +1,5 @@ +COOKIE in actix_web::http::header - Rust

Constant actix_web::http::header::COOKIE

source ·
pub const COOKIE: HeaderName;
Expand description

Contains stored HTTP cookies previously sent by the server with the +Set-Cookie header.

+

The Cookie header might be omitted entirely, if the privacy setting of +the browser are set to block them, for example.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.CROSS_ORIGIN_EMBEDDER_POLICY.html b/actix_web/http/header/constant.CROSS_ORIGIN_EMBEDDER_POLICY.html new file mode 100644 index 000000000..a3dc8bdc0 --- /dev/null +++ b/actix_web/http/header/constant.CROSS_ORIGIN_EMBEDDER_POLICY.html @@ -0,0 +1,3 @@ +CROSS_ORIGIN_EMBEDDER_POLICY in actix_web::http::header - Rust

Constant actix_web::http::header::CROSS_ORIGIN_EMBEDDER_POLICY

source ·
pub const CROSS_ORIGIN_EMBEDDER_POLICY: HeaderName;
Expand description

Response header that prevents a document from loading any cross-origin resources that don’t +explicitly grant the document permission (using CORP or CORS).

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.CROSS_ORIGIN_OPENER_POLICY.html b/actix_web/http/header/constant.CROSS_ORIGIN_OPENER_POLICY.html new file mode 100644 index 000000000..1fa54d7c1 --- /dev/null +++ b/actix_web/http/header/constant.CROSS_ORIGIN_OPENER_POLICY.html @@ -0,0 +1,3 @@ +CROSS_ORIGIN_OPENER_POLICY in actix_web::http::header - Rust

Constant actix_web::http::header::CROSS_ORIGIN_OPENER_POLICY

source ·
pub const CROSS_ORIGIN_OPENER_POLICY: HeaderName;
Expand description

Response header that allows you to ensure a top-level document does not share a browsing context +group with cross-origin documents.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.CROSS_ORIGIN_RESOURCE_POLICY.html b/actix_web/http/header/constant.CROSS_ORIGIN_RESOURCE_POLICY.html new file mode 100644 index 000000000..feee61fc9 --- /dev/null +++ b/actix_web/http/header/constant.CROSS_ORIGIN_RESOURCE_POLICY.html @@ -0,0 +1,3 @@ +CROSS_ORIGIN_RESOURCE_POLICY in actix_web::http::header - Rust

Constant actix_web::http::header::CROSS_ORIGIN_RESOURCE_POLICY

source ·
pub const CROSS_ORIGIN_RESOURCE_POLICY: HeaderName;
Expand description

Response header that conveys a desire that the browser blocks no-cors cross-origin/cross-site +requests to the given resource.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.DATE.html b/actix_web/http/header/constant.DATE.html new file mode 100644 index 000000000..dd79a5e96 --- /dev/null +++ b/actix_web/http/header/constant.DATE.html @@ -0,0 +1,2 @@ +DATE in actix_web::http::header - Rust

Constant actix_web::http::header::DATE

source ·
pub const DATE: HeaderName;
Expand description

Contains the date and time at which the message was originated.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.DNT.html b/actix_web/http/header/constant.DNT.html new file mode 100644 index 000000000..3bc45604b --- /dev/null +++ b/actix_web/http/header/constant.DNT.html @@ -0,0 +1,4 @@ +DNT in actix_web::http::header - Rust

Constant actix_web::http::header::DNT

source ·
pub const DNT: HeaderName;
Expand description

Indicates the client’s tracking preference.

+

This header lets users indicate whether they would prefer privacy rather +than personalized content.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.ETAG.html b/actix_web/http/header/constant.ETAG.html new file mode 100644 index 000000000..f14927cac --- /dev/null +++ b/actix_web/http/header/constant.ETAG.html @@ -0,0 +1,13 @@ +ETAG in actix_web::http::header - Rust

Constant actix_web::http::header::ETAG

source ·
pub const ETAG: HeaderName;
Expand description

Identifier for a specific version of a resource.

+

This header allows caches to be more efficient, and saves bandwidth, as +a web server does not need to send a full response if the content has +not changed. On the other side, if the content has changed, etags are +useful to help prevent simultaneous updates of a resource from +overwriting each other (“mid-air collisions”).

+

If the resource at a given URL changes, a new Etag value must be +generated. Etags are therefore similar to fingerprints and might also be +used for tracking purposes by some servers. A comparison of them allows +to quickly determine whether two representations of a resource are the +same, but they might also be set to persist indefinitely by a tracking +server.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.EXPECT.html b/actix_web/http/header/constant.EXPECT.html new file mode 100644 index 000000000..ec19eff60 --- /dev/null +++ b/actix_web/http/header/constant.EXPECT.html @@ -0,0 +1,19 @@ +EXPECT in actix_web::http::header - Rust

Constant actix_web::http::header::EXPECT

source ·
pub const EXPECT: HeaderName;
Expand description

Indicates expectations that need to be fulfilled by the server in order +to properly handle the request.

+

The only expectation defined in the specification is Expect: +100-continue, to which the server shall respond with:

+
    +
  • +

    100 if the information contained in the header is sufficient to cause +an immediate success,

    +
  • +
  • +

    417 (Expectation Failed) if it cannot meet the expectation; or any +other 4xx status otherwise.

    +
  • +
+

For example, the server may reject a request if its Content-Length is +too large.

+

No common browsers send the Expect header, but some other clients such +as cURL do so by default.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.EXPIRES.html b/actix_web/http/header/constant.EXPIRES.html new file mode 100644 index 000000000..6a1f2db3a --- /dev/null +++ b/actix_web/http/header/constant.EXPIRES.html @@ -0,0 +1,6 @@ +EXPIRES in actix_web::http::header - Rust

Constant actix_web::http::header::EXPIRES

source ·
pub const EXPIRES: HeaderName;
Expand description

Contains the date/time after which the response is considered stale.

+

Invalid dates, like the value 0, represent a date in the past and mean +that the resource is already expired.

+

If there is a Cache-Control header with the “max-age” or “s-max-age” +directive in the response, the Expires header is ignored.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.FORWARDED.html b/actix_web/http/header/constant.FORWARDED.html new file mode 100644 index 000000000..2aec7ed38 --- /dev/null +++ b/actix_web/http/header/constant.FORWARDED.html @@ -0,0 +1,9 @@ +FORWARDED in actix_web::http::header - Rust

Constant actix_web::http::header::FORWARDED

source ·
pub const FORWARDED: HeaderName;
Expand description

Contains information from the client-facing side of proxy servers that +is altered or lost when a proxy is involved in the path of the request.

+

The alternative and de-facto standard versions of this header are the +X-Forwarded-For, X-Forwarded-Host and X-Forwarded-Proto headers.

+

This header is used for debugging, statistics, and generating +location-dependent content and by design it exposes privacy sensitive +information, such as the IP address of the client. Therefore the user’s +privacy must be kept in mind when deploying this header.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.FROM.html b/actix_web/http/header/constant.FROM.html new file mode 100644 index 000000000..866da862b --- /dev/null +++ b/actix_web/http/header/constant.FROM.html @@ -0,0 +1,7 @@ +FROM in actix_web::http::header - Rust

Constant actix_web::http::header::FROM

source ·
pub const FROM: HeaderName;
Expand description

Contains an Internet email address for a human user who controls the +requesting user agent.

+

If you are running a robotic user agent (e.g. a crawler), the From +header should be sent, so you can be contacted if problems occur on +servers, such as if the robot is sending excessive, unwanted, or invalid +requests.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.HOST.html b/actix_web/http/header/constant.HOST.html new file mode 100644 index 000000000..d71f54880 --- /dev/null +++ b/actix_web/http/header/constant.HOST.html @@ -0,0 +1,8 @@ +HOST in actix_web::http::header - Rust

Constant actix_web::http::header::HOST

source ·
pub const HOST: HeaderName;
Expand description

Specifies the domain name of the server and (optionally) the TCP port +number on which the server is listening.

+

If no port is given, the default port for the service requested (e.g., +“80” for an HTTP URL) is implied.

+

A Host header field must be sent in all HTTP/1.1 request messages. A 400 +(Bad Request) status code will be sent to any HTTP/1.1 request message +that lacks a Host header field or contains more than one.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.IF_MATCH.html b/actix_web/http/header/constant.IF_MATCH.html new file mode 100644 index 000000000..ea4e36b7f --- /dev/null +++ b/actix_web/http/header/constant.IF_MATCH.html @@ -0,0 +1,25 @@ +IF_MATCH in actix_web::http::header - Rust

Constant actix_web::http::header::IF_MATCH

source ·
pub const IF_MATCH: HeaderName;
Expand description

Makes a request conditional based on the E-Tag.

+

For GET and HEAD methods, the server will send back the requested +resource only if it matches one of the listed ETags. For PUT and other +non-safe methods, it will only upload the resource in this case.

+

The comparison with the stored ETag uses the strong comparison +algorithm, meaning two files are considered identical byte to byte only. +This is weakened when the W/ prefix is used in front of the ETag.

+

There are two common use cases:

+
    +
  • +

    For GET and HEAD methods, used in combination with an Range header, it +can guarantee that the new ranges requested comes from the same resource +than the previous one. If it doesn’t match, then a 416 (Range Not +Satisfiable) response is returned.

    +
  • +
  • +

    For other methods, and in particular for PUT, If-Match can be used to +prevent the lost update problem. It can check if the modification of a +resource that the user wants to upload will not override another change +that has been done since the original resource was fetched. If the +request cannot be fulfilled, the 412 (Precondition Failed) response is +returned.

    +
  • +
+
\ No newline at end of file diff --git a/actix_web/http/header/constant.IF_MODIFIED_SINCE.html b/actix_web/http/header/constant.IF_MODIFIED_SINCE.html new file mode 100644 index 000000000..6351aa988 --- /dev/null +++ b/actix_web/http/header/constant.IF_MODIFIED_SINCE.html @@ -0,0 +1,13 @@ +IF_MODIFIED_SINCE in actix_web::http::header - Rust

Constant actix_web::http::header::IF_MODIFIED_SINCE

source ·
pub const IF_MODIFIED_SINCE: HeaderName;
Expand description

Makes a request conditional based on the modification date.

+

The If-Modified-Since request HTTP header makes the request conditional: +the server will send back the requested resource, with a 200 status, +only if it has been last modified after the given date. If the request +has not been modified since, the response will be a 304 without any +body; the Last-Modified header will contain the date of last +modification. Unlike If-Unmodified-Since, If-Modified-Since can only be +used with a GET or HEAD.

+

When used in combination with If-None-Match, it is ignored, unless the +server doesn’t support If-None-Match.

+

The most common use case is to update a cached entity that has no +associated ETag.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.IF_NONE_MATCH.html b/actix_web/http/header/constant.IF_NONE_MATCH.html new file mode 100644 index 000000000..6133646b4 --- /dev/null +++ b/actix_web/http/header/constant.IF_NONE_MATCH.html @@ -0,0 +1,31 @@ +IF_NONE_MATCH in actix_web::http::header - Rust

Constant actix_web::http::header::IF_NONE_MATCH

source ·
pub const IF_NONE_MATCH: HeaderName;
Expand description

Makes a request conditional based on the E-Tag.

+

The If-None-Match HTTP request header makes the request conditional. For +GET and HEAD methods, the server will send back the requested resource, +with a 200 status, only if it doesn’t have an ETag matching the given +ones. For other methods, the request will be processed only if the +eventually existing resource’s ETag doesn’t match any of the values +listed.

+

When the condition fails for GET and HEAD methods, then the server must +return HTTP status code 304 (Not Modified). For methods that apply +server-side changes, the status code 412 (Precondition Failed) is used. +Note that the server generating a 304 response MUST generate any of the +following header fields that would have been sent in a 200 (OK) response +to the same request: Cache-Control, Content-Location, Date, ETag, +Expires, and Vary.

+

The comparison with the stored ETag uses the weak comparison algorithm, +meaning two files are considered identical not only if they are +identical byte to byte, but if the content is equivalent. For example, +two pages that would differ only by the date of generation in the footer +would be considered as identical.

+

When used in combination with If-Modified-Since, it has precedence (if +the server supports it).

+

There are two common use cases:

+
    +
  • For GET and HEAD methods, to update a cached entity that has an associated ETag.
  • +
  • For other methods, and in particular for PUT, If-None-Match used with +the * value can be used to save a file not known to exist, +guaranteeing that another upload didn’t happen before, losing the data +of the previous put; this problems is the variation of the lost update +problem.
  • +
+
\ No newline at end of file diff --git a/actix_web/http/header/constant.IF_RANGE.html b/actix_web/http/header/constant.IF_RANGE.html new file mode 100644 index 000000000..c0ed533b4 --- /dev/null +++ b/actix_web/http/header/constant.IF_RANGE.html @@ -0,0 +1,12 @@ +IF_RANGE in actix_web::http::header - Rust

Constant actix_web::http::header::IF_RANGE

source ·
pub const IF_RANGE: HeaderName;
Expand description

Makes a request conditional based on range.

+

The If-Range HTTP request header makes a range request conditional: if +the condition is fulfilled, the range request will be issued and the +server sends back a 206 Partial Content answer with the appropriate +body. If the condition is not fulfilled, the full resource is sent back, +with a 200 OK status.

+

This header can be used either with a Last-Modified validator, or with +an ETag, but not with both.

+

The most common use case is to resume a download, to guarantee that the +stored resource has not been modified since the last fragment has been +received.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.IF_UNMODIFIED_SINCE.html b/actix_web/http/header/constant.IF_UNMODIFIED_SINCE.html new file mode 100644 index 000000000..34364d066 --- /dev/null +++ b/actix_web/http/header/constant.IF_UNMODIFIED_SINCE.html @@ -0,0 +1,22 @@ +IF_UNMODIFIED_SINCE in actix_web::http::header - Rust

Constant actix_web::http::header::IF_UNMODIFIED_SINCE

source ·
pub const IF_UNMODIFIED_SINCE: HeaderName;
Expand description

Makes the request conditional based on the last modification date.

+

The If-Unmodified-Since request HTTP header makes the request +conditional: the server will send back the requested resource, or accept +it in the case of a POST or another non-safe method, only if it has not +been last modified after the given date. If the request has been +modified after the given date, the response will be a 412 (Precondition +Failed) error.

+

There are two common use cases:

+
    +
  • +

    In conjunction non-safe methods, like POST, it can be used to +implement an optimistic concurrency control, like done by some wikis: +editions are rejected if the stored document has been modified since the +original has been retrieved.

    +
  • +
  • +

    In conjunction with a range request with a If-Range header, it can be +used to ensure that the new fragment requested comes from an unmodified +document.

    +
  • +
+
\ No newline at end of file diff --git a/actix_web/http/header/constant.LAST_MODIFIED.html b/actix_web/http/header/constant.LAST_MODIFIED.html new file mode 100644 index 000000000..6b9f1df35 --- /dev/null +++ b/actix_web/http/header/constant.LAST_MODIFIED.html @@ -0,0 +1,2 @@ +LAST_MODIFIED in actix_web::http::header - Rust

Constant actix_web::http::header::LAST_MODIFIED

source ·
pub const LAST_MODIFIED: HeaderName;
Expand description

Content-Types that are acceptable for the response.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.LINK.html b/actix_web/http/header/constant.LINK.html new file mode 100644 index 000000000..ee5a5adde --- /dev/null +++ b/actix_web/http/header/constant.LINK.html @@ -0,0 +1,3 @@ +LINK in actix_web::http::header - Rust

Constant actix_web::http::header::LINK

source ·
pub const LINK: HeaderName;
Expand description

Allows the server to point an interested client to another resource +containing metadata about the requested resource.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.LOCATION.html b/actix_web/http/header/constant.LOCATION.html new file mode 100644 index 000000000..01d426202 --- /dev/null +++ b/actix_web/http/header/constant.LOCATION.html @@ -0,0 +1,29 @@ +LOCATION in actix_web::http::header - Rust

Constant actix_web::http::header::LOCATION

source ·
pub const LOCATION: HeaderName;
Expand description

Indicates the URL to redirect a page to.

+

The Location response header indicates the URL to redirect a page to. It +only provides a meaning when served with a 3xx status response.

+

The HTTP method used to make the new request to fetch the page pointed +to by Location depends of the original method and of the kind of +redirection:

+
    +
  • +

    If 303 (See Also) responses always lead to the use of a GET method, +307 (Temporary Redirect) and 308 (Permanent Redirect) don’t change the +method used in the original request;

    +
  • +
  • +

    301 (Permanent Redirect) and 302 (Found) doesn’t change the method +most of the time, though older user-agents may (so you basically don’t +know).

    +
  • +
+

All responses with one of these status codes send a Location header.

+

Beside redirect response, messages with 201 (Created) status also +include the Location header. It indicates the URL to the newly created +resource.

+

Location and Content-Location are different: Location indicates the +target of a redirection (or the URL of a newly created resource), while +Content-Location indicates the direct URL to use to access the resource +when content negotiation happened, without the need of further content +negotiation. Location is a header associated with the response, while +Content-Location is associated with the entity returned.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.MAX_FORWARDS.html b/actix_web/http/header/constant.MAX_FORWARDS.html new file mode 100644 index 000000000..13e6916d6 --- /dev/null +++ b/actix_web/http/header/constant.MAX_FORWARDS.html @@ -0,0 +1,3 @@ +MAX_FORWARDS in actix_web::http::header - Rust

Constant actix_web::http::header::MAX_FORWARDS

source ·
pub const MAX_FORWARDS: HeaderName;
Expand description

Indicates the max number of intermediaries the request should be sent +through.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.ORIGIN.html b/actix_web/http/header/constant.ORIGIN.html new file mode 100644 index 000000000..96b999f55 --- /dev/null +++ b/actix_web/http/header/constant.ORIGIN.html @@ -0,0 +1,6 @@ +ORIGIN in actix_web::http::header - Rust

Constant actix_web::http::header::ORIGIN

source ·
pub const ORIGIN: HeaderName;
Expand description

Indicates where a fetch originates from.

+

It doesn’t include any path information, but only the server name. It is +sent with CORS requests, as well as with POST requests. It is similar to +the Referer header, but, unlike this header, it doesn’t disclose the +whole path.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.PERMISSIONS_POLICY.html b/actix_web/http/header/constant.PERMISSIONS_POLICY.html new file mode 100644 index 000000000..d676c75d2 --- /dev/null +++ b/actix_web/http/header/constant.PERMISSIONS_POLICY.html @@ -0,0 +1,3 @@ +PERMISSIONS_POLICY in actix_web::http::header - Rust

Constant actix_web::http::header::PERMISSIONS_POLICY

source ·
pub const PERMISSIONS_POLICY: HeaderName;
Expand description

Response header that provides a mechanism to allow and deny the use of browser features in a +document or within any <iframe> elements in the document.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.PRAGMA.html b/actix_web/http/header/constant.PRAGMA.html new file mode 100644 index 000000000..2cb7d2139 --- /dev/null +++ b/actix_web/http/header/constant.PRAGMA.html @@ -0,0 +1,6 @@ +PRAGMA in actix_web::http::header - Rust

Constant actix_web::http::header::PRAGMA

source ·
pub const PRAGMA: HeaderName;
Expand description

HTTP/1.0 header usually used for backwards compatibility.

+

The Pragma HTTP/1.0 general header is an implementation-specific header +that may have various effects along the request-response chain. It is +used for backwards compatibility with HTTP/1.0 caches where the +Cache-Control HTTP/1.1 header is not yet present.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.PROXY_AUTHENTICATE.html b/actix_web/http/header/constant.PROXY_AUTHENTICATE.html new file mode 100644 index 000000000..c499c90e7 --- /dev/null +++ b/actix_web/http/header/constant.PROXY_AUTHENTICATE.html @@ -0,0 +1,14 @@ +PROXY_AUTHENTICATE in actix_web::http::header - Rust

Constant actix_web::http::header::PROXY_AUTHENTICATE

source ·
pub const PROXY_AUTHENTICATE: HeaderName;
Expand description

Defines the authentication method that should be used to gain access to +a proxy.

+

Unlike www-authenticate, the proxy-authenticate header field applies +only to the next outbound client on the response chain. This is because +only the client that chose a given proxy is likely to have the +credentials necessary for authentication. However, when multiple proxies +are used within the same administrative domain, such as office and +regional caching proxies within a large corporate network, it is common +for credentials to be generated by the user agent and passed through the +hierarchy until consumed. Hence, in such a configuration, it will appear +as if Proxy-Authenticate is being forwarded because each proxy will send +the same challenge set.

+

The proxy-authenticate header is sent along with a 407 Proxy Authentication Required.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.PROXY_AUTHORIZATION.html b/actix_web/http/header/constant.PROXY_AUTHORIZATION.html new file mode 100644 index 000000000..01ea122ee --- /dev/null +++ b/actix_web/http/header/constant.PROXY_AUTHORIZATION.html @@ -0,0 +1,5 @@ +PROXY_AUTHORIZATION in actix_web::http::header - Rust

Constant actix_web::http::header::PROXY_AUTHORIZATION

source ·
pub const PROXY_AUTHORIZATION: HeaderName;
Expand description

Contains the credentials to authenticate a user agent to a proxy server.

+

This header is usually included after the server has responded with a +407 Proxy Authentication Required status and the Proxy-Authenticate +header.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.PUBLIC_KEY_PINS.html b/actix_web/http/header/constant.PUBLIC_KEY_PINS.html new file mode 100644 index 000000000..5f4631844 --- /dev/null +++ b/actix_web/http/header/constant.PUBLIC_KEY_PINS.html @@ -0,0 +1,6 @@ +PUBLIC_KEY_PINS in actix_web::http::header - Rust

Constant actix_web::http::header::PUBLIC_KEY_PINS

source ·
pub const PUBLIC_KEY_PINS: HeaderName;
Expand description

Associates a specific cryptographic public key with a certain server.

+

This decreases the risk of MITM attacks with forged certificates. If one +or several keys are pinned and none of them are used by the server, the +browser will not accept the response as legitimate, and will not display +it.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.PUBLIC_KEY_PINS_REPORT_ONLY.html b/actix_web/http/header/constant.PUBLIC_KEY_PINS_REPORT_ONLY.html new file mode 100644 index 000000000..57e1ca5e4 --- /dev/null +++ b/actix_web/http/header/constant.PUBLIC_KEY_PINS_REPORT_ONLY.html @@ -0,0 +1,5 @@ +PUBLIC_KEY_PINS_REPORT_ONLY in actix_web::http::header - Rust

Constant actix_web::http::header::PUBLIC_KEY_PINS_REPORT_ONLY

source ·
pub const PUBLIC_KEY_PINS_REPORT_ONLY: HeaderName;
Expand description

Sends reports of pinning violation to the report-uri specified in the +header.

+

Unlike Public-Key-Pins, this header still allows browsers to connect +to the server if the pinning is violated.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.RANGE.html b/actix_web/http/header/constant.RANGE.html new file mode 100644 index 000000000..c7201ea2b --- /dev/null +++ b/actix_web/http/header/constant.RANGE.html @@ -0,0 +1,8 @@ +RANGE in actix_web::http::header - Rust

Constant actix_web::http::header::RANGE

source ·
pub const RANGE: HeaderName;
Expand description

Indicates the part of a document that the server should return.

+

Several parts can be requested with one Range header at once, and the +server may send back these ranges in a multipart document. If the server +sends back ranges, it uses the 206 Partial Content for the response. If +the ranges are invalid, the server returns the 416 Range Not Satisfiable +error. The server can also ignore the Range header and return the whole +document with a 200 status code.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.REFERER.html b/actix_web/http/header/constant.REFERER.html new file mode 100644 index 000000000..52dac0930 --- /dev/null +++ b/actix_web/http/header/constant.REFERER.html @@ -0,0 +1,6 @@ +REFERER in actix_web::http::header - Rust

Constant actix_web::http::header::REFERER

source ·
pub const REFERER: HeaderName;
Expand description

Contains the address of the previous web page from which a link to the +currently requested page was followed.

+

The Referer header allows servers to identify where people are visiting +them from and may use that data for analytics, logging, or optimized +caching, for example.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.REFERRER_POLICY.html b/actix_web/http/header/constant.REFERRER_POLICY.html new file mode 100644 index 000000000..08d650639 --- /dev/null +++ b/actix_web/http/header/constant.REFERRER_POLICY.html @@ -0,0 +1,3 @@ +REFERRER_POLICY in actix_web::http::header - Rust

Constant actix_web::http::header::REFERRER_POLICY

source ·
pub const REFERRER_POLICY: HeaderName;
Expand description

Governs which referrer information should be included with requests +made.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.REFRESH.html b/actix_web/http/header/constant.REFRESH.html new file mode 100644 index 000000000..ab89e8cc3 --- /dev/null +++ b/actix_web/http/header/constant.REFRESH.html @@ -0,0 +1,3 @@ +REFRESH in actix_web::http::header - Rust

Constant actix_web::http::header::REFRESH

source ·
pub const REFRESH: HeaderName;
Expand description

Informs the web browser that the current page or frame should be +refreshed.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.RETRY_AFTER.html b/actix_web/http/header/constant.RETRY_AFTER.html new file mode 100644 index 000000000..9b8da81b1 --- /dev/null +++ b/actix_web/http/header/constant.RETRY_AFTER.html @@ -0,0 +1,15 @@ +RETRY_AFTER in actix_web::http::header - Rust

Constant actix_web::http::header::RETRY_AFTER

source ·
pub const RETRY_AFTER: HeaderName;
Expand description

The Retry-After response HTTP header indicates how long the user agent +should wait before making a follow-up request. There are two main cases +this header is used:

+
    +
  • +

    When sent with a 503 (Service Unavailable) response, it indicates how +long the service is expected to be unavailable.

    +
  • +
  • +

    When sent with a redirect response, such as 301 (Moved Permanently), +it indicates the minimum time that the user agent is asked to wait +before issuing the redirected request.

    +
  • +
+
\ No newline at end of file diff --git a/actix_web/http/header/constant.SEC_WEBSOCKET_ACCEPT.html b/actix_web/http/header/constant.SEC_WEBSOCKET_ACCEPT.html new file mode 100644 index 000000000..32b7eb444 --- /dev/null +++ b/actix_web/http/header/constant.SEC_WEBSOCKET_ACCEPT.html @@ -0,0 +1,5 @@ +SEC_WEBSOCKET_ACCEPT in actix_web::http::header - Rust

Constant actix_web::http::header::SEC_WEBSOCKET_ACCEPT

source ·
pub const SEC_WEBSOCKET_ACCEPT: HeaderName;
Expand description

The |Sec-WebSocket-Accept| header field is used in the WebSocket +opening handshake. It is sent from the server to the client to +confirm that the server is willing to initiate the WebSocket +connection.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.SEC_WEBSOCKET_EXTENSIONS.html b/actix_web/http/header/constant.SEC_WEBSOCKET_EXTENSIONS.html new file mode 100644 index 000000000..5c9c4eacf --- /dev/null +++ b/actix_web/http/header/constant.SEC_WEBSOCKET_EXTENSIONS.html @@ -0,0 +1,6 @@ +SEC_WEBSOCKET_EXTENSIONS in actix_web::http::header - Rust

Constant actix_web::http::header::SEC_WEBSOCKET_EXTENSIONS

source ·
pub const SEC_WEBSOCKET_EXTENSIONS: HeaderName;
Expand description

The |Sec-WebSocket-Extensions| header field is used in the WebSocket +opening handshake. It is initially sent from the client to the +server, and then subsequently sent from the server to the client, to +agree on a set of protocol-level extensions to use for the duration +of the connection.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.SEC_WEBSOCKET_KEY.html b/actix_web/http/header/constant.SEC_WEBSOCKET_KEY.html new file mode 100644 index 000000000..c7f86a1a3 --- /dev/null +++ b/actix_web/http/header/constant.SEC_WEBSOCKET_KEY.html @@ -0,0 +1,8 @@ +SEC_WEBSOCKET_KEY in actix_web::http::header - Rust

Constant actix_web::http::header::SEC_WEBSOCKET_KEY

source ·
pub const SEC_WEBSOCKET_KEY: HeaderName;
Expand description

The |Sec-WebSocket-Key| header field is used in the WebSocket opening +handshake. It is sent from the client to the server to provide part +of the information used by the server to prove that it received a +valid WebSocket opening handshake. This helps ensure that the server +does not accept connections from non-WebSocket clients (e.g., HTTP +clients) that are being abused to send data to unsuspecting WebSocket +servers.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.SEC_WEBSOCKET_PROTOCOL.html b/actix_web/http/header/constant.SEC_WEBSOCKET_PROTOCOL.html new file mode 100644 index 000000000..019b7eb39 --- /dev/null +++ b/actix_web/http/header/constant.SEC_WEBSOCKET_PROTOCOL.html @@ -0,0 +1,6 @@ +SEC_WEBSOCKET_PROTOCOL in actix_web::http::header - Rust

Constant actix_web::http::header::SEC_WEBSOCKET_PROTOCOL

source ·
pub const SEC_WEBSOCKET_PROTOCOL: HeaderName;
Expand description

The |Sec-WebSocket-Protocol| header field is used in the WebSocket +opening handshake. It is sent from the client to the server and back +from the server to the client to confirm the subprotocol of the +connection. This enables scripts to both select a subprotocol and be +sure that the server agreed to serve that subprotocol.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.SEC_WEBSOCKET_VERSION.html b/actix_web/http/header/constant.SEC_WEBSOCKET_VERSION.html new file mode 100644 index 000000000..1faef978d --- /dev/null +++ b/actix_web/http/header/constant.SEC_WEBSOCKET_VERSION.html @@ -0,0 +1,7 @@ +SEC_WEBSOCKET_VERSION in actix_web::http::header - Rust

Constant actix_web::http::header::SEC_WEBSOCKET_VERSION

source ·
pub const SEC_WEBSOCKET_VERSION: HeaderName;
Expand description

The |Sec-WebSocket-Version| header field is used in the WebSocket +opening handshake. It is sent from the client to the server to +indicate the protocol version of the connection. This enables +servers to correctly interpret the opening handshake and subsequent +data being sent from the data, and close the connection if the server +cannot interpret that data in a safe manner.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.SERVER.html b/actix_web/http/header/constant.SERVER.html new file mode 100644 index 000000000..19299bf2e --- /dev/null +++ b/actix_web/http/header/constant.SERVER.html @@ -0,0 +1,7 @@ +SERVER in actix_web::http::header - Rust

Constant actix_web::http::header::SERVER

source ·
pub const SERVER: HeaderName;
Expand description

Contains information about the software used by the origin server to +handle the request.

+

Overly long and detailed Server values should be avoided as they +potentially reveal internal implementation details that might make it +(slightly) easier for attackers to find and exploit known security +holes.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.SET_COOKIE.html b/actix_web/http/header/constant.SET_COOKIE.html new file mode 100644 index 000000000..3d812f318 --- /dev/null +++ b/actix_web/http/header/constant.SET_COOKIE.html @@ -0,0 +1,2 @@ +SET_COOKIE in actix_web::http::header - Rust

Constant actix_web::http::header::SET_COOKIE

source ·
pub const SET_COOKIE: HeaderName;
Expand description

Used to send cookies from the server to the user agent.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.STRICT_TRANSPORT_SECURITY.html b/actix_web/http/header/constant.STRICT_TRANSPORT_SECURITY.html new file mode 100644 index 000000000..b96bfd160 --- /dev/null +++ b/actix_web/http/header/constant.STRICT_TRANSPORT_SECURITY.html @@ -0,0 +1,2 @@ +STRICT_TRANSPORT_SECURITY in actix_web::http::header - Rust

Constant actix_web::http::header::STRICT_TRANSPORT_SECURITY

source ·
pub const STRICT_TRANSPORT_SECURITY: HeaderName;
Expand description

Tells the client to communicate with HTTPS instead of using HTTP.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.TE.html b/actix_web/http/header/constant.TE.html new file mode 100644 index 000000000..6dfda536e --- /dev/null +++ b/actix_web/http/header/constant.TE.html @@ -0,0 +1,8 @@ +TE in actix_web::http::header - Rust

Constant actix_web::http::header::TE

source ·
pub const TE: HeaderName;
Expand description

Informs the server of transfer encodings willing to be accepted as part +of the response.

+

See also the Transfer-Encoding response header for more details on +transfer encodings. Note that chunked is always acceptable for HTTP/1.1 +recipients and you that don’t have to specify “chunked” using the TE +header. However, it is useful for setting if the client is accepting +trailer fields in a chunked transfer coding using the “trailers” value.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.TRAILER.html b/actix_web/http/header/constant.TRAILER.html new file mode 100644 index 000000000..d56137052 --- /dev/null +++ b/actix_web/http/header/constant.TRAILER.html @@ -0,0 +1,3 @@ +TRAILER in actix_web::http::header - Rust

Constant actix_web::http::header::TRAILER

source ·
pub const TRAILER: HeaderName;
Expand description

Allows the sender to include additional fields at the end of chunked +messages.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.TRANSFER_ENCODING.html b/actix_web/http/header/constant.TRANSFER_ENCODING.html new file mode 100644 index 000000000..0d00c933e --- /dev/null +++ b/actix_web/http/header/constant.TRANSFER_ENCODING.html @@ -0,0 +1,11 @@ +TRANSFER_ENCODING in actix_web::http::header - Rust

Constant actix_web::http::header::TRANSFER_ENCODING

source ·
pub const TRANSFER_ENCODING: HeaderName;
Expand description

Specifies the form of encoding used to safely transfer the entity to the +client.

+

transfer-encoding is a hop-by-hop header, that is applying to a +message between two nodes, not to a resource itself. Each segment of a +multi-node connection can use different transfer-encoding values. If +you want to compress data over the whole connection, use the end-to-end +header content-encoding header instead.

+

When present on a response to a HEAD request that has no body, it +indicates the value that would have applied to the corresponding GET +message.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.UPGRADE.html b/actix_web/http/header/constant.UPGRADE.html new file mode 100644 index 000000000..59f203460 --- /dev/null +++ b/actix_web/http/header/constant.UPGRADE.html @@ -0,0 +1,2 @@ +UPGRADE in actix_web::http::header - Rust

Constant actix_web::http::header::UPGRADE

source ·
pub const UPGRADE: HeaderName;
Expand description

Used as part of the exchange to upgrade the protocol.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.UPGRADE_INSECURE_REQUESTS.html b/actix_web/http/header/constant.UPGRADE_INSECURE_REQUESTS.html new file mode 100644 index 000000000..7af55b54b --- /dev/null +++ b/actix_web/http/header/constant.UPGRADE_INSECURE_REQUESTS.html @@ -0,0 +1,3 @@ +UPGRADE_INSECURE_REQUESTS in actix_web::http::header - Rust

Constant actix_web::http::header::UPGRADE_INSECURE_REQUESTS

source ·
pub const UPGRADE_INSECURE_REQUESTS: HeaderName;
Expand description

Sends a signal to the server expressing the client’s preference for an +encrypted and authenticated response.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.USER_AGENT.html b/actix_web/http/header/constant.USER_AGENT.html new file mode 100644 index 000000000..18f0fbfbc --- /dev/null +++ b/actix_web/http/header/constant.USER_AGENT.html @@ -0,0 +1,3 @@ +USER_AGENT in actix_web::http::header - Rust

Constant actix_web::http::header::USER_AGENT

source ·
pub const USER_AGENT: HeaderName;
Expand description

Contains a string that allows identifying the requesting client’s +software.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.VARY.html b/actix_web/http/header/constant.VARY.html new file mode 100644 index 000000000..770d3da07 --- /dev/null +++ b/actix_web/http/header/constant.VARY.html @@ -0,0 +1,9 @@ +VARY in actix_web::http::header - Rust

Constant actix_web::http::header::VARY

source ·
pub const VARY: HeaderName;
Expand description

Determines how to match future requests with cached responses.

+

The vary HTTP response header determines how to match future request +headers to decide whether a cached response can be used rather than +requesting a fresh one from the origin server. It is used by the server +to indicate which headers it used when selecting a representation of a +resource in a content negotiation algorithm.

+

The vary header should be set on a 304 Not Modified response exactly +like it would have been set on an equivalent 200 OK response.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.VIA.html b/actix_web/http/header/constant.VIA.html new file mode 100644 index 000000000..54d8a50a1 --- /dev/null +++ b/actix_web/http/header/constant.VIA.html @@ -0,0 +1,7 @@ +VIA in actix_web::http::header - Rust

Constant actix_web::http::header::VIA

source ·
pub const VIA: HeaderName;
Expand description

Added by proxies to track routing.

+

The via general header is added by proxies, both forward and reverse +proxies, and can appear in the request headers and the response headers. +It is used for tracking message forwards, avoiding request loops, and +identifying the protocol capabilities of senders along the +request/response chain.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.WARNING.html b/actix_web/http/header/constant.WARNING.html new file mode 100644 index 000000000..15cf670ab --- /dev/null +++ b/actix_web/http/header/constant.WARNING.html @@ -0,0 +1,6 @@ +WARNING in actix_web::http::header - Rust

Constant actix_web::http::header::WARNING

source ·
pub const WARNING: HeaderName;
Expand description

General HTTP header contains information about possible problems with +the status of the message.

+

More than one warning header may appear in a response. Warning header +fields can in general be applied to any message, however some warn-codes +are specific to caches and can only be applied to response messages.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.WWW_AUTHENTICATE.html b/actix_web/http/header/constant.WWW_AUTHENTICATE.html new file mode 100644 index 000000000..c4c400da8 --- /dev/null +++ b/actix_web/http/header/constant.WWW_AUTHENTICATE.html @@ -0,0 +1,3 @@ +WWW_AUTHENTICATE in actix_web::http::header - Rust

Constant actix_web::http::header::WWW_AUTHENTICATE

source ·
pub const WWW_AUTHENTICATE: HeaderName;
Expand description

Defines the authentication method that should be used to gain access to +a resource.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.X_CONTENT_TYPE_OPTIONS.html b/actix_web/http/header/constant.X_CONTENT_TYPE_OPTIONS.html new file mode 100644 index 000000000..c386fded2 --- /dev/null +++ b/actix_web/http/header/constant.X_CONTENT_TYPE_OPTIONS.html @@ -0,0 +1,11 @@ +X_CONTENT_TYPE_OPTIONS in actix_web::http::header - Rust

Constant actix_web::http::header::X_CONTENT_TYPE_OPTIONS

source ·
pub const X_CONTENT_TYPE_OPTIONS: HeaderName;
Expand description

Marker used by the server to indicate that the MIME types advertised in +the content-type headers should not be changed and be followed.

+

This allows to opt-out of MIME type sniffing, or, in other words, it is +a way to say that the webmasters knew what they were doing.

+

This header was introduced by Microsoft in IE 8 as a way for webmasters +to block content sniffing that was happening and could transform +non-executable MIME types into executable MIME types. Since then, other +browsers have introduced it, even if their MIME sniffing algorithms were +less aggressive.

+

Site security testers usually expect this header to be set.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.X_DNS_PREFETCH_CONTROL.html b/actix_web/http/header/constant.X_DNS_PREFETCH_CONTROL.html new file mode 100644 index 000000000..19cb70771 --- /dev/null +++ b/actix_web/http/header/constant.X_DNS_PREFETCH_CONTROL.html @@ -0,0 +1,10 @@ +X_DNS_PREFETCH_CONTROL in actix_web::http::header - Rust

Constant actix_web::http::header::X_DNS_PREFETCH_CONTROL

source ·
pub const X_DNS_PREFETCH_CONTROL: HeaderName;
Expand description

Controls DNS prefetching.

+

The x-dns-prefetch-control HTTP response header controls DNS +prefetching, a feature by which browsers proactively perform domain name +resolution on both links that the user may choose to follow as well as +URLs for items referenced by the document, including images, CSS, +JavaScript, and so forth.

+

This prefetching is performed in the background, so that the DNS is +likely to have been resolved by the time the referenced items are +needed. This reduces latency when the user clicks a link.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.X_FORWARDED_FOR.html b/actix_web/http/header/constant.X_FORWARDED_FOR.html new file mode 100644 index 000000000..5c665334b --- /dev/null +++ b/actix_web/http/header/constant.X_FORWARDED_FOR.html @@ -0,0 +1,3 @@ +X_FORWARDED_FOR in actix_web::http::header - Rust

Constant actix_web::http::header::X_FORWARDED_FOR

source ·
pub const X_FORWARDED_FOR: HeaderName;
Expand description

Request header (de-facto standard) for identifying the originating IP address of a client +connecting to a web server through a proxy server.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.X_FORWARDED_HOST.html b/actix_web/http/header/constant.X_FORWARDED_HOST.html new file mode 100644 index 000000000..887ec2339 --- /dev/null +++ b/actix_web/http/header/constant.X_FORWARDED_HOST.html @@ -0,0 +1,3 @@ +X_FORWARDED_HOST in actix_web::http::header - Rust

Constant actix_web::http::header::X_FORWARDED_HOST

source ·
pub const X_FORWARDED_HOST: HeaderName;
Expand description

Request header (de-facto standard) for identifying the original host requested by the client in +the Host HTTP request header.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.X_FORWARDED_PROTO.html b/actix_web/http/header/constant.X_FORWARDED_PROTO.html new file mode 100644 index 000000000..cb2d0374d --- /dev/null +++ b/actix_web/http/header/constant.X_FORWARDED_PROTO.html @@ -0,0 +1,3 @@ +X_FORWARDED_PROTO in actix_web::http::header - Rust

Constant actix_web::http::header::X_FORWARDED_PROTO

source ·
pub const X_FORWARDED_PROTO: HeaderName;
Expand description

Request header (de-facto standard) for identifying the protocol that a client used to connect to +your proxy or load balancer.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.X_FRAME_OPTIONS.html b/actix_web/http/header/constant.X_FRAME_OPTIONS.html new file mode 100644 index 000000000..c2df19f78 --- /dev/null +++ b/actix_web/http/header/constant.X_FRAME_OPTIONS.html @@ -0,0 +1,7 @@ +X_FRAME_OPTIONS in actix_web::http::header - Rust

Constant actix_web::http::header::X_FRAME_OPTIONS

source ·
pub const X_FRAME_OPTIONS: HeaderName;
Expand description

Indicates whether or not a browser should be allowed to render a page in +a frame.

+

Sites can use this to avoid clickjacking attacks, by ensuring that their +content is not embedded into other sites.

+

The added security is only provided if the user accessing the document +is using a browser supporting x-frame-options.

+
\ No newline at end of file diff --git a/actix_web/http/header/constant.X_XSS_PROTECTION.html b/actix_web/http/header/constant.X_XSS_PROTECTION.html new file mode 100644 index 000000000..dfcc56635 --- /dev/null +++ b/actix_web/http/header/constant.X_XSS_PROTECTION.html @@ -0,0 +1,9 @@ +X_XSS_PROTECTION in actix_web::http::header - Rust

Constant actix_web::http::header::X_XSS_PROTECTION

source ·
pub const X_XSS_PROTECTION: HeaderName;
Expand description

Stop pages from loading when an XSS attack is detected.

+

The HTTP X-XSS-Protection response header is a feature of Internet +Explorer, Chrome and Safari that stops pages from loading when they +detect reflected cross-site scripting (XSS) attacks. Although these +protections are largely unnecessary in modern browsers when sites +implement a strong Content-Security-Policy that disables the use of +inline JavaScript (‘unsafe-inline’), they can still provide protections +for users of older web browsers that don’t yet support CSP.

+
\ No newline at end of file diff --git a/actix_web/http/header/content_disposition/enum.DispositionParam.html b/actix_web/http/header/content_disposition/enum.DispositionParam.html new file mode 100644 index 000000000..ee4183e2d --- /dev/null +++ b/actix_web/http/header/content_disposition/enum.DispositionParam.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/enum.DispositionParam.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/content_disposition/enum.DispositionType.html b/actix_web/http/header/content_disposition/enum.DispositionType.html new file mode 100644 index 000000000..4a4a9bbf7 --- /dev/null +++ b/actix_web/http/header/content_disposition/enum.DispositionType.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/enum.DispositionType.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/content_disposition/struct.ContentDisposition.html b/actix_web/http/header/content_disposition/struct.ContentDisposition.html new file mode 100644 index 000000000..55aaa0b63 --- /dev/null +++ b/actix_web/http/header/content_disposition/struct.ContentDisposition.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.ContentDisposition.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/content_language/struct.ContentLanguage.html b/actix_web/http/header/content_language/struct.ContentLanguage.html new file mode 100644 index 000000000..e817cccc0 --- /dev/null +++ b/actix_web/http/header/content_language/struct.ContentLanguage.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.ContentLanguage.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/content_length/struct.ContentLength.html b/actix_web/http/header/content_length/struct.ContentLength.html new file mode 100644 index 000000000..1d7625f37 --- /dev/null +++ b/actix_web/http/header/content_length/struct.ContentLength.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.ContentLength.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/content_range/enum.ContentRangeSpec.html b/actix_web/http/header/content_range/enum.ContentRangeSpec.html new file mode 100644 index 000000000..c8a8522db --- /dev/null +++ b/actix_web/http/header/content_range/enum.ContentRangeSpec.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/enum.ContentRangeSpec.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/content_range/struct.ContentRange.html b/actix_web/http/header/content_range/struct.ContentRange.html new file mode 100644 index 000000000..fa456d9ba --- /dev/null +++ b/actix_web/http/header/content_range/struct.ContentRange.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.ContentRange.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/content_type/struct.ContentType.html b/actix_web/http/header/content_type/struct.ContentType.html new file mode 100644 index 000000000..41a5235f2 --- /dev/null +++ b/actix_web/http/header/content_type/struct.ContentType.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.ContentType.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/date/struct.Date.html b/actix_web/http/header/date/struct.Date.html new file mode 100644 index 000000000..43745de20 --- /dev/null +++ b/actix_web/http/header/date/struct.Date.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.Date.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/encoding/enum.Encoding.html b/actix_web/http/header/encoding/enum.Encoding.html new file mode 100644 index 000000000..a9d61fae9 --- /dev/null +++ b/actix_web/http/header/encoding/enum.Encoding.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/enum.Encoding.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/entity/struct.EntityTag.html b/actix_web/http/header/entity/struct.EntityTag.html new file mode 100644 index 000000000..e1019f821 --- /dev/null +++ b/actix_web/http/header/entity/struct.EntityTag.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.EntityTag.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/enum.ByteRangeSpec.html b/actix_web/http/header/enum.ByteRangeSpec.html new file mode 100644 index 000000000..738d0d698 --- /dev/null +++ b/actix_web/http/header/enum.ByteRangeSpec.html @@ -0,0 +1,63 @@ +ByteRangeSpec in actix_web::http::header - Rust

Enum actix_web::http::header::ByteRangeSpec

source ·
pub enum ByteRangeSpec {
+    FromTo(u64, u64),
+    From(u64),
+    Last(u64),
+}
Expand description

A range of bytes to fetch.

+

Each Range::Bytes header can contain one or more ByteRangeSpecs.

+

Variants§

§

FromTo(u64, u64)

All bytes from x to y, inclusive.

+

Serialized as x-y.

+

Example: bytes=500-999 would represent the second 500 bytes.

+
§

From(u64)

All bytes starting from x, inclusive.

+

Serialized as x-.

+

Example: For a file of 1000 bytes, bytes=950- would represent bytes 950-999, inclusive.

+
§

Last(u64)

The last y bytes, inclusive.

+

Using the spec terminology, this is suffix-byte-range-spec. Serialized as -y.

+

Example: For a file of 1000 bytes, bytes=-50 is equivalent to bytes=950-.

+

Implementations§

source§

impl ByteRangeSpec

source

pub fn to_satisfiable_range(&self, full_length: u64) -> Option<(u64, u64)>

Given the full length of the entity, attempt to normalize the byte range into an satisfiable +end-inclusive (from, to) range.

+

The resulting range is guaranteed to be a satisfiable range within the bounds +of 0 <= from <= to < full_length.

+

If the byte range is deemed unsatisfiable, None is returned. An unsatisfiable range is +generally cause for a server to either reject the client request with a +416 Range Not Satisfiable status code, or to simply ignore the range header and serve the +full entity using a 200 OK status code.

+

This function closely follows RFC 7233 §2.1. As such, it considers ranges to be +satisfiable if they meet the following conditions:

+
+

If a valid byte-range-set includes at least one byte-range-spec with a first-byte-pos that +is less than the current length of the representation, or at least one +suffix-byte-range-spec with a non-zero suffix-length, then the byte-range-set +is satisfiable. Otherwise, the byte-range-set is unsatisfiable.

+
+

The function also computes remainder ranges based on the RFC:

+
+

If the last-byte-pos value is absent, or if the value is greater than or equal to the +current length of the representation data, the byte range is interpreted as the remainder +of the representation (i.e., the server replaces the value of last-byte-pos with a value +that is one less than the current length of the selected representation).

+
+

Trait Implementations§

source§

impl Clone for ByteRangeSpec

source§

fn clone(&self) -> ByteRangeSpec

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ByteRangeSpec

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for ByteRangeSpec

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl FromStr for ByteRangeSpec

§

type Err = ParseError

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<ByteRangeSpec, ParseError>

Parses a string s to return a value of this type. Read more
source§

impl PartialEq for ByteRangeSpec

source§

fn eq(&self, other: &ByteRangeSpec) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for ByteRangeSpec

source§

impl StructuralPartialEq for ByteRangeSpec

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/enum.CacheDirective.html b/actix_web/http/header/enum.CacheDirective.html new file mode 100644 index 000000000..c3300275b --- /dev/null +++ b/actix_web/http/header/enum.CacheDirective.html @@ -0,0 +1,53 @@ +CacheDirective in actix_web::http::header - Rust

Enum actix_web::http::header::CacheDirective

source ·
pub enum CacheDirective {
+
Show 13 variants NoCache, + NoStore, + NoTransform, + OnlyIfCached, + MaxAge(u32), + MaxStale(u32), + MinFresh(u32), + MustRevalidate, + Public, + Private, + ProxyRevalidate, + SMaxAge(u32), + Extension(String, Option<String>), +
}
Expand description

CacheControl contains a list of these directives.

+

Variants§

§

NoCache

“no-cache”

+
§

NoStore

“no-store”

+
§

NoTransform

“no-transform”

+
§

OnlyIfCached

“only-if-cached”

+
§

MaxAge(u32)

“max-age=delta”

+
§

MaxStale(u32)

“max-stale=delta”

+
§

MinFresh(u32)

“min-fresh=delta”

+
§

MustRevalidate

“must-revalidate”

+
§

Public

“public”

+
§

Private

“private”

+
§

ProxyRevalidate

“proxy-revalidate”

+
§

SMaxAge(u32)

“s-maxage=delta”

+
§

Extension(String, Option<String>)

Extension directives. Optionally include an argument.

+

Trait Implementations§

source§

impl Clone for CacheDirective

source§

fn clone(&self) -> CacheDirective

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for CacheDirective

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for CacheDirective

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl FromStr for CacheDirective

§

type Err = Option<<u32 as FromStr>::Err>

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Self, Self::Err>

Parses a string s to return a value of this type. Read more
source§

impl PartialEq for CacheDirective

source§

fn eq(&self, other: &CacheDirective) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for CacheDirective

source§

impl StructuralPartialEq for CacheDirective

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/enum.Charset.html b/actix_web/http/header/enum.Charset.html new file mode 100644 index 000000000..71788f045 --- /dev/null +++ b/actix_web/http/header/enum.Charset.html @@ -0,0 +1,79 @@ +Charset in actix_web::http::header - Rust

Enum actix_web::http::header::Charset

source ·
pub enum Charset {
+
Show 25 variants Us_Ascii, + Iso_8859_1, + Iso_8859_2, + Iso_8859_3, + Iso_8859_4, + Iso_8859_5, + Iso_8859_6, + Iso_8859_7, + Iso_8859_8, + Iso_8859_9, + Iso_8859_10, + Shift_Jis, + Euc_Jp, + Iso_2022_Kr, + Euc_Kr, + Iso_2022_Jp, + Iso_2022_Jp_2, + Iso_8859_6_E, + Iso_8859_6_I, + Iso_8859_8_E, + Iso_8859_8_I, + Gb2312, + Big5, + Koi8_R, + Ext(String), +
}
Expand description

A MIME character set.

+

The string representation is normalized to upper case.

+

See http://www.iana.org/assignments/character-sets/character-sets.xhtml.

+

Variants§

§

Us_Ascii

US ASCII

+
§

Iso_8859_1

ISO-8859-1

+
§

Iso_8859_2

ISO-8859-2

+
§

Iso_8859_3

ISO-8859-3

+
§

Iso_8859_4

ISO-8859-4

+
§

Iso_8859_5

ISO-8859-5

+
§

Iso_8859_6

ISO-8859-6

+
§

Iso_8859_7

ISO-8859-7

+
§

Iso_8859_8

ISO-8859-8

+
§

Iso_8859_9

ISO-8859-9

+
§

Iso_8859_10

ISO-8859-10

+
§

Shift_Jis

Shift_JIS

+
§

Euc_Jp

EUC-JP

+
§

Iso_2022_Kr

ISO-2022-KR

+
§

Euc_Kr

EUC-KR

+
§

Iso_2022_Jp

ISO-2022-JP

+
§

Iso_2022_Jp_2

ISO-2022-JP-2

+
§

Iso_8859_6_E

ISO-8859-6-E

+
§

Iso_8859_6_I

ISO-8859-6-I

+
§

Iso_8859_8_E

ISO-8859-8-E

+
§

Iso_8859_8_I

ISO-8859-8-I

+
§

Gb2312

GB2312

+
§

Big5

Big5

+
§

Koi8_R

KOI8-R

+
§

Ext(String)

An arbitrary charset specified as a string

+

Trait Implementations§

source§

impl Clone for Charset

source§

fn clone(&self) -> Charset

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Charset

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for Charset

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl FromStr for Charset

§

type Err = Error

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Charset, Error>

Parses a string s to return a value of this type. Read more
source§

impl PartialEq for Charset

source§

fn eq(&self, other: &Charset) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for Charset

source§

impl StructuralPartialEq for Charset

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/enum.ContentEncoding.html b/actix_web/http/header/enum.ContentEncoding.html new file mode 100644 index 000000000..c7237c9d3 --- /dev/null +++ b/actix_web/http/header/enum.ContentEncoding.html @@ -0,0 +1,54 @@ +ContentEncoding in actix_web::http::header - Rust

Enum actix_web::http::header::ContentEncoding

source ·
#[non_exhaustive]
pub enum ContentEncoding { + Identity, + Brotli, + Deflate, + Gzip, + Zstd, +}
Expand description

Represents a supported content encoding.

+

Includes a commonly-used subset of media types appropriate for use as HTTP content encodings. +See IANA HTTP Content Coding Registry.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Identity

Indicates the no-op identity encoding.

+

I.e., no compression or modification.

+
§

Brotli

A format using the Brotli algorithm.

+
§

Deflate

A format using the zlib structure with deflate algorithm.

+
§

Gzip

Gzip algorithm.

+
§

Zstd

Zstd algorithm.

+

Implementations§

source§

impl ContentEncoding

source

pub const fn as_str(self) -> &'static str

Convert content encoding to string.

+
source

pub const fn to_header_value(self) -> HeaderValue

Convert content encoding to header value.

+

Trait Implementations§

source§

impl Clone for ContentEncoding

source§

fn clone(&self) -> ContentEncoding

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ContentEncoding

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for ContentEncoding

source§

fn default() -> ContentEncoding

Returns the “default value” for a type. Read more
source§

impl FromStr for ContentEncoding

§

type Err = ContentEncodingParseError

The associated error which can be returned from parsing.
source§

fn from_str( + enc: &str +) -> Result<ContentEncoding, <ContentEncoding as FromStr>::Err>

Parses a string s to return a value of this type. Read more
source§

impl Hash for ContentEncoding

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Header for ContentEncoding

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<T>(msg: &T) -> Result<ContentEncoding, ParseError>
where + T: HttpMessage,

Parse the header from a HTTP message.
source§

impl PartialEq for ContentEncoding

source§

fn eq(&self, other: &ContentEncoding) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryFrom<&str> for ContentEncoding

§

type Error = ContentEncodingParseError

The type returned in the event of a conversion error.
source§

fn try_from( + val: &str +) -> Result<ContentEncoding, <ContentEncoding as TryFrom<&str>>::Error>

Performs the conversion.
source§

impl TryIntoHeaderValue for ContentEncoding

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value( + self +) -> Result<HeaderValue, <ContentEncoding as TryIntoHeaderValue>::Error>

Try to convert value to a HeaderValue.
source§

impl Copy for ContentEncoding

source§

impl Eq for ContentEncoding

source§

impl StructuralPartialEq for ContentEncoding

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/enum.ContentRangeSpec.html b/actix_web/http/header/enum.ContentRangeSpec.html new file mode 100644 index 000000000..a04f8ddf3 --- /dev/null +++ b/actix_web/http/header/enum.ContentRangeSpec.html @@ -0,0 +1,57 @@ +ContentRangeSpec in actix_web::http::header - Rust

Enum actix_web::http::header::ContentRangeSpec

source ·
pub enum ContentRangeSpec {
+    Bytes {
+        range: Option<(u64, u64)>,
+        instance_length: Option<u64>,
+    },
+    Unregistered {
+        unit: String,
+        resp: String,
+    },
+}
Expand description

Content-Range header, defined +in RFC 7233 §4.2

+

§ABNF

Content-Range       = byte-content-range
+                    / other-content-range
+
+byte-content-range  = bytes-unit SP
+                      ( byte-range-resp / unsatisfied-range )
+
+byte-range-resp     = byte-range "/" ( complete-length / "*" )
+byte-range          = first-byte-pos "-" last-byte-pos
+unsatisfied-range   = "*/" complete-length
+
+complete-length     = 1*DIGIT
+
+other-content-range = other-range-unit SP other-range-resp
+other-range-resp    = *CHAR
+

Variants§

§

Bytes

Byte range

+

Fields

§range: Option<(u64, u64)>

First and last bytes of the range, omitted if request could not be +satisfied

+
§instance_length: Option<u64>

Total length of the instance, can be omitted if unknown

+
§

Unregistered

Custom range, with unit not registered at IANA

+

Fields

§unit: String

other-range-unit

+
§resp: String

other-range-resp

+

Trait Implementations§

source§

impl Clone for ContentRangeSpec

source§

fn clone(&self) -> ContentRangeSpec

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ContentRangeSpec

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for ContentRangeSpec

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl FromStr for ContentRangeSpec

§

type Err = ParseError

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Self, ParseError>

Parses a string s to return a value of this type. Read more
source§

impl PartialEq for ContentRangeSpec

source§

fn eq(&self, other: &ContentRangeSpec) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for ContentRangeSpec

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for ContentRangeSpec

source§

impl StructuralPartialEq for ContentRangeSpec

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/enum.DispositionParam.html b/actix_web/http/header/enum.DispositionParam.html new file mode 100644 index 000000000..0f0fe2d09 --- /dev/null +++ b/actix_web/http/header/enum.DispositionParam.html @@ -0,0 +1,72 @@ +DispositionParam in actix_web::http::header - Rust

Enum actix_web::http::header::DispositionParam

source ·
pub enum DispositionParam {
+    Name(String),
+    Filename(String),
+    FilenameExt(ExtendedValue),
+    Unknown(String, String),
+    UnknownExt(String, ExtendedValue),
+}
Expand description

Parameter in ContentDisposition.

+

§Examples

+
use actix_web::http::header::DispositionParam;
+
+let param = DispositionParam::Filename(String::from("sample.txt"));
+assert!(param.is_filename());
+assert_eq!(param.as_filename().unwrap(), "sample.txt");
+

Variants§

§

Name(String)

For DispositionType::FormData (i.e. multipart/form-data), the name of an field from +the form.

+
§

Filename(String)

A plain file name.

+

It is not supposed to contain +any non-ASCII characters when used in a Content-Disposition HTTP response header, where +FilenameExt with charset UTF-8 may be used instead +in case there are Unicode characters in file names.

+
§

FilenameExt(ExtendedValue)

An extended file name. It must not exist for ContentType::Formdata according to +RFC 7578 §4.2.

+
§

Unknown(String, String)

An unrecognized regular parameter as defined in +RFC 5987 §3.2.1 as +reg-parameter, in +RFC 6266 §4.1 as +token "=" value. Recipients should ignore unrecognizable parameters.

+
§

UnknownExt(String, ExtendedValue)

An unrecognized extended parameter as defined in +RFC 5987 §3.2.1 as +ext-parameter, in +RFC 6266 §4.1 as +ext-token "=" ext-value. The single trailing asterisk is not included. Recipients should +ignore unrecognizable parameters.

+

Implementations§

source§

impl DispositionParam

source

pub fn is_name(&self) -> bool

Returns true if the parameter is Name.

+
source

pub fn is_filename(&self) -> bool

Returns true if the parameter is Filename.

+
source

pub fn is_filename_ext(&self) -> bool

Returns true if the parameter is FilenameExt.

+
source

pub fn is_unknown<T: AsRef<str>>(&self, name: T) -> bool

Returns true if the parameter is Unknown and the name +matches.

+
source

pub fn is_unknown_ext<T: AsRef<str>>(&self, name: T) -> bool

Returns true if the parameter is UnknownExt and the +name matches.

+
source

pub fn as_name(&self) -> Option<&str>

Returns the name if applicable.

+
source

pub fn as_filename(&self) -> Option<&str>

Returns the filename if applicable.

+
source

pub fn as_filename_ext(&self) -> Option<&ExtendedValue>

Returns the filename* if applicable.

+
source

pub fn as_unknown<T: AsRef<str>>(&self, name: T) -> Option<&str>

Returns the value of the unrecognized regular parameter if it is +Unknown and the name matches.

+
source

pub fn as_unknown_ext<T: AsRef<str>>(&self, name: T) -> Option<&ExtendedValue>

Returns the value of the unrecognized extended parameter if it is +Unknown and the name matches.

+

Trait Implementations§

source§

impl Clone for DispositionParam

source§

fn clone(&self) -> DispositionParam

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for DispositionParam

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for DispositionParam

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl PartialEq for DispositionParam

source§

fn eq(&self, other: &DispositionParam) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for DispositionParam

source§

impl StructuralPartialEq for DispositionParam

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/enum.DispositionType.html b/actix_web/http/header/enum.DispositionType.html new file mode 100644 index 000000000..02e7de152 --- /dev/null +++ b/actix_web/http/header/enum.DispositionType.html @@ -0,0 +1,38 @@ +DispositionType in actix_web::http::header - Rust

Enum actix_web::http::header::DispositionType

source ·
pub enum DispositionType {
+    Inline,
+    Attachment,
+    FormData,
+    Ext(String),
+}
Expand description

The implied disposition of the content of the HTTP body.

+

Variants§

§

Inline

Inline implies default processing.

+
§

Attachment

Attachment implies that the recipient should prompt the user to save the response locally, +rather than process it normally (as per its media type).

+
§

FormData

Used in multipart/form-data as defined in +RFC 7578 to carry the field name and +optional filename.

+
§

Ext(String)

Extension type. Should be handled by recipients the same way as Attachment.

+

Trait Implementations§

source§

impl Clone for DispositionType

source§

fn clone(&self) -> DispositionType

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for DispositionType

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for DispositionType

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a str> for DispositionType

source§

fn from(origin: &'a str) -> DispositionType

Converts to this type from the input type.
source§

impl PartialEq for DispositionType

source§

fn eq(&self, other: &DispositionType) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for DispositionType

source§

impl StructuralPartialEq for DispositionType

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/enum.Encoding.html b/actix_web/http/header/enum.Encoding.html new file mode 100644 index 000000000..dbb73d140 --- /dev/null +++ b/actix_web/http/header/enum.Encoding.html @@ -0,0 +1,33 @@ +Encoding in actix_web::http::header - Rust

Enum actix_web::http::header::Encoding

source ·
pub enum Encoding {
+    Known(ContentEncoding),
+    Unknown(String),
+}
Expand description

A value to represent an encoding used in the Accept-Encoding and Content-Encoding header.

+

Variants§

§

Known(ContentEncoding)

A supported content encoding. See ContentEncoding for variants.

+
§

Unknown(String)

Some other encoding that is less common, can be any string.

+

Implementations§

source§

impl Encoding

source

pub const fn identity() -> Self

source

pub const fn brotli() -> Self

source

pub const fn deflate() -> Self

source

pub const fn gzip() -> Self

source

pub const fn zstd() -> Self

Trait Implementations§

source§

impl Clone for Encoding

source§

fn clone(&self) -> Encoding

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Encoding

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for Encoding

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl FromStr for Encoding

§

type Err = ParseError

The associated error which can be returned from parsing.
source§

fn from_str(enc: &str) -> Result<Self, ParseError>

Parses a string s to return a value of this type. Read more
source§

impl Hash for Encoding

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq for Encoding

source§

fn eq(&self, other: &Encoding) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for Encoding

source§

impl StructuralPartialEq for Encoding

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/enum.IfMatch.html b/actix_web/http/header/enum.IfMatch.html new file mode 100644 index 000000000..e9340d0c2 --- /dev/null +++ b/actix_web/http/header/enum.IfMatch.html @@ -0,0 +1,69 @@ +IfMatch in actix_web::http::header - Rust

Enum actix_web::http::header::IfMatch

source ·
pub enum IfMatch {
+    Any,
+    Items(Vec<EntityTag>),
+}
Expand description

If-Match header, defined +in RFC 7232 §3.1

+

The If-Match header field makes the request method conditional on +the recipient origin server either having at least one current +representation of the target resource, when the field-value is “*”, +or having a current representation of the target resource that has an +entity-tag matching a member of the list of entity-tags provided in +the field-value.

+

An origin server MUST use the strong comparison function when +comparing entity-tags for If-Match, since the client +intends this precondition to prevent the method from being applied if +there have been any changes to the representation data.

+

§ABNF

If-Match = "*" / 1#entity-tag
+

§Example Values

+
    +
  • "xyzzy"
  • +
  • “xyzzy”, “r2d2xxxx”, “c3piozzzz”
  • +
+

§Examples

+
use actix_web::HttpResponse;
+use actix_web::http::header::IfMatch;
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(IfMatch::Any);
+ +
use actix_web::HttpResponse;
+use actix_web::http::header::{IfMatch, EntityTag};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    IfMatch::Items(vec![
+        EntityTag::new(false, "xyzzy".to_owned()),
+        EntityTag::new(false, "foobar".to_owned()),
+        EntityTag::new(false, "bazquux".to_owned()),
+    ])
+);
+

Variants§

§

Any

Any value is a match

+
§

Items(Vec<EntityTag>)

Only the listed items are a match

+

Trait Implementations§

source§

impl Clone for IfMatch

source§

fn clone(&self) -> IfMatch

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for IfMatch

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for IfMatch

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for IfMatch

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for IfMatch

source§

fn eq(&self, other: &IfMatch) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for IfMatch

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for IfMatch

source§

impl StructuralPartialEq for IfMatch

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/enum.IfNoneMatch.html b/actix_web/http/header/enum.IfNoneMatch.html new file mode 100644 index 000000000..db5290093 --- /dev/null +++ b/actix_web/http/header/enum.IfNoneMatch.html @@ -0,0 +1,71 @@ +IfNoneMatch in actix_web::http::header - Rust

Enum actix_web::http::header::IfNoneMatch

source ·
pub enum IfNoneMatch {
+    Any,
+    Items(Vec<EntityTag>),
+}
Expand description

If-None-Match header, defined +in RFC 7232 §3.2

+

The If-None-Match header field makes the request method conditional +on a recipient cache or origin server either not having any current +representation of the target resource, when the field-value is “*”, +or having a selected representation with an entity-tag that does not +match any of those listed in the field-value.

+

A recipient MUST use the weak comparison function when comparing +entity-tags for If-None-Match (Section 2.3.2), since weak entity-tags +can be used for cache validation even if there have been changes to +the representation data.

+

§ABNF

If-None-Match = "*" / 1#entity-tag
+

§Example Values

+
    +
  • "xyzzy"
  • +
  • W/"xyzzy"
  • +
  • "xyzzy", "r2d2xxxx", "c3piozzzz"
  • +
  • W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"
  • +
  • *
  • +
+

§Examples

+
use actix_web::HttpResponse;
+use actix_web::http::header::IfNoneMatch;
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(IfNoneMatch::Any);
+ +
use actix_web::HttpResponse;
+use actix_web::http::header::{IfNoneMatch, EntityTag};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    IfNoneMatch::Items(vec![
+        EntityTag::new(false, "xyzzy".to_owned()),
+        EntityTag::new(false, "foobar".to_owned()),
+        EntityTag::new(false, "bazquux".to_owned()),
+    ])
+);
+

Variants§

§

Any

Any value is a match

+
§

Items(Vec<EntityTag>)

Only the listed items are a match

+

Trait Implementations§

source§

impl Clone for IfNoneMatch

source§

fn clone(&self) -> IfNoneMatch

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for IfNoneMatch

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for IfNoneMatch

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for IfNoneMatch

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for IfNoneMatch

source§

fn eq(&self, other: &IfNoneMatch) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for IfNoneMatch

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for IfNoneMatch

source§

impl StructuralPartialEq for IfNoneMatch

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/enum.IfRange.html b/actix_web/http/header/enum.IfRange.html new file mode 100644 index 000000000..6030fc6eb --- /dev/null +++ b/actix_web/http/header/enum.IfRange.html @@ -0,0 +1,72 @@ +IfRange in actix_web::http::header - Rust

Enum actix_web::http::header::IfRange

source ·
pub enum IfRange {
+    EntityTag(EntityTag),
+    Date(HttpDate),
+}
Expand description

If-Range header, defined +in RFC 7233 §3.2

+

If a client has a partial copy of a representation and wishes to have +an up-to-date copy of the entire representation, it could use the +Range header field with a conditional GET (using either or both of +If-Unmodified-Since and If-Match.) However, if the precondition +fails because the representation has been modified, the client would +then have to make a second request to obtain the entire current +representation.

+

The If-Range header field allows a client to "short-circuit" the +second request. Informally, its meaning is as follows: if the +representation is unchanged, send me the part(s) that I am requesting +in Range; otherwise, send me the entire representation.

+

§ABNF

If-Range = entity-tag / HTTP-date
+

§Example Values

+
    +
  • Sat, 29 Oct 1994 19:43:31 GMT
  • +
  • \"xyzzy\"
  • +
+

§Examples

+
use actix_web::HttpResponse;
+use actix_web::http::header::{EntityTag, IfRange};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    IfRange::EntityTag(
+        EntityTag::new(false, "abc".to_owned())
+    )
+);
+ +
use std::time::{Duration, SystemTime};
+use actix_web::{http::header::IfRange, HttpResponse};
+
+let mut builder = HttpResponse::Ok();
+let fetched = SystemTime::now() - Duration::from_secs(60 * 60 * 24);
+builder.insert_header(
+    IfRange::Date(fetched.into())
+);
+

Variants§

§

EntityTag(EntityTag)

The entity-tag the client has of the resource.

+
§

Date(HttpDate)

The date when the client retrieved the resource.

+

Trait Implementations§

source§

impl Clone for IfRange

source§

fn clone(&self) -> IfRange

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for IfRange

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for IfRange

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for IfRange

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<T>(msg: &T) -> Result<Self, ParseError>
where + T: HttpMessage,

Parse the header from a HTTP message.
source§

impl PartialEq for IfRange

source§

fn eq(&self, other: &IfRange) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for IfRange

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for IfRange

source§

impl StructuralPartialEq for IfRange

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/enum.Preference.html b/actix_web/http/header/enum.Preference.html new file mode 100644 index 000000000..8ef7fc051 --- /dev/null +++ b/actix_web/http/header/enum.Preference.html @@ -0,0 +1,50 @@ +Preference in actix_web::http::header - Rust

Enum actix_web::http::header::Preference

source ·
pub enum Preference<T> {
+    Any,
+    Specific(T),
+}
Expand description

A wrapper for types used in header values where wildcard (*) items are allowed but the +underlying type does not support them.

+

For example, we use the language-tags crate for the AcceptLanguage +typed header but it does not parse * successfully. On the other hand, the mime crate, used +for Accept, has first-party support for wildcard items so this wrapper is not +used in those header types.

+

Variants§

§

Any

A wildcard value.

+
§

Specific(T)

A valid T.

+

Implementations§

source§

impl<T> Preference<T>

source

pub fn is_any(&self) -> bool

Returns true if preference is the any/wildcard (*) value.

+
source

pub fn is_specific(&self) -> bool

Returns true if preference is the specific item (T) variant.

+
source

pub fn item(&self) -> Option<&T>

Returns reference to value in Specific variant, if it is set.

+
source

pub fn into_item(self) -> Option<T>

Consumes the container, returning the value in the Specific variant, if it is set.

+

Trait Implementations§

source§

impl<T: Clone> Clone for Preference<T>

source§

fn clone(&self) -> Preference<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for Preference<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: Display> Display for Preference<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: FromStr> FromStr for Preference<T>

§

type Err = <T as FromStr>::Err

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Self, Self::Err>

Parses a string s to return a value of this type. Read more
source§

impl<T: Hash> Hash for Preference<T>

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<T: PartialEq> PartialEq for Preference<T>

source§

fn eq(&self, other: &Preference<T>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<T: PartialOrd> PartialOrd for Preference<T>

source§

fn partial_cmp(&self, other: &Preference<T>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<T: Copy> Copy for Preference<T>

source§

impl<T: Eq> Eq for Preference<T>

source§

impl<T> StructuralPartialEq for Preference<T>

Auto Trait Implementations§

§

impl<T> Freeze for Preference<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for Preference<T>
where + T: RefUnwindSafe,

§

impl<T> Send for Preference<T>
where + T: Send,

§

impl<T> Sync for Preference<T>
where + T: Sync,

§

impl<T> Unpin for Preference<T>
where + T: Unpin,

§

impl<T> UnwindSafe for Preference<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/enum.Range.html b/actix_web/http/header/enum.Range.html new file mode 100644 index 000000000..d842ef985 --- /dev/null +++ b/actix_web/http/header/enum.Range.html @@ -0,0 +1,76 @@ +Range in actix_web::http::header - Rust

Enum actix_web::http::header::Range

source ·
pub enum Range {
+    Bytes(Vec<ByteRangeSpec>),
+    Unregistered(String, String),
+}
Expand description

Range header, defined +in RFC 7233 §3.1

+

The “Range” header field on a GET request modifies the method semantics to request transfer of +only one or more sub-ranges of the selected representation data, rather than the entire selected +representation data.

+

§ABNF

Range = byte-ranges-specifier / other-ranges-specifier
+other-ranges-specifier = other-range-unit "=" other-range-set
+other-range-set = 1*VCHAR
+
+bytes-unit = "bytes"
+
+byte-ranges-specifier = bytes-unit "=" byte-range-set
+byte-range-set = 1#(byte-range-spec / suffix-byte-range-spec)
+byte-range-spec = first-byte-pos "-" [last-byte-pos]
+suffix-byte-range-spec = "-" suffix-length
+suffix-length = 1*DIGIT
+first-byte-pos = 1*DIGIT
+last-byte-pos = 1*DIGIT
+

§Example Values

+
    +
  • bytes=1000-
  • +
  • bytes=-50
  • +
  • bytes=0-1,30-40
  • +
  • bytes=0-10,20-90,-100
  • +
  • custom_unit=0-123
  • +
  • custom_unit=xxx-yyy
  • +
+

§Examples

+
use actix_web::http::header::{Range, ByteRangeSpec};
+use actix_web::HttpResponse;
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(Range::Bytes(
+    vec![ByteRangeSpec::FromTo(1, 100), ByteRangeSpec::From(200)]
+));
+builder.insert_header(Range::Unregistered("letters".to_owned(), "a-f".to_owned()));
+builder.insert_header(Range::bytes(1, 100));
+builder.insert_header(Range::bytes_multi(vec![(1, 100), (200, 300)]));
+

Variants§

§

Bytes(Vec<ByteRangeSpec>)

Byte range.

+
§

Unregistered(String, String)

Custom range, with unit not registered at IANA.

+

(other-range-unit: String , other-range-set: String)

+

Implementations§

source§

impl Range

source

pub fn bytes(from: u64, to: u64) -> Range

Constructs a common byte range header.

+

Eg: bytes=from-to

+
source

pub fn bytes_multi(ranges: Vec<(u64, u64)>) -> Range

Constructs a byte range header with multiple subranges.

+

Eg: bytes=from1-to1,from2-to2,fromX-toX

+

Trait Implementations§

source§

impl Clone for Range

source§

fn clone(&self) -> Range

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Range

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for Range

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl FromStr for Range

§

type Err = ParseError

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Range, ParseError>

Parses a string s to return a value of this type. Read more
source§

impl Header for Range

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<T: HttpMessage>(msg: &T) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for Range

source§

fn eq(&self, other: &Range) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for Range

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for Range

source§

impl StructuralPartialEq for Range

Auto Trait Implementations§

§

impl Freeze for Range

§

impl RefUnwindSafe for Range

§

impl Send for Range

§

impl Sync for Range

§

impl Unpin for Range

§

impl UnwindSafe for Range

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/etag/struct.ETag.html b/actix_web/http/header/etag/struct.ETag.html new file mode 100644 index 000000000..e15800c51 --- /dev/null +++ b/actix_web/http/header/etag/struct.ETag.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.ETag.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/expires/struct.Expires.html b/actix_web/http/header/expires/struct.Expires.html new file mode 100644 index 000000000..aedbcf939 --- /dev/null +++ b/actix_web/http/header/expires/struct.Expires.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.Expires.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/fn.fmt_comma_delimited.html b/actix_web/http/header/fn.fmt_comma_delimited.html new file mode 100644 index 000000000..087d35c32 --- /dev/null +++ b/actix_web/http/header/fn.fmt_comma_delimited.html @@ -0,0 +1,6 @@ +fmt_comma_delimited in actix_web::http::header - Rust

Function actix_web::http::header::fmt_comma_delimited

source ·
pub fn fmt_comma_delimited<T>(
+    f: &mut Formatter<'_>,
+    parts: &[T]
+) -> Result<(), Error>
where + T: Display,
Expand description

Format an array into a comma-delimited string.

+
\ No newline at end of file diff --git a/actix_web/http/header/fn.from_comma_delimited.html b/actix_web/http/header/fn.from_comma_delimited.html new file mode 100644 index 000000000..d17fda6c3 --- /dev/null +++ b/actix_web/http/header/fn.from_comma_delimited.html @@ -0,0 +1,4 @@ +from_comma_delimited in actix_web::http::header - Rust

Function actix_web::http::header::from_comma_delimited

source ·
pub fn from_comma_delimited<'a, I, T>(all: I) -> Result<Vec<T>, ParseError>
where + I: Iterator<Item = &'a HeaderValue> + 'a, + T: FromStr,
Expand description

Reads a comma-delimited raw header into a Vec.

+
\ No newline at end of file diff --git a/actix_web/http/header/fn.from_one_raw_str.html b/actix_web/http/header/fn.from_one_raw_str.html new file mode 100644 index 000000000..6a621c14c --- /dev/null +++ b/actix_web/http/header/fn.from_one_raw_str.html @@ -0,0 +1,3 @@ +from_one_raw_str in actix_web::http::header - Rust

Function actix_web::http::header::from_one_raw_str

source ·
pub fn from_one_raw_str<T>(val: Option<&HeaderValue>) -> Result<T, ParseError>
where + T: FromStr,
Expand description

Reads a single string when parsing a header.

+
\ No newline at end of file diff --git a/actix_web/http/header/fn.http_percent_encode.html b/actix_web/http/header/fn.http_percent_encode.html new file mode 100644 index 000000000..4283b5ba6 --- /dev/null +++ b/actix_web/http/header/fn.http_percent_encode.html @@ -0,0 +1,5 @@ +http_percent_encode in actix_web::http::header - Rust

Function actix_web::http::header::http_percent_encode

source ·
pub fn http_percent_encode(
+    f: &mut Formatter<'_>,
+    bytes: &[u8]
+) -> Result<(), Error>
Expand description

Percent encode a sequence of bytes with a character set defined in RFC 5987 §3.2.

+
\ No newline at end of file diff --git a/actix_web/http/header/fn.parse_extended_value.html b/actix_web/http/header/fn.parse_extended_value.html new file mode 100644 index 000000000..98a9c6b61 --- /dev/null +++ b/actix_web/http/header/fn.parse_extended_value.html @@ -0,0 +1,30 @@ +parse_extended_value in actix_web::http::header - Rust

Function actix_web::http::header::parse_extended_value

source ·
pub fn parse_extended_value(val: &str) -> Result<ExtendedValue, ParseError>
Expand description

Parses extended header parameter values (ext-value), as defined +in RFC 5987 §3.2.

+

Extended values are denoted by parameter names that end with *.

+

§ABNF

ext-value     = charset  "'" [ language ] "'" value-chars
+              ; like RFC 2231's <extended-initial-value>
+              ; (see [RFC 2231 §7])
+
+charset       = "UTF-8" / "ISO-8859-1" / mime-charset
+
+mime-charset  = 1*mime-charsetc
+mime-charsetc = ALPHA / DIGIT
+              / "!" / "#" / "$" / "%" / "&"
+              / "+" / "-" / "^" / "_" / "`"
+              / "{" / "}" / "~"
+              ; as <mime-charset> in [RFC 2978 §2.3]
+              ; except that the single quote is not included
+              ; SHOULD be registered in the IANA charset registry
+
+language      = <Language-Tag, defined in [RFC 5646 §2.1]>
+
+value-chars   = *( pct-encoded / attr-char )
+
+pct-encoded   = "%" HEXDIG HEXDIG
+              ; see [RFC 3986 §2.1]
+
+attr-char     = ALPHA / DIGIT
+              / "!" / "#" / "$" / "&" / "+" / "-" / "."
+              / "^" / "_" / "`" / "|" / "~"
+              ; token except ( "*" / "'" / "%" )
+
\ No newline at end of file diff --git a/actix_web/http/header/fn.q.html b/actix_web/http/header/fn.q.html new file mode 100644 index 000000000..70d327b82 --- /dev/null +++ b/actix_web/http/header/fn.q.html @@ -0,0 +1,21 @@ +q in actix_web::http::header - Rust

Function actix_web::http::header::q

source ·
pub fn q<T>(quality: T) -> Quality
where + T: TryInto<Quality>, + <T as TryInto<Quality>>::Error: Debug,
Expand description

Convenience function to create a Quality from an f32 (0.0–1.0).

+

Not recommended for use with user input. Rely on the TryFrom impls where possible.

+

§Panics

+

Panics if value is out of range.

+

§Examples

+
let q1 = q(1.0);
+assert_eq!(q1, Quality::MAX);
+
+let q2 = q(0.001);
+assert_eq!(q2, Quality::MIN);
+
+let q3 = q(0.0);
+assert_eq!(q3, Quality::ZERO);
+
+let q4 = q(0.42);
+

An out-of-range f32 quality will panic.

+ +
let _q2 = q(1.42);
+
\ No newline at end of file diff --git a/actix_web/http/header/if_match/enum.IfMatch.html b/actix_web/http/header/if_match/enum.IfMatch.html new file mode 100644 index 000000000..bb4faae41 --- /dev/null +++ b/actix_web/http/header/if_match/enum.IfMatch.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/enum.IfMatch.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/if_modified_since/struct.IfModifiedSince.html b/actix_web/http/header/if_modified_since/struct.IfModifiedSince.html new file mode 100644 index 000000000..ac7d7e145 --- /dev/null +++ b/actix_web/http/header/if_modified_since/struct.IfModifiedSince.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.IfModifiedSince.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/if_none_match/enum.IfNoneMatch.html b/actix_web/http/header/if_none_match/enum.IfNoneMatch.html new file mode 100644 index 000000000..82c9e06f5 --- /dev/null +++ b/actix_web/http/header/if_none_match/enum.IfNoneMatch.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/enum.IfNoneMatch.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/if_range/enum.IfRange.html b/actix_web/http/header/if_range/enum.IfRange.html new file mode 100644 index 000000000..d5bc90c88 --- /dev/null +++ b/actix_web/http/header/if_range/enum.IfRange.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/enum.IfRange.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/if_unmodified_since/struct.IfUnmodifiedSince.html b/actix_web/http/header/if_unmodified_since/struct.IfUnmodifiedSince.html new file mode 100644 index 000000000..562ab630b --- /dev/null +++ b/actix_web/http/header/if_unmodified_since/struct.IfUnmodifiedSince.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.IfUnmodifiedSince.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/index.html b/actix_web/http/header/index.html new file mode 100644 index 000000000..694ea995b --- /dev/null +++ b/actix_web/http/header/index.html @@ -0,0 +1,94 @@ +actix_web::http::header - Rust

Module actix_web::http::header

source ·
Expand description

A Collection of Header implementations for common HTTP Headers.

+

§Mime Types

+

Several header fields use MIME values for their contents. Keeping with the strongly-typed theme, +the mime crate is used in such headers as ContentType and Accept.

+

Modules§

Structs§

Enums§

Constants§

  • Advertises which content types the client is able to understand.
  • Advertises which character set the client is able to understand.
  • Advertises which content encoding the client is able to understand.
  • Advertises which languages the client is able to understand.
  • Marker used by the server to advertise partial request support.
  • Preflight response indicating if the response to the request can be +exposed to the page.
  • Preflight response indicating permitted HTTP headers.
  • Preflight header response indicating permitted access methods.
  • Indicates whether the response can be shared with resources with the +given origin.
  • Indicates which headers can be exposed as part of the response by +listing their names.
  • Indicates how long the results of a preflight request can be cached.
  • Informs the server which HTTP headers will be used when an actual +request is made.
  • Informs the server know which HTTP method will be used when the actual +request is made.
  • Indicates the time in seconds the object has been in a proxy cache.
  • Lists the set of methods support by a resource.
  • Advertises the availability of alternate services to clients.
  • Contains the credentials to authenticate a user agent with a server.
  • Specifies directives for caching mechanisms in both requests and +responses.
  • Response header field that indicates how caches have handled that response and its corresponding +request.
  • Response header field that allows origin servers to control the behavior of CDN caches +interposed between them and clients separately from other caches that might handle the response.
  • Controls whether or not the network connection stays open after the +current transaction finishes.
  • Indicates if the content is expected to be displayed inline.
  • Used to compress the media-type.
  • Used to describe the languages intended for the audience.
  • Indicates the size of the entity-body.
  • Indicates an alternate location for the returned data.
  • Indicates where in a full body message a partial message belongs.
  • Allows controlling resources the user agent is allowed to load for a +given page.
  • Allows experimenting with policies by monitoring their effects.
  • Used to indicate the media type of the resource.
  • Contains stored HTTP cookies previously sent by the server with the +Set-Cookie header.
  • Response header that prevents a document from loading any cross-origin resources that don’t +explicitly grant the document permission (using CORP or CORS).
  • Response header that allows you to ensure a top-level document does not share a browsing context +group with cross-origin documents.
  • Response header that conveys a desire that the browser blocks no-cors cross-origin/cross-site +requests to the given resource.
  • Contains the date and time at which the message was originated.
  • Indicates the client’s tracking preference.
  • Identifier for a specific version of a resource.
  • Indicates expectations that need to be fulfilled by the server in order +to properly handle the request.
  • Contains the date/time after which the response is considered stale.
  • Contains information from the client-facing side of proxy servers that +is altered or lost when a proxy is involved in the path of the request.
  • Contains an Internet email address for a human user who controls the +requesting user agent.
  • Specifies the domain name of the server and (optionally) the TCP port +number on which the server is listening.
  • Makes a request conditional based on the E-Tag.
  • Makes a request conditional based on the modification date.
  • Makes a request conditional based on the E-Tag.
  • Makes a request conditional based on range.
  • Makes the request conditional based on the last modification date.
  • Content-Types that are acceptable for the response.
  • Allows the server to point an interested client to another resource +containing metadata about the requested resource.
  • Indicates the URL to redirect a page to.
  • Indicates the max number of intermediaries the request should be sent +through.
  • Indicates where a fetch originates from.
  • Response header that provides a mechanism to allow and deny the use of browser features in a +document or within any <iframe> elements in the document.
  • HTTP/1.0 header usually used for backwards compatibility.
  • Defines the authentication method that should be used to gain access to +a proxy.
  • Contains the credentials to authenticate a user agent to a proxy server.
  • Associates a specific cryptographic public key with a certain server.
  • Sends reports of pinning violation to the report-uri specified in the +header.
  • Indicates the part of a document that the server should return.
  • Contains the address of the previous web page from which a link to the +currently requested page was followed.
  • Governs which referrer information should be included with requests +made.
  • Informs the web browser that the current page or frame should be +refreshed.
  • The Retry-After response HTTP header indicates how long the user agent +should wait before making a follow-up request. There are two main cases +this header is used:
  • The |Sec-WebSocket-Accept| header field is used in the WebSocket +opening handshake. It is sent from the server to the client to +confirm that the server is willing to initiate the WebSocket +connection.
  • The |Sec-WebSocket-Extensions| header field is used in the WebSocket +opening handshake. It is initially sent from the client to the +server, and then subsequently sent from the server to the client, to +agree on a set of protocol-level extensions to use for the duration +of the connection.
  • The |Sec-WebSocket-Key| header field is used in the WebSocket opening +handshake. It is sent from the client to the server to provide part +of the information used by the server to prove that it received a +valid WebSocket opening handshake. This helps ensure that the server +does not accept connections from non-WebSocket clients (e.g., HTTP +clients) that are being abused to send data to unsuspecting WebSocket +servers.
  • The |Sec-WebSocket-Protocol| header field is used in the WebSocket +opening handshake. It is sent from the client to the server and back +from the server to the client to confirm the subprotocol of the +connection. This enables scripts to both select a subprotocol and be +sure that the server agreed to serve that subprotocol.
  • The |Sec-WebSocket-Version| header field is used in the WebSocket +opening handshake. It is sent from the client to the server to +indicate the protocol version of the connection. This enables +servers to correctly interpret the opening handshake and subsequent +data being sent from the data, and close the connection if the server +cannot interpret that data in a safe manner.
  • Contains information about the software used by the origin server to +handle the request.
  • Used to send cookies from the server to the user agent.
  • Tells the client to communicate with HTTPS instead of using HTTP.
  • Informs the server of transfer encodings willing to be accepted as part +of the response.
  • Allows the sender to include additional fields at the end of chunked +messages.
  • Specifies the form of encoding used to safely transfer the entity to the +client.
  • Used as part of the exchange to upgrade the protocol.
  • Sends a signal to the server expressing the client’s preference for an +encrypted and authenticated response.
  • Contains a string that allows identifying the requesting client’s +software.
  • Determines how to match future requests with cached responses.
  • Added by proxies to track routing.
  • General HTTP header contains information about possible problems with +the status of the message.
  • Defines the authentication method that should be used to gain access to +a resource.
  • Marker used by the server to indicate that the MIME types advertised in +the content-type headers should not be changed and be followed.
  • Controls DNS prefetching.
  • Request header (de-facto standard) for identifying the originating IP address of a client +connecting to a web server through a proxy server.
  • Request header (de-facto standard) for identifying the original host requested by the client in +the Host HTTP request header.
  • Request header (de-facto standard) for identifying the protocol that a client used to connect to +your proxy or load balancer.
  • Indicates whether or not a browser should be allowed to render a page in +a frame.
  • Stop pages from loading when an XSS attack is detected.

Traits§

Functions§

\ No newline at end of file diff --git a/actix_web/http/header/last_modified/struct.LastModified.html b/actix_web/http/header/last_modified/struct.LastModified.html new file mode 100644 index 000000000..530e5df09 --- /dev/null +++ b/actix_web/http/header/last_modified/struct.LastModified.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/struct.LastModified.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/map/index.html b/actix_web/http/header/map/index.html new file mode 100644 index 000000000..730a618a3 --- /dev/null +++ b/actix_web/http/header/map/index.html @@ -0,0 +1,2 @@ +actix_web::http::header::map - Rust

Module actix_web::http::header::map

source ·
Expand description

A multi-value HeaderMap and its iterators.

+

Structs§

  • Iterator over drained name-value pairs.
  • A multi-map of HTTP headers.
  • Iterator over owned name-value pairs.
  • Iterator over borrowed name-value pairs.
  • Iterator over all names in the map.
  • Iterator over removed, owned values with the same associated name.
\ No newline at end of file diff --git a/actix_web/http/header/map/sidebar-items.js b/actix_web/http/header/map/sidebar-items.js new file mode 100644 index 000000000..d8f41164a --- /dev/null +++ b/actix_web/http/header/map/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Drain","HeaderMap","IntoIter","Iter","Keys","Removed"]}; \ No newline at end of file diff --git a/actix_web/http/header/map/struct.Drain.html b/actix_web/http/header/map/struct.Drain.html new file mode 100644 index 000000000..a0e7125a9 --- /dev/null +++ b/actix_web/http/header/map/struct.Drain.html @@ -0,0 +1,203 @@ +Drain in actix_web::http::header::map - Rust

Struct actix_web::http::header::map::Drain

source ·
pub struct Drain<'a> { /* private fields */ }
Expand description

Iterator over drained name-value pairs.

+

Iterator items are (Option<HeaderName>, HeaderValue) to avoid cloning.

+

Trait Implementations§

source§

impl<'a> Debug for Drain<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl ExactSizeIterator for Drain<'_>

1.0.0 · source§

fn len(&self) -> usize

Returns the exact remaining length of the iterator. Read more
source§

fn is_empty(&self) -> bool

🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
source§

impl<'a> Iterator for Drain<'a>

§

type Item = (Option<HeaderName>, HeaderValue)

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<<Drain<'a> as Iterator>::Item>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usize
where + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>
where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl FusedIterator for Drain<'_>

Auto Trait Implementations§

§

impl<'a> !Freeze for Drain<'a>

§

impl<'a> RefUnwindSafe for Drain<'a>

§

impl<'a> Send for Drain<'a>

§

impl<'a> Sync for Drain<'a>

§

impl<'a> Unpin for Drain<'a>

§

impl<'a> UnwindSafe for Drain<'a>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for I
where + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<I> IteratorRandom for I
where + I: Iterator,

source§

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where + R: Rng + ?Sized,

Collects values at random from the iterator into a supplied buffer +until that buffer is filled. Read more
source§

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where + R: Rng + ?Sized,

Available on crate feature alloc only.
Collects amount values at random from the iterator into a vector. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/map/struct.HeaderMap.html b/actix_web/http/header/map/struct.HeaderMap.html new file mode 100644 index 000000000..2d26c3689 --- /dev/null +++ b/actix_web/http/header/map/struct.HeaderMap.html @@ -0,0 +1,330 @@ +HeaderMap in actix_web::http::header::map - Rust

Struct actix_web::http::header::map::HeaderMap

source ·
pub struct HeaderMap { /* private fields */ }
Expand description

A multi-map of HTTP headers.

+

HeaderMap is a “multi-map” of HeaderName to one or more HeaderValues.

+

§Examples

+
use actix_http::header::{self, HeaderMap, HeaderValue};
+
+let mut map = HeaderMap::new();
+
+map.insert(header::CONTENT_TYPE, HeaderValue::from_static("text/plain"));
+map.insert(header::ORIGIN, HeaderValue::from_static("example.com"));
+
+assert!(map.contains_key(header::CONTENT_TYPE));
+assert!(map.contains_key(header::ORIGIN));
+
+let mut removed = map.remove(header::ORIGIN);
+assert_eq!(removed.next().unwrap(), "example.com");
+
+assert!(!map.contains_key(header::ORIGIN));
+

Implementations§

source§

impl HeaderMap

source

pub fn new() -> HeaderMap

Create an empty HeaderMap.

+

The map will be created without any capacity; this function will not allocate.

+
§Examples
+
let map = HeaderMap::new();
+
+assert!(map.is_empty());
+assert_eq!(0, map.capacity());
+
source

pub fn with_capacity(capacity: usize) -> HeaderMap

Create an empty HeaderMap with the specified capacity.

+

The map will be able to hold at least capacity elements without needing to reallocate. +If capacity is 0, the map will be created without allocating.

+
§Examples
+
let map = HeaderMap::with_capacity(16);
+
+assert!(map.is_empty());
+assert!(map.capacity() >= 16);
+
source

pub fn len(&self) -> usize

Returns the number of values stored in the map.

+

See also: len_keys.

+
§Examples
+
let mut map = HeaderMap::new();
+assert_eq!(map.len(), 0);
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+assert_eq!(map.len(), 2);
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+assert_eq!(map.len(), 3);
+
source

pub fn len_keys(&self) -> usize

Returns the number of keys stored in the map.

+

The number of values stored will be at least this number. See also: Self::len.

+
§Examples
+
let mut map = HeaderMap::new();
+assert_eq!(map.len_keys(), 0);
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+assert_eq!(map.len_keys(), 2);
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+assert_eq!(map.len_keys(), 2);
+
source

pub fn is_empty(&self) -> bool

Returns true if the map contains no elements.

+
§Examples
+
let mut map = HeaderMap::new();
+assert!(map.is_empty());
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(!map.is_empty());
+
source

pub fn clear(&mut self)

Clears the map, removing all name-value pairs.

+

Keeps the allocated memory for reuse.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+assert_eq!(map.len(), 2);
+
+map.clear();
+assert!(map.is_empty());
+
source

pub fn get(&self, key: impl AsHeaderName) -> Option<&HeaderValue>

Returns a reference to the first value associated with a header name.

+

Returns None if there is no value associated with the key.

+

Even when multiple values are associated with the key, the “first” one is returned but is +not guaranteed to be chosen with any particular order; though, the returned item will be +consistent for each call to get if the map has not changed.

+

See also: get_all.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+
+let cookie = map.get(header::SET_COOKIE).unwrap();
+assert_eq!(cookie, "one=1");
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+assert_eq!(map.get(header::SET_COOKIE).unwrap(), "one=1");
+
+assert_eq!(map.get(header::SET_COOKIE), map.get("set-cookie"));
+assert_eq!(map.get(header::SET_COOKIE), map.get("Set-Cookie"));
+
+assert!(map.get(header::HOST).is_none());
+assert!(map.get("INVALID HEADER NAME").is_none());
+
source

pub fn get_mut(&mut self, key: impl AsHeaderName) -> Option<&mut HeaderValue>

Returns a mutable reference to the first value associated a header name.

+

Returns None if there is no value associated with the key.

+

Even when multiple values are associated with the key, the “first” one is returned but is +not guaranteed to be chosen with any particular order; though, the returned item will be +consistent for each call to get_mut if the map has not changed.

+

See also: get_all.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+
+let mut cookie = map.get_mut(header::SET_COOKIE).unwrap();
+assert_eq!(cookie, "one=1");
+
+*cookie = HeaderValue::from_static("three=3");
+assert_eq!(map.get(header::SET_COOKIE).unwrap(), "three=3");
+
+assert!(map.get(header::HOST).is_none());
+assert!(map.get("INVALID HEADER NAME").is_none());
+
source

pub fn get_all(&self, key: impl AsHeaderName) -> Iter<'_, HeaderValue>

Returns an iterator over all values associated with a header name.

+

The returned iterator does not incur any allocations and will yield no items if there are no +values associated with the key. Iteration order is guaranteed to be the same as +insertion order.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut none_iter = map.get_all(header::ORIGIN);
+assert!(none_iter.next().is_none());
+
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let mut set_cookies_iter = map.get_all(header::SET_COOKIE);
+assert_eq!(set_cookies_iter.next().unwrap(), "one=1");
+assert_eq!(set_cookies_iter.next().unwrap(), "two=2");
+assert!(set_cookies_iter.next().is_none());
+
source

pub fn contains_key(&self, key: impl AsHeaderName) -> bool

Returns true if the map contains a value for the specified key.

+

Invalid header names will simply return false.

+
§Examples
+
let mut map = HeaderMap::new();
+assert!(!map.contains_key(header::ACCEPT));
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(map.contains_key(header::ACCEPT));
+
source

pub fn insert(&mut self, key: HeaderName, val: HeaderValue) -> Removed

Inserts (overrides) a name-value pair in the map.

+

If the map already contained this key, the new value is associated with the key and all +previous values are removed and returned as a Removed iterator. The key is not updated; +this matters for types that can be == without being identical.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(map.contains_key(header::ACCEPT));
+assert_eq!(map.len(), 1);
+
+let mut removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/csv"));
+assert_eq!(removed.next().unwrap(), "text/plain");
+assert!(removed.next().is_none());
+
+assert_eq!(map.len(), 1);
+

A convenience method is provided on the returned iterator to check if the insertion replaced +any values.

+ +
let mut map = HeaderMap::new();
+
+let removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(removed.is_empty());
+
+let removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/html"));
+assert!(!removed.is_empty());
+
source

pub fn append(&mut self, key: HeaderName, value: HeaderValue)

Appends a name-value pair to the map.

+

If the map already contained this key, the new value is added to the list of values +currently associated with the key. The key is not updated; this matters for types that can +be == without being identical.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.append(header::HOST, HeaderValue::from_static("example.com"));
+assert_eq!(map.len(), 1);
+
+map.append(header::ACCEPT, HeaderValue::from_static("text/csv"));
+assert_eq!(map.len(), 2);
+
+map.append(header::ACCEPT, HeaderValue::from_static("text/html"));
+assert_eq!(map.len(), 3);
+
source

pub fn remove(&mut self, key: impl AsHeaderName) -> Removed

Removes all headers for a particular header name from the map.

+

Providing an invalid header names (as a string argument) will have no effect and return +without error.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=2"));
+
+assert_eq!(map.len(), 2);
+
+let mut removed = map.remove(header::SET_COOKIE);
+assert_eq!(removed.next().unwrap(), "one=1");
+assert_eq!(removed.next().unwrap(), "one=2");
+assert!(removed.next().is_none());
+
+assert!(map.is_empty());
+

A convenience method is provided on the returned iterator to check if the remove call +actually removed any values.

+ +
let mut map = HeaderMap::new();
+
+let removed = map.remove("accept");
+assert!(removed.is_empty());
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/html"));
+let removed = map.remove("accept");
+assert!(!removed.is_empty());
+
source

pub fn capacity(&self) -> usize

Returns the number of single-value headers the map can hold without needing to reallocate.

+

Since this is a multi-value map, the actual capacity is much larger when considering +each header name can be associated with an arbitrary number of values. The effect is that +the size of len may be greater than capacity since it counts all the values. +Conversely, len_keys will never be larger than capacity.

+
§Examples
+
let map = HeaderMap::with_capacity(16);
+
+assert!(map.is_empty());
+assert!(map.capacity() >= 16);
+
source

pub fn reserve(&mut self, additional: usize)

Reserves capacity for at least additional more headers to be inserted in the map.

+

The header map may reserve more space to avoid frequent reallocations. Additional capacity +only considers single-value headers.

+
§Panics
+

Panics if the new allocation size overflows usize.

+
§Examples
+
let mut map = HeaderMap::with_capacity(2);
+assert!(map.capacity() >= 2);
+
+map.reserve(100);
+assert!(map.capacity() >= 102);
+
+assert!(map.is_empty());
+
source

pub fn iter(&self) -> Iter<'_>

An iterator over all name-value pairs.

+

Names will be yielded for each associated value. So, if a key has 3 associated values, it +will be yielded 3 times. The iteration order should be considered arbitrary.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut iter = map.iter();
+assert!(iter.next().is_none());
+
+map.append(header::HOST, HeaderValue::from_static("duck.com"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let mut iter = map.iter();
+assert!(iter.next().is_some());
+assert!(iter.next().is_some());
+assert!(iter.next().is_some());
+assert!(iter.next().is_none());
+
+let pairs = map.iter().collect::<Vec<_>>();
+assert!(pairs.contains(&(&header::HOST, &HeaderValue::from_static("duck.com"))));
+assert!(pairs.contains(&(&header::SET_COOKIE, &HeaderValue::from_static("one=1"))));
+assert!(pairs.contains(&(&header::SET_COOKIE, &HeaderValue::from_static("two=2"))));
+
source

pub fn keys(&self) -> Keys<'_>

An iterator over all contained header names.

+

Each name will only be yielded once even if it has multiple associated values. The iteration +order should be considered arbitrary.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut iter = map.keys();
+assert!(iter.next().is_none());
+
+map.append(header::HOST, HeaderValue::from_static("duck.com"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let keys = map.keys().cloned().collect::<Vec<_>>();
+assert_eq!(keys.len(), 2);
+assert!(keys.contains(&header::HOST));
+assert!(keys.contains(&header::SET_COOKIE));
+
source

pub fn retain<F>(&mut self, retain_fn: F)
where + F: FnMut(&HeaderName, &mut HeaderValue) -> bool,

Retains only the headers specified by the predicate.

+

In other words, removes all headers (name, val) for which retain_fn(&name, &mut val) +returns false.

+

The order in which headers are visited should be considered arbitrary.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.append(header::HOST, HeaderValue::from_static("duck.com"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+map.retain(|name, val| val.as_bytes().starts_with(b"one"));
+
+assert_eq!(map.len(), 1);
+assert!(map.contains_key(&header::SET_COOKIE));
+
source

pub fn drain(&mut self) -> Drain<'_>

Clears the map, returning all name-value sets as an iterator.

+

Header names will only be yielded for the first value in each set. All items that are +yielded without a name and after an item with a name are associated with that same name. +The first item will always contain a name.

+

Keeps the allocated memory for reuse.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut iter = map.drain();
+assert!(iter.next().is_none());
+drop(iter);
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let mut iter = map.drain();
+assert_eq!(iter.next().unwrap(), (Some(header::SET_COOKIE), HeaderValue::from_static("one=1")));
+assert_eq!(iter.next().unwrap(), (None, HeaderValue::from_static("two=2")));
+drop(iter);
+
+assert!(map.is_empty());
+

Trait Implementations§

source§

impl Clone for HeaderMap

source§

fn clone(&self) -> HeaderMap

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for HeaderMap

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for HeaderMap

source§

fn default() -> HeaderMap

Returns the “default value” for a type. Read more
source§

impl From<HeaderMap> for HeaderMap

Convert a http::HeaderMap to our HeaderMap.

+
source§

fn from(map: HeaderMap) -> HeaderMap

Converts to this type from the input type.
source§

impl<'a> IntoIterator for &'a HeaderMap

§

type Item = (&'a HeaderName, &'a HeaderValue)

The type of the elements being iterated over.
§

type IntoIter = Iter<'a>

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> <&'a HeaderMap as IntoIterator>::IntoIter

Creates an iterator from a value. Read more
source§

impl IntoIterator for HeaderMap

Note that this implementation will clone a HeaderName for each value. Consider using +drain to control header name cloning.

+
§

type Item = (HeaderName, HeaderValue)

The type of the elements being iterated over.
§

type IntoIter = IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> <HeaderMap as IntoIterator>::IntoIter

Creates an iterator from a value. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/map/struct.IntoIter.html b/actix_web/http/header/map/struct.IntoIter.html new file mode 100644 index 000000000..53ff8e0c4 --- /dev/null +++ b/actix_web/http/header/map/struct.IntoIter.html @@ -0,0 +1,206 @@ +IntoIter in actix_web::http::header::map - Rust

Struct actix_web::http::header::map::IntoIter

source ·
pub struct IntoIter { /* private fields */ }
Expand description

Iterator over owned name-value pairs.

+

Implementation necessarily clones header names for each value.

+

Trait Implementations§

source§

impl Debug for IntoIter

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl ExactSizeIterator for IntoIter

1.0.0 · source§

fn len(&self) -> usize

Returns the exact remaining length of the iterator. Read more
source§

fn is_empty(&self) -> bool

🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
source§

impl Iterator for IntoIter

§

type Item = (HeaderName, HeaderValue)

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<<IntoIter as Iterator>::Item>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usize
where + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>
where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
where + Self: Sized, + Self::Item: Clone,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places a copy of separator between adjacent +items of the original iterator. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl FusedIterator for IntoIter

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for I
where + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<I> IteratorRandom for I
where + I: Iterator,

source§

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where + R: Rng + ?Sized,

Collects values at random from the iterator into a supplied buffer +until that buffer is filled. Read more
source§

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where + R: Rng + ?Sized,

Available on crate feature alloc only.
Collects amount values at random from the iterator into a vector. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/map/struct.Iter.html b/actix_web/http/header/map/struct.Iter.html new file mode 100644 index 000000000..2fa17e45f --- /dev/null +++ b/actix_web/http/header/map/struct.Iter.html @@ -0,0 +1,202 @@ +Iter in actix_web::http::header::map - Rust

Struct actix_web::http::header::map::Iter

source ·
pub struct Iter<'a> { /* private fields */ }
Expand description

Iterator over borrowed name-value pairs.

+

Trait Implementations§

source§

impl<'a> Debug for Iter<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl ExactSizeIterator for Iter<'_>

1.0.0 · source§

fn len(&self) -> usize

Returns the exact remaining length of the iterator. Read more
source§

fn is_empty(&self) -> bool

🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
source§

impl<'a> Iterator for Iter<'a>

§

type Item = (&'a HeaderName, &'a HeaderValue)

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<<Iter<'a> as Iterator>::Item>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usize
where + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>
where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl FusedIterator for Iter<'_>

Auto Trait Implementations§

§

impl<'a> Freeze for Iter<'a>

§

impl<'a> RefUnwindSafe for Iter<'a>

§

impl<'a> Send for Iter<'a>

§

impl<'a> Sync for Iter<'a>

§

impl<'a> Unpin for Iter<'a>

§

impl<'a> UnwindSafe for Iter<'a>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for I
where + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<I> IteratorRandom for I
where + I: Iterator,

source§

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where + R: Rng + ?Sized,

Collects values at random from the iterator into a supplied buffer +until that buffer is filled. Read more
source§

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where + R: Rng + ?Sized,

Available on crate feature alloc only.
Collects amount values at random from the iterator into a vector. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/map/struct.Keys.html b/actix_web/http/header/map/struct.Keys.html new file mode 100644 index 000000000..b931cf813 --- /dev/null +++ b/actix_web/http/header/map/struct.Keys.html @@ -0,0 +1,202 @@ +Keys in actix_web::http::header::map - Rust

Struct actix_web::http::header::map::Keys

source ·
pub struct Keys<'a>(/* private fields */);
Expand description

Iterator over all names in the map.

+

Trait Implementations§

source§

impl<'a> Debug for Keys<'a>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl ExactSizeIterator for Keys<'_>

1.0.0 · source§

fn len(&self) -> usize

Returns the exact remaining length of the iterator. Read more
source§

fn is_empty(&self) -> bool

🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
source§

impl<'a> Iterator for Keys<'a>

§

type Item = &'a HeaderName

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<<Keys<'a> as Iterator>::Item>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usize
where + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>
where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl FusedIterator for Keys<'_>

Auto Trait Implementations§

§

impl<'a> Freeze for Keys<'a>

§

impl<'a> RefUnwindSafe for Keys<'a>

§

impl<'a> Send for Keys<'a>

§

impl<'a> Sync for Keys<'a>

§

impl<'a> Unpin for Keys<'a>

§

impl<'a> UnwindSafe for Keys<'a>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for I
where + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<I> IteratorRandom for I
where + I: Iterator,

source§

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where + R: Rng + ?Sized,

Collects values at random from the iterator into a supplied buffer +until that buffer is filled. Read more
source§

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where + R: Rng + ?Sized,

Available on crate feature alloc only.
Collects amount values at random from the iterator into a vector. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/map/struct.Removed.html b/actix_web/http/header/map/struct.Removed.html new file mode 100644 index 000000000..e805656c9 --- /dev/null +++ b/actix_web/http/header/map/struct.Removed.html @@ -0,0 +1,220 @@ +Removed in actix_web::http::header::map - Rust

Struct actix_web::http::header::map::Removed

source ·
pub struct Removed { /* private fields */ }
Expand description

Iterator over removed, owned values with the same associated name.

+

Returned from methods that remove or replace items. See HeaderMap::insert +and HeaderMap::remove.

+

Implementations§

source§

impl Removed

source

pub fn is_empty(&self) -> bool

Returns true if iterator contains no elements, without consuming it.

+

If called immediately after HeaderMap::insert or HeaderMap::remove, it will indicate +whether any items were actually replaced or removed, respectively.

+

Trait Implementations§

source§

impl Debug for Removed

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl ExactSizeIterator for Removed

1.0.0 · source§

fn len(&self) -> usize

Returns the exact remaining length of the iterator. Read more
source§

fn is_empty(&self) -> bool

🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
source§

impl Iterator for Removed

§

type Item = HeaderValue

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<<Removed as Iterator>::Item>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usize
where + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>
where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
where + Self: Sized, + Self::Item: Clone,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places a copy of separator between adjacent +items of the original iterator. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.0.0 · source§

fn max(self) -> Option<Self::Item>
where + Self: Sized, + Self::Item: Ord,

Returns the maximum element of an iterator. Read more
1.0.0 · source§

fn min(self) -> Option<Self::Item>
where + Self: Sized, + Self::Item: Ord,

Returns the minimum element of an iterator. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
1.5.0 · source§

fn cmp<I>(self, other: I) -> Ordering
where + I: IntoIterator<Item = Self::Item>, + Self::Item: Ord, + Self: Sized,

Lexicographically compares the elements of this Iterator with those +of another. Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted(self) -> bool
where + Self: Sized, + Self::Item: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
source§

impl FusedIterator for Removed

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for I
where + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<I> IteratorRandom for I
where + I: Iterator,

source§

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where + R: Rng + ?Sized,

Collects values at random from the iterator into a supplied buffer +until that buffer is filled. Read more
source§

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where + R: Rng + ?Sized,

Available on crate feature alloc only.
Collects amount values at random from the iterator into a vector. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/preference/enum.Preference.html b/actix_web/http/header/preference/enum.Preference.html new file mode 100644 index 000000000..6f852253a --- /dev/null +++ b/actix_web/http/header/preference/enum.Preference.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/enum.Preference.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/range/enum.ByteRangeSpec.html b/actix_web/http/header/range/enum.ByteRangeSpec.html new file mode 100644 index 000000000..982d74559 --- /dev/null +++ b/actix_web/http/header/range/enum.ByteRangeSpec.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/enum.ByteRangeSpec.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/range/enum.Range.html b/actix_web/http/header/range/enum.Range.html new file mode 100644 index 000000000..0eff8ed7e --- /dev/null +++ b/actix_web/http/header/range/enum.Range.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../../actix_web/http/header/enum.Range.html...

+ + + \ No newline at end of file diff --git a/actix_web/http/header/sidebar-items.js b/actix_web/http/header/sidebar-items.js new file mode 100644 index 000000000..929e60808 --- /dev/null +++ b/actix_web/http/header/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"constant":["ACCEPT","ACCEPT_CHARSET","ACCEPT_ENCODING","ACCEPT_LANGUAGE","ACCEPT_RANGES","ACCESS_CONTROL_ALLOW_CREDENTIALS","ACCESS_CONTROL_ALLOW_HEADERS","ACCESS_CONTROL_ALLOW_METHODS","ACCESS_CONTROL_ALLOW_ORIGIN","ACCESS_CONTROL_EXPOSE_HEADERS","ACCESS_CONTROL_MAX_AGE","ACCESS_CONTROL_REQUEST_HEADERS","ACCESS_CONTROL_REQUEST_METHOD","AGE","ALLOW","ALT_SVC","AUTHORIZATION","CACHE_CONTROL","CACHE_STATUS","CDN_CACHE_CONTROL","CONNECTION","CONTENT_DISPOSITION","CONTENT_ENCODING","CONTENT_LANGUAGE","CONTENT_LENGTH","CONTENT_LOCATION","CONTENT_RANGE","CONTENT_SECURITY_POLICY","CONTENT_SECURITY_POLICY_REPORT_ONLY","CONTENT_TYPE","COOKIE","CROSS_ORIGIN_EMBEDDER_POLICY","CROSS_ORIGIN_OPENER_POLICY","CROSS_ORIGIN_RESOURCE_POLICY","DATE","DNT","ETAG","EXPECT","EXPIRES","FORWARDED","FROM","HOST","IF_MATCH","IF_MODIFIED_SINCE","IF_NONE_MATCH","IF_RANGE","IF_UNMODIFIED_SINCE","LAST_MODIFIED","LINK","LOCATION","MAX_FORWARDS","ORIGIN","PERMISSIONS_POLICY","PRAGMA","PROXY_AUTHENTICATE","PROXY_AUTHORIZATION","PUBLIC_KEY_PINS","PUBLIC_KEY_PINS_REPORT_ONLY","RANGE","REFERER","REFERRER_POLICY","REFRESH","RETRY_AFTER","SEC_WEBSOCKET_ACCEPT","SEC_WEBSOCKET_EXTENSIONS","SEC_WEBSOCKET_KEY","SEC_WEBSOCKET_PROTOCOL","SEC_WEBSOCKET_VERSION","SERVER","SET_COOKIE","STRICT_TRANSPORT_SECURITY","TE","TRAILER","TRANSFER_ENCODING","UPGRADE","UPGRADE_INSECURE_REQUESTS","USER_AGENT","VARY","VIA","WARNING","WWW_AUTHENTICATE","X_CONTENT_TYPE_OPTIONS","X_DNS_PREFETCH_CONTROL","X_FORWARDED_FOR","X_FORWARDED_HOST","X_FORWARDED_PROTO","X_FRAME_OPTIONS","X_XSS_PROTECTION"],"enum":["ByteRangeSpec","CacheDirective","Charset","ContentEncoding","ContentRangeSpec","DispositionParam","DispositionType","Encoding","IfMatch","IfNoneMatch","IfRange","Preference","Range"],"fn":["fmt_comma_delimited","from_comma_delimited","from_one_raw_str","http_percent_encode","parse_extended_value","q"],"mod":["map"],"struct":["Accept","AcceptCharset","AcceptEncoding","AcceptLanguage","Allow","CacheControl","ContentDisposition","ContentLanguage","ContentLength","ContentRange","ContentType","Date","ETag","EntityTag","Expires","ExtendedValue","HeaderMap","HeaderName","HeaderValue","HttpDate","IfModifiedSince","IfUnmodifiedSince","InvalidHeaderName","InvalidHeaderValue","LanguageTag","LastModified","Quality","QualityItem","ToStrError"],"trait":["AsHeaderName","Header","TryIntoHeaderPair","TryIntoHeaderValue"]}; \ No newline at end of file diff --git a/actix_web/http/header/struct.Accept.html b/actix_web/http/header/struct.Accept.html new file mode 100644 index 000000000..6ca7197a0 --- /dev/null +++ b/actix_web/http/header/struct.Accept.html @@ -0,0 +1,3167 @@ +Accept in actix_web::http::header - Rust

Struct actix_web::http::header::Accept

source ·
pub struct Accept(pub Vec<QualityItem<Mime>>);
Expand description

Accept header, defined in RFC 7231 §5.3.2.

+

The Accept header field can be used by user agents to specify +response media types that are acceptable. Accept header fields can +be used to indicate that the request is specifically limited to a +small set of desired types, as in the case of a request for an +in-line image

+

§ABNF

Accept = #( media-range [ accept-params ] )
+
+media-range    = ( "*/*"
+                 / ( type "/" "*" )
+                 / ( type "/" subtype )
+                 ) *( OWS ";" OWS parameter )
+accept-params  = weight *( accept-ext )
+accept-ext = OWS ";" OWS token [ "=" ( token / quoted-string ) ]
+

§Example Values

+
    +
  • audio/*; q=0.2, audio/basic
  • +
  • text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c
  • +
+

§Examples

+
use actix_web::HttpResponse;
+use actix_web::http::header::{Accept, QualityItem};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    Accept(vec![
+        QualityItem::max(mime::TEXT_HTML),
+    ])
+);
+ +
use actix_web::HttpResponse;
+use actix_web::http::header::{Accept, QualityItem};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    Accept(vec![
+        QualityItem::max(mime::APPLICATION_JSON),
+    ])
+);
+ +
use actix_web::HttpResponse;
+use actix_web::http::header::{Accept, QualityItem, q};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    Accept(vec![
+        QualityItem::max(mime::TEXT_HTML),
+        QualityItem::max("application/xhtml+xml".parse().unwrap()),
+        QualityItem::new(mime::TEXT_XML, q(0.9)),
+        QualityItem::max("image/webp".parse().unwrap()),
+        QualityItem::new(mime::STAR_STAR, q(0.8)),
+    ])
+);
+

Tuple Fields§

§0: Vec<QualityItem<Mime>>

Implementations§

source§

impl Accept

source

pub fn star() -> Accept

Construct Accept: */*.

+
source

pub fn json() -> Accept

Construct Accept: application/json.

+
source

pub fn text() -> Accept

Construct Accept: text/*.

+
source

pub fn image() -> Accept

Construct Accept: image/*.

+
source

pub fn html() -> Accept

Construct Accept: text/html.

+
source

pub fn preference(&self) -> Mime

Extracts the most preferable mime type, accounting for q-factor weighting.

+

If no q-factors are provided, the first mime type is chosen. Note that items without +q-factors are given the maximum preference value.

+

As per the spec, will return mime::STAR_STAR (indicating no preference) if the contained +list is empty.

+
source

pub fn ranked(&self) -> Vec<Mime>

Returns a sorted list of mime types from highest to lowest preference, accounting for +q-factor weighting and specificity.

+

Methods from Deref<Target = Vec<QualityItem<Mime>>>§

1.0.0 · source

pub fn capacity(&self) -> usize

Returns the total number of elements the vector can hold without +reallocating.

+
§Examples
+
let mut vec: Vec<i32> = Vec::with_capacity(10);
+vec.push(42);
+assert!(vec.capacity() >= 10);
+
1.0.0 · source

pub fn reserve(&mut self, additional: usize)

Available on non-no_global_oom_handling only.

Reserves capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to +speculatively avoid frequent reallocations. After calling reserve, +capacity will be greater than or equal to self.len() + additional. +Does nothing if capacity is already sufficient.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1];
+vec.reserve(10);
+assert!(vec.capacity() >= 11);
+
1.0.0 · source

pub fn reserve_exact(&mut self, additional: usize)

Available on non-no_global_oom_handling only.

Reserves the minimum capacity for at least additional more elements to +be inserted in the given Vec<T>. Unlike reserve, this will not +deliberately over-allocate to speculatively avoid frequent allocations. +After calling reserve_exact, capacity will be greater than or equal to +self.len() + additional. Does nothing if the capacity is already +sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer reserve if future insertions are expected.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1];
+vec.reserve_exact(10);
+assert!(vec.capacity() >= 11);
+
1.57.0 · source

pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>

Tries to reserve capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to speculatively avoid +frequent reallocations. After calling try_reserve, capacity will be +greater than or equal to self.len() + additional if it returns +Ok(()). Does nothing if capacity is already sufficient. This method +preserves the contents even if an error occurs.

+
§Errors
+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+
§Examples
+
use std::collections::TryReserveError;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+
1.57.0 · source

pub fn try_reserve_exact( + &mut self, + additional: usize +) -> Result<(), TryReserveError>

Tries to reserve the minimum capacity for at least additional +elements to be inserted in the given Vec<T>. Unlike try_reserve, +this will not deliberately over-allocate to speculatively avoid frequent +allocations. After calling try_reserve_exact, capacity will be greater +than or equal to self.len() + additional if it returns Ok(()). +Does nothing if the capacity is already sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer try_reserve if future insertions are expected.

+
§Errors
+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+
§Examples
+
use std::collections::TryReserveError;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve_exact(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+
1.0.0 · source

pub fn shrink_to_fit(&mut self)

Available on non-no_global_oom_handling only.

Shrinks the capacity of the vector as much as possible.

+

The behavior of this method depends on the allocator, which may either shrink the vector +in-place or reallocate. The resulting vector might still have some excess capacity, just as +is the case for with_capacity. See Allocator::shrink for more details.

+
§Examples
+
let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3]);
+assert!(vec.capacity() >= 10);
+vec.shrink_to_fit();
+assert!(vec.capacity() >= 3);
+
1.56.0 · source

pub fn shrink_to(&mut self, min_capacity: usize)

Available on non-no_global_oom_handling only.

Shrinks the capacity of the vector with a lower bound.

+

The capacity will remain at least as large as both the length +and the supplied value.

+

If the current capacity is less than the lower limit, this is a no-op.

+
§Examples
+
let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3]);
+assert!(vec.capacity() >= 10);
+vec.shrink_to(4);
+assert!(vec.capacity() >= 4);
+vec.shrink_to(0);
+assert!(vec.capacity() >= 3);
+
1.0.0 · source

pub fn truncate(&mut self, len: usize)

Shortens the vector, keeping the first len elements and dropping +the rest.

+

If len is greater or equal to the vector’s current length, this has +no effect.

+

The drain method can emulate truncate, but causes the excess +elements to be returned instead of dropped.

+

Note that this method has no effect on the allocated capacity +of the vector.

+
§Examples
+

Truncating a five element vector to two elements:

+ +
let mut vec = vec![1, 2, 3, 4, 5];
+vec.truncate(2);
+assert_eq!(vec, [1, 2]);
+

No truncation occurs when len is greater than the vector’s current +length:

+ +
let mut vec = vec![1, 2, 3];
+vec.truncate(8);
+assert_eq!(vec, [1, 2, 3]);
+

Truncating when len == 0 is equivalent to calling the clear +method.

+ +
let mut vec = vec![1, 2, 3];
+vec.truncate(0);
+assert_eq!(vec, []);
+
1.7.0 · source

pub fn as_slice(&self) -> &[T]

Extracts a slice containing the entire vector.

+

Equivalent to &s[..].

+
§Examples
+
use std::io::{self, Write};
+let buffer = vec![1, 2, 3, 5, 8];
+io::sink().write(buffer.as_slice()).unwrap();
+
1.7.0 · source

pub fn as_mut_slice(&mut self) -> &mut [T]

Extracts a mutable slice of the entire vector.

+

Equivalent to &mut s[..].

+
§Examples
+
use std::io::{self, Read};
+let mut buffer = vec![0; 3];
+io::repeat(0b101).read_exact(buffer.as_mut_slice()).unwrap();
+
1.37.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the vector’s buffer, or a dangling raw pointer +valid for zero sized reads if the vector didn’t allocate.

+

The caller must ensure that the vector outlives the pointer this +function returns, or else it will end up pointing to garbage. +Modifying the vector may cause its buffer to be reallocated, +which would also make any pointers to it invalid.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

This method guarantees that for the purpose of the aliasing model, this method +does not materialize a reference to the underlying slice, and thus the returned pointer +will remain valid when mixed with other calls to as_ptr and as_mut_ptr. +Note that calling other methods that materialize mutable references to the slice, +or mutable references to specific elements you are planning on accessing through this pointer, +as well as writing to those elements, may still invalidate this pointer. +See the second example below for how this guarantee can be used.

+
§Examples
+
let x = vec![1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(*x_ptr.add(i), 1 << i);
+    }
+}
+

Due to the aliasing guarantee, the following code is legal:

+ +
unsafe {
+    let mut v = vec![0, 1, 2];
+    let ptr1 = v.as_ptr();
+    let _ = ptr1.read();
+    let ptr2 = v.as_mut_ptr().offset(2);
+    ptr2.write(2);
+    // Notably, the write to `ptr2` did *not* invalidate `ptr1`
+    // because it mutated a different element:
+    let _ = ptr1.read();
+}
+
1.37.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the vector’s buffer, or a dangling +raw pointer valid for zero sized reads if the vector didn’t allocate.

+

The caller must ensure that the vector outlives the pointer this +function returns, or else it will end up pointing to garbage. +Modifying the vector may cause its buffer to be reallocated, +which would also make any pointers to it invalid.

+

This method guarantees that for the purpose of the aliasing model, this method +does not materialize a reference to the underlying slice, and thus the returned pointer +will remain valid when mixed with other calls to as_ptr and as_mut_ptr. +Note that calling other methods that materialize references to the slice, +or references to specific elements you are planning on accessing through this pointer, +may still invalidate this pointer. +See the second example below for how this guarantee can be used.

+
§Examples
+
// Allocate vector big enough for 4 elements.
+let size = 4;
+let mut x: Vec<i32> = Vec::with_capacity(size);
+let x_ptr = x.as_mut_ptr();
+
+// Initialize elements via raw pointer writes, then set length.
+unsafe {
+    for i in 0..size {
+        *x_ptr.add(i) = i as i32;
+    }
+    x.set_len(size);
+}
+assert_eq!(&*x, &[0, 1, 2, 3]);
+

Due to the aliasing guarantee, the following code is legal:

+ +
unsafe {
+    let mut v = vec![0];
+    let ptr1 = v.as_mut_ptr();
+    ptr1.write(1);
+    let ptr2 = v.as_mut_ptr();
+    ptr2.write(2);
+    // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
+    ptr1.write(3);
+}
+
source

pub fn allocator(&self) -> &A

🔬This is a nightly-only experimental API. (allocator_api)

Returns a reference to the underlying allocator.

+
1.0.0 · source

pub unsafe fn set_len(&mut self, new_len: usize)

Forces the length of the vector to new_len.

+

This is a low-level operation that maintains none of the normal +invariants of the type. Normally changing the length of a vector +is done using one of the safe operations instead, such as +truncate, resize, extend, or clear.

+
§Safety
+
    +
  • new_len must be less than or equal to capacity().
  • +
  • The elements at old_len..new_len must be initialized.
  • +
+
§Examples
+

This method can be useful for situations in which the vector +is serving as a buffer for other code, particularly over FFI:

+ +
pub fn get_dictionary(&self) -> Option<Vec<u8>> {
+    // Per the FFI method's docs, "32768 bytes is always enough".
+    let mut dict = Vec::with_capacity(32_768);
+    let mut dict_length = 0;
+    // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
+    // 1. `dict_length` elements were initialized.
+    // 2. `dict_length` <= the capacity (32_768)
+    // which makes `set_len` safe to call.
+    unsafe {
+        // Make the FFI call...
+        let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
+        if r == Z_OK {
+            // ...and update the length to what was initialized.
+            dict.set_len(dict_length);
+            Some(dict)
+        } else {
+            None
+        }
+    }
+}
+

While the following example is sound, there is a memory leak since +the inner vectors were not freed prior to the set_len call:

+ +
let mut vec = vec![vec![1, 0, 0],
+                   vec![0, 1, 0],
+                   vec![0, 0, 1]];
+// SAFETY:
+// 1. `old_len..0` is empty so no elements need to be initialized.
+// 2. `0 <= capacity` always holds whatever `capacity` is.
+unsafe {
+    vec.set_len(0);
+}
+

Normally, here, one would use clear instead to correctly drop +the contents and thus not leak memory.

+
1.0.0 · source

pub fn swap_remove(&mut self, index: usize) -> T

Removes an element from the vector and returns it.

+

The removed element is replaced by the last element of the vector.

+

This does not preserve ordering of the remaining elements, but is O(1). +If you need to preserve the element order, use remove instead.

+
§Panics
+

Panics if index is out of bounds.

+
§Examples
+
let mut v = vec!["foo", "bar", "baz", "qux"];
+
+assert_eq!(v.swap_remove(1), "bar");
+assert_eq!(v, ["foo", "qux", "baz"]);
+
+assert_eq!(v.swap_remove(0), "foo");
+assert_eq!(v, ["baz", "qux"]);
+
1.0.0 · source

pub fn insert(&mut self, index: usize, element: T)

Available on non-no_global_oom_handling only.

Inserts an element at position index within the vector, shifting all +elements after it to the right.

+
§Panics
+

Panics if index > len.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+vec.insert(1, 4);
+assert_eq!(vec, [1, 4, 2, 3]);
+vec.insert(4, 5);
+assert_eq!(vec, [1, 4, 2, 3, 5]);
+
§Time complexity
+

Takes O(Vec::len) time. All items after the insertion index must be +shifted to the right. In the worst case, all elements are shifted when +the insertion index is 0.

+
1.0.0 · source

pub fn remove(&mut self, index: usize) -> T

Removes and returns the element at position index within the vector, +shifting all elements after it to the left.

+

Note: Because this shifts over the remaining elements, it has a +worst-case performance of O(n). If you don’t need the order of elements +to be preserved, use swap_remove instead. If you’d like to remove +elements from the beginning of the Vec, consider using +VecDeque::pop_front instead.

+
§Panics
+

Panics if index is out of bounds.

+
§Examples
+
let mut v = vec![1, 2, 3];
+assert_eq!(v.remove(1), 2);
+assert_eq!(v, [1, 3]);
+
1.0.0 · source

pub fn retain<F>(&mut self, f: F)
where + F: FnMut(&T) -> bool,

Retains only the elements specified by the predicate.

+

In other words, remove all elements e for which f(&e) returns false. +This method operates in place, visiting each element exactly once in the +original order, and preserves the order of the retained elements.

+
§Examples
+
let mut vec = vec![1, 2, 3, 4];
+vec.retain(|&x| x % 2 == 0);
+assert_eq!(vec, [2, 4]);
+

Because the elements are visited exactly once in the original order, +external state may be used to decide which elements to keep.

+ +
let mut vec = vec![1, 2, 3, 4, 5];
+let keep = [false, true, true, false, true];
+let mut iter = keep.iter();
+vec.retain(|_| *iter.next().unwrap());
+assert_eq!(vec, [2, 3, 5]);
+
1.61.0 · source

pub fn retain_mut<F>(&mut self, f: F)
where + F: FnMut(&mut T) -> bool,

Retains only the elements specified by the predicate, passing a mutable reference to it.

+

In other words, remove all elements e such that f(&mut e) returns false. +This method operates in place, visiting each element exactly once in the +original order, and preserves the order of the retained elements.

+
§Examples
+
let mut vec = vec![1, 2, 3, 4];
+vec.retain_mut(|x| if *x <= 3 {
+    *x += 1;
+    true
+} else {
+    false
+});
+assert_eq!(vec, [2, 3, 4]);
+
1.16.0 · source

pub fn dedup_by_key<F, K>(&mut self, key: F)
where + F: FnMut(&mut T) -> K, + K: PartialEq,

Removes all but the first of consecutive elements in the vector that resolve to the same +key.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec![10, 20, 21, 30, 20];
+
+vec.dedup_by_key(|i| *i / 10);
+
+assert_eq!(vec, [10, 20, 30, 20]);
+
1.16.0 · source

pub fn dedup_by<F>(&mut self, same_bucket: F)
where + F: FnMut(&mut T, &mut T) -> bool,

Removes all but the first of consecutive elements in the vector satisfying a given equality +relation.

+

The same_bucket function is passed references to two elements from the vector and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is removed.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
+
+vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
+
1.0.0 · source

pub fn push(&mut self, value: T)

Available on non-no_global_oom_handling only.

Appends an element to the back of a collection.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1, 2];
+vec.push(3);
+assert_eq!(vec, [1, 2, 3]);
+
§Time complexity
+

Takes amortized O(1) time. If the vector’s length would exceed its +capacity after the push, O(capacity) time is taken to copy the +vector’s elements to a larger allocation. This expensive operation is +offset by the capacity O(1) insertions it allows.

+
source

pub fn push_within_capacity(&mut self, value: T) -> Result<(), T>

🔬This is a nightly-only experimental API. (vec_push_within_capacity)

Appends an element if there is sufficient spare capacity, otherwise an error is returned +with the element.

+

Unlike push this method will not reallocate when there’s insufficient capacity. +The caller should use reserve or try_reserve to ensure that there is enough capacity.

+
§Examples
+

A manual, panic-free alternative to FromIterator:

+ +
#![feature(vec_push_within_capacity)]
+
+use std::collections::TryReserveError;
+fn from_iter_fallible<T>(iter: impl Iterator<Item=T>) -> Result<Vec<T>, TryReserveError> {
+    let mut vec = Vec::new();
+    for value in iter {
+        if let Err(value) = vec.push_within_capacity(value) {
+            vec.try_reserve(1)?;
+            // this cannot fail, the previous line either returned or added at least 1 free slot
+            let _ = vec.push_within_capacity(value);
+        }
+    }
+    Ok(vec)
+}
+assert_eq!(from_iter_fallible(0..100), Ok(Vec::from_iter(0..100)));
+
§Time complexity
+

Takes O(1) time.

+
1.0.0 · source

pub fn pop(&mut self) -> Option<T>

Removes the last element from a vector and returns it, or None if it +is empty.

+

If you’d like to pop the first element, consider using +VecDeque::pop_front instead.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+assert_eq!(vec.pop(), Some(3));
+assert_eq!(vec, [1, 2]);
+
§Time complexity
+

Takes O(1) time.

+
source

pub fn pop_if<F>(&mut self, f: F) -> Option<T>
where + F: FnOnce(&mut T) -> bool,

🔬This is a nightly-only experimental API. (vec_pop_if)

Removes and returns the last element in a vector if the predicate +returns true, or None if the predicate returns false or the vector +is empty.

+
§Examples
+
#![feature(vec_pop_if)]
+
+let mut vec = vec![1, 2, 3, 4];
+let pred = |x: &mut i32| *x % 2 == 0;
+
+assert_eq!(vec.pop_if(pred), Some(4));
+assert_eq!(vec, [1, 2, 3]);
+assert_eq!(vec.pop_if(pred), None);
+
1.4.0 · source

pub fn append(&mut self, other: &mut Vec<T, A>)

Available on non-no_global_oom_handling only.

Moves all the elements of other into self, leaving other empty.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+let mut vec2 = vec![4, 5, 6];
+vec.append(&mut vec2);
+assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
+assert_eq!(vec2, []);
+
1.6.0 · source

pub fn drain<R>(&mut self, range: R) -> Drain<'_, T, A>
where + R: RangeBounds<usize>,

Removes the specified range from the vector in bulk, returning all +removed elements as an iterator. If the iterator is dropped before +being fully consumed, it drops the remaining removed elements.

+

The returned iterator keeps a mutable borrow on the vector to optimize +its implementation.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Leaking
+

If the returned iterator goes out of scope without being dropped (due to +mem::forget, for example), the vector may have lost and leaked +elements arbitrarily, including elements outside the range.

+
§Examples
+
let mut v = vec![1, 2, 3];
+let u: Vec<_> = v.drain(1..).collect();
+assert_eq!(v, &[1]);
+assert_eq!(u, &[2, 3]);
+
+// A full range clears the vector, like `clear()` does
+v.drain(..);
+assert_eq!(v, &[]);
+
1.0.0 · source

pub fn clear(&mut self)

Clears the vector, removing all values.

+

Note that this method has no effect on the allocated capacity +of the vector.

+
§Examples
+
let mut v = vec![1, 2, 3];
+
+v.clear();
+
+assert!(v.is_empty());
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the vector, also referred to +as its ‘length’.

+
§Examples
+
let a = vec![1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the vector contains no elements.

+
§Examples
+
let mut v = Vec::new();
+assert!(v.is_empty());
+
+v.push(1);
+assert!(!v.is_empty());
+
1.4.0 · source

pub fn split_off(&mut self, at: usize) -> Vec<T, A>
where + A: Clone,

Available on non-no_global_oom_handling only.

Splits the collection into two at the given index.

+

Returns a newly allocated vector containing the elements in the range +[at, len). After the call, the original vector will be left containing +the elements [0, at) with its previous capacity unchanged.

+
    +
  • If you want to take ownership of the entire contents and capacity of +the vector, see mem::take or mem::replace.
  • +
  • If you don’t need the returned vector at all, see Vec::truncate.
  • +
  • If you want to take ownership of an arbitrary subslice, or you don’t +necessarily want to store the removed items in a vector, see Vec::drain.
  • +
+
§Panics
+

Panics if at > len.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+let vec2 = vec.split_off(1);
+assert_eq!(vec, [1]);
+assert_eq!(vec2, [2, 3]);
+
1.33.0 · source

pub fn resize_with<F>(&mut self, new_len: usize, f: F)
where + F: FnMut() -> T,

Available on non-no_global_oom_handling only.

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with the result of +calling the closure f. The return values from f will end up +in the Vec in the order they have been generated.

+

If new_len is less than len, the Vec is simply truncated.

+

This method uses a closure to create new values on every push. If +you’d rather Clone a given value, use Vec::resize. If you +want to use the Default trait to generate values, you can +pass Default::default as the second argument.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+vec.resize_with(5, Default::default);
+assert_eq!(vec, [1, 2, 3, 0, 0]);
+
+let mut vec = vec![];
+let mut p = 1;
+vec.resize_with(4, || { p *= 2; p });
+assert_eq!(vec, [2, 4, 8, 16]);
+
1.60.0 · source

pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>]

Returns the remaining spare capacity of the vector as a slice of +MaybeUninit<T>.

+

The returned slice can be used to fill the vector with data (e.g. by +reading from a file) before marking the data as initialized using the +set_len method.

+
§Examples
+
// Allocate vector big enough for 10 elements.
+let mut v = Vec::with_capacity(10);
+
+// Fill in the first 3 elements.
+let uninit = v.spare_capacity_mut();
+uninit[0].write(0);
+uninit[1].write(1);
+uninit[2].write(2);
+
+// Mark the first 3 elements of the vector as being initialized.
+unsafe {
+    v.set_len(3);
+}
+
+assert_eq!(&v, &[0, 1, 2]);
+
source

pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>])

🔬This is a nightly-only experimental API. (vec_split_at_spare)

Returns vector content as a slice of T, along with the remaining spare +capacity of the vector as a slice of MaybeUninit<T>.

+

The returned spare capacity slice can be used to fill the vector with data +(e.g. by reading from a file) before marking the data as initialized using +the set_len method.

+

Note that this is a low-level API, which should be used with care for +optimization purposes. If you need to append data to a Vec +you can use push, extend, extend_from_slice, +extend_from_within, insert, append, resize or +resize_with, depending on your exact needs.

+
§Examples
+
#![feature(vec_split_at_spare)]
+
+let mut v = vec![1, 1, 2];
+
+// Reserve additional space big enough for 10 elements.
+v.reserve(10);
+
+let (init, uninit) = v.split_at_spare_mut();
+let sum = init.iter().copied().sum::<u32>();
+
+// Fill in the next 4 elements.
+uninit[0].write(sum);
+uninit[1].write(sum * 2);
+uninit[2].write(sum * 3);
+uninit[3].write(sum * 4);
+
+// Mark the 4 elements of the vector as being initialized.
+unsafe {
+    let len = v.len();
+    v.set_len(len + 4);
+}
+
+assert_eq!(&v, &[1, 1, 2, 4, 8, 12, 16]);
+
1.5.0 · source

pub fn resize(&mut self, new_len: usize, value: T)

Available on non-no_global_oom_handling only.

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with value. +If new_len is less than len, the Vec is simply truncated.

+

This method requires T to implement Clone, +in order to be able to clone the passed value. +If you need more flexibility (or want to rely on Default instead of +Clone), use Vec::resize_with. +If you only need to resize to a smaller size, use Vec::truncate.

+
§Examples
+
let mut vec = vec!["hello"];
+vec.resize(3, "world");
+assert_eq!(vec, ["hello", "world", "world"]);
+
+let mut vec = vec![1, 2, 3, 4];
+vec.resize(2, 0);
+assert_eq!(vec, [1, 2]);
+
1.6.0 · source

pub fn extend_from_slice(&mut self, other: &[T])

Available on non-no_global_oom_handling only.

Clones and appends all elements in a slice to the Vec.

+

Iterates over the slice other, clones each element, and then appends +it to this Vec. The other slice is traversed in-order.

+

Note that this function is same as extend except that it is +specialized to work with slices instead. If and when Rust gets +specialization this function will likely be deprecated (but still +available).

+
§Examples
+
let mut vec = vec![1];
+vec.extend_from_slice(&[2, 3, 4]);
+assert_eq!(vec, [1, 2, 3, 4]);
+
1.53.0 · source

pub fn extend_from_within<R>(&mut self, src: R)
where + R: RangeBounds<usize>,

Available on non-no_global_oom_handling only.

Copies elements from src range to the end of the vector.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Examples
+
let mut vec = vec![0, 1, 2, 3, 4];
+
+vec.extend_from_within(2..);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
+
+vec.extend_from_within(..2);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
+
+vec.extend_from_within(4..8);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
+
1.0.0 · source

pub fn dedup(&mut self)

Removes consecutive repeated elements in the vector according to the +PartialEq trait implementation.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec![1, 2, 2, 3, 2];
+
+vec.dedup();
+
+assert_eq!(vec, [1, 2, 3, 2]);
+
1.21.0 · source

pub fn splice<R, I>( + &mut self, + range: R, + replace_with: I +) -> Splice<'_, <I as IntoIterator>::IntoIter, A>
where + R: RangeBounds<usize>, + I: IntoIterator<Item = T>,

Available on non-no_global_oom_handling only.

Creates a splicing iterator that replaces the specified range in the vector +with the given replace_with iterator and yields the removed items. +replace_with does not need to be the same length as range.

+

range is removed even if the iterator is not consumed until the end.

+

It is unspecified how many elements are removed from the vector +if the Splice value is leaked.

+

The input iterator replace_with is only consumed when the Splice value is dropped.

+

This is optimal if:

+
    +
  • The tail (elements in the vector after range) is empty,
  • +
  • or replace_with yields fewer or equal elements than range’s length
  • +
  • or the lower bound of its size_hint() is exact.
  • +
+

Otherwise, a temporary vector is allocated and the tail is moved twice.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Examples
+
let mut v = vec![1, 2, 3, 4];
+let new = [7, 8, 9];
+let u: Vec<_> = v.splice(1..3, new).collect();
+assert_eq!(v, &[1, 7, 8, 9, 4]);
+assert_eq!(u, &[2, 3]);
+
source

pub fn extract_if<F>(&mut self, filter: F) -> ExtractIf<'_, T, F, A>
where + F: FnMut(&mut T) -> bool,

🔬This is a nightly-only experimental API. (extract_if)

Creates an iterator which uses a closure to determine if an element should be removed.

+

If the closure returns true, then the element is removed and yielded. +If the closure returns false, the element will remain in the vector and will not be yielded +by the iterator.

+

If the returned ExtractIf is not exhausted, e.g. because it is dropped without iterating +or the iteration short-circuits, then the remaining elements will be retained. +Use retain with a negated predicate if you do not need the returned iterator.

+

Using this method is equivalent to the following code:

+ +
let mut i = 0;
+while i < vec.len() {
+    if some_predicate(&mut vec[i]) {
+        let val = vec.remove(i);
+        // your code here
+    } else {
+        i += 1;
+    }
+}
+
+

But extract_if is easier to use. extract_if is also more efficient, +because it can backshift the elements of the array in bulk.

+

Note that extract_if also lets you mutate every element in the filter closure, +regardless of whether you choose to keep or remove it.

+
§Examples
+

Splitting an array into evens and odds, reusing the original allocation:

+ +
#![feature(extract_if)]
+let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];
+
+let evens = numbers.extract_if(|x| *x % 2 == 0).collect::<Vec<_>>();
+let odds = numbers;
+
+assert_eq!(evens, vec![2, 4, 6, 8, 14]);
+assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]);
+

Methods from Deref<Target = [T]>§

1.80.0 · source

pub fn as_flattened(&self) -> &[T]

Takes a &[[T; N]], and flattens it to a &[T].

+
§Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
§Examples
+
assert_eq!([[1, 2, 3], [4, 5, 6]].as_flattened(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+    [[1, 2, 3], [4, 5, 6]].as_flattened(),
+    [[1, 2], [3, 4], [5, 6]].as_flattened(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.as_flattened().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.as_flattened().is_empty());
+
1.80.0 · source

pub fn as_flattened_mut(&mut self) -> &mut [T]

Takes a &mut [[T; N]], and flattens it to a &mut [T].

+
§Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
§Examples
+
fn add_5_to_all(slice: &mut [i32]) {
+    for i in slice {
+        *i += 5;
+    }
+}
+
+let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
+add_5_to_all(array.as_flattened_mut());
+assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f32::total_cmp.

+
§Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
§Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the slice.

+
§Examples
+
let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the slice has a length of 0.

+
§Examples
+
let a = [1, 2, 3];
+assert!(!a.is_empty());
+
+let b: &[i32] = &[];
+assert!(b.is_empty());
+
1.0.0 · source

pub fn first(&self) -> Option<&T>

Returns the first element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
+
1.0.0 · source

pub fn first_mut(&mut self) -> Option<&mut T>

Returns a mutable pointer to the first element of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_mut() {
+    *first = 5;
+}
+assert_eq!(x, &[5, 1, 2]);
+
+let y: &mut [i32] = &mut [];
+assert_eq!(None, y.first_mut());
+
1.5.0 · source

pub fn split_first(&self) -> Option<(&T, &[T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first() {
+    assert_eq!(first, &0);
+    assert_eq!(elements, &[1, 2]);
+}
+
1.5.0 · source

pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_mut() {
+    *first = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
1.5.0 · source

pub fn split_last(&self) -> Option<(&T, &[T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+    assert_eq!(last, &2);
+    assert_eq!(elements, &[0, 1]);
+}
+
1.5.0 · source

pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_mut() {
+    *last = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[4, 5, 3]);
+
1.0.0 · source

pub fn last(&self) -> Option<&T>

Returns the last element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
+
1.0.0 · source

pub fn last_mut(&mut self) -> Option<&mut T>

Returns a mutable reference to the last item in the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_mut() {
+    *last = 10;
+}
+assert_eq!(x, &[0, 1, 10]);
+
+let y: &mut [i32] = &mut [];
+assert_eq!(None, y.last_mut());
+
1.77.0 · source

pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the first N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.first_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.first_chunk::<0>());
+
1.77.0 · source

pub fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

Return a mutable array reference to the first N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_chunk_mut::<2>() {
+    first[0] = 5;
+    first[1] = 4;
+}
+assert_eq!(x, &[5, 4, 2]);
+
+assert_eq!(None, x.first_chunk_mut::<4>());
+
1.77.0 · source

pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

Return an array reference to the first N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk::<2>() {
+    assert_eq!(first, &[0, 1]);
+    assert_eq!(elements, &[2]);
+}
+
+assert_eq!(None, x.split_first_chunk::<4>());
+
1.77.0 · source

pub fn split_first_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T; N], &mut [T])>

Return a mutable array reference to the first N items in the slice and the remaining +slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk_mut::<2>() {
+    first[0] = 3;
+    first[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
+assert_eq!(None, x.split_first_chunk_mut::<4>());
+
1.77.0 · source

pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>

Return an array reference to the last N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((elements, last)) = x.split_last_chunk::<2>() {
+    assert_eq!(elements, &[0]);
+    assert_eq!(last, &[1, 2]);
+}
+
+assert_eq!(None, x.split_last_chunk::<4>());
+
1.77.0 · source

pub fn split_last_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T], &mut [T; N])>

Return a mutable array reference to the last N items in the slice and the remaining +slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((elements, last)) = x.split_last_chunk_mut::<2>() {
+    last[0] = 3;
+    last[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[5, 3, 4]);
+
+assert_eq!(None, x.split_last_chunk_mut::<4>());
+
1.77.0 · source

pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the last N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.last_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.last_chunk::<0>());
+
1.77.0 · source

pub fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

Return a mutable array reference to the last N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_chunk_mut::<2>() {
+    last[0] = 10;
+    last[1] = 20;
+}
+assert_eq!(x, &[0, 10, 20]);
+
+assert_eq!(None, x.last_chunk_mut::<4>());
+
1.0.0 · source

pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice depending on the type of +index.

+
    +
  • If given a position, returns a reference to the element at that +position or None if out of bounds.
  • +
  • If given a range, returns the subslice corresponding to that range, +or None if out of bounds.
  • +
+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
+
1.0.0 · source

pub fn get_mut<I>( + &mut self, + index: I +) -> Option<&mut <I as SliceIndex<[T]>>::Output>
where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice depending on the +type of index (see get) or None if the index is out of bounds.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(elem) = x.get_mut(1) {
+    *elem = 42;
+}
+assert_eq!(x, &[0, 42, 2]);
+
1.0.0 · source

pub unsafe fn get_unchecked<I>( + &self, + index: I +) -> &<I as SliceIndex<[T]>>::Output
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice, without doing bounds +checking.

+

For a safe alternative see get.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get(index).unwrap_unchecked(). It’s UB +to call .get_unchecked(len), even if you immediately convert to a +pointer. And it’s UB to call .get_unchecked(..len + 1), +.get_unchecked(..=len), or similar.

+
§Examples
+
let x = &[1, 2, 4];
+
+unsafe {
+    assert_eq!(x.get_unchecked(1), &2);
+}
+
1.0.0 · source

pub unsafe fn get_unchecked_mut<I>( + &mut self, + index: I +) -> &mut <I as SliceIndex<[T]>>::Output
where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice, without doing +bounds checking.

+

For a safe alternative see get_mut.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get_mut(index).unwrap_unchecked(). It’s +UB to call .get_unchecked_mut(len), even if you immediately convert +to a pointer. And it’s UB to call .get_unchecked_mut(..len + 1), +.get_unchecked_mut(..=len), or similar.

+
§Examples
+
let x = &mut [1, 2, 4];
+
+unsafe {
+    let elem = x.get_unchecked_mut(1);
+    *elem = 13;
+}
+assert_eq!(x, &[1, 13, 4]);
+
1.0.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
§Examples
+
let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+    }
+}
+
1.0.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
§Examples
+
let x = &mut [1, 2, 4];
+let x_ptr = x.as_mut_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        *x_ptr.add(i) += 2;
+    }
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.48.0 · source

pub fn as_ptr_range(&self) -> Range<*const T>

Returns the two raw pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_ptr for warnings on using these pointers. The end pointer +requires extra caution, as it does not point to a valid element in the +slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+

It can also be useful to check if a pointer to an element refers to an +element of this slice:

+ +
let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
+
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
+
1.48.0 · source

pub fn as_mut_ptr_range(&mut self) -> Range<*mut T>

Returns the two unsafe mutable pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_mut_ptr for warnings on using these pointers. The end +pointer requires extra caution, as it does not point to a valid element +in the slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+
1.0.0 · source

pub fn swap(&mut self, a: usize, b: usize)

Swaps two elements in the slice.

+

If a equals to b, it’s guaranteed that elements won’t change value.

+
§Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
§Panics
+

Panics if a or b are out of bounds.

+
§Examples
+
let mut v = ["a", "b", "c", "d", "e"];
+v.swap(2, 4);
+assert!(v == ["a", "b", "e", "d", "c"]);
+
source

pub unsafe fn swap_unchecked(&mut self, a: usize, b: usize)

🔬This is a nightly-only experimental API. (slice_swap_unchecked)

Swaps two elements in the slice, without doing bounds checking.

+

For a safe alternative see swap.

+
§Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior. +The caller has to ensure that a < self.len() and b < self.len().

+
§Examples
+
#![feature(slice_swap_unchecked)]
+
+let mut v = ["a", "b", "c", "d"];
+// SAFETY: we know that 1 and 3 are both indices of the slice
+unsafe { v.swap_unchecked(1, 3) };
+assert!(v == ["a", "d", "c", "b"]);
+
1.0.0 · source

pub fn reverse(&mut self)

Reverses the order of elements in the slice, in place.

+
§Examples
+
let mut v = [1, 2, 3];
+v.reverse();
+assert!(v == [3, 2, 1]);
+
1.0.0 · source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the slice.

+

The iterator yields all items from start to end.

+
§Examples
+
let x = &[1, 2, 4];
+let mut iterator = x.iter();
+
+assert_eq!(iterator.next(), Some(&1));
+assert_eq!(iterator.next(), Some(&2));
+assert_eq!(iterator.next(), Some(&4));
+assert_eq!(iterator.next(), None);
+
1.0.0 · source

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Returns an iterator that allows modifying each value.

+

The iterator yields all items from start to end.

+
§Examples
+
let x = &mut [1, 2, 4];
+for elem in x.iter_mut() {
+    *elem += 2;
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.0.0 · source

pub fn windows(&self, size: usize) -> Windows<'_, T>

Returns an iterator over all contiguous windows of length +size. The windows overlap. If the slice is shorter than +size, the iterator returns no values.

+
§Panics
+

Panics if size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.windows(3);
+assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']);
+assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']);
+assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']);
+assert!(iter.next().is_none());
+

If the slice is shorter than size:

+ +
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
+

There’s no windows_mut, as that existing would let safe code violate the +“only one &mut at a time to the same thing” rule. However, you can sometimes +use Cell::as_slice_of_cells in +conjunction with windows to accomplish something similar:

+ +
use std::cell::Cell;
+
+let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
+let slice = &mut array[..];
+let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
+for w in slice_of_cells.windows(3) {
+    Cell::swap(&w[0], &w[2]);
+}
+assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
+
1.0.0 · source

pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See chunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and rchunks for the same iterator but starting at the end of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See chunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and rchunks_mut for the same iterator but starting at +the end of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 3]);
+
1.31.0 · source

pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks.

+

See chunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
1.31.0 · source

pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See chunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and rchunks_exact_mut for the same iterator but starting at the end of +the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
§Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
§Examples
+
#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+
source

pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
+

If you expect the slice to be an exact multiple, you can combine +let-else with an empty slice pattern:

+ +
#![feature(slice_as_chunks)]
+let slice = ['R', 'u', 's', 't'];
+let (chunks, []) = slice.as_chunks::<2>() else {
+    panic!("slice didn't have even length")
+};
+assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
+
source

pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+
source

pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are array references and do not overlap. If N does not divide the +length of the slice, then the last up to N-1 elements will be omitted and can be +retrieved from the remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
source

pub unsafe fn as_chunks_unchecked_mut<const N: usize>( + &mut self +) -> &mut [[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
§Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
§Examples
+
#![feature(slice_as_chunks)]
+let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &mut [[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[0] = ['L'];
+assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &mut [[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[1] = ['a', 'x', '?'];
+assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
+
source

pub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (chunks, remainder) = v.as_chunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 9]);
+
source

pub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (remainder, chunks) = v.as_rchunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[9, 1, 1, 2, 2]);
+
source

pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable array references and do not overlap. If N does not divide +the length of the slice, then the last up to N-1 elements will be omitted and +can be retrieved from the into_remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact_mut.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.array_chunks_mut() {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>

🔬This is a nightly-only experimental API. (array_windows)

Returns an iterator over overlapping windows of N elements of a slice, +starting at the beginning of the slice.

+

This is the const generic equivalent of windows.

+

If N is greater than the size of the slice, it will return no windows.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and chunks for the same iterator but starting at the beginning +of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and chunks_mut for the same iterator but starting at the +beginning of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[3, 2, 2, 1, 1]);
+
1.31.0 · source

pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +end of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of rchunks.

+

See rchunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and chunks_exact for the same iterator but starting at the beginning of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
+
1.31.0 · source

pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See rchunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and chunks_exact_mut for the same iterator but starting at the beginning +of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[0, 2, 2, 1, 1]);
+
1.77.0 · source

pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
where + F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping runs +of elements using the predicate to separate them.

+

The predicate is called for every pair of consecutive elements, +meaning that it is called on slice[0] and slice[1], +followed by slice[1] and slice[2], and so on.

+
§Examples
+
let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.chunk_by(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.chunk_by(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.77.0 · source

pub fn chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F>
where + F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping mutable +runs of elements using the predicate to separate them.

+

The predicate is called for every pair of consecutive elements, +meaning that it is called on slice[0] and slice[1], +followed by slice[1] and slice[2], and so on.

+
§Examples
+
let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.chunk_by_mut(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&mut [3, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.chunk_by_mut(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.0.0 · source

pub fn split_at(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
§Panics
+

Panics if mid > len. For a non-panicking alternative see +split_at_checked.

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+{
+   let (left, right) = v.split_at(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.0.0 · source

pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
§Panics
+

Panics if mid > len. For a non-panicking alternative see +split_at_mut_checked.

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+let (left, right) = v.split_at_mut(2);
+assert_eq!(left, [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.79.0 · source

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+unsafe {
+   let (left, right) = v.split_at_unchecked(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.79.0 · source

pub unsafe fn split_at_mut_unchecked( + &mut self, + mid: usize +) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at_mut.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+// scoped to restrict the lifetime of the borrows
+unsafe {
+    let (left, right) = v.split_at_mut_unchecked(2);
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.80.0 · source

pub fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])>

Divides one slice into two at an index, returning None if the slice is +too short.

+

If mid ≤ len returns a pair of slices where the first will contain all +indices from [0, mid) (excluding the index mid itself) and the +second will contain all indices from [mid, len) (excluding the index +len itself).

+

Otherwise, if mid > len, returns None.

+
§Examples
+
let v = [1, -2, 3, -4, 5, -6];
+
+{
+   let (left, right) = v.split_at_checked(0).unwrap();
+   assert_eq!(left, []);
+   assert_eq!(right, [1, -2, 3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(2).unwrap();
+    assert_eq!(left, [1, -2]);
+    assert_eq!(right, [3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(6).unwrap();
+    assert_eq!(left, [1, -2, 3, -4, 5, -6]);
+    assert_eq!(right, []);
+}
+
+assert_eq!(None, v.split_at_checked(7));
+
1.80.0 · source

pub fn split_at_mut_checked( + &mut self, + mid: usize +) -> Option<(&mut [T], &mut [T])>

Divides one mutable slice into two at an index, returning None if the +slice is too short.

+

If mid ≤ len returns a pair of slices where the first will contain all +indices from [0, mid) (excluding the index mid itself) and the +second will contain all indices from [mid, len) (excluding the index +len itself).

+

Otherwise, if mid > len, returns None.

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+
+if let Some((left, right)) = v.split_at_mut_checked(2) {
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
+assert_eq!(None, v.split_at_mut_checked(7));
+
1.0.0 · source

pub fn split<F>(&self, pred: F) -> Split<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is not contained in the subslices.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the first element is matched, an empty slice will be the first item +returned by the iterator. Similarly, if the last element in the slice +is matched, an empty slice will be the last item returned by the +iterator:

+ +
let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
+

If two matched elements are directly adjacent, an empty slice will be +present between them:

+ +
let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is not contained in the subslices.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_mut(|num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 1]);
+
1.51.0 · source

pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is contained in the end of the previous +subslice as a terminator.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the last element of the slice is matched, +that element will be considered the terminator of the preceding slice. +That slice will be the last item returned by the iterator.

+ +
let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
+
1.51.0 · source

pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is contained in the previous +subslice as a terminator.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
+    let terminator_idx = group.len()-1;
+    group[terminator_idx] = 1;
+}
+assert_eq!(v, [10, 40, 1, 20, 1, 1]);
+
1.27.0 · source

pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, starting at the end of the slice and working backwards. +The matched element is not contained in the subslices.

+
§Examples
+
let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
+
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
+

As with split(), if the first or last element is matched, an empty +slice will be the first (or last) item returned by the iterator.

+ +
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
+
1.27.0 · source

pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred, starting at the end of the slice and working +backwards. The matched element is not contained in the subslices.

+
§Examples
+
let mut v = [100, 400, 300, 200, 600, 500];
+
+let mut count = 0;
+for group in v.rsplit_mut(|num| *num % 3 == 0) {
+    count += 1;
+    group[0] = count;
+}
+assert_eq!(v, [3, 400, 300, 2, 600, 1]);
+
1.0.0 · source

pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], +[20, 60, 50]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 50]);
+
1.0.0 · source

pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once, starting from the end, by numbers divisible +by 3 (i.e., [50], [10, 40, 30, 20]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+
let mut s = [10, 40, 30, 20, 60, 50];
+
+for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(s, [1, 40, 30, 20, 60, 1]);
+
source

pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the first element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.split_once(|&x| x == 2), Some((
+    &[1][..],
+    &[3, 2, 4][..]
+)));
+assert_eq!(s.split_once(|&x| x == 0), None);
+
source

pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the last element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.rsplit_once(|&x| x == 2), Some((
+    &[1, 2, 3][..],
+    &[4][..]
+)));
+assert_eq!(s.rsplit_once(|&x| x == 0), None);
+
1.0.0 · source

pub fn contains(&self, x: &T) -> bool
where + T: PartialEq,

Returns true if the slice contains an element with the given value.

+

This operation is O(n).

+

Note that if you have a sorted slice, binary_search may be faster.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
+

If you do not have a &T, but some other value that you can compare +with one (for example, String implements PartialEq<str>), you can +use iter().any:

+ +
let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
+
1.0.0 · source

pub fn starts_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a prefix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(v.starts_with(&v));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
+
1.0.0 · source

pub fn ends_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a suffix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(v.ends_with(&v));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
+
1.51.0 · source

pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the prefix removed.

+

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. +If prefix is empty, simply returns the original slice. If prefix is equal to the +original slice, returns an empty slice.

+

If the slice does not start with prefix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
+
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+           Some(b"llo".as_ref()));
+
1.51.0 · source

pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the suffix removed.

+

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. +If suffix is empty, simply returns the original slice. If suffix is equal to the +original slice, returns an empty slice.

+

If the slice does not end with suffix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
+

Binary searches this slice for a given element. +If the slice is not sorted, the returned result is unspecified and +meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search_by, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+assert_eq!(s.binary_search(&13),  Ok(9));
+assert_eq!(s.binary_search(&4),   Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

If you want to find that whole range of matching items, rather than +an arbitrary matching one, that can be done using partition_point:

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
+

If you want to insert an item to a sorted vector, while maintaining +sort order, consider using partition_point:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+// If `num` is unique, `s.partition_point(|&x| x < num)` (with `<`) is equivalent to
+// `s.binary_search(&num).unwrap_or_else(|x| x)`, but using `<=` will allow `insert`
+// to shift less elements.
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
1.0.0 · source

pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
where + F: FnMut(&'a T) -> Ordering,

Binary searches this slice with a comparator function.

+

The comparator function should return an order code that indicates +whether its argument is Less, Equal or Greater the desired +target. +If the slice is not sorted or if the comparator function does not +implement an order consistent with the sort order of the underlying +slice, the returned result is unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.10.0 · source

pub fn binary_search_by_key<'a, B, F>( + &'a self, + b: &B, + f: F +) -> Result<usize, usize>
where + F: FnMut(&'a T) -> B, + B: Ord,

Binary searches this slice with a key extraction function.

+

Assumes that the slice is sorted by the key, for instance with +sort_by_key using the same key extraction function. +If the slice is not sorted by the key, the returned result is +unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by, and partition_point.

+
§Examples
+

Looks up a series of four elements in a slice of pairs sorted by +their second elements. The first is found, with a uniquely +determined position; the second and third are not found; the +fourth could match any position in [1, 4].

+ +
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+         (1, 21), (2, 34), (4, 55)];
+
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.20.0 · source

pub fn sort_unstable(&mut self)
where + T: Ord,

Sorts the slice, but might not preserve the order of equal elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
§Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort_unstable();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.20.0 · source

pub fn sort_unstable_by<F>(&mut self, compare: F)
where + F: FnMut(&T, &T) -> Ordering,

Sorts the slice with a comparator function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
§Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_unstable_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_unstable_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.20.0 · source

pub fn sort_unstable_by_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(m * n * log(n)) worst-case, where the key function is +O(m).

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

Due to its key calling strategy, sort_unstable_by_key +is likely to be slower than sort_by_cached_key in +cases where the key function is expensive.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_unstable_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.49.0 · source

pub fn select_nth_unstable( + &mut self, + index: usize +) -> (&mut [T], &mut T, &mut [T])
where + T: Ord,

Reorder the slice such that the element at index after the reordering is at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index. Additionally, this reordering is +unstable (i.e. any number of equal elements may end up at position index), in-place +(i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from the reordered slice: +the subslice prior to index, the element at index, and the subslice after index; +accordingly, the values in those two subslices will respectively all be less-than-or-equal-to +and greater-than-or-equal-to the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 2, -3, 1];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median.
+let (lesser, median, greater) = v.select_nth_unstable(2);
+
+assert!(lesser == [-3, -5] || lesser == [-5, -3]);
+assert_eq!(median, &mut 1);
+assert!(greater == [4, 2] || greater == [2, 4]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [-3, -5, 1, 2, 4] ||
+        v == [-5, -3, 1, 2, 4] ||
+        v == [-3, -5, 1, 4, 2] ||
+        v == [-5, -3, 1, 4, 2]);
+
1.49.0 · source

pub fn select_nth_unstable_by<F>( + &mut self, + index: usize, + compare: F +) -> (&mut [T], &mut T, &mut [T])
where + F: FnMut(&T, &T) -> Ordering,

Reorder the slice with a comparator function such that the element at index after the reordering is at +its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the comparator function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided comparator function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 2, -3, 1];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median as if the slice were sorted in descending order.
+let (lesser, median, greater) = v.select_nth_unstable_by(2, |a, b| b.cmp(a));
+
+assert!(lesser == [4, 2] || lesser == [2, 4]);
+assert_eq!(median, &mut 1);
+assert!(greater == [-3, -5] || greater == [-5, -3]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [2, 4, 1, -5, -3] ||
+        v == [2, 4, 1, -3, -5] ||
+        v == [4, 2, 1, -5, -3] ||
+        v == [4, 2, 1, -3, -5]);
+
1.49.0 · source

pub fn select_nth_unstable_by_key<K, F>( + &mut self, + index: usize, + f: F +) -> (&mut [T], &mut T, &mut [T])
where + F: FnMut(&T) -> K, + K: Ord,

Reorder the slice with a key extraction function such that the element at index after the reordering is +at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the key extraction function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided key extraction function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median as if the slice were sorted according to absolute value.
+let (lesser, median, greater) = v.select_nth_unstable_by_key(2, |a| a.abs());
+
+assert!(lesser == [1, 2] || lesser == [2, 1]);
+assert_eq!(median, &mut -3);
+assert!(greater == [4, -5] || greater == [-5, 4]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [1, 2, -3, 4, -5] ||
+        v == [1, 2, -3, -5, 4] ||
+        v == [2, 1, -3, 4, -5] ||
+        v == [2, 1, -3, -5, 4]);
+
source

pub fn partition_dedup(&mut self) -> (&mut [T], &mut [T])
where + T: PartialEq,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all consecutive repeated elements to the end of the slice according to the +PartialEq trait implementation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
+
+let (dedup, duplicates) = slice.partition_dedup();
+
+assert_eq!(dedup, [1, 2, 3, 2, 1]);
+assert_eq!(duplicates, [2, 3, 1]);
+
source

pub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T])
where + F: FnMut(&mut T, &mut T) -> bool,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice satisfying +a given equality relation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

The same_bucket function is passed references to two elements from the slice and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is moved +at the end of the slice.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
+
+let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
+assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
+
source

pub fn partition_dedup_by_key<K, F>(&mut self, key: F) -> (&mut [T], &mut [T])
where + F: FnMut(&mut T) -> K, + K: PartialEq,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice that resolve +to the same key.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
+
+let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
+
+assert_eq!(dedup, [10, 20, 30, 20, 11]);
+assert_eq!(duplicates, [21, 30, 13]);
+
1.26.0 · source

pub fn rotate_left(&mut self, mid: usize)

Rotates the slice in-place such that the first mid elements of the +slice move to the end while the last self.len() - mid elements move to +the front. After calling rotate_left, the element previously at index +mid will become the first element in the slice.

+
§Panics
+

This function will panic if mid is greater than the length of the +slice. Note that mid == self.len() does not panic and is a no-op +rotation.

+
§Complexity
+

Takes linear (in self.len()) time.

+
§Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_left(2);
+assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_left(1);
+assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+
1.26.0 · source

pub fn rotate_right(&mut self, k: usize)

Rotates the slice in-place such that the first self.len() - k +elements of the slice move to the end while the last k elements move +to the front. After calling rotate_right, the element previously at +index self.len() - k will become the first element in the slice.

+
§Panics
+

This function will panic if k is greater than the length of the +slice. Note that k == self.len() does not panic and is a no-op +rotation.

+
§Complexity
+

Takes linear (in self.len()) time.

+
§Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_right(2);
+assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_right(1);
+assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
+
1.50.0 · source

pub fn fill(&mut self, value: T)
where + T: Clone,

Fills self with elements by cloning value.

+
§Examples
+
let mut buf = vec![0; 10];
+buf.fill(1);
+assert_eq!(buf, vec![1; 10]);
+
1.51.0 · source

pub fn fill_with<F>(&mut self, f: F)
where + F: FnMut() -> T,

Fills self with elements returned by calling a closure repeatedly.

+

This method uses a closure to create new values. If you’d rather +Clone a given value, use fill. If you want to use the Default +trait to generate values, you can pass Default::default as the +argument.

+
§Examples
+
let mut buf = vec![1; 10];
+buf.fill_with(Default::default);
+assert_eq!(buf, vec![0; 10]);
+
1.7.0 · source

pub fn clone_from_slice(&mut self, src: &[T])
where + T: Clone,

Copies the elements from src into self.

+

The length of src must be the same as self.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Examples
+

Cloning two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.clone_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use clone_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].clone_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.clone_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.9.0 · source

pub fn copy_from_slice(&mut self, src: &[T])
where + T: Copy,

Copies all elements from src into self, using a memcpy.

+

The length of src must be the same as self.

+

If T does not implement Copy, use clone_from_slice.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Examples
+

Copying two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.copy_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use copy_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].copy_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.copy_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.37.0 · source

pub fn copy_within<R>(&mut self, src: R, dest: usize)
where + R: RangeBounds<usize>, + T: Copy,

Copies elements from one part of the slice to another part of itself, +using a memmove.

+

src is the range within self to copy from. dest is the starting +index of the range within self to copy to, which will have the same +length as src. The two ranges may overlap. The ends of the two ranges +must be less than or equal to self.len().

+
§Panics
+

This function will panic if either range exceeds the end of the slice, +or if the end of src is before the start.

+
§Examples
+

Copying four bytes within a slice:

+ +
let mut bytes = *b"Hello, World!";
+
+bytes.copy_within(1..5, 8);
+
+assert_eq!(&bytes, b"Hello, Wello!");
+
1.27.0 · source

pub fn swap_with_slice(&mut self, other: &mut [T])

Swaps all elements in self with those in other.

+

The length of other must be the same as self.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Example
+

Swapping two elements across slices:

+ +
let mut slice1 = [0, 0];
+let mut slice2 = [1, 2, 3, 4];
+
+slice1.swap_with_slice(&mut slice2[2..]);
+
+assert_eq!(slice1, [3, 4]);
+assert_eq!(slice2, [1, 2, 0, 0]);
+

Rust enforces that there can only be one mutable reference to a +particular piece of data in a particular scope. Because of this, +attempting to use swap_with_slice on a single slice will result in +a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +mutable sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.swap_with_slice(&mut right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 1, 2]);
+
1.30.0 · source

pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

Transmute the slice to a slice of another type, ensuring alignment of the types is +maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The middle part will be as big as possible under +the given alignment constraint and element size.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
§Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
§Examples
+

Basic usage:

+ +
unsafe {
+    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
1.30.0 · source

pub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T])

Transmute the mutable slice to a mutable slice of another type, ensuring alignment of the +types is maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The middle part will be as big as possible under +the given alignment constraint and element size.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
§Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
§Examples
+

Basic usage:

+ +
unsafe {
+    let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
source

pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
where + Simd<T, LANES>: AsRef<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.

+

This is a safe wrapper around slice::align_to, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+
§Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
§Examples
+
#![feature(portable_simd)]
+use core::simd::prelude::*;
+
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
+
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+
+fn basic_simd_sum(x: &[f32]) -> f32 {
+    use std::ops::Add;
+    let (prefix, middle, suffix) = x.as_simd();
+    let sums = f32x4::from_array([
+        prefix.iter().copied().sum(),
+        0.0,
+        0.0,
+        suffix.iter().copied().sum(),
+    ]);
+    let sums = middle.iter().copied().fold(sums, f32x4::add);
+    sums.reduce_sum()
+}
+
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+
source

pub fn as_simd_mut<const LANES: usize>( + &mut self +) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T])
where + Simd<T, LANES>: AsMut<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a mutable slice into a mutable prefix, a middle of aligned SIMD types, +and a mutable suffix.

+

This is a safe wrapper around slice::align_to_mut, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+

This is the mutable version of slice::as_simd; see that for examples.

+
§Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
source

pub fn is_sorted(&self) -> bool
where + T: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted.

+

That is, for each element a and its following element b, a <= b must hold. If the +slice yields exactly zero or one element, true is returned.

+

Note that if Self::Item is only PartialOrd, but not Ord, the above definition +implies that this function returns false if any two consecutive items are not +comparable.

+
§Examples
+
#![feature(is_sorted)]
+let empty: [i32; 0] = [];
+
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
+
source

pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> bool
where + F: FnMut(&'a T, &'a T) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given comparator function.

+

Instead of using PartialOrd::partial_cmp, this function uses the given compare +function to determine whether two elements are to be considered in sorted order.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!([1, 2, 2, 9].is_sorted_by(|a, b| a <= b));
+assert!(![1, 2, 2, 9].is_sorted_by(|a, b| a < b));
+
+assert!([0].is_sorted_by(|a, b| true));
+assert!([0].is_sorted_by(|a, b| false));
+
+let empty: [i32; 0] = [];
+assert!(empty.is_sorted_by(|a, b| false));
+assert!(empty.is_sorted_by(|a, b| true));
+
source

pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
where + F: FnMut(&'a T) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given key extraction function.

+

Instead of comparing the slice’s elements directly, this function compares the keys of the +elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its +documentation for more information.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+
1.52.0 · source

pub fn partition_point<P>(&self, pred: P) -> usize
where + P: FnMut(&T) -> bool,

Returns the index of the partition point according to the given predicate +(the index of the first element of the second partition).

+

The slice is assumed to be partitioned according to the given predicate. +This means that all elements for which the predicate returns true are at the start of the slice +and all elements for which the predicate returns false are at the end. +For example, [7, 15, 3, 5, 4, 12, 6] is partitioned under the predicate x % 2 != 0 +(all odd numbers are at the start, all even at the end).

+

If this slice is not partitioned, the returned result is unspecified and meaningless, +as this method performs a kind of binary search.

+

See also binary_search, binary_search_by, and binary_search_by_key.

+
§Examples
+
let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
+
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
+

If all elements of the slice match the predicate, including if the slice +is empty, then the length of the slice will be returned:

+ +
let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
+

If you want to insert an item to a sorted vector, while maintaining +sort order:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
source

pub fn take<'a, R>(self: &mut &'a [T], range: R) -> Option<&'a [T]>
where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
§Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut first_three = slice.take(..3).unwrap();
+
+assert_eq!(slice, &['d']);
+assert_eq!(first_three, &['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut tail = slice.take(2..).unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(tail, &['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take(5..));
+assert_eq!(None, slice.take(..5));
+assert_eq!(None, slice.take(..=4));
+let expected: &[char] = &['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take(..4));
+
source

pub fn take_mut<'a, R>(self: &mut &'a mut [T], range: R) -> Option<&'a mut [T]>
where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a mutable reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
§Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut first_three = slice.take_mut(..3).unwrap();
+
+assert_eq!(slice, &mut ['d']);
+assert_eq!(first_three, &mut ['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut tail = slice.take_mut(2..).unwrap();
+
+assert_eq!(slice, &mut ['a', 'b']);
+assert_eq!(tail, &mut ['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take_mut(5..));
+assert_eq!(None, slice.take_mut(..5));
+assert_eq!(None, slice.take_mut(..=4));
+let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take_mut(..4));
+
source

pub fn take_first<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let first = slice.take_first().unwrap();
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'a');
+
source

pub fn take_first_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let first = slice.take_first_mut().unwrap();
+*first = 'd';
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'d');
+
source

pub fn take_last<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let last = slice.take_last().unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'c');
+
source

pub fn take_last_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let last = slice.take_last_mut().unwrap();
+*last = 'd';
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'d');
+
source

pub unsafe fn get_many_unchecked_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> [&mut T; N]

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once, without doing any checks.

+

For a safe alternative see get_many_mut.

+
§Safety
+

Calling this method with overlapping or out-of-bounds indices is undefined behavior +even if the resulting references are not used.

+
§Examples
+
#![feature(get_many_mut)]
+
+let x = &mut [1, 2, 4];
+
+unsafe {
+    let [a, b] = x.get_many_unchecked_mut([0, 2]);
+    *a *= 10;
+    *b *= 100;
+}
+assert_eq!(x, &[10, 2, 400]);
+
source

pub fn get_many_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> Result<[&mut T; N], GetManyMutError<N>>

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once.

+

Returns an error if any index is out-of-bounds, or if the same index was +passed more than once.

+
§Examples
+
#![feature(get_many_mut)]
+
+let v = &mut [1, 2, 3];
+if let Ok([a, b]) = v.get_many_mut([0, 2]) {
+    *a = 413;
+    *b = 612;
+}
+assert_eq!(v, &[413, 2, 612]);
+
1.79.0 · source

pub fn utf8_chunks(&self) -> Utf8Chunks<'_>

Creates an iterator over the contiguous valid UTF-8 ranges of this +slice, and the non-UTF-8 fragments in between.

+
§Examples
+

This function formats arbitrary but mostly-UTF-8 bytes into Rust source +code in the form of a C-string literal (c"...").

+ +
use std::fmt::Write as _;
+
+pub fn cstr_literal(bytes: &[u8]) -> String {
+    let mut repr = String::new();
+    repr.push_str("c\"");
+    for chunk in bytes.utf8_chunks() {
+        for ch in chunk.valid().chars() {
+            // Escapes \0, \t, \r, \n, \\, \', \", and uses \u{...} for non-printable characters.
+            write!(repr, "{}", ch.escape_debug()).unwrap();
+        }
+        for byte in chunk.invalid() {
+            write!(repr, "\\x{:02X}", byte).unwrap();
+        }
+    }
+    repr.push('"');
+    repr
+}
+
+fn main() {
+    let lit = cstr_literal(b"\xferris the \xf0\x9f\xa6\x80\x07");
+    let expected = stringify!(c"\xFErris the 🦀\u{7}");
+    assert_eq!(lit, expected);
+}
+
1.23.0 · source

pub fn is_ascii(&self) -> bool

Checks if all bytes in this slice are within the ASCII range.

+
source

pub fn as_ascii(&self) -> Option<&[AsciiChar]>

🔬This is a nightly-only experimental API. (ascii_char)

If this slice is_ascii, returns it as a slice of +ASCII characters, otherwise returns None.

+
source

pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]

🔬This is a nightly-only experimental API. (ascii_char)

Converts this slice of bytes into a slice of ASCII characters, +without checking whether they’re valid.

+
§Safety
+

Every byte in the slice must be in 0..=127, or else this is UB.

+
1.23.0 · source

pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool

Checks that two slices are an ASCII case-insensitive match.

+

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), +but without allocating and copying temporaries.

+
1.23.0 · source

pub fn make_ascii_uppercase(&mut self)

Converts this slice to its ASCII upper case equivalent in-place.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To return a new uppercased value without modifying the existing one, use +to_ascii_uppercase.

+
1.23.0 · source

pub fn make_ascii_lowercase(&mut self)

Converts this slice to its ASCII lower case equivalent in-place.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To return a new lowercased value without modifying the existing one, use +to_ascii_lowercase.

+
1.60.0 · source

pub fn escape_ascii(&self) -> EscapeAscii<'_>

Returns an iterator that produces an escaped version of this slice, +treating it as an ASCII string.

+
§Examples
+

+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
+
1.80.0 · source

pub fn trim_ascii_start(&self) -> &[u8]

Returns a byte slice with leading ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b"  ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
+
1.80.0 · source

pub fn trim_ascii_end(&self) -> &[u8]

Returns a byte slice with trailing ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b"  ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
+
1.80.0 · source

pub fn trim_ascii(&self) -> &[u8]

Returns a byte slice with leading and trailing ASCII whitespace bytes +removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b"  ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f64::total_cmp.

+
§Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
§Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
source

pub fn as_str(&self) -> &str

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a UTF-8 str.

+
source

pub fn as_bytes(&self) -> &[u8]

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a slice of u8 bytes.

+
1.0.0 · source

pub fn sort(&mut self)
where + T: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.0.0 · source

pub fn sort_by<F>(&mut self, compare: F)
where + F: FnMut(&T, &T) -> Ordering,

Available on non-no_global_oom_handling only.

Sorts the slice with a comparator function.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.7.0 · source

pub fn sort_by_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n * log(n)) +worst-case, where the key function is O(m).

+

For expensive key functions (e.g. functions that are not simple property accesses or +basic operations), sort_by_cached_key is likely to be +significantly faster, as it does not recompute element keys.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by_key.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.34.0 · source

pub fn sort_by_cached_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

During sorting, the key function is called at most once per element, by using +temporary storage to remember the results of key evaluation. +The order of calls to the key function is unspecified and may change in future versions +of the standard library.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n + n * log(n)) +worst-case, where the key function is O(m).

+

For simple key functions (e.g., functions that are property accesses or +basic operations), sort_by_key is likely to be +faster.

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

In the worst case, the algorithm allocates temporary storage in a Vec<(K, usize)> the +length of the slice.

+
§Examples
+
let mut v = [-5i32, 4, 32, -3, 2];
+
+v.sort_by_cached_key(|k| k.to_string());
+assert!(v == [-3, -5, 2, 32, 4]);
+
1.0.0 · source

pub fn to_vec(&self) -> Vec<T>
where + T: Clone,

Available on non-no_global_oom_handling only.

Copies self into a new Vec.

+
§Examples
+
let s = [10, 40, 30];
+let x = s.to_vec();
+// Here, `s` and `x` can be modified independently.
+
source

pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>
where + A: Allocator, + T: Clone,

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Copies self into a new Vec with an allocator.

+
§Examples
+
#![feature(allocator_api)]
+
+use std::alloc::System;
+
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
+// Here, `s` and `x` can be modified independently.
+
1.40.0 · source

pub fn repeat(&self, n: usize) -> Vec<T>
where + T: Copy,

Available on non-no_global_oom_handling only.

Creates a vector by copying a slice n times.

+
§Panics
+

This function will panic if the capacity would overflow.

+
§Examples
+

Basic usage:

+ +
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
+

A panic upon overflow:

+ +
// this will panic at runtime
+b"0123456789abcdef".repeat(usize::MAX);
+
1.0.0 · source

pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output
where + [T]: Concat<Item>, + Item: ?Sized,

Flattens a slice of T into a single value Self::Output.

+
§Examples
+
assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+
1.3.0 · source

pub fn join<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+
1.0.0 · source

pub fn connect<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

👎Deprecated since 1.3.0: renamed to join

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+
1.23.0 · source

pub fn to_ascii_uppercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII upper case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To uppercase the value in-place, use make_ascii_uppercase.

+
1.23.0 · source

pub fn to_ascii_lowercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII lower case equivalent.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To lowercase the value in-place, use make_ascii_lowercase.

+

Trait Implementations§

source§

impl Clone for Accept

source§

fn clone(&self) -> Accept

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Accept

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for Accept

§

type Target = Vec<QualityItem<Mime>>

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for Accept

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl Display for Accept

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for Accept

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for Accept

source§

fn eq(&self, other: &Accept) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for Accept

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for Accept

source§

impl StructuralPartialEq for Accept

Auto Trait Implementations§

§

impl Freeze for Accept

§

impl RefUnwindSafe for Accept

§

impl Send for Accept

§

impl Sync for Accept

§

impl Unpin for Accept

§

impl UnwindSafe for Accept

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.AcceptCharset.html b/actix_web/http/header/struct.AcceptCharset.html new file mode 100644 index 000000000..142554692 --- /dev/null +++ b/actix_web/http/header/struct.AcceptCharset.html @@ -0,0 +1,3141 @@ +AcceptCharset in actix_web::http::header - Rust

Struct actix_web::http::header::AcceptCharset

source ·
pub struct AcceptCharset(pub Vec<QualityItem<Charset>>);
Expand description

Accept-Charset header, defined in RFC 7231 §5.3.3.

+

The Accept-Charset header field can be sent by a user agent to +indicate what charsets are acceptable in textual response content. +This field allows user agents capable of understanding more +comprehensive or special-purpose charsets to signal that capability +to an origin server that is capable of representing information in +those charsets.

+

§ABNF

Accept-Charset = 1#( ( charset / "*" ) [ weight ] )
+

§Example Values

+
    +
  • iso-8859-5, unicode-1-1;q=0.8
  • +
+

§Examples

+
use actix_web::HttpResponse;
+use actix_web::http::header::{AcceptCharset, Charset, QualityItem};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    AcceptCharset(vec![QualityItem::max(Charset::Us_Ascii)])
+);
+ +
use actix_web::HttpResponse;
+use actix_web::http::header::{AcceptCharset, Charset, q, QualityItem};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    AcceptCharset(vec![
+        QualityItem::new(Charset::Us_Ascii, q(0.9)),
+        QualityItem::new(Charset::Iso_8859_10, q(0.2)),
+    ])
+);
+ +
use actix_web::HttpResponse;
+use actix_web::http::header::{AcceptCharset, Charset, QualityItem};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    AcceptCharset(vec![QualityItem::max(Charset::Ext("utf-8".to_owned()))])
+);
+

Tuple Fields§

§0: Vec<QualityItem<Charset>>

Methods from Deref<Target = Vec<QualityItem<Charset>>>§

1.0.0 · source

pub fn capacity(&self) -> usize

Returns the total number of elements the vector can hold without +reallocating.

+
§Examples
+
let mut vec: Vec<i32> = Vec::with_capacity(10);
+vec.push(42);
+assert!(vec.capacity() >= 10);
+
1.0.0 · source

pub fn reserve(&mut self, additional: usize)

Available on non-no_global_oom_handling only.

Reserves capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to +speculatively avoid frequent reallocations. After calling reserve, +capacity will be greater than or equal to self.len() + additional. +Does nothing if capacity is already sufficient.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1];
+vec.reserve(10);
+assert!(vec.capacity() >= 11);
+
1.0.0 · source

pub fn reserve_exact(&mut self, additional: usize)

Available on non-no_global_oom_handling only.

Reserves the minimum capacity for at least additional more elements to +be inserted in the given Vec<T>. Unlike reserve, this will not +deliberately over-allocate to speculatively avoid frequent allocations. +After calling reserve_exact, capacity will be greater than or equal to +self.len() + additional. Does nothing if the capacity is already +sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer reserve if future insertions are expected.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1];
+vec.reserve_exact(10);
+assert!(vec.capacity() >= 11);
+
1.57.0 · source

pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>

Tries to reserve capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to speculatively avoid +frequent reallocations. After calling try_reserve, capacity will be +greater than or equal to self.len() + additional if it returns +Ok(()). Does nothing if capacity is already sufficient. This method +preserves the contents even if an error occurs.

+
§Errors
+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+
§Examples
+
use std::collections::TryReserveError;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+
1.57.0 · source

pub fn try_reserve_exact( + &mut self, + additional: usize +) -> Result<(), TryReserveError>

Tries to reserve the minimum capacity for at least additional +elements to be inserted in the given Vec<T>. Unlike try_reserve, +this will not deliberately over-allocate to speculatively avoid frequent +allocations. After calling try_reserve_exact, capacity will be greater +than or equal to self.len() + additional if it returns Ok(()). +Does nothing if the capacity is already sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer try_reserve if future insertions are expected.

+
§Errors
+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+
§Examples
+
use std::collections::TryReserveError;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve_exact(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+
1.0.0 · source

pub fn shrink_to_fit(&mut self)

Available on non-no_global_oom_handling only.

Shrinks the capacity of the vector as much as possible.

+

The behavior of this method depends on the allocator, which may either shrink the vector +in-place or reallocate. The resulting vector might still have some excess capacity, just as +is the case for with_capacity. See Allocator::shrink for more details.

+
§Examples
+
let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3]);
+assert!(vec.capacity() >= 10);
+vec.shrink_to_fit();
+assert!(vec.capacity() >= 3);
+
1.56.0 · source

pub fn shrink_to(&mut self, min_capacity: usize)

Available on non-no_global_oom_handling only.

Shrinks the capacity of the vector with a lower bound.

+

The capacity will remain at least as large as both the length +and the supplied value.

+

If the current capacity is less than the lower limit, this is a no-op.

+
§Examples
+
let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3]);
+assert!(vec.capacity() >= 10);
+vec.shrink_to(4);
+assert!(vec.capacity() >= 4);
+vec.shrink_to(0);
+assert!(vec.capacity() >= 3);
+
1.0.0 · source

pub fn truncate(&mut self, len: usize)

Shortens the vector, keeping the first len elements and dropping +the rest.

+

If len is greater or equal to the vector’s current length, this has +no effect.

+

The drain method can emulate truncate, but causes the excess +elements to be returned instead of dropped.

+

Note that this method has no effect on the allocated capacity +of the vector.

+
§Examples
+

Truncating a five element vector to two elements:

+ +
let mut vec = vec![1, 2, 3, 4, 5];
+vec.truncate(2);
+assert_eq!(vec, [1, 2]);
+

No truncation occurs when len is greater than the vector’s current +length:

+ +
let mut vec = vec![1, 2, 3];
+vec.truncate(8);
+assert_eq!(vec, [1, 2, 3]);
+

Truncating when len == 0 is equivalent to calling the clear +method.

+ +
let mut vec = vec![1, 2, 3];
+vec.truncate(0);
+assert_eq!(vec, []);
+
1.7.0 · source

pub fn as_slice(&self) -> &[T]

Extracts a slice containing the entire vector.

+

Equivalent to &s[..].

+
§Examples
+
use std::io::{self, Write};
+let buffer = vec![1, 2, 3, 5, 8];
+io::sink().write(buffer.as_slice()).unwrap();
+
1.7.0 · source

pub fn as_mut_slice(&mut self) -> &mut [T]

Extracts a mutable slice of the entire vector.

+

Equivalent to &mut s[..].

+
§Examples
+
use std::io::{self, Read};
+let mut buffer = vec![0; 3];
+io::repeat(0b101).read_exact(buffer.as_mut_slice()).unwrap();
+
1.37.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the vector’s buffer, or a dangling raw pointer +valid for zero sized reads if the vector didn’t allocate.

+

The caller must ensure that the vector outlives the pointer this +function returns, or else it will end up pointing to garbage. +Modifying the vector may cause its buffer to be reallocated, +which would also make any pointers to it invalid.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

This method guarantees that for the purpose of the aliasing model, this method +does not materialize a reference to the underlying slice, and thus the returned pointer +will remain valid when mixed with other calls to as_ptr and as_mut_ptr. +Note that calling other methods that materialize mutable references to the slice, +or mutable references to specific elements you are planning on accessing through this pointer, +as well as writing to those elements, may still invalidate this pointer. +See the second example below for how this guarantee can be used.

+
§Examples
+
let x = vec![1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(*x_ptr.add(i), 1 << i);
+    }
+}
+

Due to the aliasing guarantee, the following code is legal:

+ +
unsafe {
+    let mut v = vec![0, 1, 2];
+    let ptr1 = v.as_ptr();
+    let _ = ptr1.read();
+    let ptr2 = v.as_mut_ptr().offset(2);
+    ptr2.write(2);
+    // Notably, the write to `ptr2` did *not* invalidate `ptr1`
+    // because it mutated a different element:
+    let _ = ptr1.read();
+}
+
1.37.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the vector’s buffer, or a dangling +raw pointer valid for zero sized reads if the vector didn’t allocate.

+

The caller must ensure that the vector outlives the pointer this +function returns, or else it will end up pointing to garbage. +Modifying the vector may cause its buffer to be reallocated, +which would also make any pointers to it invalid.

+

This method guarantees that for the purpose of the aliasing model, this method +does not materialize a reference to the underlying slice, and thus the returned pointer +will remain valid when mixed with other calls to as_ptr and as_mut_ptr. +Note that calling other methods that materialize references to the slice, +or references to specific elements you are planning on accessing through this pointer, +may still invalidate this pointer. +See the second example below for how this guarantee can be used.

+
§Examples
+
// Allocate vector big enough for 4 elements.
+let size = 4;
+let mut x: Vec<i32> = Vec::with_capacity(size);
+let x_ptr = x.as_mut_ptr();
+
+// Initialize elements via raw pointer writes, then set length.
+unsafe {
+    for i in 0..size {
+        *x_ptr.add(i) = i as i32;
+    }
+    x.set_len(size);
+}
+assert_eq!(&*x, &[0, 1, 2, 3]);
+

Due to the aliasing guarantee, the following code is legal:

+ +
unsafe {
+    let mut v = vec![0];
+    let ptr1 = v.as_mut_ptr();
+    ptr1.write(1);
+    let ptr2 = v.as_mut_ptr();
+    ptr2.write(2);
+    // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
+    ptr1.write(3);
+}
+
source

pub fn allocator(&self) -> &A

🔬This is a nightly-only experimental API. (allocator_api)

Returns a reference to the underlying allocator.

+
1.0.0 · source

pub unsafe fn set_len(&mut self, new_len: usize)

Forces the length of the vector to new_len.

+

This is a low-level operation that maintains none of the normal +invariants of the type. Normally changing the length of a vector +is done using one of the safe operations instead, such as +truncate, resize, extend, or clear.

+
§Safety
+
    +
  • new_len must be less than or equal to capacity().
  • +
  • The elements at old_len..new_len must be initialized.
  • +
+
§Examples
+

This method can be useful for situations in which the vector +is serving as a buffer for other code, particularly over FFI:

+ +
pub fn get_dictionary(&self) -> Option<Vec<u8>> {
+    // Per the FFI method's docs, "32768 bytes is always enough".
+    let mut dict = Vec::with_capacity(32_768);
+    let mut dict_length = 0;
+    // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
+    // 1. `dict_length` elements were initialized.
+    // 2. `dict_length` <= the capacity (32_768)
+    // which makes `set_len` safe to call.
+    unsafe {
+        // Make the FFI call...
+        let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
+        if r == Z_OK {
+            // ...and update the length to what was initialized.
+            dict.set_len(dict_length);
+            Some(dict)
+        } else {
+            None
+        }
+    }
+}
+

While the following example is sound, there is a memory leak since +the inner vectors were not freed prior to the set_len call:

+ +
let mut vec = vec![vec![1, 0, 0],
+                   vec![0, 1, 0],
+                   vec![0, 0, 1]];
+// SAFETY:
+// 1. `old_len..0` is empty so no elements need to be initialized.
+// 2. `0 <= capacity` always holds whatever `capacity` is.
+unsafe {
+    vec.set_len(0);
+}
+

Normally, here, one would use clear instead to correctly drop +the contents and thus not leak memory.

+
1.0.0 · source

pub fn swap_remove(&mut self, index: usize) -> T

Removes an element from the vector and returns it.

+

The removed element is replaced by the last element of the vector.

+

This does not preserve ordering of the remaining elements, but is O(1). +If you need to preserve the element order, use remove instead.

+
§Panics
+

Panics if index is out of bounds.

+
§Examples
+
let mut v = vec!["foo", "bar", "baz", "qux"];
+
+assert_eq!(v.swap_remove(1), "bar");
+assert_eq!(v, ["foo", "qux", "baz"]);
+
+assert_eq!(v.swap_remove(0), "foo");
+assert_eq!(v, ["baz", "qux"]);
+
1.0.0 · source

pub fn insert(&mut self, index: usize, element: T)

Available on non-no_global_oom_handling only.

Inserts an element at position index within the vector, shifting all +elements after it to the right.

+
§Panics
+

Panics if index > len.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+vec.insert(1, 4);
+assert_eq!(vec, [1, 4, 2, 3]);
+vec.insert(4, 5);
+assert_eq!(vec, [1, 4, 2, 3, 5]);
+
§Time complexity
+

Takes O(Vec::len) time. All items after the insertion index must be +shifted to the right. In the worst case, all elements are shifted when +the insertion index is 0.

+
1.0.0 · source

pub fn remove(&mut self, index: usize) -> T

Removes and returns the element at position index within the vector, +shifting all elements after it to the left.

+

Note: Because this shifts over the remaining elements, it has a +worst-case performance of O(n). If you don’t need the order of elements +to be preserved, use swap_remove instead. If you’d like to remove +elements from the beginning of the Vec, consider using +VecDeque::pop_front instead.

+
§Panics
+

Panics if index is out of bounds.

+
§Examples
+
let mut v = vec![1, 2, 3];
+assert_eq!(v.remove(1), 2);
+assert_eq!(v, [1, 3]);
+
1.0.0 · source

pub fn retain<F>(&mut self, f: F)
where + F: FnMut(&T) -> bool,

Retains only the elements specified by the predicate.

+

In other words, remove all elements e for which f(&e) returns false. +This method operates in place, visiting each element exactly once in the +original order, and preserves the order of the retained elements.

+
§Examples
+
let mut vec = vec![1, 2, 3, 4];
+vec.retain(|&x| x % 2 == 0);
+assert_eq!(vec, [2, 4]);
+

Because the elements are visited exactly once in the original order, +external state may be used to decide which elements to keep.

+ +
let mut vec = vec![1, 2, 3, 4, 5];
+let keep = [false, true, true, false, true];
+let mut iter = keep.iter();
+vec.retain(|_| *iter.next().unwrap());
+assert_eq!(vec, [2, 3, 5]);
+
1.61.0 · source

pub fn retain_mut<F>(&mut self, f: F)
where + F: FnMut(&mut T) -> bool,

Retains only the elements specified by the predicate, passing a mutable reference to it.

+

In other words, remove all elements e such that f(&mut e) returns false. +This method operates in place, visiting each element exactly once in the +original order, and preserves the order of the retained elements.

+
§Examples
+
let mut vec = vec![1, 2, 3, 4];
+vec.retain_mut(|x| if *x <= 3 {
+    *x += 1;
+    true
+} else {
+    false
+});
+assert_eq!(vec, [2, 3, 4]);
+
1.16.0 · source

pub fn dedup_by_key<F, K>(&mut self, key: F)
where + F: FnMut(&mut T) -> K, + K: PartialEq,

Removes all but the first of consecutive elements in the vector that resolve to the same +key.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec![10, 20, 21, 30, 20];
+
+vec.dedup_by_key(|i| *i / 10);
+
+assert_eq!(vec, [10, 20, 30, 20]);
+
1.16.0 · source

pub fn dedup_by<F>(&mut self, same_bucket: F)
where + F: FnMut(&mut T, &mut T) -> bool,

Removes all but the first of consecutive elements in the vector satisfying a given equality +relation.

+

The same_bucket function is passed references to two elements from the vector and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is removed.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
+
+vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
+
1.0.0 · source

pub fn push(&mut self, value: T)

Available on non-no_global_oom_handling only.

Appends an element to the back of a collection.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1, 2];
+vec.push(3);
+assert_eq!(vec, [1, 2, 3]);
+
§Time complexity
+

Takes amortized O(1) time. If the vector’s length would exceed its +capacity after the push, O(capacity) time is taken to copy the +vector’s elements to a larger allocation. This expensive operation is +offset by the capacity O(1) insertions it allows.

+
source

pub fn push_within_capacity(&mut self, value: T) -> Result<(), T>

🔬This is a nightly-only experimental API. (vec_push_within_capacity)

Appends an element if there is sufficient spare capacity, otherwise an error is returned +with the element.

+

Unlike push this method will not reallocate when there’s insufficient capacity. +The caller should use reserve or try_reserve to ensure that there is enough capacity.

+
§Examples
+

A manual, panic-free alternative to FromIterator:

+ +
#![feature(vec_push_within_capacity)]
+
+use std::collections::TryReserveError;
+fn from_iter_fallible<T>(iter: impl Iterator<Item=T>) -> Result<Vec<T>, TryReserveError> {
+    let mut vec = Vec::new();
+    for value in iter {
+        if let Err(value) = vec.push_within_capacity(value) {
+            vec.try_reserve(1)?;
+            // this cannot fail, the previous line either returned or added at least 1 free slot
+            let _ = vec.push_within_capacity(value);
+        }
+    }
+    Ok(vec)
+}
+assert_eq!(from_iter_fallible(0..100), Ok(Vec::from_iter(0..100)));
+
§Time complexity
+

Takes O(1) time.

+
1.0.0 · source

pub fn pop(&mut self) -> Option<T>

Removes the last element from a vector and returns it, or None if it +is empty.

+

If you’d like to pop the first element, consider using +VecDeque::pop_front instead.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+assert_eq!(vec.pop(), Some(3));
+assert_eq!(vec, [1, 2]);
+
§Time complexity
+

Takes O(1) time.

+
source

pub fn pop_if<F>(&mut self, f: F) -> Option<T>
where + F: FnOnce(&mut T) -> bool,

🔬This is a nightly-only experimental API. (vec_pop_if)

Removes and returns the last element in a vector if the predicate +returns true, or None if the predicate returns false or the vector +is empty.

+
§Examples
+
#![feature(vec_pop_if)]
+
+let mut vec = vec![1, 2, 3, 4];
+let pred = |x: &mut i32| *x % 2 == 0;
+
+assert_eq!(vec.pop_if(pred), Some(4));
+assert_eq!(vec, [1, 2, 3]);
+assert_eq!(vec.pop_if(pred), None);
+
1.4.0 · source

pub fn append(&mut self, other: &mut Vec<T, A>)

Available on non-no_global_oom_handling only.

Moves all the elements of other into self, leaving other empty.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+let mut vec2 = vec![4, 5, 6];
+vec.append(&mut vec2);
+assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
+assert_eq!(vec2, []);
+
1.6.0 · source

pub fn drain<R>(&mut self, range: R) -> Drain<'_, T, A>
where + R: RangeBounds<usize>,

Removes the specified range from the vector in bulk, returning all +removed elements as an iterator. If the iterator is dropped before +being fully consumed, it drops the remaining removed elements.

+

The returned iterator keeps a mutable borrow on the vector to optimize +its implementation.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Leaking
+

If the returned iterator goes out of scope without being dropped (due to +mem::forget, for example), the vector may have lost and leaked +elements arbitrarily, including elements outside the range.

+
§Examples
+
let mut v = vec![1, 2, 3];
+let u: Vec<_> = v.drain(1..).collect();
+assert_eq!(v, &[1]);
+assert_eq!(u, &[2, 3]);
+
+// A full range clears the vector, like `clear()` does
+v.drain(..);
+assert_eq!(v, &[]);
+
1.0.0 · source

pub fn clear(&mut self)

Clears the vector, removing all values.

+

Note that this method has no effect on the allocated capacity +of the vector.

+
§Examples
+
let mut v = vec![1, 2, 3];
+
+v.clear();
+
+assert!(v.is_empty());
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the vector, also referred to +as its ‘length’.

+
§Examples
+
let a = vec![1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the vector contains no elements.

+
§Examples
+
let mut v = Vec::new();
+assert!(v.is_empty());
+
+v.push(1);
+assert!(!v.is_empty());
+
1.4.0 · source

pub fn split_off(&mut self, at: usize) -> Vec<T, A>
where + A: Clone,

Available on non-no_global_oom_handling only.

Splits the collection into two at the given index.

+

Returns a newly allocated vector containing the elements in the range +[at, len). After the call, the original vector will be left containing +the elements [0, at) with its previous capacity unchanged.

+
    +
  • If you want to take ownership of the entire contents and capacity of +the vector, see mem::take or mem::replace.
  • +
  • If you don’t need the returned vector at all, see Vec::truncate.
  • +
  • If you want to take ownership of an arbitrary subslice, or you don’t +necessarily want to store the removed items in a vector, see Vec::drain.
  • +
+
§Panics
+

Panics if at > len.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+let vec2 = vec.split_off(1);
+assert_eq!(vec, [1]);
+assert_eq!(vec2, [2, 3]);
+
1.33.0 · source

pub fn resize_with<F>(&mut self, new_len: usize, f: F)
where + F: FnMut() -> T,

Available on non-no_global_oom_handling only.

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with the result of +calling the closure f. The return values from f will end up +in the Vec in the order they have been generated.

+

If new_len is less than len, the Vec is simply truncated.

+

This method uses a closure to create new values on every push. If +you’d rather Clone a given value, use Vec::resize. If you +want to use the Default trait to generate values, you can +pass Default::default as the second argument.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+vec.resize_with(5, Default::default);
+assert_eq!(vec, [1, 2, 3, 0, 0]);
+
+let mut vec = vec![];
+let mut p = 1;
+vec.resize_with(4, || { p *= 2; p });
+assert_eq!(vec, [2, 4, 8, 16]);
+
1.60.0 · source

pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>]

Returns the remaining spare capacity of the vector as a slice of +MaybeUninit<T>.

+

The returned slice can be used to fill the vector with data (e.g. by +reading from a file) before marking the data as initialized using the +set_len method.

+
§Examples
+
// Allocate vector big enough for 10 elements.
+let mut v = Vec::with_capacity(10);
+
+// Fill in the first 3 elements.
+let uninit = v.spare_capacity_mut();
+uninit[0].write(0);
+uninit[1].write(1);
+uninit[2].write(2);
+
+// Mark the first 3 elements of the vector as being initialized.
+unsafe {
+    v.set_len(3);
+}
+
+assert_eq!(&v, &[0, 1, 2]);
+
source

pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>])

🔬This is a nightly-only experimental API. (vec_split_at_spare)

Returns vector content as a slice of T, along with the remaining spare +capacity of the vector as a slice of MaybeUninit<T>.

+

The returned spare capacity slice can be used to fill the vector with data +(e.g. by reading from a file) before marking the data as initialized using +the set_len method.

+

Note that this is a low-level API, which should be used with care for +optimization purposes. If you need to append data to a Vec +you can use push, extend, extend_from_slice, +extend_from_within, insert, append, resize or +resize_with, depending on your exact needs.

+
§Examples
+
#![feature(vec_split_at_spare)]
+
+let mut v = vec![1, 1, 2];
+
+// Reserve additional space big enough for 10 elements.
+v.reserve(10);
+
+let (init, uninit) = v.split_at_spare_mut();
+let sum = init.iter().copied().sum::<u32>();
+
+// Fill in the next 4 elements.
+uninit[0].write(sum);
+uninit[1].write(sum * 2);
+uninit[2].write(sum * 3);
+uninit[3].write(sum * 4);
+
+// Mark the 4 elements of the vector as being initialized.
+unsafe {
+    let len = v.len();
+    v.set_len(len + 4);
+}
+
+assert_eq!(&v, &[1, 1, 2, 4, 8, 12, 16]);
+
1.5.0 · source

pub fn resize(&mut self, new_len: usize, value: T)

Available on non-no_global_oom_handling only.

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with value. +If new_len is less than len, the Vec is simply truncated.

+

This method requires T to implement Clone, +in order to be able to clone the passed value. +If you need more flexibility (or want to rely on Default instead of +Clone), use Vec::resize_with. +If you only need to resize to a smaller size, use Vec::truncate.

+
§Examples
+
let mut vec = vec!["hello"];
+vec.resize(3, "world");
+assert_eq!(vec, ["hello", "world", "world"]);
+
+let mut vec = vec![1, 2, 3, 4];
+vec.resize(2, 0);
+assert_eq!(vec, [1, 2]);
+
1.6.0 · source

pub fn extend_from_slice(&mut self, other: &[T])

Available on non-no_global_oom_handling only.

Clones and appends all elements in a slice to the Vec.

+

Iterates over the slice other, clones each element, and then appends +it to this Vec. The other slice is traversed in-order.

+

Note that this function is same as extend except that it is +specialized to work with slices instead. If and when Rust gets +specialization this function will likely be deprecated (but still +available).

+
§Examples
+
let mut vec = vec![1];
+vec.extend_from_slice(&[2, 3, 4]);
+assert_eq!(vec, [1, 2, 3, 4]);
+
1.53.0 · source

pub fn extend_from_within<R>(&mut self, src: R)
where + R: RangeBounds<usize>,

Available on non-no_global_oom_handling only.

Copies elements from src range to the end of the vector.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Examples
+
let mut vec = vec![0, 1, 2, 3, 4];
+
+vec.extend_from_within(2..);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
+
+vec.extend_from_within(..2);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
+
+vec.extend_from_within(4..8);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
+
1.0.0 · source

pub fn dedup(&mut self)

Removes consecutive repeated elements in the vector according to the +PartialEq trait implementation.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec![1, 2, 2, 3, 2];
+
+vec.dedup();
+
+assert_eq!(vec, [1, 2, 3, 2]);
+
1.21.0 · source

pub fn splice<R, I>( + &mut self, + range: R, + replace_with: I +) -> Splice<'_, <I as IntoIterator>::IntoIter, A>
where + R: RangeBounds<usize>, + I: IntoIterator<Item = T>,

Available on non-no_global_oom_handling only.

Creates a splicing iterator that replaces the specified range in the vector +with the given replace_with iterator and yields the removed items. +replace_with does not need to be the same length as range.

+

range is removed even if the iterator is not consumed until the end.

+

It is unspecified how many elements are removed from the vector +if the Splice value is leaked.

+

The input iterator replace_with is only consumed when the Splice value is dropped.

+

This is optimal if:

+
    +
  • The tail (elements in the vector after range) is empty,
  • +
  • or replace_with yields fewer or equal elements than range’s length
  • +
  • or the lower bound of its size_hint() is exact.
  • +
+

Otherwise, a temporary vector is allocated and the tail is moved twice.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Examples
+
let mut v = vec![1, 2, 3, 4];
+let new = [7, 8, 9];
+let u: Vec<_> = v.splice(1..3, new).collect();
+assert_eq!(v, &[1, 7, 8, 9, 4]);
+assert_eq!(u, &[2, 3]);
+
source

pub fn extract_if<F>(&mut self, filter: F) -> ExtractIf<'_, T, F, A>
where + F: FnMut(&mut T) -> bool,

🔬This is a nightly-only experimental API. (extract_if)

Creates an iterator which uses a closure to determine if an element should be removed.

+

If the closure returns true, then the element is removed and yielded. +If the closure returns false, the element will remain in the vector and will not be yielded +by the iterator.

+

If the returned ExtractIf is not exhausted, e.g. because it is dropped without iterating +or the iteration short-circuits, then the remaining elements will be retained. +Use retain with a negated predicate if you do not need the returned iterator.

+

Using this method is equivalent to the following code:

+ +
let mut i = 0;
+while i < vec.len() {
+    if some_predicate(&mut vec[i]) {
+        let val = vec.remove(i);
+        // your code here
+    } else {
+        i += 1;
+    }
+}
+
+

But extract_if is easier to use. extract_if is also more efficient, +because it can backshift the elements of the array in bulk.

+

Note that extract_if also lets you mutate every element in the filter closure, +regardless of whether you choose to keep or remove it.

+
§Examples
+

Splitting an array into evens and odds, reusing the original allocation:

+ +
#![feature(extract_if)]
+let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];
+
+let evens = numbers.extract_if(|x| *x % 2 == 0).collect::<Vec<_>>();
+let odds = numbers;
+
+assert_eq!(evens, vec![2, 4, 6, 8, 14]);
+assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]);
+

Methods from Deref<Target = [T]>§

1.80.0 · source

pub fn as_flattened(&self) -> &[T]

Takes a &[[T; N]], and flattens it to a &[T].

+
§Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
§Examples
+
assert_eq!([[1, 2, 3], [4, 5, 6]].as_flattened(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+    [[1, 2, 3], [4, 5, 6]].as_flattened(),
+    [[1, 2], [3, 4], [5, 6]].as_flattened(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.as_flattened().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.as_flattened().is_empty());
+
1.80.0 · source

pub fn as_flattened_mut(&mut self) -> &mut [T]

Takes a &mut [[T; N]], and flattens it to a &mut [T].

+
§Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
§Examples
+
fn add_5_to_all(slice: &mut [i32]) {
+    for i in slice {
+        *i += 5;
+    }
+}
+
+let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
+add_5_to_all(array.as_flattened_mut());
+assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f32::total_cmp.

+
§Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
§Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the slice.

+
§Examples
+
let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the slice has a length of 0.

+
§Examples
+
let a = [1, 2, 3];
+assert!(!a.is_empty());
+
+let b: &[i32] = &[];
+assert!(b.is_empty());
+
1.0.0 · source

pub fn first(&self) -> Option<&T>

Returns the first element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
+
1.0.0 · source

pub fn first_mut(&mut self) -> Option<&mut T>

Returns a mutable pointer to the first element of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_mut() {
+    *first = 5;
+}
+assert_eq!(x, &[5, 1, 2]);
+
+let y: &mut [i32] = &mut [];
+assert_eq!(None, y.first_mut());
+
1.5.0 · source

pub fn split_first(&self) -> Option<(&T, &[T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first() {
+    assert_eq!(first, &0);
+    assert_eq!(elements, &[1, 2]);
+}
+
1.5.0 · source

pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_mut() {
+    *first = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
1.5.0 · source

pub fn split_last(&self) -> Option<(&T, &[T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+    assert_eq!(last, &2);
+    assert_eq!(elements, &[0, 1]);
+}
+
1.5.0 · source

pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_mut() {
+    *last = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[4, 5, 3]);
+
1.0.0 · source

pub fn last(&self) -> Option<&T>

Returns the last element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
+
1.0.0 · source

pub fn last_mut(&mut self) -> Option<&mut T>

Returns a mutable reference to the last item in the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_mut() {
+    *last = 10;
+}
+assert_eq!(x, &[0, 1, 10]);
+
+let y: &mut [i32] = &mut [];
+assert_eq!(None, y.last_mut());
+
1.77.0 · source

pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the first N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.first_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.first_chunk::<0>());
+
1.77.0 · source

pub fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

Return a mutable array reference to the first N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_chunk_mut::<2>() {
+    first[0] = 5;
+    first[1] = 4;
+}
+assert_eq!(x, &[5, 4, 2]);
+
+assert_eq!(None, x.first_chunk_mut::<4>());
+
1.77.0 · source

pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

Return an array reference to the first N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk::<2>() {
+    assert_eq!(first, &[0, 1]);
+    assert_eq!(elements, &[2]);
+}
+
+assert_eq!(None, x.split_first_chunk::<4>());
+
1.77.0 · source

pub fn split_first_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T; N], &mut [T])>

Return a mutable array reference to the first N items in the slice and the remaining +slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk_mut::<2>() {
+    first[0] = 3;
+    first[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
+assert_eq!(None, x.split_first_chunk_mut::<4>());
+
1.77.0 · source

pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>

Return an array reference to the last N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((elements, last)) = x.split_last_chunk::<2>() {
+    assert_eq!(elements, &[0]);
+    assert_eq!(last, &[1, 2]);
+}
+
+assert_eq!(None, x.split_last_chunk::<4>());
+
1.77.0 · source

pub fn split_last_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T], &mut [T; N])>

Return a mutable array reference to the last N items in the slice and the remaining +slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((elements, last)) = x.split_last_chunk_mut::<2>() {
+    last[0] = 3;
+    last[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[5, 3, 4]);
+
+assert_eq!(None, x.split_last_chunk_mut::<4>());
+
1.77.0 · source

pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the last N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.last_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.last_chunk::<0>());
+
1.77.0 · source

pub fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

Return a mutable array reference to the last N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_chunk_mut::<2>() {
+    last[0] = 10;
+    last[1] = 20;
+}
+assert_eq!(x, &[0, 10, 20]);
+
+assert_eq!(None, x.last_chunk_mut::<4>());
+
1.0.0 · source

pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice depending on the type of +index.

+
    +
  • If given a position, returns a reference to the element at that +position or None if out of bounds.
  • +
  • If given a range, returns the subslice corresponding to that range, +or None if out of bounds.
  • +
+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
+
1.0.0 · source

pub fn get_mut<I>( + &mut self, + index: I +) -> Option<&mut <I as SliceIndex<[T]>>::Output>
where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice depending on the +type of index (see get) or None if the index is out of bounds.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(elem) = x.get_mut(1) {
+    *elem = 42;
+}
+assert_eq!(x, &[0, 42, 2]);
+
1.0.0 · source

pub unsafe fn get_unchecked<I>( + &self, + index: I +) -> &<I as SliceIndex<[T]>>::Output
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice, without doing bounds +checking.

+

For a safe alternative see get.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get(index).unwrap_unchecked(). It’s UB +to call .get_unchecked(len), even if you immediately convert to a +pointer. And it’s UB to call .get_unchecked(..len + 1), +.get_unchecked(..=len), or similar.

+
§Examples
+
let x = &[1, 2, 4];
+
+unsafe {
+    assert_eq!(x.get_unchecked(1), &2);
+}
+
1.0.0 · source

pub unsafe fn get_unchecked_mut<I>( + &mut self, + index: I +) -> &mut <I as SliceIndex<[T]>>::Output
where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice, without doing +bounds checking.

+

For a safe alternative see get_mut.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get_mut(index).unwrap_unchecked(). It’s +UB to call .get_unchecked_mut(len), even if you immediately convert +to a pointer. And it’s UB to call .get_unchecked_mut(..len + 1), +.get_unchecked_mut(..=len), or similar.

+
§Examples
+
let x = &mut [1, 2, 4];
+
+unsafe {
+    let elem = x.get_unchecked_mut(1);
+    *elem = 13;
+}
+assert_eq!(x, &[1, 13, 4]);
+
1.0.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
§Examples
+
let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+    }
+}
+
1.0.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
§Examples
+
let x = &mut [1, 2, 4];
+let x_ptr = x.as_mut_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        *x_ptr.add(i) += 2;
+    }
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.48.0 · source

pub fn as_ptr_range(&self) -> Range<*const T>

Returns the two raw pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_ptr for warnings on using these pointers. The end pointer +requires extra caution, as it does not point to a valid element in the +slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+

It can also be useful to check if a pointer to an element refers to an +element of this slice:

+ +
let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
+
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
+
1.48.0 · source

pub fn as_mut_ptr_range(&mut self) -> Range<*mut T>

Returns the two unsafe mutable pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_mut_ptr for warnings on using these pointers. The end +pointer requires extra caution, as it does not point to a valid element +in the slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+
1.0.0 · source

pub fn swap(&mut self, a: usize, b: usize)

Swaps two elements in the slice.

+

If a equals to b, it’s guaranteed that elements won’t change value.

+
§Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
§Panics
+

Panics if a or b are out of bounds.

+
§Examples
+
let mut v = ["a", "b", "c", "d", "e"];
+v.swap(2, 4);
+assert!(v == ["a", "b", "e", "d", "c"]);
+
source

pub unsafe fn swap_unchecked(&mut self, a: usize, b: usize)

🔬This is a nightly-only experimental API. (slice_swap_unchecked)

Swaps two elements in the slice, without doing bounds checking.

+

For a safe alternative see swap.

+
§Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior. +The caller has to ensure that a < self.len() and b < self.len().

+
§Examples
+
#![feature(slice_swap_unchecked)]
+
+let mut v = ["a", "b", "c", "d"];
+// SAFETY: we know that 1 and 3 are both indices of the slice
+unsafe { v.swap_unchecked(1, 3) };
+assert!(v == ["a", "d", "c", "b"]);
+
1.0.0 · source

pub fn reverse(&mut self)

Reverses the order of elements in the slice, in place.

+
§Examples
+
let mut v = [1, 2, 3];
+v.reverse();
+assert!(v == [3, 2, 1]);
+
1.0.0 · source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the slice.

+

The iterator yields all items from start to end.

+
§Examples
+
let x = &[1, 2, 4];
+let mut iterator = x.iter();
+
+assert_eq!(iterator.next(), Some(&1));
+assert_eq!(iterator.next(), Some(&2));
+assert_eq!(iterator.next(), Some(&4));
+assert_eq!(iterator.next(), None);
+
1.0.0 · source

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Returns an iterator that allows modifying each value.

+

The iterator yields all items from start to end.

+
§Examples
+
let x = &mut [1, 2, 4];
+for elem in x.iter_mut() {
+    *elem += 2;
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.0.0 · source

pub fn windows(&self, size: usize) -> Windows<'_, T>

Returns an iterator over all contiguous windows of length +size. The windows overlap. If the slice is shorter than +size, the iterator returns no values.

+
§Panics
+

Panics if size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.windows(3);
+assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']);
+assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']);
+assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']);
+assert!(iter.next().is_none());
+

If the slice is shorter than size:

+ +
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
+

There’s no windows_mut, as that existing would let safe code violate the +“only one &mut at a time to the same thing” rule. However, you can sometimes +use Cell::as_slice_of_cells in +conjunction with windows to accomplish something similar:

+ +
use std::cell::Cell;
+
+let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
+let slice = &mut array[..];
+let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
+for w in slice_of_cells.windows(3) {
+    Cell::swap(&w[0], &w[2]);
+}
+assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
+
1.0.0 · source

pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See chunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and rchunks for the same iterator but starting at the end of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See chunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and rchunks_mut for the same iterator but starting at +the end of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 3]);
+
1.31.0 · source

pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks.

+

See chunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
1.31.0 · source

pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See chunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and rchunks_exact_mut for the same iterator but starting at the end of +the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
§Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
§Examples
+
#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+
source

pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
+

If you expect the slice to be an exact multiple, you can combine +let-else with an empty slice pattern:

+ +
#![feature(slice_as_chunks)]
+let slice = ['R', 'u', 's', 't'];
+let (chunks, []) = slice.as_chunks::<2>() else {
+    panic!("slice didn't have even length")
+};
+assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
+
source

pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+
source

pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are array references and do not overlap. If N does not divide the +length of the slice, then the last up to N-1 elements will be omitted and can be +retrieved from the remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
source

pub unsafe fn as_chunks_unchecked_mut<const N: usize>( + &mut self +) -> &mut [[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
§Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
§Examples
+
#![feature(slice_as_chunks)]
+let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &mut [[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[0] = ['L'];
+assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &mut [[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[1] = ['a', 'x', '?'];
+assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
+
source

pub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (chunks, remainder) = v.as_chunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 9]);
+
source

pub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (remainder, chunks) = v.as_rchunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[9, 1, 1, 2, 2]);
+
source

pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable array references and do not overlap. If N does not divide +the length of the slice, then the last up to N-1 elements will be omitted and +can be retrieved from the into_remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact_mut.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.array_chunks_mut() {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>

🔬This is a nightly-only experimental API. (array_windows)

Returns an iterator over overlapping windows of N elements of a slice, +starting at the beginning of the slice.

+

This is the const generic equivalent of windows.

+

If N is greater than the size of the slice, it will return no windows.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and chunks for the same iterator but starting at the beginning +of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and chunks_mut for the same iterator but starting at the +beginning of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[3, 2, 2, 1, 1]);
+
1.31.0 · source

pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +end of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of rchunks.

+

See rchunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and chunks_exact for the same iterator but starting at the beginning of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
+
1.31.0 · source

pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See rchunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and chunks_exact_mut for the same iterator but starting at the beginning +of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[0, 2, 2, 1, 1]);
+
1.77.0 · source

pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
where + F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping runs +of elements using the predicate to separate them.

+

The predicate is called for every pair of consecutive elements, +meaning that it is called on slice[0] and slice[1], +followed by slice[1] and slice[2], and so on.

+
§Examples
+
let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.chunk_by(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.chunk_by(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.77.0 · source

pub fn chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F>
where + F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping mutable +runs of elements using the predicate to separate them.

+

The predicate is called for every pair of consecutive elements, +meaning that it is called on slice[0] and slice[1], +followed by slice[1] and slice[2], and so on.

+
§Examples
+
let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.chunk_by_mut(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&mut [3, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.chunk_by_mut(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.0.0 · source

pub fn split_at(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
§Panics
+

Panics if mid > len. For a non-panicking alternative see +split_at_checked.

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+{
+   let (left, right) = v.split_at(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.0.0 · source

pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
§Panics
+

Panics if mid > len. For a non-panicking alternative see +split_at_mut_checked.

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+let (left, right) = v.split_at_mut(2);
+assert_eq!(left, [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.79.0 · source

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+unsafe {
+   let (left, right) = v.split_at_unchecked(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.79.0 · source

pub unsafe fn split_at_mut_unchecked( + &mut self, + mid: usize +) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at_mut.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+// scoped to restrict the lifetime of the borrows
+unsafe {
+    let (left, right) = v.split_at_mut_unchecked(2);
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.80.0 · source

pub fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])>

Divides one slice into two at an index, returning None if the slice is +too short.

+

If mid ≤ len returns a pair of slices where the first will contain all +indices from [0, mid) (excluding the index mid itself) and the +second will contain all indices from [mid, len) (excluding the index +len itself).

+

Otherwise, if mid > len, returns None.

+
§Examples
+
let v = [1, -2, 3, -4, 5, -6];
+
+{
+   let (left, right) = v.split_at_checked(0).unwrap();
+   assert_eq!(left, []);
+   assert_eq!(right, [1, -2, 3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(2).unwrap();
+    assert_eq!(left, [1, -2]);
+    assert_eq!(right, [3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(6).unwrap();
+    assert_eq!(left, [1, -2, 3, -4, 5, -6]);
+    assert_eq!(right, []);
+}
+
+assert_eq!(None, v.split_at_checked(7));
+
1.80.0 · source

pub fn split_at_mut_checked( + &mut self, + mid: usize +) -> Option<(&mut [T], &mut [T])>

Divides one mutable slice into two at an index, returning None if the +slice is too short.

+

If mid ≤ len returns a pair of slices where the first will contain all +indices from [0, mid) (excluding the index mid itself) and the +second will contain all indices from [mid, len) (excluding the index +len itself).

+

Otherwise, if mid > len, returns None.

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+
+if let Some((left, right)) = v.split_at_mut_checked(2) {
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
+assert_eq!(None, v.split_at_mut_checked(7));
+
1.0.0 · source

pub fn split<F>(&self, pred: F) -> Split<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is not contained in the subslices.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the first element is matched, an empty slice will be the first item +returned by the iterator. Similarly, if the last element in the slice +is matched, an empty slice will be the last item returned by the +iterator:

+ +
let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
+

If two matched elements are directly adjacent, an empty slice will be +present between them:

+ +
let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is not contained in the subslices.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_mut(|num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 1]);
+
1.51.0 · source

pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is contained in the end of the previous +subslice as a terminator.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the last element of the slice is matched, +that element will be considered the terminator of the preceding slice. +That slice will be the last item returned by the iterator.

+ +
let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
+
1.51.0 · source

pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is contained in the previous +subslice as a terminator.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
+    let terminator_idx = group.len()-1;
+    group[terminator_idx] = 1;
+}
+assert_eq!(v, [10, 40, 1, 20, 1, 1]);
+
1.27.0 · source

pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, starting at the end of the slice and working backwards. +The matched element is not contained in the subslices.

+
§Examples
+
let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
+
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
+

As with split(), if the first or last element is matched, an empty +slice will be the first (or last) item returned by the iterator.

+ +
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
+
1.27.0 · source

pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred, starting at the end of the slice and working +backwards. The matched element is not contained in the subslices.

+
§Examples
+
let mut v = [100, 400, 300, 200, 600, 500];
+
+let mut count = 0;
+for group in v.rsplit_mut(|num| *num % 3 == 0) {
+    count += 1;
+    group[0] = count;
+}
+assert_eq!(v, [3, 400, 300, 2, 600, 1]);
+
1.0.0 · source

pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], +[20, 60, 50]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 50]);
+
1.0.0 · source

pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once, starting from the end, by numbers divisible +by 3 (i.e., [50], [10, 40, 30, 20]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+
let mut s = [10, 40, 30, 20, 60, 50];
+
+for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(s, [1, 40, 30, 20, 60, 1]);
+
source

pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the first element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.split_once(|&x| x == 2), Some((
+    &[1][..],
+    &[3, 2, 4][..]
+)));
+assert_eq!(s.split_once(|&x| x == 0), None);
+
source

pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the last element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.rsplit_once(|&x| x == 2), Some((
+    &[1, 2, 3][..],
+    &[4][..]
+)));
+assert_eq!(s.rsplit_once(|&x| x == 0), None);
+
1.0.0 · source

pub fn contains(&self, x: &T) -> bool
where + T: PartialEq,

Returns true if the slice contains an element with the given value.

+

This operation is O(n).

+

Note that if you have a sorted slice, binary_search may be faster.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
+

If you do not have a &T, but some other value that you can compare +with one (for example, String implements PartialEq<str>), you can +use iter().any:

+ +
let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
+
1.0.0 · source

pub fn starts_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a prefix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(v.starts_with(&v));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
+
1.0.0 · source

pub fn ends_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a suffix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(v.ends_with(&v));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
+
1.51.0 · source

pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the prefix removed.

+

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. +If prefix is empty, simply returns the original slice. If prefix is equal to the +original slice, returns an empty slice.

+

If the slice does not start with prefix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
+
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+           Some(b"llo".as_ref()));
+
1.51.0 · source

pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the suffix removed.

+

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. +If suffix is empty, simply returns the original slice. If suffix is equal to the +original slice, returns an empty slice.

+

If the slice does not end with suffix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
+

Binary searches this slice for a given element. +If the slice is not sorted, the returned result is unspecified and +meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search_by, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+assert_eq!(s.binary_search(&13),  Ok(9));
+assert_eq!(s.binary_search(&4),   Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

If you want to find that whole range of matching items, rather than +an arbitrary matching one, that can be done using partition_point:

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
+

If you want to insert an item to a sorted vector, while maintaining +sort order, consider using partition_point:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+// If `num` is unique, `s.partition_point(|&x| x < num)` (with `<`) is equivalent to
+// `s.binary_search(&num).unwrap_or_else(|x| x)`, but using `<=` will allow `insert`
+// to shift less elements.
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
1.0.0 · source

pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
where + F: FnMut(&'a T) -> Ordering,

Binary searches this slice with a comparator function.

+

The comparator function should return an order code that indicates +whether its argument is Less, Equal or Greater the desired +target. +If the slice is not sorted or if the comparator function does not +implement an order consistent with the sort order of the underlying +slice, the returned result is unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.10.0 · source

pub fn binary_search_by_key<'a, B, F>( + &'a self, + b: &B, + f: F +) -> Result<usize, usize>
where + F: FnMut(&'a T) -> B, + B: Ord,

Binary searches this slice with a key extraction function.

+

Assumes that the slice is sorted by the key, for instance with +sort_by_key using the same key extraction function. +If the slice is not sorted by the key, the returned result is +unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by, and partition_point.

+
§Examples
+

Looks up a series of four elements in a slice of pairs sorted by +their second elements. The first is found, with a uniquely +determined position; the second and third are not found; the +fourth could match any position in [1, 4].

+ +
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+         (1, 21), (2, 34), (4, 55)];
+
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.20.0 · source

pub fn sort_unstable(&mut self)
where + T: Ord,

Sorts the slice, but might not preserve the order of equal elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
§Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort_unstable();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.20.0 · source

pub fn sort_unstable_by<F>(&mut self, compare: F)
where + F: FnMut(&T, &T) -> Ordering,

Sorts the slice with a comparator function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
§Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_unstable_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_unstable_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.20.0 · source

pub fn sort_unstable_by_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(m * n * log(n)) worst-case, where the key function is +O(m).

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

Due to its key calling strategy, sort_unstable_by_key +is likely to be slower than sort_by_cached_key in +cases where the key function is expensive.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_unstable_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.49.0 · source

pub fn select_nth_unstable( + &mut self, + index: usize +) -> (&mut [T], &mut T, &mut [T])
where + T: Ord,

Reorder the slice such that the element at index after the reordering is at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index. Additionally, this reordering is +unstable (i.e. any number of equal elements may end up at position index), in-place +(i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from the reordered slice: +the subslice prior to index, the element at index, and the subslice after index; +accordingly, the values in those two subslices will respectively all be less-than-or-equal-to +and greater-than-or-equal-to the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 2, -3, 1];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median.
+let (lesser, median, greater) = v.select_nth_unstable(2);
+
+assert!(lesser == [-3, -5] || lesser == [-5, -3]);
+assert_eq!(median, &mut 1);
+assert!(greater == [4, 2] || greater == [2, 4]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [-3, -5, 1, 2, 4] ||
+        v == [-5, -3, 1, 2, 4] ||
+        v == [-3, -5, 1, 4, 2] ||
+        v == [-5, -3, 1, 4, 2]);
+
1.49.0 · source

pub fn select_nth_unstable_by<F>( + &mut self, + index: usize, + compare: F +) -> (&mut [T], &mut T, &mut [T])
where + F: FnMut(&T, &T) -> Ordering,

Reorder the slice with a comparator function such that the element at index after the reordering is at +its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the comparator function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided comparator function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 2, -3, 1];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median as if the slice were sorted in descending order.
+let (lesser, median, greater) = v.select_nth_unstable_by(2, |a, b| b.cmp(a));
+
+assert!(lesser == [4, 2] || lesser == [2, 4]);
+assert_eq!(median, &mut 1);
+assert!(greater == [-3, -5] || greater == [-5, -3]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [2, 4, 1, -5, -3] ||
+        v == [2, 4, 1, -3, -5] ||
+        v == [4, 2, 1, -5, -3] ||
+        v == [4, 2, 1, -3, -5]);
+
1.49.0 · source

pub fn select_nth_unstable_by_key<K, F>( + &mut self, + index: usize, + f: F +) -> (&mut [T], &mut T, &mut [T])
where + F: FnMut(&T) -> K, + K: Ord,

Reorder the slice with a key extraction function such that the element at index after the reordering is +at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the key extraction function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided key extraction function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median as if the slice were sorted according to absolute value.
+let (lesser, median, greater) = v.select_nth_unstable_by_key(2, |a| a.abs());
+
+assert!(lesser == [1, 2] || lesser == [2, 1]);
+assert_eq!(median, &mut -3);
+assert!(greater == [4, -5] || greater == [-5, 4]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [1, 2, -3, 4, -5] ||
+        v == [1, 2, -3, -5, 4] ||
+        v == [2, 1, -3, 4, -5] ||
+        v == [2, 1, -3, -5, 4]);
+
source

pub fn partition_dedup(&mut self) -> (&mut [T], &mut [T])
where + T: PartialEq,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all consecutive repeated elements to the end of the slice according to the +PartialEq trait implementation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
+
+let (dedup, duplicates) = slice.partition_dedup();
+
+assert_eq!(dedup, [1, 2, 3, 2, 1]);
+assert_eq!(duplicates, [2, 3, 1]);
+
source

pub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T])
where + F: FnMut(&mut T, &mut T) -> bool,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice satisfying +a given equality relation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

The same_bucket function is passed references to two elements from the slice and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is moved +at the end of the slice.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
+
+let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
+assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
+
source

pub fn partition_dedup_by_key<K, F>(&mut self, key: F) -> (&mut [T], &mut [T])
where + F: FnMut(&mut T) -> K, + K: PartialEq,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice that resolve +to the same key.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
+
+let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
+
+assert_eq!(dedup, [10, 20, 30, 20, 11]);
+assert_eq!(duplicates, [21, 30, 13]);
+
1.26.0 · source

pub fn rotate_left(&mut self, mid: usize)

Rotates the slice in-place such that the first mid elements of the +slice move to the end while the last self.len() - mid elements move to +the front. After calling rotate_left, the element previously at index +mid will become the first element in the slice.

+
§Panics
+

This function will panic if mid is greater than the length of the +slice. Note that mid == self.len() does not panic and is a no-op +rotation.

+
§Complexity
+

Takes linear (in self.len()) time.

+
§Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_left(2);
+assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_left(1);
+assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+
1.26.0 · source

pub fn rotate_right(&mut self, k: usize)

Rotates the slice in-place such that the first self.len() - k +elements of the slice move to the end while the last k elements move +to the front. After calling rotate_right, the element previously at +index self.len() - k will become the first element in the slice.

+
§Panics
+

This function will panic if k is greater than the length of the +slice. Note that k == self.len() does not panic and is a no-op +rotation.

+
§Complexity
+

Takes linear (in self.len()) time.

+
§Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_right(2);
+assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_right(1);
+assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
+
1.50.0 · source

pub fn fill(&mut self, value: T)
where + T: Clone,

Fills self with elements by cloning value.

+
§Examples
+
let mut buf = vec![0; 10];
+buf.fill(1);
+assert_eq!(buf, vec![1; 10]);
+
1.51.0 · source

pub fn fill_with<F>(&mut self, f: F)
where + F: FnMut() -> T,

Fills self with elements returned by calling a closure repeatedly.

+

This method uses a closure to create new values. If you’d rather +Clone a given value, use fill. If you want to use the Default +trait to generate values, you can pass Default::default as the +argument.

+
§Examples
+
let mut buf = vec![1; 10];
+buf.fill_with(Default::default);
+assert_eq!(buf, vec![0; 10]);
+
1.7.0 · source

pub fn clone_from_slice(&mut self, src: &[T])
where + T: Clone,

Copies the elements from src into self.

+

The length of src must be the same as self.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Examples
+

Cloning two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.clone_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use clone_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].clone_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.clone_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.9.0 · source

pub fn copy_from_slice(&mut self, src: &[T])
where + T: Copy,

Copies all elements from src into self, using a memcpy.

+

The length of src must be the same as self.

+

If T does not implement Copy, use clone_from_slice.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Examples
+

Copying two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.copy_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use copy_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].copy_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.copy_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.37.0 · source

pub fn copy_within<R>(&mut self, src: R, dest: usize)
where + R: RangeBounds<usize>, + T: Copy,

Copies elements from one part of the slice to another part of itself, +using a memmove.

+

src is the range within self to copy from. dest is the starting +index of the range within self to copy to, which will have the same +length as src. The two ranges may overlap. The ends of the two ranges +must be less than or equal to self.len().

+
§Panics
+

This function will panic if either range exceeds the end of the slice, +or if the end of src is before the start.

+
§Examples
+

Copying four bytes within a slice:

+ +
let mut bytes = *b"Hello, World!";
+
+bytes.copy_within(1..5, 8);
+
+assert_eq!(&bytes, b"Hello, Wello!");
+
1.27.0 · source

pub fn swap_with_slice(&mut self, other: &mut [T])

Swaps all elements in self with those in other.

+

The length of other must be the same as self.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Example
+

Swapping two elements across slices:

+ +
let mut slice1 = [0, 0];
+let mut slice2 = [1, 2, 3, 4];
+
+slice1.swap_with_slice(&mut slice2[2..]);
+
+assert_eq!(slice1, [3, 4]);
+assert_eq!(slice2, [1, 2, 0, 0]);
+

Rust enforces that there can only be one mutable reference to a +particular piece of data in a particular scope. Because of this, +attempting to use swap_with_slice on a single slice will result in +a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +mutable sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.swap_with_slice(&mut right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 1, 2]);
+
1.30.0 · source

pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

Transmute the slice to a slice of another type, ensuring alignment of the types is +maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The middle part will be as big as possible under +the given alignment constraint and element size.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
§Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
§Examples
+

Basic usage:

+ +
unsafe {
+    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
1.30.0 · source

pub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T])

Transmute the mutable slice to a mutable slice of another type, ensuring alignment of the +types is maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The middle part will be as big as possible under +the given alignment constraint and element size.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
§Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
§Examples
+

Basic usage:

+ +
unsafe {
+    let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
source

pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
where + Simd<T, LANES>: AsRef<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.

+

This is a safe wrapper around slice::align_to, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+
§Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
§Examples
+
#![feature(portable_simd)]
+use core::simd::prelude::*;
+
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
+
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+
+fn basic_simd_sum(x: &[f32]) -> f32 {
+    use std::ops::Add;
+    let (prefix, middle, suffix) = x.as_simd();
+    let sums = f32x4::from_array([
+        prefix.iter().copied().sum(),
+        0.0,
+        0.0,
+        suffix.iter().copied().sum(),
+    ]);
+    let sums = middle.iter().copied().fold(sums, f32x4::add);
+    sums.reduce_sum()
+}
+
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+
source

pub fn as_simd_mut<const LANES: usize>( + &mut self +) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T])
where + Simd<T, LANES>: AsMut<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a mutable slice into a mutable prefix, a middle of aligned SIMD types, +and a mutable suffix.

+

This is a safe wrapper around slice::align_to_mut, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+

This is the mutable version of slice::as_simd; see that for examples.

+
§Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
source

pub fn is_sorted(&self) -> bool
where + T: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted.

+

That is, for each element a and its following element b, a <= b must hold. If the +slice yields exactly zero or one element, true is returned.

+

Note that if Self::Item is only PartialOrd, but not Ord, the above definition +implies that this function returns false if any two consecutive items are not +comparable.

+
§Examples
+
#![feature(is_sorted)]
+let empty: [i32; 0] = [];
+
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
+
source

pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> bool
where + F: FnMut(&'a T, &'a T) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given comparator function.

+

Instead of using PartialOrd::partial_cmp, this function uses the given compare +function to determine whether two elements are to be considered in sorted order.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!([1, 2, 2, 9].is_sorted_by(|a, b| a <= b));
+assert!(![1, 2, 2, 9].is_sorted_by(|a, b| a < b));
+
+assert!([0].is_sorted_by(|a, b| true));
+assert!([0].is_sorted_by(|a, b| false));
+
+let empty: [i32; 0] = [];
+assert!(empty.is_sorted_by(|a, b| false));
+assert!(empty.is_sorted_by(|a, b| true));
+
source

pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
where + F: FnMut(&'a T) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given key extraction function.

+

Instead of comparing the slice’s elements directly, this function compares the keys of the +elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its +documentation for more information.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+
1.52.0 · source

pub fn partition_point<P>(&self, pred: P) -> usize
where + P: FnMut(&T) -> bool,

Returns the index of the partition point according to the given predicate +(the index of the first element of the second partition).

+

The slice is assumed to be partitioned according to the given predicate. +This means that all elements for which the predicate returns true are at the start of the slice +and all elements for which the predicate returns false are at the end. +For example, [7, 15, 3, 5, 4, 12, 6] is partitioned under the predicate x % 2 != 0 +(all odd numbers are at the start, all even at the end).

+

If this slice is not partitioned, the returned result is unspecified and meaningless, +as this method performs a kind of binary search.

+

See also binary_search, binary_search_by, and binary_search_by_key.

+
§Examples
+
let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
+
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
+

If all elements of the slice match the predicate, including if the slice +is empty, then the length of the slice will be returned:

+ +
let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
+

If you want to insert an item to a sorted vector, while maintaining +sort order:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
source

pub fn take<'a, R>(self: &mut &'a [T], range: R) -> Option<&'a [T]>
where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
§Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut first_three = slice.take(..3).unwrap();
+
+assert_eq!(slice, &['d']);
+assert_eq!(first_three, &['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut tail = slice.take(2..).unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(tail, &['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take(5..));
+assert_eq!(None, slice.take(..5));
+assert_eq!(None, slice.take(..=4));
+let expected: &[char] = &['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take(..4));
+
source

pub fn take_mut<'a, R>(self: &mut &'a mut [T], range: R) -> Option<&'a mut [T]>
where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a mutable reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
§Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut first_three = slice.take_mut(..3).unwrap();
+
+assert_eq!(slice, &mut ['d']);
+assert_eq!(first_three, &mut ['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut tail = slice.take_mut(2..).unwrap();
+
+assert_eq!(slice, &mut ['a', 'b']);
+assert_eq!(tail, &mut ['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take_mut(5..));
+assert_eq!(None, slice.take_mut(..5));
+assert_eq!(None, slice.take_mut(..=4));
+let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take_mut(..4));
+
source

pub fn take_first<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let first = slice.take_first().unwrap();
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'a');
+
source

pub fn take_first_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let first = slice.take_first_mut().unwrap();
+*first = 'd';
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'d');
+
source

pub fn take_last<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let last = slice.take_last().unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'c');
+
source

pub fn take_last_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let last = slice.take_last_mut().unwrap();
+*last = 'd';
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'d');
+
source

pub unsafe fn get_many_unchecked_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> [&mut T; N]

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once, without doing any checks.

+

For a safe alternative see get_many_mut.

+
§Safety
+

Calling this method with overlapping or out-of-bounds indices is undefined behavior +even if the resulting references are not used.

+
§Examples
+
#![feature(get_many_mut)]
+
+let x = &mut [1, 2, 4];
+
+unsafe {
+    let [a, b] = x.get_many_unchecked_mut([0, 2]);
+    *a *= 10;
+    *b *= 100;
+}
+assert_eq!(x, &[10, 2, 400]);
+
source

pub fn get_many_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> Result<[&mut T; N], GetManyMutError<N>>

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once.

+

Returns an error if any index is out-of-bounds, or if the same index was +passed more than once.

+
§Examples
+
#![feature(get_many_mut)]
+
+let v = &mut [1, 2, 3];
+if let Ok([a, b]) = v.get_many_mut([0, 2]) {
+    *a = 413;
+    *b = 612;
+}
+assert_eq!(v, &[413, 2, 612]);
+
1.79.0 · source

pub fn utf8_chunks(&self) -> Utf8Chunks<'_>

Creates an iterator over the contiguous valid UTF-8 ranges of this +slice, and the non-UTF-8 fragments in between.

+
§Examples
+

This function formats arbitrary but mostly-UTF-8 bytes into Rust source +code in the form of a C-string literal (c"...").

+ +
use std::fmt::Write as _;
+
+pub fn cstr_literal(bytes: &[u8]) -> String {
+    let mut repr = String::new();
+    repr.push_str("c\"");
+    for chunk in bytes.utf8_chunks() {
+        for ch in chunk.valid().chars() {
+            // Escapes \0, \t, \r, \n, \\, \', \", and uses \u{...} for non-printable characters.
+            write!(repr, "{}", ch.escape_debug()).unwrap();
+        }
+        for byte in chunk.invalid() {
+            write!(repr, "\\x{:02X}", byte).unwrap();
+        }
+    }
+    repr.push('"');
+    repr
+}
+
+fn main() {
+    let lit = cstr_literal(b"\xferris the \xf0\x9f\xa6\x80\x07");
+    let expected = stringify!(c"\xFErris the 🦀\u{7}");
+    assert_eq!(lit, expected);
+}
+
1.23.0 · source

pub fn is_ascii(&self) -> bool

Checks if all bytes in this slice are within the ASCII range.

+
source

pub fn as_ascii(&self) -> Option<&[AsciiChar]>

🔬This is a nightly-only experimental API. (ascii_char)

If this slice is_ascii, returns it as a slice of +ASCII characters, otherwise returns None.

+
source

pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]

🔬This is a nightly-only experimental API. (ascii_char)

Converts this slice of bytes into a slice of ASCII characters, +without checking whether they’re valid.

+
§Safety
+

Every byte in the slice must be in 0..=127, or else this is UB.

+
1.23.0 · source

pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool

Checks that two slices are an ASCII case-insensitive match.

+

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), +but without allocating and copying temporaries.

+
1.23.0 · source

pub fn make_ascii_uppercase(&mut self)

Converts this slice to its ASCII upper case equivalent in-place.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To return a new uppercased value without modifying the existing one, use +to_ascii_uppercase.

+
1.23.0 · source

pub fn make_ascii_lowercase(&mut self)

Converts this slice to its ASCII lower case equivalent in-place.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To return a new lowercased value without modifying the existing one, use +to_ascii_lowercase.

+
1.60.0 · source

pub fn escape_ascii(&self) -> EscapeAscii<'_>

Returns an iterator that produces an escaped version of this slice, +treating it as an ASCII string.

+
§Examples
+

+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
+
1.80.0 · source

pub fn trim_ascii_start(&self) -> &[u8]

Returns a byte slice with leading ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b"  ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
+
1.80.0 · source

pub fn trim_ascii_end(&self) -> &[u8]

Returns a byte slice with trailing ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b"  ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
+
1.80.0 · source

pub fn trim_ascii(&self) -> &[u8]

Returns a byte slice with leading and trailing ASCII whitespace bytes +removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b"  ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f64::total_cmp.

+
§Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
§Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
source

pub fn as_str(&self) -> &str

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a UTF-8 str.

+
source

pub fn as_bytes(&self) -> &[u8]

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a slice of u8 bytes.

+
1.0.0 · source

pub fn sort(&mut self)
where + T: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.0.0 · source

pub fn sort_by<F>(&mut self, compare: F)
where + F: FnMut(&T, &T) -> Ordering,

Available on non-no_global_oom_handling only.

Sorts the slice with a comparator function.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.7.0 · source

pub fn sort_by_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n * log(n)) +worst-case, where the key function is O(m).

+

For expensive key functions (e.g. functions that are not simple property accesses or +basic operations), sort_by_cached_key is likely to be +significantly faster, as it does not recompute element keys.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by_key.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.34.0 · source

pub fn sort_by_cached_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

During sorting, the key function is called at most once per element, by using +temporary storage to remember the results of key evaluation. +The order of calls to the key function is unspecified and may change in future versions +of the standard library.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n + n * log(n)) +worst-case, where the key function is O(m).

+

For simple key functions (e.g., functions that are property accesses or +basic operations), sort_by_key is likely to be +faster.

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

In the worst case, the algorithm allocates temporary storage in a Vec<(K, usize)> the +length of the slice.

+
§Examples
+
let mut v = [-5i32, 4, 32, -3, 2];
+
+v.sort_by_cached_key(|k| k.to_string());
+assert!(v == [-3, -5, 2, 32, 4]);
+
1.0.0 · source

pub fn to_vec(&self) -> Vec<T>
where + T: Clone,

Available on non-no_global_oom_handling only.

Copies self into a new Vec.

+
§Examples
+
let s = [10, 40, 30];
+let x = s.to_vec();
+// Here, `s` and `x` can be modified independently.
+
source

pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>
where + A: Allocator, + T: Clone,

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Copies self into a new Vec with an allocator.

+
§Examples
+
#![feature(allocator_api)]
+
+use std::alloc::System;
+
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
+// Here, `s` and `x` can be modified independently.
+
1.40.0 · source

pub fn repeat(&self, n: usize) -> Vec<T>
where + T: Copy,

Available on non-no_global_oom_handling only.

Creates a vector by copying a slice n times.

+
§Panics
+

This function will panic if the capacity would overflow.

+
§Examples
+

Basic usage:

+ +
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
+

A panic upon overflow:

+ +
// this will panic at runtime
+b"0123456789abcdef".repeat(usize::MAX);
+
1.0.0 · source

pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output
where + [T]: Concat<Item>, + Item: ?Sized,

Flattens a slice of T into a single value Self::Output.

+
§Examples
+
assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+
1.3.0 · source

pub fn join<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+
1.0.0 · source

pub fn connect<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

👎Deprecated since 1.3.0: renamed to join

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+
1.23.0 · source

pub fn to_ascii_uppercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII upper case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To uppercase the value in-place, use make_ascii_uppercase.

+
1.23.0 · source

pub fn to_ascii_lowercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII lower case equivalent.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To lowercase the value in-place, use make_ascii_lowercase.

+

Trait Implementations§

source§

impl Clone for AcceptCharset

source§

fn clone(&self) -> AcceptCharset

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for AcceptCharset

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for AcceptCharset

§

type Target = Vec<QualityItem<Charset>>

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for AcceptCharset

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl Display for AcceptCharset

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for AcceptCharset

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for AcceptCharset

source§

fn eq(&self, other: &AcceptCharset) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for AcceptCharset

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for AcceptCharset

source§

impl StructuralPartialEq for AcceptCharset

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.AcceptEncoding.html b/actix_web/http/header/struct.AcceptEncoding.html new file mode 100644 index 000000000..ce9000e2d --- /dev/null +++ b/actix_web/http/header/struct.AcceptEncoding.html @@ -0,0 +1,3155 @@ +AcceptEncoding in actix_web::http::header - Rust

Struct actix_web::http::header::AcceptEncoding

source ·
pub struct AcceptEncoding(pub Vec<QualityItem<Preference<Encoding>>>);
Expand description

Accept-Encoding header, defined +in RFC 7231

+

The Accept-Encoding header field can be used by user agents to indicate what response +content-codings are acceptable in the response. An identity token is used as a synonym +for “no encoding” in order to communicate when no encoding is preferred.

+

§ABNF

Accept-Encoding  = #( codings [ weight ] )
+codings          = content-coding / "identity" / "*"
+

§Example Values

+
    +
  • compress, gzip
  • +
  • ``
  • +
  • *
  • +
  • compress;q=0.5, gzip;q=1
  • +
  • gzip;q=1.0, identity; q=0.5, *;q=0
  • +
+

§Examples

+
use actix_web::HttpResponse;
+use actix_web::http::header::{AcceptEncoding, Encoding, Preference, QualityItem};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    AcceptEncoding(vec![QualityItem::max(Preference::Specific(Encoding::gzip()))])
+);
+ +
use actix_web::HttpResponse;
+use actix_web::http::header::{AcceptEncoding, Encoding, QualityItem};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    AcceptEncoding(vec![
+        "gzip".parse().unwrap(),
+        "br".parse().unwrap(),
+    ])
+);
+

Tuple Fields§

§0: Vec<QualityItem<Preference<Encoding>>>

Implementations§

source§

impl AcceptEncoding

source

pub fn negotiate<'a>( + &self, + supported: impl Iterator<Item = &'a Encoding> +) -> Option<Encoding>

Selects the most acceptable encoding according to client preference and supported types.

+

The “identity” encoding is not assumed and should be included in the supported iterator +if a non-encoded representation can be selected.

+

If None is returned, this indicates that none of the supported encodings are acceptable to +the client. The caller should generate a 406 Not Acceptable response (unencoded) that +includes the server’s supported encodings in the body plus a Vary header.

+
source

pub fn preference(&self) -> Option<Preference<Encoding>>

Extracts the most preferable encoding, accounting for q-factor weighting.

+

If no q-factors are provided, we prefer brotli > zstd > gzip. Note that items without +q-factors are given the maximum preference value.

+

As per the spec, returns Preference::Any if acceptable list is empty. Though, if this is +returned, it is recommended to use an un-encoded representation.

+

If None is returned, it means that the client has signalled that no representations +are acceptable. This should never occur for a well behaved user-agent.

+
source

pub fn ranked(&self) -> Vec<Preference<Encoding>>

Returns a sorted list of encodings from highest to lowest precedence, accounting +for q-factor weighting.

+

If no q-factors are provided, we prefer brotli > zstd > gzip.

+

Methods from Deref<Target = Vec<QualityItem<Preference<Encoding>>>>§

1.0.0 · source

pub fn capacity(&self) -> usize

Returns the total number of elements the vector can hold without +reallocating.

+
§Examples
+
let mut vec: Vec<i32> = Vec::with_capacity(10);
+vec.push(42);
+assert!(vec.capacity() >= 10);
+
1.0.0 · source

pub fn reserve(&mut self, additional: usize)

Available on non-no_global_oom_handling only.

Reserves capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to +speculatively avoid frequent reallocations. After calling reserve, +capacity will be greater than or equal to self.len() + additional. +Does nothing if capacity is already sufficient.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1];
+vec.reserve(10);
+assert!(vec.capacity() >= 11);
+
1.0.0 · source

pub fn reserve_exact(&mut self, additional: usize)

Available on non-no_global_oom_handling only.

Reserves the minimum capacity for at least additional more elements to +be inserted in the given Vec<T>. Unlike reserve, this will not +deliberately over-allocate to speculatively avoid frequent allocations. +After calling reserve_exact, capacity will be greater than or equal to +self.len() + additional. Does nothing if the capacity is already +sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer reserve if future insertions are expected.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1];
+vec.reserve_exact(10);
+assert!(vec.capacity() >= 11);
+
1.57.0 · source

pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>

Tries to reserve capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to speculatively avoid +frequent reallocations. After calling try_reserve, capacity will be +greater than or equal to self.len() + additional if it returns +Ok(()). Does nothing if capacity is already sufficient. This method +preserves the contents even if an error occurs.

+
§Errors
+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+
§Examples
+
use std::collections::TryReserveError;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+
1.57.0 · source

pub fn try_reserve_exact( + &mut self, + additional: usize +) -> Result<(), TryReserveError>

Tries to reserve the minimum capacity for at least additional +elements to be inserted in the given Vec<T>. Unlike try_reserve, +this will not deliberately over-allocate to speculatively avoid frequent +allocations. After calling try_reserve_exact, capacity will be greater +than or equal to self.len() + additional if it returns Ok(()). +Does nothing if the capacity is already sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer try_reserve if future insertions are expected.

+
§Errors
+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+
§Examples
+
use std::collections::TryReserveError;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve_exact(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+
1.0.0 · source

pub fn shrink_to_fit(&mut self)

Available on non-no_global_oom_handling only.

Shrinks the capacity of the vector as much as possible.

+

The behavior of this method depends on the allocator, which may either shrink the vector +in-place or reallocate. The resulting vector might still have some excess capacity, just as +is the case for with_capacity. See Allocator::shrink for more details.

+
§Examples
+
let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3]);
+assert!(vec.capacity() >= 10);
+vec.shrink_to_fit();
+assert!(vec.capacity() >= 3);
+
1.56.0 · source

pub fn shrink_to(&mut self, min_capacity: usize)

Available on non-no_global_oom_handling only.

Shrinks the capacity of the vector with a lower bound.

+

The capacity will remain at least as large as both the length +and the supplied value.

+

If the current capacity is less than the lower limit, this is a no-op.

+
§Examples
+
let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3]);
+assert!(vec.capacity() >= 10);
+vec.shrink_to(4);
+assert!(vec.capacity() >= 4);
+vec.shrink_to(0);
+assert!(vec.capacity() >= 3);
+
1.0.0 · source

pub fn truncate(&mut self, len: usize)

Shortens the vector, keeping the first len elements and dropping +the rest.

+

If len is greater or equal to the vector’s current length, this has +no effect.

+

The drain method can emulate truncate, but causes the excess +elements to be returned instead of dropped.

+

Note that this method has no effect on the allocated capacity +of the vector.

+
§Examples
+

Truncating a five element vector to two elements:

+ +
let mut vec = vec![1, 2, 3, 4, 5];
+vec.truncate(2);
+assert_eq!(vec, [1, 2]);
+

No truncation occurs when len is greater than the vector’s current +length:

+ +
let mut vec = vec![1, 2, 3];
+vec.truncate(8);
+assert_eq!(vec, [1, 2, 3]);
+

Truncating when len == 0 is equivalent to calling the clear +method.

+ +
let mut vec = vec![1, 2, 3];
+vec.truncate(0);
+assert_eq!(vec, []);
+
1.7.0 · source

pub fn as_slice(&self) -> &[T]

Extracts a slice containing the entire vector.

+

Equivalent to &s[..].

+
§Examples
+
use std::io::{self, Write};
+let buffer = vec![1, 2, 3, 5, 8];
+io::sink().write(buffer.as_slice()).unwrap();
+
1.7.0 · source

pub fn as_mut_slice(&mut self) -> &mut [T]

Extracts a mutable slice of the entire vector.

+

Equivalent to &mut s[..].

+
§Examples
+
use std::io::{self, Read};
+let mut buffer = vec![0; 3];
+io::repeat(0b101).read_exact(buffer.as_mut_slice()).unwrap();
+
1.37.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the vector’s buffer, or a dangling raw pointer +valid for zero sized reads if the vector didn’t allocate.

+

The caller must ensure that the vector outlives the pointer this +function returns, or else it will end up pointing to garbage. +Modifying the vector may cause its buffer to be reallocated, +which would also make any pointers to it invalid.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

This method guarantees that for the purpose of the aliasing model, this method +does not materialize a reference to the underlying slice, and thus the returned pointer +will remain valid when mixed with other calls to as_ptr and as_mut_ptr. +Note that calling other methods that materialize mutable references to the slice, +or mutable references to specific elements you are planning on accessing through this pointer, +as well as writing to those elements, may still invalidate this pointer. +See the second example below for how this guarantee can be used.

+
§Examples
+
let x = vec![1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(*x_ptr.add(i), 1 << i);
+    }
+}
+

Due to the aliasing guarantee, the following code is legal:

+ +
unsafe {
+    let mut v = vec![0, 1, 2];
+    let ptr1 = v.as_ptr();
+    let _ = ptr1.read();
+    let ptr2 = v.as_mut_ptr().offset(2);
+    ptr2.write(2);
+    // Notably, the write to `ptr2` did *not* invalidate `ptr1`
+    // because it mutated a different element:
+    let _ = ptr1.read();
+}
+
1.37.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the vector’s buffer, or a dangling +raw pointer valid for zero sized reads if the vector didn’t allocate.

+

The caller must ensure that the vector outlives the pointer this +function returns, or else it will end up pointing to garbage. +Modifying the vector may cause its buffer to be reallocated, +which would also make any pointers to it invalid.

+

This method guarantees that for the purpose of the aliasing model, this method +does not materialize a reference to the underlying slice, and thus the returned pointer +will remain valid when mixed with other calls to as_ptr and as_mut_ptr. +Note that calling other methods that materialize references to the slice, +or references to specific elements you are planning on accessing through this pointer, +may still invalidate this pointer. +See the second example below for how this guarantee can be used.

+
§Examples
+
// Allocate vector big enough for 4 elements.
+let size = 4;
+let mut x: Vec<i32> = Vec::with_capacity(size);
+let x_ptr = x.as_mut_ptr();
+
+// Initialize elements via raw pointer writes, then set length.
+unsafe {
+    for i in 0..size {
+        *x_ptr.add(i) = i as i32;
+    }
+    x.set_len(size);
+}
+assert_eq!(&*x, &[0, 1, 2, 3]);
+

Due to the aliasing guarantee, the following code is legal:

+ +
unsafe {
+    let mut v = vec![0];
+    let ptr1 = v.as_mut_ptr();
+    ptr1.write(1);
+    let ptr2 = v.as_mut_ptr();
+    ptr2.write(2);
+    // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
+    ptr1.write(3);
+}
+
source

pub fn allocator(&self) -> &A

🔬This is a nightly-only experimental API. (allocator_api)

Returns a reference to the underlying allocator.

+
1.0.0 · source

pub unsafe fn set_len(&mut self, new_len: usize)

Forces the length of the vector to new_len.

+

This is a low-level operation that maintains none of the normal +invariants of the type. Normally changing the length of a vector +is done using one of the safe operations instead, such as +truncate, resize, extend, or clear.

+
§Safety
+
    +
  • new_len must be less than or equal to capacity().
  • +
  • The elements at old_len..new_len must be initialized.
  • +
+
§Examples
+

This method can be useful for situations in which the vector +is serving as a buffer for other code, particularly over FFI:

+ +
pub fn get_dictionary(&self) -> Option<Vec<u8>> {
+    // Per the FFI method's docs, "32768 bytes is always enough".
+    let mut dict = Vec::with_capacity(32_768);
+    let mut dict_length = 0;
+    // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
+    // 1. `dict_length` elements were initialized.
+    // 2. `dict_length` <= the capacity (32_768)
+    // which makes `set_len` safe to call.
+    unsafe {
+        // Make the FFI call...
+        let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
+        if r == Z_OK {
+            // ...and update the length to what was initialized.
+            dict.set_len(dict_length);
+            Some(dict)
+        } else {
+            None
+        }
+    }
+}
+

While the following example is sound, there is a memory leak since +the inner vectors were not freed prior to the set_len call:

+ +
let mut vec = vec![vec![1, 0, 0],
+                   vec![0, 1, 0],
+                   vec![0, 0, 1]];
+// SAFETY:
+// 1. `old_len..0` is empty so no elements need to be initialized.
+// 2. `0 <= capacity` always holds whatever `capacity` is.
+unsafe {
+    vec.set_len(0);
+}
+

Normally, here, one would use clear instead to correctly drop +the contents and thus not leak memory.

+
1.0.0 · source

pub fn swap_remove(&mut self, index: usize) -> T

Removes an element from the vector and returns it.

+

The removed element is replaced by the last element of the vector.

+

This does not preserve ordering of the remaining elements, but is O(1). +If you need to preserve the element order, use remove instead.

+
§Panics
+

Panics if index is out of bounds.

+
§Examples
+
let mut v = vec!["foo", "bar", "baz", "qux"];
+
+assert_eq!(v.swap_remove(1), "bar");
+assert_eq!(v, ["foo", "qux", "baz"]);
+
+assert_eq!(v.swap_remove(0), "foo");
+assert_eq!(v, ["baz", "qux"]);
+
1.0.0 · source

pub fn insert(&mut self, index: usize, element: T)

Available on non-no_global_oom_handling only.

Inserts an element at position index within the vector, shifting all +elements after it to the right.

+
§Panics
+

Panics if index > len.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+vec.insert(1, 4);
+assert_eq!(vec, [1, 4, 2, 3]);
+vec.insert(4, 5);
+assert_eq!(vec, [1, 4, 2, 3, 5]);
+
§Time complexity
+

Takes O(Vec::len) time. All items after the insertion index must be +shifted to the right. In the worst case, all elements are shifted when +the insertion index is 0.

+
1.0.0 · source

pub fn remove(&mut self, index: usize) -> T

Removes and returns the element at position index within the vector, +shifting all elements after it to the left.

+

Note: Because this shifts over the remaining elements, it has a +worst-case performance of O(n). If you don’t need the order of elements +to be preserved, use swap_remove instead. If you’d like to remove +elements from the beginning of the Vec, consider using +VecDeque::pop_front instead.

+
§Panics
+

Panics if index is out of bounds.

+
§Examples
+
let mut v = vec![1, 2, 3];
+assert_eq!(v.remove(1), 2);
+assert_eq!(v, [1, 3]);
+
1.0.0 · source

pub fn retain<F>(&mut self, f: F)
where + F: FnMut(&T) -> bool,

Retains only the elements specified by the predicate.

+

In other words, remove all elements e for which f(&e) returns false. +This method operates in place, visiting each element exactly once in the +original order, and preserves the order of the retained elements.

+
§Examples
+
let mut vec = vec![1, 2, 3, 4];
+vec.retain(|&x| x % 2 == 0);
+assert_eq!(vec, [2, 4]);
+

Because the elements are visited exactly once in the original order, +external state may be used to decide which elements to keep.

+ +
let mut vec = vec![1, 2, 3, 4, 5];
+let keep = [false, true, true, false, true];
+let mut iter = keep.iter();
+vec.retain(|_| *iter.next().unwrap());
+assert_eq!(vec, [2, 3, 5]);
+
1.61.0 · source

pub fn retain_mut<F>(&mut self, f: F)
where + F: FnMut(&mut T) -> bool,

Retains only the elements specified by the predicate, passing a mutable reference to it.

+

In other words, remove all elements e such that f(&mut e) returns false. +This method operates in place, visiting each element exactly once in the +original order, and preserves the order of the retained elements.

+
§Examples
+
let mut vec = vec![1, 2, 3, 4];
+vec.retain_mut(|x| if *x <= 3 {
+    *x += 1;
+    true
+} else {
+    false
+});
+assert_eq!(vec, [2, 3, 4]);
+
1.16.0 · source

pub fn dedup_by_key<F, K>(&mut self, key: F)
where + F: FnMut(&mut T) -> K, + K: PartialEq,

Removes all but the first of consecutive elements in the vector that resolve to the same +key.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec![10, 20, 21, 30, 20];
+
+vec.dedup_by_key(|i| *i / 10);
+
+assert_eq!(vec, [10, 20, 30, 20]);
+
1.16.0 · source

pub fn dedup_by<F>(&mut self, same_bucket: F)
where + F: FnMut(&mut T, &mut T) -> bool,

Removes all but the first of consecutive elements in the vector satisfying a given equality +relation.

+

The same_bucket function is passed references to two elements from the vector and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is removed.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
+
+vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
+
1.0.0 · source

pub fn push(&mut self, value: T)

Available on non-no_global_oom_handling only.

Appends an element to the back of a collection.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1, 2];
+vec.push(3);
+assert_eq!(vec, [1, 2, 3]);
+
§Time complexity
+

Takes amortized O(1) time. If the vector’s length would exceed its +capacity after the push, O(capacity) time is taken to copy the +vector’s elements to a larger allocation. This expensive operation is +offset by the capacity O(1) insertions it allows.

+
source

pub fn push_within_capacity(&mut self, value: T) -> Result<(), T>

🔬This is a nightly-only experimental API. (vec_push_within_capacity)

Appends an element if there is sufficient spare capacity, otherwise an error is returned +with the element.

+

Unlike push this method will not reallocate when there’s insufficient capacity. +The caller should use reserve or try_reserve to ensure that there is enough capacity.

+
§Examples
+

A manual, panic-free alternative to FromIterator:

+ +
#![feature(vec_push_within_capacity)]
+
+use std::collections::TryReserveError;
+fn from_iter_fallible<T>(iter: impl Iterator<Item=T>) -> Result<Vec<T>, TryReserveError> {
+    let mut vec = Vec::new();
+    for value in iter {
+        if let Err(value) = vec.push_within_capacity(value) {
+            vec.try_reserve(1)?;
+            // this cannot fail, the previous line either returned or added at least 1 free slot
+            let _ = vec.push_within_capacity(value);
+        }
+    }
+    Ok(vec)
+}
+assert_eq!(from_iter_fallible(0..100), Ok(Vec::from_iter(0..100)));
+
§Time complexity
+

Takes O(1) time.

+
1.0.0 · source

pub fn pop(&mut self) -> Option<T>

Removes the last element from a vector and returns it, or None if it +is empty.

+

If you’d like to pop the first element, consider using +VecDeque::pop_front instead.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+assert_eq!(vec.pop(), Some(3));
+assert_eq!(vec, [1, 2]);
+
§Time complexity
+

Takes O(1) time.

+
source

pub fn pop_if<F>(&mut self, f: F) -> Option<T>
where + F: FnOnce(&mut T) -> bool,

🔬This is a nightly-only experimental API. (vec_pop_if)

Removes and returns the last element in a vector if the predicate +returns true, or None if the predicate returns false or the vector +is empty.

+
§Examples
+
#![feature(vec_pop_if)]
+
+let mut vec = vec![1, 2, 3, 4];
+let pred = |x: &mut i32| *x % 2 == 0;
+
+assert_eq!(vec.pop_if(pred), Some(4));
+assert_eq!(vec, [1, 2, 3]);
+assert_eq!(vec.pop_if(pred), None);
+
1.4.0 · source

pub fn append(&mut self, other: &mut Vec<T, A>)

Available on non-no_global_oom_handling only.

Moves all the elements of other into self, leaving other empty.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+let mut vec2 = vec![4, 5, 6];
+vec.append(&mut vec2);
+assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
+assert_eq!(vec2, []);
+
1.6.0 · source

pub fn drain<R>(&mut self, range: R) -> Drain<'_, T, A>
where + R: RangeBounds<usize>,

Removes the specified range from the vector in bulk, returning all +removed elements as an iterator. If the iterator is dropped before +being fully consumed, it drops the remaining removed elements.

+

The returned iterator keeps a mutable borrow on the vector to optimize +its implementation.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Leaking
+

If the returned iterator goes out of scope without being dropped (due to +mem::forget, for example), the vector may have lost and leaked +elements arbitrarily, including elements outside the range.

+
§Examples
+
let mut v = vec![1, 2, 3];
+let u: Vec<_> = v.drain(1..).collect();
+assert_eq!(v, &[1]);
+assert_eq!(u, &[2, 3]);
+
+// A full range clears the vector, like `clear()` does
+v.drain(..);
+assert_eq!(v, &[]);
+
1.0.0 · source

pub fn clear(&mut self)

Clears the vector, removing all values.

+

Note that this method has no effect on the allocated capacity +of the vector.

+
§Examples
+
let mut v = vec![1, 2, 3];
+
+v.clear();
+
+assert!(v.is_empty());
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the vector, also referred to +as its ‘length’.

+
§Examples
+
let a = vec![1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the vector contains no elements.

+
§Examples
+
let mut v = Vec::new();
+assert!(v.is_empty());
+
+v.push(1);
+assert!(!v.is_empty());
+
1.4.0 · source

pub fn split_off(&mut self, at: usize) -> Vec<T, A>
where + A: Clone,

Available on non-no_global_oom_handling only.

Splits the collection into two at the given index.

+

Returns a newly allocated vector containing the elements in the range +[at, len). After the call, the original vector will be left containing +the elements [0, at) with its previous capacity unchanged.

+
    +
  • If you want to take ownership of the entire contents and capacity of +the vector, see mem::take or mem::replace.
  • +
  • If you don’t need the returned vector at all, see Vec::truncate.
  • +
  • If you want to take ownership of an arbitrary subslice, or you don’t +necessarily want to store the removed items in a vector, see Vec::drain.
  • +
+
§Panics
+

Panics if at > len.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+let vec2 = vec.split_off(1);
+assert_eq!(vec, [1]);
+assert_eq!(vec2, [2, 3]);
+
1.33.0 · source

pub fn resize_with<F>(&mut self, new_len: usize, f: F)
where + F: FnMut() -> T,

Available on non-no_global_oom_handling only.

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with the result of +calling the closure f. The return values from f will end up +in the Vec in the order they have been generated.

+

If new_len is less than len, the Vec is simply truncated.

+

This method uses a closure to create new values on every push. If +you’d rather Clone a given value, use Vec::resize. If you +want to use the Default trait to generate values, you can +pass Default::default as the second argument.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+vec.resize_with(5, Default::default);
+assert_eq!(vec, [1, 2, 3, 0, 0]);
+
+let mut vec = vec![];
+let mut p = 1;
+vec.resize_with(4, || { p *= 2; p });
+assert_eq!(vec, [2, 4, 8, 16]);
+
1.60.0 · source

pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>]

Returns the remaining spare capacity of the vector as a slice of +MaybeUninit<T>.

+

The returned slice can be used to fill the vector with data (e.g. by +reading from a file) before marking the data as initialized using the +set_len method.

+
§Examples
+
// Allocate vector big enough for 10 elements.
+let mut v = Vec::with_capacity(10);
+
+// Fill in the first 3 elements.
+let uninit = v.spare_capacity_mut();
+uninit[0].write(0);
+uninit[1].write(1);
+uninit[2].write(2);
+
+// Mark the first 3 elements of the vector as being initialized.
+unsafe {
+    v.set_len(3);
+}
+
+assert_eq!(&v, &[0, 1, 2]);
+
source

pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>])

🔬This is a nightly-only experimental API. (vec_split_at_spare)

Returns vector content as a slice of T, along with the remaining spare +capacity of the vector as a slice of MaybeUninit<T>.

+

The returned spare capacity slice can be used to fill the vector with data +(e.g. by reading from a file) before marking the data as initialized using +the set_len method.

+

Note that this is a low-level API, which should be used with care for +optimization purposes. If you need to append data to a Vec +you can use push, extend, extend_from_slice, +extend_from_within, insert, append, resize or +resize_with, depending on your exact needs.

+
§Examples
+
#![feature(vec_split_at_spare)]
+
+let mut v = vec![1, 1, 2];
+
+// Reserve additional space big enough for 10 elements.
+v.reserve(10);
+
+let (init, uninit) = v.split_at_spare_mut();
+let sum = init.iter().copied().sum::<u32>();
+
+// Fill in the next 4 elements.
+uninit[0].write(sum);
+uninit[1].write(sum * 2);
+uninit[2].write(sum * 3);
+uninit[3].write(sum * 4);
+
+// Mark the 4 elements of the vector as being initialized.
+unsafe {
+    let len = v.len();
+    v.set_len(len + 4);
+}
+
+assert_eq!(&v, &[1, 1, 2, 4, 8, 12, 16]);
+
1.5.0 · source

pub fn resize(&mut self, new_len: usize, value: T)

Available on non-no_global_oom_handling only.

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with value. +If new_len is less than len, the Vec is simply truncated.

+

This method requires T to implement Clone, +in order to be able to clone the passed value. +If you need more flexibility (or want to rely on Default instead of +Clone), use Vec::resize_with. +If you only need to resize to a smaller size, use Vec::truncate.

+
§Examples
+
let mut vec = vec!["hello"];
+vec.resize(3, "world");
+assert_eq!(vec, ["hello", "world", "world"]);
+
+let mut vec = vec![1, 2, 3, 4];
+vec.resize(2, 0);
+assert_eq!(vec, [1, 2]);
+
1.6.0 · source

pub fn extend_from_slice(&mut self, other: &[T])

Available on non-no_global_oom_handling only.

Clones and appends all elements in a slice to the Vec.

+

Iterates over the slice other, clones each element, and then appends +it to this Vec. The other slice is traversed in-order.

+

Note that this function is same as extend except that it is +specialized to work with slices instead. If and when Rust gets +specialization this function will likely be deprecated (but still +available).

+
§Examples
+
let mut vec = vec![1];
+vec.extend_from_slice(&[2, 3, 4]);
+assert_eq!(vec, [1, 2, 3, 4]);
+
1.53.0 · source

pub fn extend_from_within<R>(&mut self, src: R)
where + R: RangeBounds<usize>,

Available on non-no_global_oom_handling only.

Copies elements from src range to the end of the vector.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Examples
+
let mut vec = vec![0, 1, 2, 3, 4];
+
+vec.extend_from_within(2..);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
+
+vec.extend_from_within(..2);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
+
+vec.extend_from_within(4..8);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
+
1.0.0 · source

pub fn dedup(&mut self)

Removes consecutive repeated elements in the vector according to the +PartialEq trait implementation.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec![1, 2, 2, 3, 2];
+
+vec.dedup();
+
+assert_eq!(vec, [1, 2, 3, 2]);
+
1.21.0 · source

pub fn splice<R, I>( + &mut self, + range: R, + replace_with: I +) -> Splice<'_, <I as IntoIterator>::IntoIter, A>
where + R: RangeBounds<usize>, + I: IntoIterator<Item = T>,

Available on non-no_global_oom_handling only.

Creates a splicing iterator that replaces the specified range in the vector +with the given replace_with iterator and yields the removed items. +replace_with does not need to be the same length as range.

+

range is removed even if the iterator is not consumed until the end.

+

It is unspecified how many elements are removed from the vector +if the Splice value is leaked.

+

The input iterator replace_with is only consumed when the Splice value is dropped.

+

This is optimal if:

+
    +
  • The tail (elements in the vector after range) is empty,
  • +
  • or replace_with yields fewer or equal elements than range’s length
  • +
  • or the lower bound of its size_hint() is exact.
  • +
+

Otherwise, a temporary vector is allocated and the tail is moved twice.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Examples
+
let mut v = vec![1, 2, 3, 4];
+let new = [7, 8, 9];
+let u: Vec<_> = v.splice(1..3, new).collect();
+assert_eq!(v, &[1, 7, 8, 9, 4]);
+assert_eq!(u, &[2, 3]);
+
source

pub fn extract_if<F>(&mut self, filter: F) -> ExtractIf<'_, T, F, A>
where + F: FnMut(&mut T) -> bool,

🔬This is a nightly-only experimental API. (extract_if)

Creates an iterator which uses a closure to determine if an element should be removed.

+

If the closure returns true, then the element is removed and yielded. +If the closure returns false, the element will remain in the vector and will not be yielded +by the iterator.

+

If the returned ExtractIf is not exhausted, e.g. because it is dropped without iterating +or the iteration short-circuits, then the remaining elements will be retained. +Use retain with a negated predicate if you do not need the returned iterator.

+

Using this method is equivalent to the following code:

+ +
let mut i = 0;
+while i < vec.len() {
+    if some_predicate(&mut vec[i]) {
+        let val = vec.remove(i);
+        // your code here
+    } else {
+        i += 1;
+    }
+}
+
+

But extract_if is easier to use. extract_if is also more efficient, +because it can backshift the elements of the array in bulk.

+

Note that extract_if also lets you mutate every element in the filter closure, +regardless of whether you choose to keep or remove it.

+
§Examples
+

Splitting an array into evens and odds, reusing the original allocation:

+ +
#![feature(extract_if)]
+let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];
+
+let evens = numbers.extract_if(|x| *x % 2 == 0).collect::<Vec<_>>();
+let odds = numbers;
+
+assert_eq!(evens, vec![2, 4, 6, 8, 14]);
+assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]);
+

Methods from Deref<Target = [T]>§

1.80.0 · source

pub fn as_flattened(&self) -> &[T]

Takes a &[[T; N]], and flattens it to a &[T].

+
§Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
§Examples
+
assert_eq!([[1, 2, 3], [4, 5, 6]].as_flattened(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+    [[1, 2, 3], [4, 5, 6]].as_flattened(),
+    [[1, 2], [3, 4], [5, 6]].as_flattened(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.as_flattened().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.as_flattened().is_empty());
+
1.80.0 · source

pub fn as_flattened_mut(&mut self) -> &mut [T]

Takes a &mut [[T; N]], and flattens it to a &mut [T].

+
§Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
§Examples
+
fn add_5_to_all(slice: &mut [i32]) {
+    for i in slice {
+        *i += 5;
+    }
+}
+
+let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
+add_5_to_all(array.as_flattened_mut());
+assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f32::total_cmp.

+
§Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
§Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the slice.

+
§Examples
+
let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the slice has a length of 0.

+
§Examples
+
let a = [1, 2, 3];
+assert!(!a.is_empty());
+
+let b: &[i32] = &[];
+assert!(b.is_empty());
+
1.0.0 · source

pub fn first(&self) -> Option<&T>

Returns the first element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
+
1.0.0 · source

pub fn first_mut(&mut self) -> Option<&mut T>

Returns a mutable pointer to the first element of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_mut() {
+    *first = 5;
+}
+assert_eq!(x, &[5, 1, 2]);
+
+let y: &mut [i32] = &mut [];
+assert_eq!(None, y.first_mut());
+
1.5.0 · source

pub fn split_first(&self) -> Option<(&T, &[T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first() {
+    assert_eq!(first, &0);
+    assert_eq!(elements, &[1, 2]);
+}
+
1.5.0 · source

pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_mut() {
+    *first = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
1.5.0 · source

pub fn split_last(&self) -> Option<(&T, &[T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+    assert_eq!(last, &2);
+    assert_eq!(elements, &[0, 1]);
+}
+
1.5.0 · source

pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_mut() {
+    *last = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[4, 5, 3]);
+
1.0.0 · source

pub fn last(&self) -> Option<&T>

Returns the last element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
+
1.0.0 · source

pub fn last_mut(&mut self) -> Option<&mut T>

Returns a mutable reference to the last item in the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_mut() {
+    *last = 10;
+}
+assert_eq!(x, &[0, 1, 10]);
+
+let y: &mut [i32] = &mut [];
+assert_eq!(None, y.last_mut());
+
1.77.0 · source

pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the first N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.first_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.first_chunk::<0>());
+
1.77.0 · source

pub fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

Return a mutable array reference to the first N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_chunk_mut::<2>() {
+    first[0] = 5;
+    first[1] = 4;
+}
+assert_eq!(x, &[5, 4, 2]);
+
+assert_eq!(None, x.first_chunk_mut::<4>());
+
1.77.0 · source

pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

Return an array reference to the first N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk::<2>() {
+    assert_eq!(first, &[0, 1]);
+    assert_eq!(elements, &[2]);
+}
+
+assert_eq!(None, x.split_first_chunk::<4>());
+
1.77.0 · source

pub fn split_first_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T; N], &mut [T])>

Return a mutable array reference to the first N items in the slice and the remaining +slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk_mut::<2>() {
+    first[0] = 3;
+    first[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
+assert_eq!(None, x.split_first_chunk_mut::<4>());
+
1.77.0 · source

pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>

Return an array reference to the last N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((elements, last)) = x.split_last_chunk::<2>() {
+    assert_eq!(elements, &[0]);
+    assert_eq!(last, &[1, 2]);
+}
+
+assert_eq!(None, x.split_last_chunk::<4>());
+
1.77.0 · source

pub fn split_last_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T], &mut [T; N])>

Return a mutable array reference to the last N items in the slice and the remaining +slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((elements, last)) = x.split_last_chunk_mut::<2>() {
+    last[0] = 3;
+    last[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[5, 3, 4]);
+
+assert_eq!(None, x.split_last_chunk_mut::<4>());
+
1.77.0 · source

pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the last N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.last_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.last_chunk::<0>());
+
1.77.0 · source

pub fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

Return a mutable array reference to the last N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_chunk_mut::<2>() {
+    last[0] = 10;
+    last[1] = 20;
+}
+assert_eq!(x, &[0, 10, 20]);
+
+assert_eq!(None, x.last_chunk_mut::<4>());
+
1.0.0 · source

pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice depending on the type of +index.

+
    +
  • If given a position, returns a reference to the element at that +position or None if out of bounds.
  • +
  • If given a range, returns the subslice corresponding to that range, +or None if out of bounds.
  • +
+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
+
1.0.0 · source

pub fn get_mut<I>( + &mut self, + index: I +) -> Option<&mut <I as SliceIndex<[T]>>::Output>
where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice depending on the +type of index (see get) or None if the index is out of bounds.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(elem) = x.get_mut(1) {
+    *elem = 42;
+}
+assert_eq!(x, &[0, 42, 2]);
+
1.0.0 · source

pub unsafe fn get_unchecked<I>( + &self, + index: I +) -> &<I as SliceIndex<[T]>>::Output
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice, without doing bounds +checking.

+

For a safe alternative see get.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get(index).unwrap_unchecked(). It’s UB +to call .get_unchecked(len), even if you immediately convert to a +pointer. And it’s UB to call .get_unchecked(..len + 1), +.get_unchecked(..=len), or similar.

+
§Examples
+
let x = &[1, 2, 4];
+
+unsafe {
+    assert_eq!(x.get_unchecked(1), &2);
+}
+
1.0.0 · source

pub unsafe fn get_unchecked_mut<I>( + &mut self, + index: I +) -> &mut <I as SliceIndex<[T]>>::Output
where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice, without doing +bounds checking.

+

For a safe alternative see get_mut.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get_mut(index).unwrap_unchecked(). It’s +UB to call .get_unchecked_mut(len), even if you immediately convert +to a pointer. And it’s UB to call .get_unchecked_mut(..len + 1), +.get_unchecked_mut(..=len), or similar.

+
§Examples
+
let x = &mut [1, 2, 4];
+
+unsafe {
+    let elem = x.get_unchecked_mut(1);
+    *elem = 13;
+}
+assert_eq!(x, &[1, 13, 4]);
+
1.0.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
§Examples
+
let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+    }
+}
+
1.0.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
§Examples
+
let x = &mut [1, 2, 4];
+let x_ptr = x.as_mut_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        *x_ptr.add(i) += 2;
+    }
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.48.0 · source

pub fn as_ptr_range(&self) -> Range<*const T>

Returns the two raw pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_ptr for warnings on using these pointers. The end pointer +requires extra caution, as it does not point to a valid element in the +slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+

It can also be useful to check if a pointer to an element refers to an +element of this slice:

+ +
let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
+
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
+
1.48.0 · source

pub fn as_mut_ptr_range(&mut self) -> Range<*mut T>

Returns the two unsafe mutable pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_mut_ptr for warnings on using these pointers. The end +pointer requires extra caution, as it does not point to a valid element +in the slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+
1.0.0 · source

pub fn swap(&mut self, a: usize, b: usize)

Swaps two elements in the slice.

+

If a equals to b, it’s guaranteed that elements won’t change value.

+
§Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
§Panics
+

Panics if a or b are out of bounds.

+
§Examples
+
let mut v = ["a", "b", "c", "d", "e"];
+v.swap(2, 4);
+assert!(v == ["a", "b", "e", "d", "c"]);
+
source

pub unsafe fn swap_unchecked(&mut self, a: usize, b: usize)

🔬This is a nightly-only experimental API. (slice_swap_unchecked)

Swaps two elements in the slice, without doing bounds checking.

+

For a safe alternative see swap.

+
§Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior. +The caller has to ensure that a < self.len() and b < self.len().

+
§Examples
+
#![feature(slice_swap_unchecked)]
+
+let mut v = ["a", "b", "c", "d"];
+// SAFETY: we know that 1 and 3 are both indices of the slice
+unsafe { v.swap_unchecked(1, 3) };
+assert!(v == ["a", "d", "c", "b"]);
+
1.0.0 · source

pub fn reverse(&mut self)

Reverses the order of elements in the slice, in place.

+
§Examples
+
let mut v = [1, 2, 3];
+v.reverse();
+assert!(v == [3, 2, 1]);
+
1.0.0 · source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the slice.

+

The iterator yields all items from start to end.

+
§Examples
+
let x = &[1, 2, 4];
+let mut iterator = x.iter();
+
+assert_eq!(iterator.next(), Some(&1));
+assert_eq!(iterator.next(), Some(&2));
+assert_eq!(iterator.next(), Some(&4));
+assert_eq!(iterator.next(), None);
+
1.0.0 · source

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Returns an iterator that allows modifying each value.

+

The iterator yields all items from start to end.

+
§Examples
+
let x = &mut [1, 2, 4];
+for elem in x.iter_mut() {
+    *elem += 2;
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.0.0 · source

pub fn windows(&self, size: usize) -> Windows<'_, T>

Returns an iterator over all contiguous windows of length +size. The windows overlap. If the slice is shorter than +size, the iterator returns no values.

+
§Panics
+

Panics if size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.windows(3);
+assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']);
+assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']);
+assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']);
+assert!(iter.next().is_none());
+

If the slice is shorter than size:

+ +
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
+

There’s no windows_mut, as that existing would let safe code violate the +“only one &mut at a time to the same thing” rule. However, you can sometimes +use Cell::as_slice_of_cells in +conjunction with windows to accomplish something similar:

+ +
use std::cell::Cell;
+
+let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
+let slice = &mut array[..];
+let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
+for w in slice_of_cells.windows(3) {
+    Cell::swap(&w[0], &w[2]);
+}
+assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
+
1.0.0 · source

pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See chunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and rchunks for the same iterator but starting at the end of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See chunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and rchunks_mut for the same iterator but starting at +the end of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 3]);
+
1.31.0 · source

pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks.

+

See chunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
1.31.0 · source

pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See chunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and rchunks_exact_mut for the same iterator but starting at the end of +the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
§Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
§Examples
+
#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+
source

pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
+

If you expect the slice to be an exact multiple, you can combine +let-else with an empty slice pattern:

+ +
#![feature(slice_as_chunks)]
+let slice = ['R', 'u', 's', 't'];
+let (chunks, []) = slice.as_chunks::<2>() else {
+    panic!("slice didn't have even length")
+};
+assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
+
source

pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+
source

pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are array references and do not overlap. If N does not divide the +length of the slice, then the last up to N-1 elements will be omitted and can be +retrieved from the remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
source

pub unsafe fn as_chunks_unchecked_mut<const N: usize>( + &mut self +) -> &mut [[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
§Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
§Examples
+
#![feature(slice_as_chunks)]
+let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &mut [[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[0] = ['L'];
+assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &mut [[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[1] = ['a', 'x', '?'];
+assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
+
source

pub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (chunks, remainder) = v.as_chunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 9]);
+
source

pub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (remainder, chunks) = v.as_rchunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[9, 1, 1, 2, 2]);
+
source

pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable array references and do not overlap. If N does not divide +the length of the slice, then the last up to N-1 elements will be omitted and +can be retrieved from the into_remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact_mut.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.array_chunks_mut() {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>

🔬This is a nightly-only experimental API. (array_windows)

Returns an iterator over overlapping windows of N elements of a slice, +starting at the beginning of the slice.

+

This is the const generic equivalent of windows.

+

If N is greater than the size of the slice, it will return no windows.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and chunks for the same iterator but starting at the beginning +of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and chunks_mut for the same iterator but starting at the +beginning of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[3, 2, 2, 1, 1]);
+
1.31.0 · source

pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +end of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of rchunks.

+

See rchunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and chunks_exact for the same iterator but starting at the beginning of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
+
1.31.0 · source

pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See rchunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and chunks_exact_mut for the same iterator but starting at the beginning +of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[0, 2, 2, 1, 1]);
+
1.77.0 · source

pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
where + F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping runs +of elements using the predicate to separate them.

+

The predicate is called for every pair of consecutive elements, +meaning that it is called on slice[0] and slice[1], +followed by slice[1] and slice[2], and so on.

+
§Examples
+
let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.chunk_by(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.chunk_by(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.77.0 · source

pub fn chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F>
where + F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping mutable +runs of elements using the predicate to separate them.

+

The predicate is called for every pair of consecutive elements, +meaning that it is called on slice[0] and slice[1], +followed by slice[1] and slice[2], and so on.

+
§Examples
+
let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.chunk_by_mut(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&mut [3, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.chunk_by_mut(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.0.0 · source

pub fn split_at(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
§Panics
+

Panics if mid > len. For a non-panicking alternative see +split_at_checked.

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+{
+   let (left, right) = v.split_at(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.0.0 · source

pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
§Panics
+

Panics if mid > len. For a non-panicking alternative see +split_at_mut_checked.

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+let (left, right) = v.split_at_mut(2);
+assert_eq!(left, [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.79.0 · source

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+unsafe {
+   let (left, right) = v.split_at_unchecked(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.79.0 · source

pub unsafe fn split_at_mut_unchecked( + &mut self, + mid: usize +) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at_mut.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+// scoped to restrict the lifetime of the borrows
+unsafe {
+    let (left, right) = v.split_at_mut_unchecked(2);
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.80.0 · source

pub fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])>

Divides one slice into two at an index, returning None if the slice is +too short.

+

If mid ≤ len returns a pair of slices where the first will contain all +indices from [0, mid) (excluding the index mid itself) and the +second will contain all indices from [mid, len) (excluding the index +len itself).

+

Otherwise, if mid > len, returns None.

+
§Examples
+
let v = [1, -2, 3, -4, 5, -6];
+
+{
+   let (left, right) = v.split_at_checked(0).unwrap();
+   assert_eq!(left, []);
+   assert_eq!(right, [1, -2, 3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(2).unwrap();
+    assert_eq!(left, [1, -2]);
+    assert_eq!(right, [3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(6).unwrap();
+    assert_eq!(left, [1, -2, 3, -4, 5, -6]);
+    assert_eq!(right, []);
+}
+
+assert_eq!(None, v.split_at_checked(7));
+
1.80.0 · source

pub fn split_at_mut_checked( + &mut self, + mid: usize +) -> Option<(&mut [T], &mut [T])>

Divides one mutable slice into two at an index, returning None if the +slice is too short.

+

If mid ≤ len returns a pair of slices where the first will contain all +indices from [0, mid) (excluding the index mid itself) and the +second will contain all indices from [mid, len) (excluding the index +len itself).

+

Otherwise, if mid > len, returns None.

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+
+if let Some((left, right)) = v.split_at_mut_checked(2) {
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
+assert_eq!(None, v.split_at_mut_checked(7));
+
1.0.0 · source

pub fn split<F>(&self, pred: F) -> Split<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is not contained in the subslices.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the first element is matched, an empty slice will be the first item +returned by the iterator. Similarly, if the last element in the slice +is matched, an empty slice will be the last item returned by the +iterator:

+ +
let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
+

If two matched elements are directly adjacent, an empty slice will be +present between them:

+ +
let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is not contained in the subslices.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_mut(|num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 1]);
+
1.51.0 · source

pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is contained in the end of the previous +subslice as a terminator.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the last element of the slice is matched, +that element will be considered the terminator of the preceding slice. +That slice will be the last item returned by the iterator.

+ +
let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
+
1.51.0 · source

pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is contained in the previous +subslice as a terminator.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
+    let terminator_idx = group.len()-1;
+    group[terminator_idx] = 1;
+}
+assert_eq!(v, [10, 40, 1, 20, 1, 1]);
+
1.27.0 · source

pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, starting at the end of the slice and working backwards. +The matched element is not contained in the subslices.

+
§Examples
+
let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
+
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
+

As with split(), if the first or last element is matched, an empty +slice will be the first (or last) item returned by the iterator.

+ +
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
+
1.27.0 · source

pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred, starting at the end of the slice and working +backwards. The matched element is not contained in the subslices.

+
§Examples
+
let mut v = [100, 400, 300, 200, 600, 500];
+
+let mut count = 0;
+for group in v.rsplit_mut(|num| *num % 3 == 0) {
+    count += 1;
+    group[0] = count;
+}
+assert_eq!(v, [3, 400, 300, 2, 600, 1]);
+
1.0.0 · source

pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], +[20, 60, 50]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 50]);
+
1.0.0 · source

pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once, starting from the end, by numbers divisible +by 3 (i.e., [50], [10, 40, 30, 20]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+
let mut s = [10, 40, 30, 20, 60, 50];
+
+for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(s, [1, 40, 30, 20, 60, 1]);
+
source

pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the first element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.split_once(|&x| x == 2), Some((
+    &[1][..],
+    &[3, 2, 4][..]
+)));
+assert_eq!(s.split_once(|&x| x == 0), None);
+
source

pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the last element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.rsplit_once(|&x| x == 2), Some((
+    &[1, 2, 3][..],
+    &[4][..]
+)));
+assert_eq!(s.rsplit_once(|&x| x == 0), None);
+
1.0.0 · source

pub fn contains(&self, x: &T) -> bool
where + T: PartialEq,

Returns true if the slice contains an element with the given value.

+

This operation is O(n).

+

Note that if you have a sorted slice, binary_search may be faster.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
+

If you do not have a &T, but some other value that you can compare +with one (for example, String implements PartialEq<str>), you can +use iter().any:

+ +
let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
+
1.0.0 · source

pub fn starts_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a prefix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(v.starts_with(&v));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
+
1.0.0 · source

pub fn ends_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a suffix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(v.ends_with(&v));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
+
1.51.0 · source

pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the prefix removed.

+

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. +If prefix is empty, simply returns the original slice. If prefix is equal to the +original slice, returns an empty slice.

+

If the slice does not start with prefix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
+
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+           Some(b"llo".as_ref()));
+
1.51.0 · source

pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the suffix removed.

+

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. +If suffix is empty, simply returns the original slice. If suffix is equal to the +original slice, returns an empty slice.

+

If the slice does not end with suffix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
+

Binary searches this slice for a given element. +If the slice is not sorted, the returned result is unspecified and +meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search_by, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+assert_eq!(s.binary_search(&13),  Ok(9));
+assert_eq!(s.binary_search(&4),   Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

If you want to find that whole range of matching items, rather than +an arbitrary matching one, that can be done using partition_point:

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
+

If you want to insert an item to a sorted vector, while maintaining +sort order, consider using partition_point:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+// If `num` is unique, `s.partition_point(|&x| x < num)` (with `<`) is equivalent to
+// `s.binary_search(&num).unwrap_or_else(|x| x)`, but using `<=` will allow `insert`
+// to shift less elements.
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
1.0.0 · source

pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
where + F: FnMut(&'a T) -> Ordering,

Binary searches this slice with a comparator function.

+

The comparator function should return an order code that indicates +whether its argument is Less, Equal or Greater the desired +target. +If the slice is not sorted or if the comparator function does not +implement an order consistent with the sort order of the underlying +slice, the returned result is unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.10.0 · source

pub fn binary_search_by_key<'a, B, F>( + &'a self, + b: &B, + f: F +) -> Result<usize, usize>
where + F: FnMut(&'a T) -> B, + B: Ord,

Binary searches this slice with a key extraction function.

+

Assumes that the slice is sorted by the key, for instance with +sort_by_key using the same key extraction function. +If the slice is not sorted by the key, the returned result is +unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by, and partition_point.

+
§Examples
+

Looks up a series of four elements in a slice of pairs sorted by +their second elements. The first is found, with a uniquely +determined position; the second and third are not found; the +fourth could match any position in [1, 4].

+ +
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+         (1, 21), (2, 34), (4, 55)];
+
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.20.0 · source

pub fn sort_unstable(&mut self)
where + T: Ord,

Sorts the slice, but might not preserve the order of equal elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
§Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort_unstable();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.20.0 · source

pub fn sort_unstable_by<F>(&mut self, compare: F)
where + F: FnMut(&T, &T) -> Ordering,

Sorts the slice with a comparator function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
§Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_unstable_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_unstable_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.20.0 · source

pub fn sort_unstable_by_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(m * n * log(n)) worst-case, where the key function is +O(m).

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

Due to its key calling strategy, sort_unstable_by_key +is likely to be slower than sort_by_cached_key in +cases where the key function is expensive.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_unstable_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.49.0 · source

pub fn select_nth_unstable( + &mut self, + index: usize +) -> (&mut [T], &mut T, &mut [T])
where + T: Ord,

Reorder the slice such that the element at index after the reordering is at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index. Additionally, this reordering is +unstable (i.e. any number of equal elements may end up at position index), in-place +(i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from the reordered slice: +the subslice prior to index, the element at index, and the subslice after index; +accordingly, the values in those two subslices will respectively all be less-than-or-equal-to +and greater-than-or-equal-to the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 2, -3, 1];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median.
+let (lesser, median, greater) = v.select_nth_unstable(2);
+
+assert!(lesser == [-3, -5] || lesser == [-5, -3]);
+assert_eq!(median, &mut 1);
+assert!(greater == [4, 2] || greater == [2, 4]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [-3, -5, 1, 2, 4] ||
+        v == [-5, -3, 1, 2, 4] ||
+        v == [-3, -5, 1, 4, 2] ||
+        v == [-5, -3, 1, 4, 2]);
+
1.49.0 · source

pub fn select_nth_unstable_by<F>( + &mut self, + index: usize, + compare: F +) -> (&mut [T], &mut T, &mut [T])
where + F: FnMut(&T, &T) -> Ordering,

Reorder the slice with a comparator function such that the element at index after the reordering is at +its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the comparator function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided comparator function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 2, -3, 1];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median as if the slice were sorted in descending order.
+let (lesser, median, greater) = v.select_nth_unstable_by(2, |a, b| b.cmp(a));
+
+assert!(lesser == [4, 2] || lesser == [2, 4]);
+assert_eq!(median, &mut 1);
+assert!(greater == [-3, -5] || greater == [-5, -3]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [2, 4, 1, -5, -3] ||
+        v == [2, 4, 1, -3, -5] ||
+        v == [4, 2, 1, -5, -3] ||
+        v == [4, 2, 1, -3, -5]);
+
1.49.0 · source

pub fn select_nth_unstable_by_key<K, F>( + &mut self, + index: usize, + f: F +) -> (&mut [T], &mut T, &mut [T])
where + F: FnMut(&T) -> K, + K: Ord,

Reorder the slice with a key extraction function such that the element at index after the reordering is +at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the key extraction function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided key extraction function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median as if the slice were sorted according to absolute value.
+let (lesser, median, greater) = v.select_nth_unstable_by_key(2, |a| a.abs());
+
+assert!(lesser == [1, 2] || lesser == [2, 1]);
+assert_eq!(median, &mut -3);
+assert!(greater == [4, -5] || greater == [-5, 4]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [1, 2, -3, 4, -5] ||
+        v == [1, 2, -3, -5, 4] ||
+        v == [2, 1, -3, 4, -5] ||
+        v == [2, 1, -3, -5, 4]);
+
source

pub fn partition_dedup(&mut self) -> (&mut [T], &mut [T])
where + T: PartialEq,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all consecutive repeated elements to the end of the slice according to the +PartialEq trait implementation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
+
+let (dedup, duplicates) = slice.partition_dedup();
+
+assert_eq!(dedup, [1, 2, 3, 2, 1]);
+assert_eq!(duplicates, [2, 3, 1]);
+
source

pub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T])
where + F: FnMut(&mut T, &mut T) -> bool,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice satisfying +a given equality relation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

The same_bucket function is passed references to two elements from the slice and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is moved +at the end of the slice.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
+
+let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
+assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
+
source

pub fn partition_dedup_by_key<K, F>(&mut self, key: F) -> (&mut [T], &mut [T])
where + F: FnMut(&mut T) -> K, + K: PartialEq,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice that resolve +to the same key.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
+
+let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
+
+assert_eq!(dedup, [10, 20, 30, 20, 11]);
+assert_eq!(duplicates, [21, 30, 13]);
+
1.26.0 · source

pub fn rotate_left(&mut self, mid: usize)

Rotates the slice in-place such that the first mid elements of the +slice move to the end while the last self.len() - mid elements move to +the front. After calling rotate_left, the element previously at index +mid will become the first element in the slice.

+
§Panics
+

This function will panic if mid is greater than the length of the +slice. Note that mid == self.len() does not panic and is a no-op +rotation.

+
§Complexity
+

Takes linear (in self.len()) time.

+
§Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_left(2);
+assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_left(1);
+assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+
1.26.0 · source

pub fn rotate_right(&mut self, k: usize)

Rotates the slice in-place such that the first self.len() - k +elements of the slice move to the end while the last k elements move +to the front. After calling rotate_right, the element previously at +index self.len() - k will become the first element in the slice.

+
§Panics
+

This function will panic if k is greater than the length of the +slice. Note that k == self.len() does not panic and is a no-op +rotation.

+
§Complexity
+

Takes linear (in self.len()) time.

+
§Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_right(2);
+assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_right(1);
+assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
+
1.50.0 · source

pub fn fill(&mut self, value: T)
where + T: Clone,

Fills self with elements by cloning value.

+
§Examples
+
let mut buf = vec![0; 10];
+buf.fill(1);
+assert_eq!(buf, vec![1; 10]);
+
1.51.0 · source

pub fn fill_with<F>(&mut self, f: F)
where + F: FnMut() -> T,

Fills self with elements returned by calling a closure repeatedly.

+

This method uses a closure to create new values. If you’d rather +Clone a given value, use fill. If you want to use the Default +trait to generate values, you can pass Default::default as the +argument.

+
§Examples
+
let mut buf = vec![1; 10];
+buf.fill_with(Default::default);
+assert_eq!(buf, vec![0; 10]);
+
1.7.0 · source

pub fn clone_from_slice(&mut self, src: &[T])
where + T: Clone,

Copies the elements from src into self.

+

The length of src must be the same as self.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Examples
+

Cloning two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.clone_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use clone_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].clone_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.clone_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.9.0 · source

pub fn copy_from_slice(&mut self, src: &[T])
where + T: Copy,

Copies all elements from src into self, using a memcpy.

+

The length of src must be the same as self.

+

If T does not implement Copy, use clone_from_slice.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Examples
+

Copying two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.copy_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use copy_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].copy_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.copy_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.37.0 · source

pub fn copy_within<R>(&mut self, src: R, dest: usize)
where + R: RangeBounds<usize>, + T: Copy,

Copies elements from one part of the slice to another part of itself, +using a memmove.

+

src is the range within self to copy from. dest is the starting +index of the range within self to copy to, which will have the same +length as src. The two ranges may overlap. The ends of the two ranges +must be less than or equal to self.len().

+
§Panics
+

This function will panic if either range exceeds the end of the slice, +or if the end of src is before the start.

+
§Examples
+

Copying four bytes within a slice:

+ +
let mut bytes = *b"Hello, World!";
+
+bytes.copy_within(1..5, 8);
+
+assert_eq!(&bytes, b"Hello, Wello!");
+
1.27.0 · source

pub fn swap_with_slice(&mut self, other: &mut [T])

Swaps all elements in self with those in other.

+

The length of other must be the same as self.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Example
+

Swapping two elements across slices:

+ +
let mut slice1 = [0, 0];
+let mut slice2 = [1, 2, 3, 4];
+
+slice1.swap_with_slice(&mut slice2[2..]);
+
+assert_eq!(slice1, [3, 4]);
+assert_eq!(slice2, [1, 2, 0, 0]);
+

Rust enforces that there can only be one mutable reference to a +particular piece of data in a particular scope. Because of this, +attempting to use swap_with_slice on a single slice will result in +a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +mutable sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.swap_with_slice(&mut right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 1, 2]);
+
1.30.0 · source

pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

Transmute the slice to a slice of another type, ensuring alignment of the types is +maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The middle part will be as big as possible under +the given alignment constraint and element size.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
§Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
§Examples
+

Basic usage:

+ +
unsafe {
+    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
1.30.0 · source

pub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T])

Transmute the mutable slice to a mutable slice of another type, ensuring alignment of the +types is maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The middle part will be as big as possible under +the given alignment constraint and element size.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
§Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
§Examples
+

Basic usage:

+ +
unsafe {
+    let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
source

pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
where + Simd<T, LANES>: AsRef<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.

+

This is a safe wrapper around slice::align_to, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+
§Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
§Examples
+
#![feature(portable_simd)]
+use core::simd::prelude::*;
+
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
+
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+
+fn basic_simd_sum(x: &[f32]) -> f32 {
+    use std::ops::Add;
+    let (prefix, middle, suffix) = x.as_simd();
+    let sums = f32x4::from_array([
+        prefix.iter().copied().sum(),
+        0.0,
+        0.0,
+        suffix.iter().copied().sum(),
+    ]);
+    let sums = middle.iter().copied().fold(sums, f32x4::add);
+    sums.reduce_sum()
+}
+
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+
source

pub fn as_simd_mut<const LANES: usize>( + &mut self +) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T])
where + Simd<T, LANES>: AsMut<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a mutable slice into a mutable prefix, a middle of aligned SIMD types, +and a mutable suffix.

+

This is a safe wrapper around slice::align_to_mut, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+

This is the mutable version of slice::as_simd; see that for examples.

+
§Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
source

pub fn is_sorted(&self) -> bool
where + T: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted.

+

That is, for each element a and its following element b, a <= b must hold. If the +slice yields exactly zero or one element, true is returned.

+

Note that if Self::Item is only PartialOrd, but not Ord, the above definition +implies that this function returns false if any two consecutive items are not +comparable.

+
§Examples
+
#![feature(is_sorted)]
+let empty: [i32; 0] = [];
+
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
+
source

pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> bool
where + F: FnMut(&'a T, &'a T) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given comparator function.

+

Instead of using PartialOrd::partial_cmp, this function uses the given compare +function to determine whether two elements are to be considered in sorted order.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!([1, 2, 2, 9].is_sorted_by(|a, b| a <= b));
+assert!(![1, 2, 2, 9].is_sorted_by(|a, b| a < b));
+
+assert!([0].is_sorted_by(|a, b| true));
+assert!([0].is_sorted_by(|a, b| false));
+
+let empty: [i32; 0] = [];
+assert!(empty.is_sorted_by(|a, b| false));
+assert!(empty.is_sorted_by(|a, b| true));
+
source

pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
where + F: FnMut(&'a T) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given key extraction function.

+

Instead of comparing the slice’s elements directly, this function compares the keys of the +elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its +documentation for more information.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+
1.52.0 · source

pub fn partition_point<P>(&self, pred: P) -> usize
where + P: FnMut(&T) -> bool,

Returns the index of the partition point according to the given predicate +(the index of the first element of the second partition).

+

The slice is assumed to be partitioned according to the given predicate. +This means that all elements for which the predicate returns true are at the start of the slice +and all elements for which the predicate returns false are at the end. +For example, [7, 15, 3, 5, 4, 12, 6] is partitioned under the predicate x % 2 != 0 +(all odd numbers are at the start, all even at the end).

+

If this slice is not partitioned, the returned result is unspecified and meaningless, +as this method performs a kind of binary search.

+

See also binary_search, binary_search_by, and binary_search_by_key.

+
§Examples
+
let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
+
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
+

If all elements of the slice match the predicate, including if the slice +is empty, then the length of the slice will be returned:

+ +
let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
+

If you want to insert an item to a sorted vector, while maintaining +sort order:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
source

pub fn take<'a, R>(self: &mut &'a [T], range: R) -> Option<&'a [T]>
where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
§Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut first_three = slice.take(..3).unwrap();
+
+assert_eq!(slice, &['d']);
+assert_eq!(first_three, &['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut tail = slice.take(2..).unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(tail, &['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take(5..));
+assert_eq!(None, slice.take(..5));
+assert_eq!(None, slice.take(..=4));
+let expected: &[char] = &['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take(..4));
+
source

pub fn take_mut<'a, R>(self: &mut &'a mut [T], range: R) -> Option<&'a mut [T]>
where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a mutable reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
§Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut first_three = slice.take_mut(..3).unwrap();
+
+assert_eq!(slice, &mut ['d']);
+assert_eq!(first_three, &mut ['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut tail = slice.take_mut(2..).unwrap();
+
+assert_eq!(slice, &mut ['a', 'b']);
+assert_eq!(tail, &mut ['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take_mut(5..));
+assert_eq!(None, slice.take_mut(..5));
+assert_eq!(None, slice.take_mut(..=4));
+let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take_mut(..4));
+
source

pub fn take_first<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let first = slice.take_first().unwrap();
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'a');
+
source

pub fn take_first_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let first = slice.take_first_mut().unwrap();
+*first = 'd';
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'d');
+
source

pub fn take_last<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let last = slice.take_last().unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'c');
+
source

pub fn take_last_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let last = slice.take_last_mut().unwrap();
+*last = 'd';
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'d');
+
source

pub unsafe fn get_many_unchecked_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> [&mut T; N]

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once, without doing any checks.

+

For a safe alternative see get_many_mut.

+
§Safety
+

Calling this method with overlapping or out-of-bounds indices is undefined behavior +even if the resulting references are not used.

+
§Examples
+
#![feature(get_many_mut)]
+
+let x = &mut [1, 2, 4];
+
+unsafe {
+    let [a, b] = x.get_many_unchecked_mut([0, 2]);
+    *a *= 10;
+    *b *= 100;
+}
+assert_eq!(x, &[10, 2, 400]);
+
source

pub fn get_many_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> Result<[&mut T; N], GetManyMutError<N>>

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once.

+

Returns an error if any index is out-of-bounds, or if the same index was +passed more than once.

+
§Examples
+
#![feature(get_many_mut)]
+
+let v = &mut [1, 2, 3];
+if let Ok([a, b]) = v.get_many_mut([0, 2]) {
+    *a = 413;
+    *b = 612;
+}
+assert_eq!(v, &[413, 2, 612]);
+
1.79.0 · source

pub fn utf8_chunks(&self) -> Utf8Chunks<'_>

Creates an iterator over the contiguous valid UTF-8 ranges of this +slice, and the non-UTF-8 fragments in between.

+
§Examples
+

This function formats arbitrary but mostly-UTF-8 bytes into Rust source +code in the form of a C-string literal (c"...").

+ +
use std::fmt::Write as _;
+
+pub fn cstr_literal(bytes: &[u8]) -> String {
+    let mut repr = String::new();
+    repr.push_str("c\"");
+    for chunk in bytes.utf8_chunks() {
+        for ch in chunk.valid().chars() {
+            // Escapes \0, \t, \r, \n, \\, \', \", and uses \u{...} for non-printable characters.
+            write!(repr, "{}", ch.escape_debug()).unwrap();
+        }
+        for byte in chunk.invalid() {
+            write!(repr, "\\x{:02X}", byte).unwrap();
+        }
+    }
+    repr.push('"');
+    repr
+}
+
+fn main() {
+    let lit = cstr_literal(b"\xferris the \xf0\x9f\xa6\x80\x07");
+    let expected = stringify!(c"\xFErris the 🦀\u{7}");
+    assert_eq!(lit, expected);
+}
+
1.23.0 · source

pub fn is_ascii(&self) -> bool

Checks if all bytes in this slice are within the ASCII range.

+
source

pub fn as_ascii(&self) -> Option<&[AsciiChar]>

🔬This is a nightly-only experimental API. (ascii_char)

If this slice is_ascii, returns it as a slice of +ASCII characters, otherwise returns None.

+
source

pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]

🔬This is a nightly-only experimental API. (ascii_char)

Converts this slice of bytes into a slice of ASCII characters, +without checking whether they’re valid.

+
§Safety
+

Every byte in the slice must be in 0..=127, or else this is UB.

+
1.23.0 · source

pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool

Checks that two slices are an ASCII case-insensitive match.

+

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), +but without allocating and copying temporaries.

+
1.23.0 · source

pub fn make_ascii_uppercase(&mut self)

Converts this slice to its ASCII upper case equivalent in-place.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To return a new uppercased value without modifying the existing one, use +to_ascii_uppercase.

+
1.23.0 · source

pub fn make_ascii_lowercase(&mut self)

Converts this slice to its ASCII lower case equivalent in-place.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To return a new lowercased value without modifying the existing one, use +to_ascii_lowercase.

+
1.60.0 · source

pub fn escape_ascii(&self) -> EscapeAscii<'_>

Returns an iterator that produces an escaped version of this slice, +treating it as an ASCII string.

+
§Examples
+

+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
+
1.80.0 · source

pub fn trim_ascii_start(&self) -> &[u8]

Returns a byte slice with leading ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b"  ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
+
1.80.0 · source

pub fn trim_ascii_end(&self) -> &[u8]

Returns a byte slice with trailing ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b"  ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
+
1.80.0 · source

pub fn trim_ascii(&self) -> &[u8]

Returns a byte slice with leading and trailing ASCII whitespace bytes +removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b"  ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f64::total_cmp.

+
§Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
§Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
source

pub fn as_str(&self) -> &str

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a UTF-8 str.

+
source

pub fn as_bytes(&self) -> &[u8]

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a slice of u8 bytes.

+
1.0.0 · source

pub fn sort(&mut self)
where + T: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.0.0 · source

pub fn sort_by<F>(&mut self, compare: F)
where + F: FnMut(&T, &T) -> Ordering,

Available on non-no_global_oom_handling only.

Sorts the slice with a comparator function.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.7.0 · source

pub fn sort_by_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n * log(n)) +worst-case, where the key function is O(m).

+

For expensive key functions (e.g. functions that are not simple property accesses or +basic operations), sort_by_cached_key is likely to be +significantly faster, as it does not recompute element keys.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by_key.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.34.0 · source

pub fn sort_by_cached_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

During sorting, the key function is called at most once per element, by using +temporary storage to remember the results of key evaluation. +The order of calls to the key function is unspecified and may change in future versions +of the standard library.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n + n * log(n)) +worst-case, where the key function is O(m).

+

For simple key functions (e.g., functions that are property accesses or +basic operations), sort_by_key is likely to be +faster.

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

In the worst case, the algorithm allocates temporary storage in a Vec<(K, usize)> the +length of the slice.

+
§Examples
+
let mut v = [-5i32, 4, 32, -3, 2];
+
+v.sort_by_cached_key(|k| k.to_string());
+assert!(v == [-3, -5, 2, 32, 4]);
+
1.0.0 · source

pub fn to_vec(&self) -> Vec<T>
where + T: Clone,

Available on non-no_global_oom_handling only.

Copies self into a new Vec.

+
§Examples
+
let s = [10, 40, 30];
+let x = s.to_vec();
+// Here, `s` and `x` can be modified independently.
+
source

pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>
where + A: Allocator, + T: Clone,

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Copies self into a new Vec with an allocator.

+
§Examples
+
#![feature(allocator_api)]
+
+use std::alloc::System;
+
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
+// Here, `s` and `x` can be modified independently.
+
1.40.0 · source

pub fn repeat(&self, n: usize) -> Vec<T>
where + T: Copy,

Available on non-no_global_oom_handling only.

Creates a vector by copying a slice n times.

+
§Panics
+

This function will panic if the capacity would overflow.

+
§Examples
+

Basic usage:

+ +
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
+

A panic upon overflow:

+ +
// this will panic at runtime
+b"0123456789abcdef".repeat(usize::MAX);
+
1.0.0 · source

pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output
where + [T]: Concat<Item>, + Item: ?Sized,

Flattens a slice of T into a single value Self::Output.

+
§Examples
+
assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+
1.3.0 · source

pub fn join<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+
1.0.0 · source

pub fn connect<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

👎Deprecated since 1.3.0: renamed to join

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+
1.23.0 · source

pub fn to_ascii_uppercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII upper case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To uppercase the value in-place, use make_ascii_uppercase.

+
1.23.0 · source

pub fn to_ascii_lowercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII lower case equivalent.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To lowercase the value in-place, use make_ascii_lowercase.

+

Trait Implementations§

source§

impl Clone for AcceptEncoding

source§

fn clone(&self) -> AcceptEncoding

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for AcceptEncoding

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for AcceptEncoding

§

type Target = Vec<QualityItem<Preference<Encoding>>>

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for AcceptEncoding

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl Display for AcceptEncoding

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for AcceptEncoding

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for AcceptEncoding

source§

fn eq(&self, other: &AcceptEncoding) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for AcceptEncoding

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for AcceptEncoding

source§

impl StructuralPartialEq for AcceptEncoding

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.AcceptLanguage.html b/actix_web/http/header/struct.AcceptLanguage.html new file mode 100644 index 000000000..a4a28789e --- /dev/null +++ b/actix_web/http/header/struct.AcceptLanguage.html @@ -0,0 +1,3149 @@ +AcceptLanguage in actix_web::http::header - Rust

Struct actix_web::http::header::AcceptLanguage

source ·
pub struct AcceptLanguage(pub Vec<QualityItem<Preference<LanguageTag>>>);
Expand description

Accept-Language header, defined +in RFC 7231 §5.3.5

+

The Accept-Language header field can be used by user agents to indicate the set of natural +languages that are preferred in the response.

+

The Accept-Language header is defined in +RFC 7231 §5.3.5 using language +ranges defined in RFC 4647 §2.1.

+

§ABNF

Accept-Language = 1#( language-range [ weight ] )
+language-range  = (1*8ALPHA *("-" 1*8alphanum)) / "*"
+alphanum        = ALPHA / DIGIT
+weight          = OWS ";" OWS "q=" qvalue
+qvalue          = ( "0" [ "." 0*3DIGIT ] )
+                / ( "1" [ "." 0*3("0") ] )
+

§Example Values

+
    +
  • da, en-gb;q=0.8, en;q=0.7
  • +
  • en-us;q=1.0, en;q=0.5, fr
  • +
  • fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5
  • +
+

§Examples

+
use actix_web::HttpResponse;
+use actix_web::http::header::{AcceptLanguage, QualityItem};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    AcceptLanguage(vec![
+        "en-US".parse().unwrap(),
+    ])
+);
+ +
use actix_web::HttpResponse;
+use actix_web::http::header::{AcceptLanguage, QualityItem, q};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    AcceptLanguage(vec![
+        "da".parse().unwrap(),
+        "en-GB;q=0.8".parse().unwrap(),
+        "en;q=0.7".parse().unwrap(),
+    ])
+);
+

Tuple Fields§

§0: Vec<QualityItem<Preference<LanguageTag>>>

Implementations§

source§

impl AcceptLanguage

source

pub fn preference(&self) -> Preference<LanguageTag>

Extracts the most preferable language, accounting for q-factor weighting.

+

If no q-factors are provided, the first language is chosen. Note that items without +q-factors are given the maximum preference value.

+

As per the spec, returns Preference::Any if contained list is empty.

+
source

pub fn ranked(&self) -> Vec<Preference<LanguageTag>>

Returns a sorted list of languages from highest to lowest precedence, accounting +for q-factor weighting.

+

Methods from Deref<Target = Vec<QualityItem<Preference<LanguageTag>>>>§

1.0.0 · source

pub fn capacity(&self) -> usize

Returns the total number of elements the vector can hold without +reallocating.

+
§Examples
+
let mut vec: Vec<i32> = Vec::with_capacity(10);
+vec.push(42);
+assert!(vec.capacity() >= 10);
+
1.0.0 · source

pub fn reserve(&mut self, additional: usize)

Available on non-no_global_oom_handling only.

Reserves capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to +speculatively avoid frequent reallocations. After calling reserve, +capacity will be greater than or equal to self.len() + additional. +Does nothing if capacity is already sufficient.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1];
+vec.reserve(10);
+assert!(vec.capacity() >= 11);
+
1.0.0 · source

pub fn reserve_exact(&mut self, additional: usize)

Available on non-no_global_oom_handling only.

Reserves the minimum capacity for at least additional more elements to +be inserted in the given Vec<T>. Unlike reserve, this will not +deliberately over-allocate to speculatively avoid frequent allocations. +After calling reserve_exact, capacity will be greater than or equal to +self.len() + additional. Does nothing if the capacity is already +sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer reserve if future insertions are expected.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1];
+vec.reserve_exact(10);
+assert!(vec.capacity() >= 11);
+
1.57.0 · source

pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>

Tries to reserve capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to speculatively avoid +frequent reallocations. After calling try_reserve, capacity will be +greater than or equal to self.len() + additional if it returns +Ok(()). Does nothing if capacity is already sufficient. This method +preserves the contents even if an error occurs.

+
§Errors
+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+
§Examples
+
use std::collections::TryReserveError;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+
1.57.0 · source

pub fn try_reserve_exact( + &mut self, + additional: usize +) -> Result<(), TryReserveError>

Tries to reserve the minimum capacity for at least additional +elements to be inserted in the given Vec<T>. Unlike try_reserve, +this will not deliberately over-allocate to speculatively avoid frequent +allocations. After calling try_reserve_exact, capacity will be greater +than or equal to self.len() + additional if it returns Ok(()). +Does nothing if the capacity is already sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer try_reserve if future insertions are expected.

+
§Errors
+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+
§Examples
+
use std::collections::TryReserveError;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve_exact(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+
1.0.0 · source

pub fn shrink_to_fit(&mut self)

Available on non-no_global_oom_handling only.

Shrinks the capacity of the vector as much as possible.

+

The behavior of this method depends on the allocator, which may either shrink the vector +in-place or reallocate. The resulting vector might still have some excess capacity, just as +is the case for with_capacity. See Allocator::shrink for more details.

+
§Examples
+
let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3]);
+assert!(vec.capacity() >= 10);
+vec.shrink_to_fit();
+assert!(vec.capacity() >= 3);
+
1.56.0 · source

pub fn shrink_to(&mut self, min_capacity: usize)

Available on non-no_global_oom_handling only.

Shrinks the capacity of the vector with a lower bound.

+

The capacity will remain at least as large as both the length +and the supplied value.

+

If the current capacity is less than the lower limit, this is a no-op.

+
§Examples
+
let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3]);
+assert!(vec.capacity() >= 10);
+vec.shrink_to(4);
+assert!(vec.capacity() >= 4);
+vec.shrink_to(0);
+assert!(vec.capacity() >= 3);
+
1.0.0 · source

pub fn truncate(&mut self, len: usize)

Shortens the vector, keeping the first len elements and dropping +the rest.

+

If len is greater or equal to the vector’s current length, this has +no effect.

+

The drain method can emulate truncate, but causes the excess +elements to be returned instead of dropped.

+

Note that this method has no effect on the allocated capacity +of the vector.

+
§Examples
+

Truncating a five element vector to two elements:

+ +
let mut vec = vec![1, 2, 3, 4, 5];
+vec.truncate(2);
+assert_eq!(vec, [1, 2]);
+

No truncation occurs when len is greater than the vector’s current +length:

+ +
let mut vec = vec![1, 2, 3];
+vec.truncate(8);
+assert_eq!(vec, [1, 2, 3]);
+

Truncating when len == 0 is equivalent to calling the clear +method.

+ +
let mut vec = vec![1, 2, 3];
+vec.truncate(0);
+assert_eq!(vec, []);
+
1.7.0 · source

pub fn as_slice(&self) -> &[T]

Extracts a slice containing the entire vector.

+

Equivalent to &s[..].

+
§Examples
+
use std::io::{self, Write};
+let buffer = vec![1, 2, 3, 5, 8];
+io::sink().write(buffer.as_slice()).unwrap();
+
1.7.0 · source

pub fn as_mut_slice(&mut self) -> &mut [T]

Extracts a mutable slice of the entire vector.

+

Equivalent to &mut s[..].

+
§Examples
+
use std::io::{self, Read};
+let mut buffer = vec![0; 3];
+io::repeat(0b101).read_exact(buffer.as_mut_slice()).unwrap();
+
1.37.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the vector’s buffer, or a dangling raw pointer +valid for zero sized reads if the vector didn’t allocate.

+

The caller must ensure that the vector outlives the pointer this +function returns, or else it will end up pointing to garbage. +Modifying the vector may cause its buffer to be reallocated, +which would also make any pointers to it invalid.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

This method guarantees that for the purpose of the aliasing model, this method +does not materialize a reference to the underlying slice, and thus the returned pointer +will remain valid when mixed with other calls to as_ptr and as_mut_ptr. +Note that calling other methods that materialize mutable references to the slice, +or mutable references to specific elements you are planning on accessing through this pointer, +as well as writing to those elements, may still invalidate this pointer. +See the second example below for how this guarantee can be used.

+
§Examples
+
let x = vec![1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(*x_ptr.add(i), 1 << i);
+    }
+}
+

Due to the aliasing guarantee, the following code is legal:

+ +
unsafe {
+    let mut v = vec![0, 1, 2];
+    let ptr1 = v.as_ptr();
+    let _ = ptr1.read();
+    let ptr2 = v.as_mut_ptr().offset(2);
+    ptr2.write(2);
+    // Notably, the write to `ptr2` did *not* invalidate `ptr1`
+    // because it mutated a different element:
+    let _ = ptr1.read();
+}
+
1.37.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the vector’s buffer, or a dangling +raw pointer valid for zero sized reads if the vector didn’t allocate.

+

The caller must ensure that the vector outlives the pointer this +function returns, or else it will end up pointing to garbage. +Modifying the vector may cause its buffer to be reallocated, +which would also make any pointers to it invalid.

+

This method guarantees that for the purpose of the aliasing model, this method +does not materialize a reference to the underlying slice, and thus the returned pointer +will remain valid when mixed with other calls to as_ptr and as_mut_ptr. +Note that calling other methods that materialize references to the slice, +or references to specific elements you are planning on accessing through this pointer, +may still invalidate this pointer. +See the second example below for how this guarantee can be used.

+
§Examples
+
// Allocate vector big enough for 4 elements.
+let size = 4;
+let mut x: Vec<i32> = Vec::with_capacity(size);
+let x_ptr = x.as_mut_ptr();
+
+// Initialize elements via raw pointer writes, then set length.
+unsafe {
+    for i in 0..size {
+        *x_ptr.add(i) = i as i32;
+    }
+    x.set_len(size);
+}
+assert_eq!(&*x, &[0, 1, 2, 3]);
+

Due to the aliasing guarantee, the following code is legal:

+ +
unsafe {
+    let mut v = vec![0];
+    let ptr1 = v.as_mut_ptr();
+    ptr1.write(1);
+    let ptr2 = v.as_mut_ptr();
+    ptr2.write(2);
+    // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
+    ptr1.write(3);
+}
+
source

pub fn allocator(&self) -> &A

🔬This is a nightly-only experimental API. (allocator_api)

Returns a reference to the underlying allocator.

+
1.0.0 · source

pub unsafe fn set_len(&mut self, new_len: usize)

Forces the length of the vector to new_len.

+

This is a low-level operation that maintains none of the normal +invariants of the type. Normally changing the length of a vector +is done using one of the safe operations instead, such as +truncate, resize, extend, or clear.

+
§Safety
+
    +
  • new_len must be less than or equal to capacity().
  • +
  • The elements at old_len..new_len must be initialized.
  • +
+
§Examples
+

This method can be useful for situations in which the vector +is serving as a buffer for other code, particularly over FFI:

+ +
pub fn get_dictionary(&self) -> Option<Vec<u8>> {
+    // Per the FFI method's docs, "32768 bytes is always enough".
+    let mut dict = Vec::with_capacity(32_768);
+    let mut dict_length = 0;
+    // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
+    // 1. `dict_length` elements were initialized.
+    // 2. `dict_length` <= the capacity (32_768)
+    // which makes `set_len` safe to call.
+    unsafe {
+        // Make the FFI call...
+        let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
+        if r == Z_OK {
+            // ...and update the length to what was initialized.
+            dict.set_len(dict_length);
+            Some(dict)
+        } else {
+            None
+        }
+    }
+}
+

While the following example is sound, there is a memory leak since +the inner vectors were not freed prior to the set_len call:

+ +
let mut vec = vec![vec![1, 0, 0],
+                   vec![0, 1, 0],
+                   vec![0, 0, 1]];
+// SAFETY:
+// 1. `old_len..0` is empty so no elements need to be initialized.
+// 2. `0 <= capacity` always holds whatever `capacity` is.
+unsafe {
+    vec.set_len(0);
+}
+

Normally, here, one would use clear instead to correctly drop +the contents and thus not leak memory.

+
1.0.0 · source

pub fn swap_remove(&mut self, index: usize) -> T

Removes an element from the vector and returns it.

+

The removed element is replaced by the last element of the vector.

+

This does not preserve ordering of the remaining elements, but is O(1). +If you need to preserve the element order, use remove instead.

+
§Panics
+

Panics if index is out of bounds.

+
§Examples
+
let mut v = vec!["foo", "bar", "baz", "qux"];
+
+assert_eq!(v.swap_remove(1), "bar");
+assert_eq!(v, ["foo", "qux", "baz"]);
+
+assert_eq!(v.swap_remove(0), "foo");
+assert_eq!(v, ["baz", "qux"]);
+
1.0.0 · source

pub fn insert(&mut self, index: usize, element: T)

Available on non-no_global_oom_handling only.

Inserts an element at position index within the vector, shifting all +elements after it to the right.

+
§Panics
+

Panics if index > len.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+vec.insert(1, 4);
+assert_eq!(vec, [1, 4, 2, 3]);
+vec.insert(4, 5);
+assert_eq!(vec, [1, 4, 2, 3, 5]);
+
§Time complexity
+

Takes O(Vec::len) time. All items after the insertion index must be +shifted to the right. In the worst case, all elements are shifted when +the insertion index is 0.

+
1.0.0 · source

pub fn remove(&mut self, index: usize) -> T

Removes and returns the element at position index within the vector, +shifting all elements after it to the left.

+

Note: Because this shifts over the remaining elements, it has a +worst-case performance of O(n). If you don’t need the order of elements +to be preserved, use swap_remove instead. If you’d like to remove +elements from the beginning of the Vec, consider using +VecDeque::pop_front instead.

+
§Panics
+

Panics if index is out of bounds.

+
§Examples
+
let mut v = vec![1, 2, 3];
+assert_eq!(v.remove(1), 2);
+assert_eq!(v, [1, 3]);
+
1.0.0 · source

pub fn retain<F>(&mut self, f: F)
where + F: FnMut(&T) -> bool,

Retains only the elements specified by the predicate.

+

In other words, remove all elements e for which f(&e) returns false. +This method operates in place, visiting each element exactly once in the +original order, and preserves the order of the retained elements.

+
§Examples
+
let mut vec = vec![1, 2, 3, 4];
+vec.retain(|&x| x % 2 == 0);
+assert_eq!(vec, [2, 4]);
+

Because the elements are visited exactly once in the original order, +external state may be used to decide which elements to keep.

+ +
let mut vec = vec![1, 2, 3, 4, 5];
+let keep = [false, true, true, false, true];
+let mut iter = keep.iter();
+vec.retain(|_| *iter.next().unwrap());
+assert_eq!(vec, [2, 3, 5]);
+
1.61.0 · source

pub fn retain_mut<F>(&mut self, f: F)
where + F: FnMut(&mut T) -> bool,

Retains only the elements specified by the predicate, passing a mutable reference to it.

+

In other words, remove all elements e such that f(&mut e) returns false. +This method operates in place, visiting each element exactly once in the +original order, and preserves the order of the retained elements.

+
§Examples
+
let mut vec = vec![1, 2, 3, 4];
+vec.retain_mut(|x| if *x <= 3 {
+    *x += 1;
+    true
+} else {
+    false
+});
+assert_eq!(vec, [2, 3, 4]);
+
1.16.0 · source

pub fn dedup_by_key<F, K>(&mut self, key: F)
where + F: FnMut(&mut T) -> K, + K: PartialEq,

Removes all but the first of consecutive elements in the vector that resolve to the same +key.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec![10, 20, 21, 30, 20];
+
+vec.dedup_by_key(|i| *i / 10);
+
+assert_eq!(vec, [10, 20, 30, 20]);
+
1.16.0 · source

pub fn dedup_by<F>(&mut self, same_bucket: F)
where + F: FnMut(&mut T, &mut T) -> bool,

Removes all but the first of consecutive elements in the vector satisfying a given equality +relation.

+

The same_bucket function is passed references to two elements from the vector and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is removed.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
+
+vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
+
1.0.0 · source

pub fn push(&mut self, value: T)

Available on non-no_global_oom_handling only.

Appends an element to the back of a collection.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1, 2];
+vec.push(3);
+assert_eq!(vec, [1, 2, 3]);
+
§Time complexity
+

Takes amortized O(1) time. If the vector’s length would exceed its +capacity after the push, O(capacity) time is taken to copy the +vector’s elements to a larger allocation. This expensive operation is +offset by the capacity O(1) insertions it allows.

+
source

pub fn push_within_capacity(&mut self, value: T) -> Result<(), T>

🔬This is a nightly-only experimental API. (vec_push_within_capacity)

Appends an element if there is sufficient spare capacity, otherwise an error is returned +with the element.

+

Unlike push this method will not reallocate when there’s insufficient capacity. +The caller should use reserve or try_reserve to ensure that there is enough capacity.

+
§Examples
+

A manual, panic-free alternative to FromIterator:

+ +
#![feature(vec_push_within_capacity)]
+
+use std::collections::TryReserveError;
+fn from_iter_fallible<T>(iter: impl Iterator<Item=T>) -> Result<Vec<T>, TryReserveError> {
+    let mut vec = Vec::new();
+    for value in iter {
+        if let Err(value) = vec.push_within_capacity(value) {
+            vec.try_reserve(1)?;
+            // this cannot fail, the previous line either returned or added at least 1 free slot
+            let _ = vec.push_within_capacity(value);
+        }
+    }
+    Ok(vec)
+}
+assert_eq!(from_iter_fallible(0..100), Ok(Vec::from_iter(0..100)));
+
§Time complexity
+

Takes O(1) time.

+
1.0.0 · source

pub fn pop(&mut self) -> Option<T>

Removes the last element from a vector and returns it, or None if it +is empty.

+

If you’d like to pop the first element, consider using +VecDeque::pop_front instead.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+assert_eq!(vec.pop(), Some(3));
+assert_eq!(vec, [1, 2]);
+
§Time complexity
+

Takes O(1) time.

+
source

pub fn pop_if<F>(&mut self, f: F) -> Option<T>
where + F: FnOnce(&mut T) -> bool,

🔬This is a nightly-only experimental API. (vec_pop_if)

Removes and returns the last element in a vector if the predicate +returns true, or None if the predicate returns false or the vector +is empty.

+
§Examples
+
#![feature(vec_pop_if)]
+
+let mut vec = vec![1, 2, 3, 4];
+let pred = |x: &mut i32| *x % 2 == 0;
+
+assert_eq!(vec.pop_if(pred), Some(4));
+assert_eq!(vec, [1, 2, 3]);
+assert_eq!(vec.pop_if(pred), None);
+
1.4.0 · source

pub fn append(&mut self, other: &mut Vec<T, A>)

Available on non-no_global_oom_handling only.

Moves all the elements of other into self, leaving other empty.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+let mut vec2 = vec![4, 5, 6];
+vec.append(&mut vec2);
+assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
+assert_eq!(vec2, []);
+
1.6.0 · source

pub fn drain<R>(&mut self, range: R) -> Drain<'_, T, A>
where + R: RangeBounds<usize>,

Removes the specified range from the vector in bulk, returning all +removed elements as an iterator. If the iterator is dropped before +being fully consumed, it drops the remaining removed elements.

+

The returned iterator keeps a mutable borrow on the vector to optimize +its implementation.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Leaking
+

If the returned iterator goes out of scope without being dropped (due to +mem::forget, for example), the vector may have lost and leaked +elements arbitrarily, including elements outside the range.

+
§Examples
+
let mut v = vec![1, 2, 3];
+let u: Vec<_> = v.drain(1..).collect();
+assert_eq!(v, &[1]);
+assert_eq!(u, &[2, 3]);
+
+// A full range clears the vector, like `clear()` does
+v.drain(..);
+assert_eq!(v, &[]);
+
1.0.0 · source

pub fn clear(&mut self)

Clears the vector, removing all values.

+

Note that this method has no effect on the allocated capacity +of the vector.

+
§Examples
+
let mut v = vec![1, 2, 3];
+
+v.clear();
+
+assert!(v.is_empty());
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the vector, also referred to +as its ‘length’.

+
§Examples
+
let a = vec![1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the vector contains no elements.

+
§Examples
+
let mut v = Vec::new();
+assert!(v.is_empty());
+
+v.push(1);
+assert!(!v.is_empty());
+
1.4.0 · source

pub fn split_off(&mut self, at: usize) -> Vec<T, A>
where + A: Clone,

Available on non-no_global_oom_handling only.

Splits the collection into two at the given index.

+

Returns a newly allocated vector containing the elements in the range +[at, len). After the call, the original vector will be left containing +the elements [0, at) with its previous capacity unchanged.

+
    +
  • If you want to take ownership of the entire contents and capacity of +the vector, see mem::take or mem::replace.
  • +
  • If you don’t need the returned vector at all, see Vec::truncate.
  • +
  • If you want to take ownership of an arbitrary subslice, or you don’t +necessarily want to store the removed items in a vector, see Vec::drain.
  • +
+
§Panics
+

Panics if at > len.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+let vec2 = vec.split_off(1);
+assert_eq!(vec, [1]);
+assert_eq!(vec2, [2, 3]);
+
1.33.0 · source

pub fn resize_with<F>(&mut self, new_len: usize, f: F)
where + F: FnMut() -> T,

Available on non-no_global_oom_handling only.

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with the result of +calling the closure f. The return values from f will end up +in the Vec in the order they have been generated.

+

If new_len is less than len, the Vec is simply truncated.

+

This method uses a closure to create new values on every push. If +you’d rather Clone a given value, use Vec::resize. If you +want to use the Default trait to generate values, you can +pass Default::default as the second argument.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+vec.resize_with(5, Default::default);
+assert_eq!(vec, [1, 2, 3, 0, 0]);
+
+let mut vec = vec![];
+let mut p = 1;
+vec.resize_with(4, || { p *= 2; p });
+assert_eq!(vec, [2, 4, 8, 16]);
+
1.60.0 · source

pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>]

Returns the remaining spare capacity of the vector as a slice of +MaybeUninit<T>.

+

The returned slice can be used to fill the vector with data (e.g. by +reading from a file) before marking the data as initialized using the +set_len method.

+
§Examples
+
// Allocate vector big enough for 10 elements.
+let mut v = Vec::with_capacity(10);
+
+// Fill in the first 3 elements.
+let uninit = v.spare_capacity_mut();
+uninit[0].write(0);
+uninit[1].write(1);
+uninit[2].write(2);
+
+// Mark the first 3 elements of the vector as being initialized.
+unsafe {
+    v.set_len(3);
+}
+
+assert_eq!(&v, &[0, 1, 2]);
+
source

pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>])

🔬This is a nightly-only experimental API. (vec_split_at_spare)

Returns vector content as a slice of T, along with the remaining spare +capacity of the vector as a slice of MaybeUninit<T>.

+

The returned spare capacity slice can be used to fill the vector with data +(e.g. by reading from a file) before marking the data as initialized using +the set_len method.

+

Note that this is a low-level API, which should be used with care for +optimization purposes. If you need to append data to a Vec +you can use push, extend, extend_from_slice, +extend_from_within, insert, append, resize or +resize_with, depending on your exact needs.

+
§Examples
+
#![feature(vec_split_at_spare)]
+
+let mut v = vec![1, 1, 2];
+
+// Reserve additional space big enough for 10 elements.
+v.reserve(10);
+
+let (init, uninit) = v.split_at_spare_mut();
+let sum = init.iter().copied().sum::<u32>();
+
+// Fill in the next 4 elements.
+uninit[0].write(sum);
+uninit[1].write(sum * 2);
+uninit[2].write(sum * 3);
+uninit[3].write(sum * 4);
+
+// Mark the 4 elements of the vector as being initialized.
+unsafe {
+    let len = v.len();
+    v.set_len(len + 4);
+}
+
+assert_eq!(&v, &[1, 1, 2, 4, 8, 12, 16]);
+
1.5.0 · source

pub fn resize(&mut self, new_len: usize, value: T)

Available on non-no_global_oom_handling only.

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with value. +If new_len is less than len, the Vec is simply truncated.

+

This method requires T to implement Clone, +in order to be able to clone the passed value. +If you need more flexibility (or want to rely on Default instead of +Clone), use Vec::resize_with. +If you only need to resize to a smaller size, use Vec::truncate.

+
§Examples
+
let mut vec = vec!["hello"];
+vec.resize(3, "world");
+assert_eq!(vec, ["hello", "world", "world"]);
+
+let mut vec = vec![1, 2, 3, 4];
+vec.resize(2, 0);
+assert_eq!(vec, [1, 2]);
+
1.6.0 · source

pub fn extend_from_slice(&mut self, other: &[T])

Available on non-no_global_oom_handling only.

Clones and appends all elements in a slice to the Vec.

+

Iterates over the slice other, clones each element, and then appends +it to this Vec. The other slice is traversed in-order.

+

Note that this function is same as extend except that it is +specialized to work with slices instead. If and when Rust gets +specialization this function will likely be deprecated (but still +available).

+
§Examples
+
let mut vec = vec![1];
+vec.extend_from_slice(&[2, 3, 4]);
+assert_eq!(vec, [1, 2, 3, 4]);
+
1.53.0 · source

pub fn extend_from_within<R>(&mut self, src: R)
where + R: RangeBounds<usize>,

Available on non-no_global_oom_handling only.

Copies elements from src range to the end of the vector.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Examples
+
let mut vec = vec![0, 1, 2, 3, 4];
+
+vec.extend_from_within(2..);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
+
+vec.extend_from_within(..2);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
+
+vec.extend_from_within(4..8);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
+
1.0.0 · source

pub fn dedup(&mut self)

Removes consecutive repeated elements in the vector according to the +PartialEq trait implementation.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec![1, 2, 2, 3, 2];
+
+vec.dedup();
+
+assert_eq!(vec, [1, 2, 3, 2]);
+
1.21.0 · source

pub fn splice<R, I>( + &mut self, + range: R, + replace_with: I +) -> Splice<'_, <I as IntoIterator>::IntoIter, A>
where + R: RangeBounds<usize>, + I: IntoIterator<Item = T>,

Available on non-no_global_oom_handling only.

Creates a splicing iterator that replaces the specified range in the vector +with the given replace_with iterator and yields the removed items. +replace_with does not need to be the same length as range.

+

range is removed even if the iterator is not consumed until the end.

+

It is unspecified how many elements are removed from the vector +if the Splice value is leaked.

+

The input iterator replace_with is only consumed when the Splice value is dropped.

+

This is optimal if:

+
    +
  • The tail (elements in the vector after range) is empty,
  • +
  • or replace_with yields fewer or equal elements than range’s length
  • +
  • or the lower bound of its size_hint() is exact.
  • +
+

Otherwise, a temporary vector is allocated and the tail is moved twice.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Examples
+
let mut v = vec![1, 2, 3, 4];
+let new = [7, 8, 9];
+let u: Vec<_> = v.splice(1..3, new).collect();
+assert_eq!(v, &[1, 7, 8, 9, 4]);
+assert_eq!(u, &[2, 3]);
+
source

pub fn extract_if<F>(&mut self, filter: F) -> ExtractIf<'_, T, F, A>
where + F: FnMut(&mut T) -> bool,

🔬This is a nightly-only experimental API. (extract_if)

Creates an iterator which uses a closure to determine if an element should be removed.

+

If the closure returns true, then the element is removed and yielded. +If the closure returns false, the element will remain in the vector and will not be yielded +by the iterator.

+

If the returned ExtractIf is not exhausted, e.g. because it is dropped without iterating +or the iteration short-circuits, then the remaining elements will be retained. +Use retain with a negated predicate if you do not need the returned iterator.

+

Using this method is equivalent to the following code:

+ +
let mut i = 0;
+while i < vec.len() {
+    if some_predicate(&mut vec[i]) {
+        let val = vec.remove(i);
+        // your code here
+    } else {
+        i += 1;
+    }
+}
+
+

But extract_if is easier to use. extract_if is also more efficient, +because it can backshift the elements of the array in bulk.

+

Note that extract_if also lets you mutate every element in the filter closure, +regardless of whether you choose to keep or remove it.

+
§Examples
+

Splitting an array into evens and odds, reusing the original allocation:

+ +
#![feature(extract_if)]
+let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];
+
+let evens = numbers.extract_if(|x| *x % 2 == 0).collect::<Vec<_>>();
+let odds = numbers;
+
+assert_eq!(evens, vec![2, 4, 6, 8, 14]);
+assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]);
+

Methods from Deref<Target = [T]>§

1.80.0 · source

pub fn as_flattened(&self) -> &[T]

Takes a &[[T; N]], and flattens it to a &[T].

+
§Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
§Examples
+
assert_eq!([[1, 2, 3], [4, 5, 6]].as_flattened(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+    [[1, 2, 3], [4, 5, 6]].as_flattened(),
+    [[1, 2], [3, 4], [5, 6]].as_flattened(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.as_flattened().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.as_flattened().is_empty());
+
1.80.0 · source

pub fn as_flattened_mut(&mut self) -> &mut [T]

Takes a &mut [[T; N]], and flattens it to a &mut [T].

+
§Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
§Examples
+
fn add_5_to_all(slice: &mut [i32]) {
+    for i in slice {
+        *i += 5;
+    }
+}
+
+let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
+add_5_to_all(array.as_flattened_mut());
+assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f32::total_cmp.

+
§Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
§Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the slice.

+
§Examples
+
let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the slice has a length of 0.

+
§Examples
+
let a = [1, 2, 3];
+assert!(!a.is_empty());
+
+let b: &[i32] = &[];
+assert!(b.is_empty());
+
1.0.0 · source

pub fn first(&self) -> Option<&T>

Returns the first element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
+
1.0.0 · source

pub fn first_mut(&mut self) -> Option<&mut T>

Returns a mutable pointer to the first element of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_mut() {
+    *first = 5;
+}
+assert_eq!(x, &[5, 1, 2]);
+
+let y: &mut [i32] = &mut [];
+assert_eq!(None, y.first_mut());
+
1.5.0 · source

pub fn split_first(&self) -> Option<(&T, &[T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first() {
+    assert_eq!(first, &0);
+    assert_eq!(elements, &[1, 2]);
+}
+
1.5.0 · source

pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_mut() {
+    *first = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
1.5.0 · source

pub fn split_last(&self) -> Option<(&T, &[T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+    assert_eq!(last, &2);
+    assert_eq!(elements, &[0, 1]);
+}
+
1.5.0 · source

pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_mut() {
+    *last = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[4, 5, 3]);
+
1.0.0 · source

pub fn last(&self) -> Option<&T>

Returns the last element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
+
1.0.0 · source

pub fn last_mut(&mut self) -> Option<&mut T>

Returns a mutable reference to the last item in the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_mut() {
+    *last = 10;
+}
+assert_eq!(x, &[0, 1, 10]);
+
+let y: &mut [i32] = &mut [];
+assert_eq!(None, y.last_mut());
+
1.77.0 · source

pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the first N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.first_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.first_chunk::<0>());
+
1.77.0 · source

pub fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

Return a mutable array reference to the first N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_chunk_mut::<2>() {
+    first[0] = 5;
+    first[1] = 4;
+}
+assert_eq!(x, &[5, 4, 2]);
+
+assert_eq!(None, x.first_chunk_mut::<4>());
+
1.77.0 · source

pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

Return an array reference to the first N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk::<2>() {
+    assert_eq!(first, &[0, 1]);
+    assert_eq!(elements, &[2]);
+}
+
+assert_eq!(None, x.split_first_chunk::<4>());
+
1.77.0 · source

pub fn split_first_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T; N], &mut [T])>

Return a mutable array reference to the first N items in the slice and the remaining +slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk_mut::<2>() {
+    first[0] = 3;
+    first[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
+assert_eq!(None, x.split_first_chunk_mut::<4>());
+
1.77.0 · source

pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>

Return an array reference to the last N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((elements, last)) = x.split_last_chunk::<2>() {
+    assert_eq!(elements, &[0]);
+    assert_eq!(last, &[1, 2]);
+}
+
+assert_eq!(None, x.split_last_chunk::<4>());
+
1.77.0 · source

pub fn split_last_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T], &mut [T; N])>

Return a mutable array reference to the last N items in the slice and the remaining +slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((elements, last)) = x.split_last_chunk_mut::<2>() {
+    last[0] = 3;
+    last[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[5, 3, 4]);
+
+assert_eq!(None, x.split_last_chunk_mut::<4>());
+
1.77.0 · source

pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the last N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.last_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.last_chunk::<0>());
+
1.77.0 · source

pub fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

Return a mutable array reference to the last N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_chunk_mut::<2>() {
+    last[0] = 10;
+    last[1] = 20;
+}
+assert_eq!(x, &[0, 10, 20]);
+
+assert_eq!(None, x.last_chunk_mut::<4>());
+
1.0.0 · source

pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice depending on the type of +index.

+
    +
  • If given a position, returns a reference to the element at that +position or None if out of bounds.
  • +
  • If given a range, returns the subslice corresponding to that range, +or None if out of bounds.
  • +
+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
+
1.0.0 · source

pub fn get_mut<I>( + &mut self, + index: I +) -> Option<&mut <I as SliceIndex<[T]>>::Output>
where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice depending on the +type of index (see get) or None if the index is out of bounds.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(elem) = x.get_mut(1) {
+    *elem = 42;
+}
+assert_eq!(x, &[0, 42, 2]);
+
1.0.0 · source

pub unsafe fn get_unchecked<I>( + &self, + index: I +) -> &<I as SliceIndex<[T]>>::Output
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice, without doing bounds +checking.

+

For a safe alternative see get.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get(index).unwrap_unchecked(). It’s UB +to call .get_unchecked(len), even if you immediately convert to a +pointer. And it’s UB to call .get_unchecked(..len + 1), +.get_unchecked(..=len), or similar.

+
§Examples
+
let x = &[1, 2, 4];
+
+unsafe {
+    assert_eq!(x.get_unchecked(1), &2);
+}
+
1.0.0 · source

pub unsafe fn get_unchecked_mut<I>( + &mut self, + index: I +) -> &mut <I as SliceIndex<[T]>>::Output
where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice, without doing +bounds checking.

+

For a safe alternative see get_mut.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get_mut(index).unwrap_unchecked(). It’s +UB to call .get_unchecked_mut(len), even if you immediately convert +to a pointer. And it’s UB to call .get_unchecked_mut(..len + 1), +.get_unchecked_mut(..=len), or similar.

+
§Examples
+
let x = &mut [1, 2, 4];
+
+unsafe {
+    let elem = x.get_unchecked_mut(1);
+    *elem = 13;
+}
+assert_eq!(x, &[1, 13, 4]);
+
1.0.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
§Examples
+
let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+    }
+}
+
1.0.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
§Examples
+
let x = &mut [1, 2, 4];
+let x_ptr = x.as_mut_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        *x_ptr.add(i) += 2;
+    }
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.48.0 · source

pub fn as_ptr_range(&self) -> Range<*const T>

Returns the two raw pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_ptr for warnings on using these pointers. The end pointer +requires extra caution, as it does not point to a valid element in the +slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+

It can also be useful to check if a pointer to an element refers to an +element of this slice:

+ +
let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
+
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
+
1.48.0 · source

pub fn as_mut_ptr_range(&mut self) -> Range<*mut T>

Returns the two unsafe mutable pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_mut_ptr for warnings on using these pointers. The end +pointer requires extra caution, as it does not point to a valid element +in the slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+
1.0.0 · source

pub fn swap(&mut self, a: usize, b: usize)

Swaps two elements in the slice.

+

If a equals to b, it’s guaranteed that elements won’t change value.

+
§Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
§Panics
+

Panics if a or b are out of bounds.

+
§Examples
+
let mut v = ["a", "b", "c", "d", "e"];
+v.swap(2, 4);
+assert!(v == ["a", "b", "e", "d", "c"]);
+
source

pub unsafe fn swap_unchecked(&mut self, a: usize, b: usize)

🔬This is a nightly-only experimental API. (slice_swap_unchecked)

Swaps two elements in the slice, without doing bounds checking.

+

For a safe alternative see swap.

+
§Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior. +The caller has to ensure that a < self.len() and b < self.len().

+
§Examples
+
#![feature(slice_swap_unchecked)]
+
+let mut v = ["a", "b", "c", "d"];
+// SAFETY: we know that 1 and 3 are both indices of the slice
+unsafe { v.swap_unchecked(1, 3) };
+assert!(v == ["a", "d", "c", "b"]);
+
1.0.0 · source

pub fn reverse(&mut self)

Reverses the order of elements in the slice, in place.

+
§Examples
+
let mut v = [1, 2, 3];
+v.reverse();
+assert!(v == [3, 2, 1]);
+
1.0.0 · source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the slice.

+

The iterator yields all items from start to end.

+
§Examples
+
let x = &[1, 2, 4];
+let mut iterator = x.iter();
+
+assert_eq!(iterator.next(), Some(&1));
+assert_eq!(iterator.next(), Some(&2));
+assert_eq!(iterator.next(), Some(&4));
+assert_eq!(iterator.next(), None);
+
1.0.0 · source

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Returns an iterator that allows modifying each value.

+

The iterator yields all items from start to end.

+
§Examples
+
let x = &mut [1, 2, 4];
+for elem in x.iter_mut() {
+    *elem += 2;
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.0.0 · source

pub fn windows(&self, size: usize) -> Windows<'_, T>

Returns an iterator over all contiguous windows of length +size. The windows overlap. If the slice is shorter than +size, the iterator returns no values.

+
§Panics
+

Panics if size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.windows(3);
+assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']);
+assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']);
+assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']);
+assert!(iter.next().is_none());
+

If the slice is shorter than size:

+ +
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
+

There’s no windows_mut, as that existing would let safe code violate the +“only one &mut at a time to the same thing” rule. However, you can sometimes +use Cell::as_slice_of_cells in +conjunction with windows to accomplish something similar:

+ +
use std::cell::Cell;
+
+let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
+let slice = &mut array[..];
+let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
+for w in slice_of_cells.windows(3) {
+    Cell::swap(&w[0], &w[2]);
+}
+assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
+
1.0.0 · source

pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See chunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and rchunks for the same iterator but starting at the end of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See chunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and rchunks_mut for the same iterator but starting at +the end of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 3]);
+
1.31.0 · source

pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks.

+

See chunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
1.31.0 · source

pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See chunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and rchunks_exact_mut for the same iterator but starting at the end of +the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
§Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
§Examples
+
#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+
source

pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
+

If you expect the slice to be an exact multiple, you can combine +let-else with an empty slice pattern:

+ +
#![feature(slice_as_chunks)]
+let slice = ['R', 'u', 's', 't'];
+let (chunks, []) = slice.as_chunks::<2>() else {
+    panic!("slice didn't have even length")
+};
+assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
+
source

pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+
source

pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are array references and do not overlap. If N does not divide the +length of the slice, then the last up to N-1 elements will be omitted and can be +retrieved from the remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
source

pub unsafe fn as_chunks_unchecked_mut<const N: usize>( + &mut self +) -> &mut [[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
§Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
§Examples
+
#![feature(slice_as_chunks)]
+let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &mut [[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[0] = ['L'];
+assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &mut [[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[1] = ['a', 'x', '?'];
+assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
+
source

pub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (chunks, remainder) = v.as_chunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 9]);
+
source

pub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (remainder, chunks) = v.as_rchunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[9, 1, 1, 2, 2]);
+
source

pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable array references and do not overlap. If N does not divide +the length of the slice, then the last up to N-1 elements will be omitted and +can be retrieved from the into_remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact_mut.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.array_chunks_mut() {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>

🔬This is a nightly-only experimental API. (array_windows)

Returns an iterator over overlapping windows of N elements of a slice, +starting at the beginning of the slice.

+

This is the const generic equivalent of windows.

+

If N is greater than the size of the slice, it will return no windows.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and chunks for the same iterator but starting at the beginning +of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and chunks_mut for the same iterator but starting at the +beginning of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[3, 2, 2, 1, 1]);
+
1.31.0 · source

pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +end of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of rchunks.

+

See rchunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and chunks_exact for the same iterator but starting at the beginning of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
+
1.31.0 · source

pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See rchunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and chunks_exact_mut for the same iterator but starting at the beginning +of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[0, 2, 2, 1, 1]);
+
1.77.0 · source

pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
where + F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping runs +of elements using the predicate to separate them.

+

The predicate is called for every pair of consecutive elements, +meaning that it is called on slice[0] and slice[1], +followed by slice[1] and slice[2], and so on.

+
§Examples
+
let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.chunk_by(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.chunk_by(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.77.0 · source

pub fn chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F>
where + F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping mutable +runs of elements using the predicate to separate them.

+

The predicate is called for every pair of consecutive elements, +meaning that it is called on slice[0] and slice[1], +followed by slice[1] and slice[2], and so on.

+
§Examples
+
let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.chunk_by_mut(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&mut [3, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.chunk_by_mut(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.0.0 · source

pub fn split_at(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
§Panics
+

Panics if mid > len. For a non-panicking alternative see +split_at_checked.

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+{
+   let (left, right) = v.split_at(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.0.0 · source

pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
§Panics
+

Panics if mid > len. For a non-panicking alternative see +split_at_mut_checked.

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+let (left, right) = v.split_at_mut(2);
+assert_eq!(left, [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.79.0 · source

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+unsafe {
+   let (left, right) = v.split_at_unchecked(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.79.0 · source

pub unsafe fn split_at_mut_unchecked( + &mut self, + mid: usize +) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at_mut.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+// scoped to restrict the lifetime of the borrows
+unsafe {
+    let (left, right) = v.split_at_mut_unchecked(2);
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.80.0 · source

pub fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])>

Divides one slice into two at an index, returning None if the slice is +too short.

+

If mid ≤ len returns a pair of slices where the first will contain all +indices from [0, mid) (excluding the index mid itself) and the +second will contain all indices from [mid, len) (excluding the index +len itself).

+

Otherwise, if mid > len, returns None.

+
§Examples
+
let v = [1, -2, 3, -4, 5, -6];
+
+{
+   let (left, right) = v.split_at_checked(0).unwrap();
+   assert_eq!(left, []);
+   assert_eq!(right, [1, -2, 3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(2).unwrap();
+    assert_eq!(left, [1, -2]);
+    assert_eq!(right, [3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(6).unwrap();
+    assert_eq!(left, [1, -2, 3, -4, 5, -6]);
+    assert_eq!(right, []);
+}
+
+assert_eq!(None, v.split_at_checked(7));
+
1.80.0 · source

pub fn split_at_mut_checked( + &mut self, + mid: usize +) -> Option<(&mut [T], &mut [T])>

Divides one mutable slice into two at an index, returning None if the +slice is too short.

+

If mid ≤ len returns a pair of slices where the first will contain all +indices from [0, mid) (excluding the index mid itself) and the +second will contain all indices from [mid, len) (excluding the index +len itself).

+

Otherwise, if mid > len, returns None.

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+
+if let Some((left, right)) = v.split_at_mut_checked(2) {
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
+assert_eq!(None, v.split_at_mut_checked(7));
+
1.0.0 · source

pub fn split<F>(&self, pred: F) -> Split<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is not contained in the subslices.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the first element is matched, an empty slice will be the first item +returned by the iterator. Similarly, if the last element in the slice +is matched, an empty slice will be the last item returned by the +iterator:

+ +
let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
+

If two matched elements are directly adjacent, an empty slice will be +present between them:

+ +
let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is not contained in the subslices.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_mut(|num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 1]);
+
1.51.0 · source

pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is contained in the end of the previous +subslice as a terminator.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the last element of the slice is matched, +that element will be considered the terminator of the preceding slice. +That slice will be the last item returned by the iterator.

+ +
let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
+
1.51.0 · source

pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is contained in the previous +subslice as a terminator.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
+    let terminator_idx = group.len()-1;
+    group[terminator_idx] = 1;
+}
+assert_eq!(v, [10, 40, 1, 20, 1, 1]);
+
1.27.0 · source

pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, starting at the end of the slice and working backwards. +The matched element is not contained in the subslices.

+
§Examples
+
let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
+
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
+

As with split(), if the first or last element is matched, an empty +slice will be the first (or last) item returned by the iterator.

+ +
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
+
1.27.0 · source

pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred, starting at the end of the slice and working +backwards. The matched element is not contained in the subslices.

+
§Examples
+
let mut v = [100, 400, 300, 200, 600, 500];
+
+let mut count = 0;
+for group in v.rsplit_mut(|num| *num % 3 == 0) {
+    count += 1;
+    group[0] = count;
+}
+assert_eq!(v, [3, 400, 300, 2, 600, 1]);
+
1.0.0 · source

pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], +[20, 60, 50]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 50]);
+
1.0.0 · source

pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once, starting from the end, by numbers divisible +by 3 (i.e., [50], [10, 40, 30, 20]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+
let mut s = [10, 40, 30, 20, 60, 50];
+
+for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(s, [1, 40, 30, 20, 60, 1]);
+
source

pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the first element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.split_once(|&x| x == 2), Some((
+    &[1][..],
+    &[3, 2, 4][..]
+)));
+assert_eq!(s.split_once(|&x| x == 0), None);
+
source

pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the last element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.rsplit_once(|&x| x == 2), Some((
+    &[1, 2, 3][..],
+    &[4][..]
+)));
+assert_eq!(s.rsplit_once(|&x| x == 0), None);
+
1.0.0 · source

pub fn contains(&self, x: &T) -> bool
where + T: PartialEq,

Returns true if the slice contains an element with the given value.

+

This operation is O(n).

+

Note that if you have a sorted slice, binary_search may be faster.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
+

If you do not have a &T, but some other value that you can compare +with one (for example, String implements PartialEq<str>), you can +use iter().any:

+ +
let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
+
1.0.0 · source

pub fn starts_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a prefix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(v.starts_with(&v));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
+
1.0.0 · source

pub fn ends_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a suffix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(v.ends_with(&v));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
+
1.51.0 · source

pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the prefix removed.

+

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. +If prefix is empty, simply returns the original slice. If prefix is equal to the +original slice, returns an empty slice.

+

If the slice does not start with prefix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
+
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+           Some(b"llo".as_ref()));
+
1.51.0 · source

pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the suffix removed.

+

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. +If suffix is empty, simply returns the original slice. If suffix is equal to the +original slice, returns an empty slice.

+

If the slice does not end with suffix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
+

Binary searches this slice for a given element. +If the slice is not sorted, the returned result is unspecified and +meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search_by, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+assert_eq!(s.binary_search(&13),  Ok(9));
+assert_eq!(s.binary_search(&4),   Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

If you want to find that whole range of matching items, rather than +an arbitrary matching one, that can be done using partition_point:

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
+

If you want to insert an item to a sorted vector, while maintaining +sort order, consider using partition_point:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+// If `num` is unique, `s.partition_point(|&x| x < num)` (with `<`) is equivalent to
+// `s.binary_search(&num).unwrap_or_else(|x| x)`, but using `<=` will allow `insert`
+// to shift less elements.
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
1.0.0 · source

pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
where + F: FnMut(&'a T) -> Ordering,

Binary searches this slice with a comparator function.

+

The comparator function should return an order code that indicates +whether its argument is Less, Equal or Greater the desired +target. +If the slice is not sorted or if the comparator function does not +implement an order consistent with the sort order of the underlying +slice, the returned result is unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.10.0 · source

pub fn binary_search_by_key<'a, B, F>( + &'a self, + b: &B, + f: F +) -> Result<usize, usize>
where + F: FnMut(&'a T) -> B, + B: Ord,

Binary searches this slice with a key extraction function.

+

Assumes that the slice is sorted by the key, for instance with +sort_by_key using the same key extraction function. +If the slice is not sorted by the key, the returned result is +unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by, and partition_point.

+
§Examples
+

Looks up a series of four elements in a slice of pairs sorted by +their second elements. The first is found, with a uniquely +determined position; the second and third are not found; the +fourth could match any position in [1, 4].

+ +
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+         (1, 21), (2, 34), (4, 55)];
+
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.20.0 · source

pub fn sort_unstable(&mut self)
where + T: Ord,

Sorts the slice, but might not preserve the order of equal elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
§Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort_unstable();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.20.0 · source

pub fn sort_unstable_by<F>(&mut self, compare: F)
where + F: FnMut(&T, &T) -> Ordering,

Sorts the slice with a comparator function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
§Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_unstable_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_unstable_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.20.0 · source

pub fn sort_unstable_by_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(m * n * log(n)) worst-case, where the key function is +O(m).

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

Due to its key calling strategy, sort_unstable_by_key +is likely to be slower than sort_by_cached_key in +cases where the key function is expensive.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_unstable_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.49.0 · source

pub fn select_nth_unstable( + &mut self, + index: usize +) -> (&mut [T], &mut T, &mut [T])
where + T: Ord,

Reorder the slice such that the element at index after the reordering is at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index. Additionally, this reordering is +unstable (i.e. any number of equal elements may end up at position index), in-place +(i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from the reordered slice: +the subslice prior to index, the element at index, and the subslice after index; +accordingly, the values in those two subslices will respectively all be less-than-or-equal-to +and greater-than-or-equal-to the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 2, -3, 1];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median.
+let (lesser, median, greater) = v.select_nth_unstable(2);
+
+assert!(lesser == [-3, -5] || lesser == [-5, -3]);
+assert_eq!(median, &mut 1);
+assert!(greater == [4, 2] || greater == [2, 4]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [-3, -5, 1, 2, 4] ||
+        v == [-5, -3, 1, 2, 4] ||
+        v == [-3, -5, 1, 4, 2] ||
+        v == [-5, -3, 1, 4, 2]);
+
1.49.0 · source

pub fn select_nth_unstable_by<F>( + &mut self, + index: usize, + compare: F +) -> (&mut [T], &mut T, &mut [T])
where + F: FnMut(&T, &T) -> Ordering,

Reorder the slice with a comparator function such that the element at index after the reordering is at +its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the comparator function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided comparator function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 2, -3, 1];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median as if the slice were sorted in descending order.
+let (lesser, median, greater) = v.select_nth_unstable_by(2, |a, b| b.cmp(a));
+
+assert!(lesser == [4, 2] || lesser == [2, 4]);
+assert_eq!(median, &mut 1);
+assert!(greater == [-3, -5] || greater == [-5, -3]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [2, 4, 1, -5, -3] ||
+        v == [2, 4, 1, -3, -5] ||
+        v == [4, 2, 1, -5, -3] ||
+        v == [4, 2, 1, -3, -5]);
+
1.49.0 · source

pub fn select_nth_unstable_by_key<K, F>( + &mut self, + index: usize, + f: F +) -> (&mut [T], &mut T, &mut [T])
where + F: FnMut(&T) -> K, + K: Ord,

Reorder the slice with a key extraction function such that the element at index after the reordering is +at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the key extraction function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided key extraction function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median as if the slice were sorted according to absolute value.
+let (lesser, median, greater) = v.select_nth_unstable_by_key(2, |a| a.abs());
+
+assert!(lesser == [1, 2] || lesser == [2, 1]);
+assert_eq!(median, &mut -3);
+assert!(greater == [4, -5] || greater == [-5, 4]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [1, 2, -3, 4, -5] ||
+        v == [1, 2, -3, -5, 4] ||
+        v == [2, 1, -3, 4, -5] ||
+        v == [2, 1, -3, -5, 4]);
+
source

pub fn partition_dedup(&mut self) -> (&mut [T], &mut [T])
where + T: PartialEq,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all consecutive repeated elements to the end of the slice according to the +PartialEq trait implementation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
+
+let (dedup, duplicates) = slice.partition_dedup();
+
+assert_eq!(dedup, [1, 2, 3, 2, 1]);
+assert_eq!(duplicates, [2, 3, 1]);
+
source

pub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T])
where + F: FnMut(&mut T, &mut T) -> bool,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice satisfying +a given equality relation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

The same_bucket function is passed references to two elements from the slice and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is moved +at the end of the slice.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
+
+let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
+assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
+
source

pub fn partition_dedup_by_key<K, F>(&mut self, key: F) -> (&mut [T], &mut [T])
where + F: FnMut(&mut T) -> K, + K: PartialEq,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice that resolve +to the same key.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
+
+let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
+
+assert_eq!(dedup, [10, 20, 30, 20, 11]);
+assert_eq!(duplicates, [21, 30, 13]);
+
1.26.0 · source

pub fn rotate_left(&mut self, mid: usize)

Rotates the slice in-place such that the first mid elements of the +slice move to the end while the last self.len() - mid elements move to +the front. After calling rotate_left, the element previously at index +mid will become the first element in the slice.

+
§Panics
+

This function will panic if mid is greater than the length of the +slice. Note that mid == self.len() does not panic and is a no-op +rotation.

+
§Complexity
+

Takes linear (in self.len()) time.

+
§Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_left(2);
+assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_left(1);
+assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+
1.26.0 · source

pub fn rotate_right(&mut self, k: usize)

Rotates the slice in-place such that the first self.len() - k +elements of the slice move to the end while the last k elements move +to the front. After calling rotate_right, the element previously at +index self.len() - k will become the first element in the slice.

+
§Panics
+

This function will panic if k is greater than the length of the +slice. Note that k == self.len() does not panic and is a no-op +rotation.

+
§Complexity
+

Takes linear (in self.len()) time.

+
§Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_right(2);
+assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_right(1);
+assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
+
1.50.0 · source

pub fn fill(&mut self, value: T)
where + T: Clone,

Fills self with elements by cloning value.

+
§Examples
+
let mut buf = vec![0; 10];
+buf.fill(1);
+assert_eq!(buf, vec![1; 10]);
+
1.51.0 · source

pub fn fill_with<F>(&mut self, f: F)
where + F: FnMut() -> T,

Fills self with elements returned by calling a closure repeatedly.

+

This method uses a closure to create new values. If you’d rather +Clone a given value, use fill. If you want to use the Default +trait to generate values, you can pass Default::default as the +argument.

+
§Examples
+
let mut buf = vec![1; 10];
+buf.fill_with(Default::default);
+assert_eq!(buf, vec![0; 10]);
+
1.7.0 · source

pub fn clone_from_slice(&mut self, src: &[T])
where + T: Clone,

Copies the elements from src into self.

+

The length of src must be the same as self.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Examples
+

Cloning two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.clone_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use clone_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].clone_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.clone_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.9.0 · source

pub fn copy_from_slice(&mut self, src: &[T])
where + T: Copy,

Copies all elements from src into self, using a memcpy.

+

The length of src must be the same as self.

+

If T does not implement Copy, use clone_from_slice.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Examples
+

Copying two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.copy_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use copy_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].copy_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.copy_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.37.0 · source

pub fn copy_within<R>(&mut self, src: R, dest: usize)
where + R: RangeBounds<usize>, + T: Copy,

Copies elements from one part of the slice to another part of itself, +using a memmove.

+

src is the range within self to copy from. dest is the starting +index of the range within self to copy to, which will have the same +length as src. The two ranges may overlap. The ends of the two ranges +must be less than or equal to self.len().

+
§Panics
+

This function will panic if either range exceeds the end of the slice, +or if the end of src is before the start.

+
§Examples
+

Copying four bytes within a slice:

+ +
let mut bytes = *b"Hello, World!";
+
+bytes.copy_within(1..5, 8);
+
+assert_eq!(&bytes, b"Hello, Wello!");
+
1.27.0 · source

pub fn swap_with_slice(&mut self, other: &mut [T])

Swaps all elements in self with those in other.

+

The length of other must be the same as self.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Example
+

Swapping two elements across slices:

+ +
let mut slice1 = [0, 0];
+let mut slice2 = [1, 2, 3, 4];
+
+slice1.swap_with_slice(&mut slice2[2..]);
+
+assert_eq!(slice1, [3, 4]);
+assert_eq!(slice2, [1, 2, 0, 0]);
+

Rust enforces that there can only be one mutable reference to a +particular piece of data in a particular scope. Because of this, +attempting to use swap_with_slice on a single slice will result in +a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +mutable sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.swap_with_slice(&mut right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 1, 2]);
+
1.30.0 · source

pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

Transmute the slice to a slice of another type, ensuring alignment of the types is +maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The middle part will be as big as possible under +the given alignment constraint and element size.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
§Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
§Examples
+

Basic usage:

+ +
unsafe {
+    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
1.30.0 · source

pub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T])

Transmute the mutable slice to a mutable slice of another type, ensuring alignment of the +types is maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The middle part will be as big as possible under +the given alignment constraint and element size.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
§Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
§Examples
+

Basic usage:

+ +
unsafe {
+    let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
source

pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
where + Simd<T, LANES>: AsRef<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.

+

This is a safe wrapper around slice::align_to, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+
§Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
§Examples
+
#![feature(portable_simd)]
+use core::simd::prelude::*;
+
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
+
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+
+fn basic_simd_sum(x: &[f32]) -> f32 {
+    use std::ops::Add;
+    let (prefix, middle, suffix) = x.as_simd();
+    let sums = f32x4::from_array([
+        prefix.iter().copied().sum(),
+        0.0,
+        0.0,
+        suffix.iter().copied().sum(),
+    ]);
+    let sums = middle.iter().copied().fold(sums, f32x4::add);
+    sums.reduce_sum()
+}
+
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+
source

pub fn as_simd_mut<const LANES: usize>( + &mut self +) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T])
where + Simd<T, LANES>: AsMut<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a mutable slice into a mutable prefix, a middle of aligned SIMD types, +and a mutable suffix.

+

This is a safe wrapper around slice::align_to_mut, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+

This is the mutable version of slice::as_simd; see that for examples.

+
§Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
source

pub fn is_sorted(&self) -> bool
where + T: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted.

+

That is, for each element a and its following element b, a <= b must hold. If the +slice yields exactly zero or one element, true is returned.

+

Note that if Self::Item is only PartialOrd, but not Ord, the above definition +implies that this function returns false if any two consecutive items are not +comparable.

+
§Examples
+
#![feature(is_sorted)]
+let empty: [i32; 0] = [];
+
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
+
source

pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> bool
where + F: FnMut(&'a T, &'a T) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given comparator function.

+

Instead of using PartialOrd::partial_cmp, this function uses the given compare +function to determine whether two elements are to be considered in sorted order.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!([1, 2, 2, 9].is_sorted_by(|a, b| a <= b));
+assert!(![1, 2, 2, 9].is_sorted_by(|a, b| a < b));
+
+assert!([0].is_sorted_by(|a, b| true));
+assert!([0].is_sorted_by(|a, b| false));
+
+let empty: [i32; 0] = [];
+assert!(empty.is_sorted_by(|a, b| false));
+assert!(empty.is_sorted_by(|a, b| true));
+
source

pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
where + F: FnMut(&'a T) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given key extraction function.

+

Instead of comparing the slice’s elements directly, this function compares the keys of the +elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its +documentation for more information.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+
1.52.0 · source

pub fn partition_point<P>(&self, pred: P) -> usize
where + P: FnMut(&T) -> bool,

Returns the index of the partition point according to the given predicate +(the index of the first element of the second partition).

+

The slice is assumed to be partitioned according to the given predicate. +This means that all elements for which the predicate returns true are at the start of the slice +and all elements for which the predicate returns false are at the end. +For example, [7, 15, 3, 5, 4, 12, 6] is partitioned under the predicate x % 2 != 0 +(all odd numbers are at the start, all even at the end).

+

If this slice is not partitioned, the returned result is unspecified and meaningless, +as this method performs a kind of binary search.

+

See also binary_search, binary_search_by, and binary_search_by_key.

+
§Examples
+
let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
+
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
+

If all elements of the slice match the predicate, including if the slice +is empty, then the length of the slice will be returned:

+ +
let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
+

If you want to insert an item to a sorted vector, while maintaining +sort order:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
source

pub fn take<'a, R>(self: &mut &'a [T], range: R) -> Option<&'a [T]>
where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
§Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut first_three = slice.take(..3).unwrap();
+
+assert_eq!(slice, &['d']);
+assert_eq!(first_three, &['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut tail = slice.take(2..).unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(tail, &['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take(5..));
+assert_eq!(None, slice.take(..5));
+assert_eq!(None, slice.take(..=4));
+let expected: &[char] = &['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take(..4));
+
source

pub fn take_mut<'a, R>(self: &mut &'a mut [T], range: R) -> Option<&'a mut [T]>
where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a mutable reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
§Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut first_three = slice.take_mut(..3).unwrap();
+
+assert_eq!(slice, &mut ['d']);
+assert_eq!(first_three, &mut ['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut tail = slice.take_mut(2..).unwrap();
+
+assert_eq!(slice, &mut ['a', 'b']);
+assert_eq!(tail, &mut ['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take_mut(5..));
+assert_eq!(None, slice.take_mut(..5));
+assert_eq!(None, slice.take_mut(..=4));
+let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take_mut(..4));
+
source

pub fn take_first<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let first = slice.take_first().unwrap();
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'a');
+
source

pub fn take_first_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let first = slice.take_first_mut().unwrap();
+*first = 'd';
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'d');
+
source

pub fn take_last<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let last = slice.take_last().unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'c');
+
source

pub fn take_last_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let last = slice.take_last_mut().unwrap();
+*last = 'd';
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'d');
+
source

pub unsafe fn get_many_unchecked_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> [&mut T; N]

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once, without doing any checks.

+

For a safe alternative see get_many_mut.

+
§Safety
+

Calling this method with overlapping or out-of-bounds indices is undefined behavior +even if the resulting references are not used.

+
§Examples
+
#![feature(get_many_mut)]
+
+let x = &mut [1, 2, 4];
+
+unsafe {
+    let [a, b] = x.get_many_unchecked_mut([0, 2]);
+    *a *= 10;
+    *b *= 100;
+}
+assert_eq!(x, &[10, 2, 400]);
+
source

pub fn get_many_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> Result<[&mut T; N], GetManyMutError<N>>

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once.

+

Returns an error if any index is out-of-bounds, or if the same index was +passed more than once.

+
§Examples
+
#![feature(get_many_mut)]
+
+let v = &mut [1, 2, 3];
+if let Ok([a, b]) = v.get_many_mut([0, 2]) {
+    *a = 413;
+    *b = 612;
+}
+assert_eq!(v, &[413, 2, 612]);
+
1.79.0 · source

pub fn utf8_chunks(&self) -> Utf8Chunks<'_>

Creates an iterator over the contiguous valid UTF-8 ranges of this +slice, and the non-UTF-8 fragments in between.

+
§Examples
+

This function formats arbitrary but mostly-UTF-8 bytes into Rust source +code in the form of a C-string literal (c"...").

+ +
use std::fmt::Write as _;
+
+pub fn cstr_literal(bytes: &[u8]) -> String {
+    let mut repr = String::new();
+    repr.push_str("c\"");
+    for chunk in bytes.utf8_chunks() {
+        for ch in chunk.valid().chars() {
+            // Escapes \0, \t, \r, \n, \\, \', \", and uses \u{...} for non-printable characters.
+            write!(repr, "{}", ch.escape_debug()).unwrap();
+        }
+        for byte in chunk.invalid() {
+            write!(repr, "\\x{:02X}", byte).unwrap();
+        }
+    }
+    repr.push('"');
+    repr
+}
+
+fn main() {
+    let lit = cstr_literal(b"\xferris the \xf0\x9f\xa6\x80\x07");
+    let expected = stringify!(c"\xFErris the 🦀\u{7}");
+    assert_eq!(lit, expected);
+}
+
1.23.0 · source

pub fn is_ascii(&self) -> bool

Checks if all bytes in this slice are within the ASCII range.

+
source

pub fn as_ascii(&self) -> Option<&[AsciiChar]>

🔬This is a nightly-only experimental API. (ascii_char)

If this slice is_ascii, returns it as a slice of +ASCII characters, otherwise returns None.

+
source

pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]

🔬This is a nightly-only experimental API. (ascii_char)

Converts this slice of bytes into a slice of ASCII characters, +without checking whether they’re valid.

+
§Safety
+

Every byte in the slice must be in 0..=127, or else this is UB.

+
1.23.0 · source

pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool

Checks that two slices are an ASCII case-insensitive match.

+

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), +but without allocating and copying temporaries.

+
1.23.0 · source

pub fn make_ascii_uppercase(&mut self)

Converts this slice to its ASCII upper case equivalent in-place.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To return a new uppercased value without modifying the existing one, use +to_ascii_uppercase.

+
1.23.0 · source

pub fn make_ascii_lowercase(&mut self)

Converts this slice to its ASCII lower case equivalent in-place.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To return a new lowercased value without modifying the existing one, use +to_ascii_lowercase.

+
1.60.0 · source

pub fn escape_ascii(&self) -> EscapeAscii<'_>

Returns an iterator that produces an escaped version of this slice, +treating it as an ASCII string.

+
§Examples
+

+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
+
1.80.0 · source

pub fn trim_ascii_start(&self) -> &[u8]

Returns a byte slice with leading ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b"  ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
+
1.80.0 · source

pub fn trim_ascii_end(&self) -> &[u8]

Returns a byte slice with trailing ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b"  ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
+
1.80.0 · source

pub fn trim_ascii(&self) -> &[u8]

Returns a byte slice with leading and trailing ASCII whitespace bytes +removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b"  ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f64::total_cmp.

+
§Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
§Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
source

pub fn as_str(&self) -> &str

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a UTF-8 str.

+
source

pub fn as_bytes(&self) -> &[u8]

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a slice of u8 bytes.

+
1.0.0 · source

pub fn sort(&mut self)
where + T: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.0.0 · source

pub fn sort_by<F>(&mut self, compare: F)
where + F: FnMut(&T, &T) -> Ordering,

Available on non-no_global_oom_handling only.

Sorts the slice with a comparator function.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.7.0 · source

pub fn sort_by_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n * log(n)) +worst-case, where the key function is O(m).

+

For expensive key functions (e.g. functions that are not simple property accesses or +basic operations), sort_by_cached_key is likely to be +significantly faster, as it does not recompute element keys.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by_key.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.34.0 · source

pub fn sort_by_cached_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

During sorting, the key function is called at most once per element, by using +temporary storage to remember the results of key evaluation. +The order of calls to the key function is unspecified and may change in future versions +of the standard library.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n + n * log(n)) +worst-case, where the key function is O(m).

+

For simple key functions (e.g., functions that are property accesses or +basic operations), sort_by_key is likely to be +faster.

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

In the worst case, the algorithm allocates temporary storage in a Vec<(K, usize)> the +length of the slice.

+
§Examples
+
let mut v = [-5i32, 4, 32, -3, 2];
+
+v.sort_by_cached_key(|k| k.to_string());
+assert!(v == [-3, -5, 2, 32, 4]);
+
1.0.0 · source

pub fn to_vec(&self) -> Vec<T>
where + T: Clone,

Available on non-no_global_oom_handling only.

Copies self into a new Vec.

+
§Examples
+
let s = [10, 40, 30];
+let x = s.to_vec();
+// Here, `s` and `x` can be modified independently.
+
source

pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>
where + A: Allocator, + T: Clone,

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Copies self into a new Vec with an allocator.

+
§Examples
+
#![feature(allocator_api)]
+
+use std::alloc::System;
+
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
+// Here, `s` and `x` can be modified independently.
+
1.40.0 · source

pub fn repeat(&self, n: usize) -> Vec<T>
where + T: Copy,

Available on non-no_global_oom_handling only.

Creates a vector by copying a slice n times.

+
§Panics
+

This function will panic if the capacity would overflow.

+
§Examples
+

Basic usage:

+ +
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
+

A panic upon overflow:

+ +
// this will panic at runtime
+b"0123456789abcdef".repeat(usize::MAX);
+
1.0.0 · source

pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output
where + [T]: Concat<Item>, + Item: ?Sized,

Flattens a slice of T into a single value Self::Output.

+
§Examples
+
assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+
1.3.0 · source

pub fn join<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+
1.0.0 · source

pub fn connect<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

👎Deprecated since 1.3.0: renamed to join

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+
1.23.0 · source

pub fn to_ascii_uppercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII upper case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To uppercase the value in-place, use make_ascii_uppercase.

+
1.23.0 · source

pub fn to_ascii_lowercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII lower case equivalent.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To lowercase the value in-place, use make_ascii_lowercase.

+

Trait Implementations§

source§

impl Clone for AcceptLanguage

source§

fn clone(&self) -> AcceptLanguage

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for AcceptLanguage

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for AcceptLanguage

§

type Target = Vec<QualityItem<Preference<LanguageTag>>>

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for AcceptLanguage

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl Display for AcceptLanguage

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for AcceptLanguage

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for AcceptLanguage

source§

fn eq(&self, other: &AcceptLanguage) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for AcceptLanguage

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for AcceptLanguage

source§

impl StructuralPartialEq for AcceptLanguage

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.Allow.html b/actix_web/http/header/struct.Allow.html new file mode 100644 index 000000000..154c0e11a --- /dev/null +++ b/actix_web/http/header/struct.Allow.html @@ -0,0 +1,3135 @@ +Allow in actix_web::http::header - Rust

Struct actix_web::http::header::Allow

source ·
pub struct Allow(pub Vec<Method>);
Expand description

Allow header, defined +in RFC 7231 §7.4.1

+

The Allow header field lists the set of methods advertised as +supported by the target resource. The purpose of this field is +strictly to inform the recipient of valid request methods associated +with the resource.

+

§ABNF

Allow = #method
+

§Example Values

+
    +
  • GET, HEAD, PUT
  • +
  • OPTIONS, GET, PUT, POST, DELETE, HEAD, TRACE, CONNECT, PATCH, fOObAr
  • +
  • ``
  • +
+

§Examples

+
use actix_web::HttpResponse;
+use actix_web::http::{header::Allow, Method};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    Allow(vec![Method::GET])
+);
+ +
use actix_web::HttpResponse;
+use actix_web::http::{header::Allow, Method};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    Allow(vec![
+        Method::GET,
+        Method::POST,
+        Method::PATCH,
+    ])
+);
+

Tuple Fields§

§0: Vec<Method>

Methods from Deref<Target = Vec<Method>>§

1.0.0 · source

pub fn capacity(&self) -> usize

Returns the total number of elements the vector can hold without +reallocating.

+
§Examples
+
let mut vec: Vec<i32> = Vec::with_capacity(10);
+vec.push(42);
+assert!(vec.capacity() >= 10);
+
1.0.0 · source

pub fn reserve(&mut self, additional: usize)

Available on non-no_global_oom_handling only.

Reserves capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to +speculatively avoid frequent reallocations. After calling reserve, +capacity will be greater than or equal to self.len() + additional. +Does nothing if capacity is already sufficient.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1];
+vec.reserve(10);
+assert!(vec.capacity() >= 11);
+
1.0.0 · source

pub fn reserve_exact(&mut self, additional: usize)

Available on non-no_global_oom_handling only.

Reserves the minimum capacity for at least additional more elements to +be inserted in the given Vec<T>. Unlike reserve, this will not +deliberately over-allocate to speculatively avoid frequent allocations. +After calling reserve_exact, capacity will be greater than or equal to +self.len() + additional. Does nothing if the capacity is already +sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer reserve if future insertions are expected.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1];
+vec.reserve_exact(10);
+assert!(vec.capacity() >= 11);
+
1.57.0 · source

pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>

Tries to reserve capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to speculatively avoid +frequent reallocations. After calling try_reserve, capacity will be +greater than or equal to self.len() + additional if it returns +Ok(()). Does nothing if capacity is already sufficient. This method +preserves the contents even if an error occurs.

+
§Errors
+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+
§Examples
+
use std::collections::TryReserveError;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+
1.57.0 · source

pub fn try_reserve_exact( + &mut self, + additional: usize +) -> Result<(), TryReserveError>

Tries to reserve the minimum capacity for at least additional +elements to be inserted in the given Vec<T>. Unlike try_reserve, +this will not deliberately over-allocate to speculatively avoid frequent +allocations. After calling try_reserve_exact, capacity will be greater +than or equal to self.len() + additional if it returns Ok(()). +Does nothing if the capacity is already sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer try_reserve if future insertions are expected.

+
§Errors
+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+
§Examples
+
use std::collections::TryReserveError;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve_exact(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+
1.0.0 · source

pub fn shrink_to_fit(&mut self)

Available on non-no_global_oom_handling only.

Shrinks the capacity of the vector as much as possible.

+

The behavior of this method depends on the allocator, which may either shrink the vector +in-place or reallocate. The resulting vector might still have some excess capacity, just as +is the case for with_capacity. See Allocator::shrink for more details.

+
§Examples
+
let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3]);
+assert!(vec.capacity() >= 10);
+vec.shrink_to_fit();
+assert!(vec.capacity() >= 3);
+
1.56.0 · source

pub fn shrink_to(&mut self, min_capacity: usize)

Available on non-no_global_oom_handling only.

Shrinks the capacity of the vector with a lower bound.

+

The capacity will remain at least as large as both the length +and the supplied value.

+

If the current capacity is less than the lower limit, this is a no-op.

+
§Examples
+
let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3]);
+assert!(vec.capacity() >= 10);
+vec.shrink_to(4);
+assert!(vec.capacity() >= 4);
+vec.shrink_to(0);
+assert!(vec.capacity() >= 3);
+
1.0.0 · source

pub fn truncate(&mut self, len: usize)

Shortens the vector, keeping the first len elements and dropping +the rest.

+

If len is greater or equal to the vector’s current length, this has +no effect.

+

The drain method can emulate truncate, but causes the excess +elements to be returned instead of dropped.

+

Note that this method has no effect on the allocated capacity +of the vector.

+
§Examples
+

Truncating a five element vector to two elements:

+ +
let mut vec = vec![1, 2, 3, 4, 5];
+vec.truncate(2);
+assert_eq!(vec, [1, 2]);
+

No truncation occurs when len is greater than the vector’s current +length:

+ +
let mut vec = vec![1, 2, 3];
+vec.truncate(8);
+assert_eq!(vec, [1, 2, 3]);
+

Truncating when len == 0 is equivalent to calling the clear +method.

+ +
let mut vec = vec![1, 2, 3];
+vec.truncate(0);
+assert_eq!(vec, []);
+
1.7.0 · source

pub fn as_slice(&self) -> &[T]

Extracts a slice containing the entire vector.

+

Equivalent to &s[..].

+
§Examples
+
use std::io::{self, Write};
+let buffer = vec![1, 2, 3, 5, 8];
+io::sink().write(buffer.as_slice()).unwrap();
+
1.7.0 · source

pub fn as_mut_slice(&mut self) -> &mut [T]

Extracts a mutable slice of the entire vector.

+

Equivalent to &mut s[..].

+
§Examples
+
use std::io::{self, Read};
+let mut buffer = vec![0; 3];
+io::repeat(0b101).read_exact(buffer.as_mut_slice()).unwrap();
+
1.37.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the vector’s buffer, or a dangling raw pointer +valid for zero sized reads if the vector didn’t allocate.

+

The caller must ensure that the vector outlives the pointer this +function returns, or else it will end up pointing to garbage. +Modifying the vector may cause its buffer to be reallocated, +which would also make any pointers to it invalid.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

This method guarantees that for the purpose of the aliasing model, this method +does not materialize a reference to the underlying slice, and thus the returned pointer +will remain valid when mixed with other calls to as_ptr and as_mut_ptr. +Note that calling other methods that materialize mutable references to the slice, +or mutable references to specific elements you are planning on accessing through this pointer, +as well as writing to those elements, may still invalidate this pointer. +See the second example below for how this guarantee can be used.

+
§Examples
+
let x = vec![1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(*x_ptr.add(i), 1 << i);
+    }
+}
+

Due to the aliasing guarantee, the following code is legal:

+ +
unsafe {
+    let mut v = vec![0, 1, 2];
+    let ptr1 = v.as_ptr();
+    let _ = ptr1.read();
+    let ptr2 = v.as_mut_ptr().offset(2);
+    ptr2.write(2);
+    // Notably, the write to `ptr2` did *not* invalidate `ptr1`
+    // because it mutated a different element:
+    let _ = ptr1.read();
+}
+
1.37.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the vector’s buffer, or a dangling +raw pointer valid for zero sized reads if the vector didn’t allocate.

+

The caller must ensure that the vector outlives the pointer this +function returns, or else it will end up pointing to garbage. +Modifying the vector may cause its buffer to be reallocated, +which would also make any pointers to it invalid.

+

This method guarantees that for the purpose of the aliasing model, this method +does not materialize a reference to the underlying slice, and thus the returned pointer +will remain valid when mixed with other calls to as_ptr and as_mut_ptr. +Note that calling other methods that materialize references to the slice, +or references to specific elements you are planning on accessing through this pointer, +may still invalidate this pointer. +See the second example below for how this guarantee can be used.

+
§Examples
+
// Allocate vector big enough for 4 elements.
+let size = 4;
+let mut x: Vec<i32> = Vec::with_capacity(size);
+let x_ptr = x.as_mut_ptr();
+
+// Initialize elements via raw pointer writes, then set length.
+unsafe {
+    for i in 0..size {
+        *x_ptr.add(i) = i as i32;
+    }
+    x.set_len(size);
+}
+assert_eq!(&*x, &[0, 1, 2, 3]);
+

Due to the aliasing guarantee, the following code is legal:

+ +
unsafe {
+    let mut v = vec![0];
+    let ptr1 = v.as_mut_ptr();
+    ptr1.write(1);
+    let ptr2 = v.as_mut_ptr();
+    ptr2.write(2);
+    // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
+    ptr1.write(3);
+}
+
source

pub fn allocator(&self) -> &A

🔬This is a nightly-only experimental API. (allocator_api)

Returns a reference to the underlying allocator.

+
1.0.0 · source

pub unsafe fn set_len(&mut self, new_len: usize)

Forces the length of the vector to new_len.

+

This is a low-level operation that maintains none of the normal +invariants of the type. Normally changing the length of a vector +is done using one of the safe operations instead, such as +truncate, resize, extend, or clear.

+
§Safety
+
    +
  • new_len must be less than or equal to capacity().
  • +
  • The elements at old_len..new_len must be initialized.
  • +
+
§Examples
+

This method can be useful for situations in which the vector +is serving as a buffer for other code, particularly over FFI:

+ +
pub fn get_dictionary(&self) -> Option<Vec<u8>> {
+    // Per the FFI method's docs, "32768 bytes is always enough".
+    let mut dict = Vec::with_capacity(32_768);
+    let mut dict_length = 0;
+    // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
+    // 1. `dict_length` elements were initialized.
+    // 2. `dict_length` <= the capacity (32_768)
+    // which makes `set_len` safe to call.
+    unsafe {
+        // Make the FFI call...
+        let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
+        if r == Z_OK {
+            // ...and update the length to what was initialized.
+            dict.set_len(dict_length);
+            Some(dict)
+        } else {
+            None
+        }
+    }
+}
+

While the following example is sound, there is a memory leak since +the inner vectors were not freed prior to the set_len call:

+ +
let mut vec = vec![vec![1, 0, 0],
+                   vec![0, 1, 0],
+                   vec![0, 0, 1]];
+// SAFETY:
+// 1. `old_len..0` is empty so no elements need to be initialized.
+// 2. `0 <= capacity` always holds whatever `capacity` is.
+unsafe {
+    vec.set_len(0);
+}
+

Normally, here, one would use clear instead to correctly drop +the contents and thus not leak memory.

+
1.0.0 · source

pub fn swap_remove(&mut self, index: usize) -> T

Removes an element from the vector and returns it.

+

The removed element is replaced by the last element of the vector.

+

This does not preserve ordering of the remaining elements, but is O(1). +If you need to preserve the element order, use remove instead.

+
§Panics
+

Panics if index is out of bounds.

+
§Examples
+
let mut v = vec!["foo", "bar", "baz", "qux"];
+
+assert_eq!(v.swap_remove(1), "bar");
+assert_eq!(v, ["foo", "qux", "baz"]);
+
+assert_eq!(v.swap_remove(0), "foo");
+assert_eq!(v, ["baz", "qux"]);
+
1.0.0 · source

pub fn insert(&mut self, index: usize, element: T)

Available on non-no_global_oom_handling only.

Inserts an element at position index within the vector, shifting all +elements after it to the right.

+
§Panics
+

Panics if index > len.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+vec.insert(1, 4);
+assert_eq!(vec, [1, 4, 2, 3]);
+vec.insert(4, 5);
+assert_eq!(vec, [1, 4, 2, 3, 5]);
+
§Time complexity
+

Takes O(Vec::len) time. All items after the insertion index must be +shifted to the right. In the worst case, all elements are shifted when +the insertion index is 0.

+
1.0.0 · source

pub fn remove(&mut self, index: usize) -> T

Removes and returns the element at position index within the vector, +shifting all elements after it to the left.

+

Note: Because this shifts over the remaining elements, it has a +worst-case performance of O(n). If you don’t need the order of elements +to be preserved, use swap_remove instead. If you’d like to remove +elements from the beginning of the Vec, consider using +VecDeque::pop_front instead.

+
§Panics
+

Panics if index is out of bounds.

+
§Examples
+
let mut v = vec![1, 2, 3];
+assert_eq!(v.remove(1), 2);
+assert_eq!(v, [1, 3]);
+
1.0.0 · source

pub fn retain<F>(&mut self, f: F)
where + F: FnMut(&T) -> bool,

Retains only the elements specified by the predicate.

+

In other words, remove all elements e for which f(&e) returns false. +This method operates in place, visiting each element exactly once in the +original order, and preserves the order of the retained elements.

+
§Examples
+
let mut vec = vec![1, 2, 3, 4];
+vec.retain(|&x| x % 2 == 0);
+assert_eq!(vec, [2, 4]);
+

Because the elements are visited exactly once in the original order, +external state may be used to decide which elements to keep.

+ +
let mut vec = vec![1, 2, 3, 4, 5];
+let keep = [false, true, true, false, true];
+let mut iter = keep.iter();
+vec.retain(|_| *iter.next().unwrap());
+assert_eq!(vec, [2, 3, 5]);
+
1.61.0 · source

pub fn retain_mut<F>(&mut self, f: F)
where + F: FnMut(&mut T) -> bool,

Retains only the elements specified by the predicate, passing a mutable reference to it.

+

In other words, remove all elements e such that f(&mut e) returns false. +This method operates in place, visiting each element exactly once in the +original order, and preserves the order of the retained elements.

+
§Examples
+
let mut vec = vec![1, 2, 3, 4];
+vec.retain_mut(|x| if *x <= 3 {
+    *x += 1;
+    true
+} else {
+    false
+});
+assert_eq!(vec, [2, 3, 4]);
+
1.16.0 · source

pub fn dedup_by_key<F, K>(&mut self, key: F)
where + F: FnMut(&mut T) -> K, + K: PartialEq,

Removes all but the first of consecutive elements in the vector that resolve to the same +key.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec![10, 20, 21, 30, 20];
+
+vec.dedup_by_key(|i| *i / 10);
+
+assert_eq!(vec, [10, 20, 30, 20]);
+
1.16.0 · source

pub fn dedup_by<F>(&mut self, same_bucket: F)
where + F: FnMut(&mut T, &mut T) -> bool,

Removes all but the first of consecutive elements in the vector satisfying a given equality +relation.

+

The same_bucket function is passed references to two elements from the vector and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is removed.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
+
+vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
+
1.0.0 · source

pub fn push(&mut self, value: T)

Available on non-no_global_oom_handling only.

Appends an element to the back of a collection.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1, 2];
+vec.push(3);
+assert_eq!(vec, [1, 2, 3]);
+
§Time complexity
+

Takes amortized O(1) time. If the vector’s length would exceed its +capacity after the push, O(capacity) time is taken to copy the +vector’s elements to a larger allocation. This expensive operation is +offset by the capacity O(1) insertions it allows.

+
source

pub fn push_within_capacity(&mut self, value: T) -> Result<(), T>

🔬This is a nightly-only experimental API. (vec_push_within_capacity)

Appends an element if there is sufficient spare capacity, otherwise an error is returned +with the element.

+

Unlike push this method will not reallocate when there’s insufficient capacity. +The caller should use reserve or try_reserve to ensure that there is enough capacity.

+
§Examples
+

A manual, panic-free alternative to FromIterator:

+ +
#![feature(vec_push_within_capacity)]
+
+use std::collections::TryReserveError;
+fn from_iter_fallible<T>(iter: impl Iterator<Item=T>) -> Result<Vec<T>, TryReserveError> {
+    let mut vec = Vec::new();
+    for value in iter {
+        if let Err(value) = vec.push_within_capacity(value) {
+            vec.try_reserve(1)?;
+            // this cannot fail, the previous line either returned or added at least 1 free slot
+            let _ = vec.push_within_capacity(value);
+        }
+    }
+    Ok(vec)
+}
+assert_eq!(from_iter_fallible(0..100), Ok(Vec::from_iter(0..100)));
+
§Time complexity
+

Takes O(1) time.

+
1.0.0 · source

pub fn pop(&mut self) -> Option<T>

Removes the last element from a vector and returns it, or None if it +is empty.

+

If you’d like to pop the first element, consider using +VecDeque::pop_front instead.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+assert_eq!(vec.pop(), Some(3));
+assert_eq!(vec, [1, 2]);
+
§Time complexity
+

Takes O(1) time.

+
source

pub fn pop_if<F>(&mut self, f: F) -> Option<T>
where + F: FnOnce(&mut T) -> bool,

🔬This is a nightly-only experimental API. (vec_pop_if)

Removes and returns the last element in a vector if the predicate +returns true, or None if the predicate returns false or the vector +is empty.

+
§Examples
+
#![feature(vec_pop_if)]
+
+let mut vec = vec![1, 2, 3, 4];
+let pred = |x: &mut i32| *x % 2 == 0;
+
+assert_eq!(vec.pop_if(pred), Some(4));
+assert_eq!(vec, [1, 2, 3]);
+assert_eq!(vec.pop_if(pred), None);
+
1.4.0 · source

pub fn append(&mut self, other: &mut Vec<T, A>)

Available on non-no_global_oom_handling only.

Moves all the elements of other into self, leaving other empty.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+let mut vec2 = vec![4, 5, 6];
+vec.append(&mut vec2);
+assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
+assert_eq!(vec2, []);
+
1.6.0 · source

pub fn drain<R>(&mut self, range: R) -> Drain<'_, T, A>
where + R: RangeBounds<usize>,

Removes the specified range from the vector in bulk, returning all +removed elements as an iterator. If the iterator is dropped before +being fully consumed, it drops the remaining removed elements.

+

The returned iterator keeps a mutable borrow on the vector to optimize +its implementation.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Leaking
+

If the returned iterator goes out of scope without being dropped (due to +mem::forget, for example), the vector may have lost and leaked +elements arbitrarily, including elements outside the range.

+
§Examples
+
let mut v = vec![1, 2, 3];
+let u: Vec<_> = v.drain(1..).collect();
+assert_eq!(v, &[1]);
+assert_eq!(u, &[2, 3]);
+
+// A full range clears the vector, like `clear()` does
+v.drain(..);
+assert_eq!(v, &[]);
+
1.0.0 · source

pub fn clear(&mut self)

Clears the vector, removing all values.

+

Note that this method has no effect on the allocated capacity +of the vector.

+
§Examples
+
let mut v = vec![1, 2, 3];
+
+v.clear();
+
+assert!(v.is_empty());
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the vector, also referred to +as its ‘length’.

+
§Examples
+
let a = vec![1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the vector contains no elements.

+
§Examples
+
let mut v = Vec::new();
+assert!(v.is_empty());
+
+v.push(1);
+assert!(!v.is_empty());
+
1.4.0 · source

pub fn split_off(&mut self, at: usize) -> Vec<T, A>
where + A: Clone,

Available on non-no_global_oom_handling only.

Splits the collection into two at the given index.

+

Returns a newly allocated vector containing the elements in the range +[at, len). After the call, the original vector will be left containing +the elements [0, at) with its previous capacity unchanged.

+
    +
  • If you want to take ownership of the entire contents and capacity of +the vector, see mem::take or mem::replace.
  • +
  • If you don’t need the returned vector at all, see Vec::truncate.
  • +
  • If you want to take ownership of an arbitrary subslice, or you don’t +necessarily want to store the removed items in a vector, see Vec::drain.
  • +
+
§Panics
+

Panics if at > len.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+let vec2 = vec.split_off(1);
+assert_eq!(vec, [1]);
+assert_eq!(vec2, [2, 3]);
+
1.33.0 · source

pub fn resize_with<F>(&mut self, new_len: usize, f: F)
where + F: FnMut() -> T,

Available on non-no_global_oom_handling only.

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with the result of +calling the closure f. The return values from f will end up +in the Vec in the order they have been generated.

+

If new_len is less than len, the Vec is simply truncated.

+

This method uses a closure to create new values on every push. If +you’d rather Clone a given value, use Vec::resize. If you +want to use the Default trait to generate values, you can +pass Default::default as the second argument.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+vec.resize_with(5, Default::default);
+assert_eq!(vec, [1, 2, 3, 0, 0]);
+
+let mut vec = vec![];
+let mut p = 1;
+vec.resize_with(4, || { p *= 2; p });
+assert_eq!(vec, [2, 4, 8, 16]);
+
1.60.0 · source

pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>]

Returns the remaining spare capacity of the vector as a slice of +MaybeUninit<T>.

+

The returned slice can be used to fill the vector with data (e.g. by +reading from a file) before marking the data as initialized using the +set_len method.

+
§Examples
+
// Allocate vector big enough for 10 elements.
+let mut v = Vec::with_capacity(10);
+
+// Fill in the first 3 elements.
+let uninit = v.spare_capacity_mut();
+uninit[0].write(0);
+uninit[1].write(1);
+uninit[2].write(2);
+
+// Mark the first 3 elements of the vector as being initialized.
+unsafe {
+    v.set_len(3);
+}
+
+assert_eq!(&v, &[0, 1, 2]);
+
source

pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>])

🔬This is a nightly-only experimental API. (vec_split_at_spare)

Returns vector content as a slice of T, along with the remaining spare +capacity of the vector as a slice of MaybeUninit<T>.

+

The returned spare capacity slice can be used to fill the vector with data +(e.g. by reading from a file) before marking the data as initialized using +the set_len method.

+

Note that this is a low-level API, which should be used with care for +optimization purposes. If you need to append data to a Vec +you can use push, extend, extend_from_slice, +extend_from_within, insert, append, resize or +resize_with, depending on your exact needs.

+
§Examples
+
#![feature(vec_split_at_spare)]
+
+let mut v = vec![1, 1, 2];
+
+// Reserve additional space big enough for 10 elements.
+v.reserve(10);
+
+let (init, uninit) = v.split_at_spare_mut();
+let sum = init.iter().copied().sum::<u32>();
+
+// Fill in the next 4 elements.
+uninit[0].write(sum);
+uninit[1].write(sum * 2);
+uninit[2].write(sum * 3);
+uninit[3].write(sum * 4);
+
+// Mark the 4 elements of the vector as being initialized.
+unsafe {
+    let len = v.len();
+    v.set_len(len + 4);
+}
+
+assert_eq!(&v, &[1, 1, 2, 4, 8, 12, 16]);
+
1.5.0 · source

pub fn resize(&mut self, new_len: usize, value: T)

Available on non-no_global_oom_handling only.

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with value. +If new_len is less than len, the Vec is simply truncated.

+

This method requires T to implement Clone, +in order to be able to clone the passed value. +If you need more flexibility (or want to rely on Default instead of +Clone), use Vec::resize_with. +If you only need to resize to a smaller size, use Vec::truncate.

+
§Examples
+
let mut vec = vec!["hello"];
+vec.resize(3, "world");
+assert_eq!(vec, ["hello", "world", "world"]);
+
+let mut vec = vec![1, 2, 3, 4];
+vec.resize(2, 0);
+assert_eq!(vec, [1, 2]);
+
1.6.0 · source

pub fn extend_from_slice(&mut self, other: &[T])

Available on non-no_global_oom_handling only.

Clones and appends all elements in a slice to the Vec.

+

Iterates over the slice other, clones each element, and then appends +it to this Vec. The other slice is traversed in-order.

+

Note that this function is same as extend except that it is +specialized to work with slices instead. If and when Rust gets +specialization this function will likely be deprecated (but still +available).

+
§Examples
+
let mut vec = vec![1];
+vec.extend_from_slice(&[2, 3, 4]);
+assert_eq!(vec, [1, 2, 3, 4]);
+
1.53.0 · source

pub fn extend_from_within<R>(&mut self, src: R)
where + R: RangeBounds<usize>,

Available on non-no_global_oom_handling only.

Copies elements from src range to the end of the vector.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Examples
+
let mut vec = vec![0, 1, 2, 3, 4];
+
+vec.extend_from_within(2..);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
+
+vec.extend_from_within(..2);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
+
+vec.extend_from_within(4..8);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
+
1.0.0 · source

pub fn dedup(&mut self)

Removes consecutive repeated elements in the vector according to the +PartialEq trait implementation.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec![1, 2, 2, 3, 2];
+
+vec.dedup();
+
+assert_eq!(vec, [1, 2, 3, 2]);
+
1.21.0 · source

pub fn splice<R, I>( + &mut self, + range: R, + replace_with: I +) -> Splice<'_, <I as IntoIterator>::IntoIter, A>
where + R: RangeBounds<usize>, + I: IntoIterator<Item = T>,

Available on non-no_global_oom_handling only.

Creates a splicing iterator that replaces the specified range in the vector +with the given replace_with iterator and yields the removed items. +replace_with does not need to be the same length as range.

+

range is removed even if the iterator is not consumed until the end.

+

It is unspecified how many elements are removed from the vector +if the Splice value is leaked.

+

The input iterator replace_with is only consumed when the Splice value is dropped.

+

This is optimal if:

+
    +
  • The tail (elements in the vector after range) is empty,
  • +
  • or replace_with yields fewer or equal elements than range’s length
  • +
  • or the lower bound of its size_hint() is exact.
  • +
+

Otherwise, a temporary vector is allocated and the tail is moved twice.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Examples
+
let mut v = vec![1, 2, 3, 4];
+let new = [7, 8, 9];
+let u: Vec<_> = v.splice(1..3, new).collect();
+assert_eq!(v, &[1, 7, 8, 9, 4]);
+assert_eq!(u, &[2, 3]);
+
source

pub fn extract_if<F>(&mut self, filter: F) -> ExtractIf<'_, T, F, A>
where + F: FnMut(&mut T) -> bool,

🔬This is a nightly-only experimental API. (extract_if)

Creates an iterator which uses a closure to determine if an element should be removed.

+

If the closure returns true, then the element is removed and yielded. +If the closure returns false, the element will remain in the vector and will not be yielded +by the iterator.

+

If the returned ExtractIf is not exhausted, e.g. because it is dropped without iterating +or the iteration short-circuits, then the remaining elements will be retained. +Use retain with a negated predicate if you do not need the returned iterator.

+

Using this method is equivalent to the following code:

+ +
let mut i = 0;
+while i < vec.len() {
+    if some_predicate(&mut vec[i]) {
+        let val = vec.remove(i);
+        // your code here
+    } else {
+        i += 1;
+    }
+}
+
+

But extract_if is easier to use. extract_if is also more efficient, +because it can backshift the elements of the array in bulk.

+

Note that extract_if also lets you mutate every element in the filter closure, +regardless of whether you choose to keep or remove it.

+
§Examples
+

Splitting an array into evens and odds, reusing the original allocation:

+ +
#![feature(extract_if)]
+let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];
+
+let evens = numbers.extract_if(|x| *x % 2 == 0).collect::<Vec<_>>();
+let odds = numbers;
+
+assert_eq!(evens, vec![2, 4, 6, 8, 14]);
+assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]);
+

Methods from Deref<Target = [T]>§

1.80.0 · source

pub fn as_flattened(&self) -> &[T]

Takes a &[[T; N]], and flattens it to a &[T].

+
§Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
§Examples
+
assert_eq!([[1, 2, 3], [4, 5, 6]].as_flattened(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+    [[1, 2, 3], [4, 5, 6]].as_flattened(),
+    [[1, 2], [3, 4], [5, 6]].as_flattened(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.as_flattened().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.as_flattened().is_empty());
+
1.80.0 · source

pub fn as_flattened_mut(&mut self) -> &mut [T]

Takes a &mut [[T; N]], and flattens it to a &mut [T].

+
§Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
§Examples
+
fn add_5_to_all(slice: &mut [i32]) {
+    for i in slice {
+        *i += 5;
+    }
+}
+
+let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
+add_5_to_all(array.as_flattened_mut());
+assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f32::total_cmp.

+
§Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
§Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the slice.

+
§Examples
+
let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the slice has a length of 0.

+
§Examples
+
let a = [1, 2, 3];
+assert!(!a.is_empty());
+
+let b: &[i32] = &[];
+assert!(b.is_empty());
+
1.0.0 · source

pub fn first(&self) -> Option<&T>

Returns the first element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
+
1.0.0 · source

pub fn first_mut(&mut self) -> Option<&mut T>

Returns a mutable pointer to the first element of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_mut() {
+    *first = 5;
+}
+assert_eq!(x, &[5, 1, 2]);
+
+let y: &mut [i32] = &mut [];
+assert_eq!(None, y.first_mut());
+
1.5.0 · source

pub fn split_first(&self) -> Option<(&T, &[T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first() {
+    assert_eq!(first, &0);
+    assert_eq!(elements, &[1, 2]);
+}
+
1.5.0 · source

pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_mut() {
+    *first = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
1.5.0 · source

pub fn split_last(&self) -> Option<(&T, &[T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+    assert_eq!(last, &2);
+    assert_eq!(elements, &[0, 1]);
+}
+
1.5.0 · source

pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_mut() {
+    *last = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[4, 5, 3]);
+
1.0.0 · source

pub fn last(&self) -> Option<&T>

Returns the last element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
+
1.0.0 · source

pub fn last_mut(&mut self) -> Option<&mut T>

Returns a mutable reference to the last item in the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_mut() {
+    *last = 10;
+}
+assert_eq!(x, &[0, 1, 10]);
+
+let y: &mut [i32] = &mut [];
+assert_eq!(None, y.last_mut());
+
1.77.0 · source

pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the first N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.first_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.first_chunk::<0>());
+
1.77.0 · source

pub fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

Return a mutable array reference to the first N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_chunk_mut::<2>() {
+    first[0] = 5;
+    first[1] = 4;
+}
+assert_eq!(x, &[5, 4, 2]);
+
+assert_eq!(None, x.first_chunk_mut::<4>());
+
1.77.0 · source

pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

Return an array reference to the first N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk::<2>() {
+    assert_eq!(first, &[0, 1]);
+    assert_eq!(elements, &[2]);
+}
+
+assert_eq!(None, x.split_first_chunk::<4>());
+
1.77.0 · source

pub fn split_first_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T; N], &mut [T])>

Return a mutable array reference to the first N items in the slice and the remaining +slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk_mut::<2>() {
+    first[0] = 3;
+    first[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
+assert_eq!(None, x.split_first_chunk_mut::<4>());
+
1.77.0 · source

pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>

Return an array reference to the last N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((elements, last)) = x.split_last_chunk::<2>() {
+    assert_eq!(elements, &[0]);
+    assert_eq!(last, &[1, 2]);
+}
+
+assert_eq!(None, x.split_last_chunk::<4>());
+
1.77.0 · source

pub fn split_last_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T], &mut [T; N])>

Return a mutable array reference to the last N items in the slice and the remaining +slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((elements, last)) = x.split_last_chunk_mut::<2>() {
+    last[0] = 3;
+    last[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[5, 3, 4]);
+
+assert_eq!(None, x.split_last_chunk_mut::<4>());
+
1.77.0 · source

pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the last N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.last_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.last_chunk::<0>());
+
1.77.0 · source

pub fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

Return a mutable array reference to the last N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_chunk_mut::<2>() {
+    last[0] = 10;
+    last[1] = 20;
+}
+assert_eq!(x, &[0, 10, 20]);
+
+assert_eq!(None, x.last_chunk_mut::<4>());
+
1.0.0 · source

pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice depending on the type of +index.

+
    +
  • If given a position, returns a reference to the element at that +position or None if out of bounds.
  • +
  • If given a range, returns the subslice corresponding to that range, +or None if out of bounds.
  • +
+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
+
1.0.0 · source

pub fn get_mut<I>( + &mut self, + index: I +) -> Option<&mut <I as SliceIndex<[T]>>::Output>
where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice depending on the +type of index (see get) or None if the index is out of bounds.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(elem) = x.get_mut(1) {
+    *elem = 42;
+}
+assert_eq!(x, &[0, 42, 2]);
+
1.0.0 · source

pub unsafe fn get_unchecked<I>( + &self, + index: I +) -> &<I as SliceIndex<[T]>>::Output
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice, without doing bounds +checking.

+

For a safe alternative see get.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get(index).unwrap_unchecked(). It’s UB +to call .get_unchecked(len), even if you immediately convert to a +pointer. And it’s UB to call .get_unchecked(..len + 1), +.get_unchecked(..=len), or similar.

+
§Examples
+
let x = &[1, 2, 4];
+
+unsafe {
+    assert_eq!(x.get_unchecked(1), &2);
+}
+
1.0.0 · source

pub unsafe fn get_unchecked_mut<I>( + &mut self, + index: I +) -> &mut <I as SliceIndex<[T]>>::Output
where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice, without doing +bounds checking.

+

For a safe alternative see get_mut.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get_mut(index).unwrap_unchecked(). It’s +UB to call .get_unchecked_mut(len), even if you immediately convert +to a pointer. And it’s UB to call .get_unchecked_mut(..len + 1), +.get_unchecked_mut(..=len), or similar.

+
§Examples
+
let x = &mut [1, 2, 4];
+
+unsafe {
+    let elem = x.get_unchecked_mut(1);
+    *elem = 13;
+}
+assert_eq!(x, &[1, 13, 4]);
+
1.0.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
§Examples
+
let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+    }
+}
+
1.0.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
§Examples
+
let x = &mut [1, 2, 4];
+let x_ptr = x.as_mut_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        *x_ptr.add(i) += 2;
+    }
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.48.0 · source

pub fn as_ptr_range(&self) -> Range<*const T>

Returns the two raw pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_ptr for warnings on using these pointers. The end pointer +requires extra caution, as it does not point to a valid element in the +slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+

It can also be useful to check if a pointer to an element refers to an +element of this slice:

+ +
let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
+
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
+
1.48.0 · source

pub fn as_mut_ptr_range(&mut self) -> Range<*mut T>

Returns the two unsafe mutable pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_mut_ptr for warnings on using these pointers. The end +pointer requires extra caution, as it does not point to a valid element +in the slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+
1.0.0 · source

pub fn swap(&mut self, a: usize, b: usize)

Swaps two elements in the slice.

+

If a equals to b, it’s guaranteed that elements won’t change value.

+
§Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
§Panics
+

Panics if a or b are out of bounds.

+
§Examples
+
let mut v = ["a", "b", "c", "d", "e"];
+v.swap(2, 4);
+assert!(v == ["a", "b", "e", "d", "c"]);
+
source

pub unsafe fn swap_unchecked(&mut self, a: usize, b: usize)

🔬This is a nightly-only experimental API. (slice_swap_unchecked)

Swaps two elements in the slice, without doing bounds checking.

+

For a safe alternative see swap.

+
§Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior. +The caller has to ensure that a < self.len() and b < self.len().

+
§Examples
+
#![feature(slice_swap_unchecked)]
+
+let mut v = ["a", "b", "c", "d"];
+// SAFETY: we know that 1 and 3 are both indices of the slice
+unsafe { v.swap_unchecked(1, 3) };
+assert!(v == ["a", "d", "c", "b"]);
+
1.0.0 · source

pub fn reverse(&mut self)

Reverses the order of elements in the slice, in place.

+
§Examples
+
let mut v = [1, 2, 3];
+v.reverse();
+assert!(v == [3, 2, 1]);
+
1.0.0 · source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the slice.

+

The iterator yields all items from start to end.

+
§Examples
+
let x = &[1, 2, 4];
+let mut iterator = x.iter();
+
+assert_eq!(iterator.next(), Some(&1));
+assert_eq!(iterator.next(), Some(&2));
+assert_eq!(iterator.next(), Some(&4));
+assert_eq!(iterator.next(), None);
+
1.0.0 · source

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Returns an iterator that allows modifying each value.

+

The iterator yields all items from start to end.

+
§Examples
+
let x = &mut [1, 2, 4];
+for elem in x.iter_mut() {
+    *elem += 2;
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.0.0 · source

pub fn windows(&self, size: usize) -> Windows<'_, T>

Returns an iterator over all contiguous windows of length +size. The windows overlap. If the slice is shorter than +size, the iterator returns no values.

+
§Panics
+

Panics if size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.windows(3);
+assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']);
+assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']);
+assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']);
+assert!(iter.next().is_none());
+

If the slice is shorter than size:

+ +
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
+

There’s no windows_mut, as that existing would let safe code violate the +“only one &mut at a time to the same thing” rule. However, you can sometimes +use Cell::as_slice_of_cells in +conjunction with windows to accomplish something similar:

+ +
use std::cell::Cell;
+
+let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
+let slice = &mut array[..];
+let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
+for w in slice_of_cells.windows(3) {
+    Cell::swap(&w[0], &w[2]);
+}
+assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
+
1.0.0 · source

pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See chunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and rchunks for the same iterator but starting at the end of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See chunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and rchunks_mut for the same iterator but starting at +the end of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 3]);
+
1.31.0 · source

pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks.

+

See chunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
1.31.0 · source

pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See chunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and rchunks_exact_mut for the same iterator but starting at the end of +the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
§Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
§Examples
+
#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+
source

pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
+

If you expect the slice to be an exact multiple, you can combine +let-else with an empty slice pattern:

+ +
#![feature(slice_as_chunks)]
+let slice = ['R', 'u', 's', 't'];
+let (chunks, []) = slice.as_chunks::<2>() else {
+    panic!("slice didn't have even length")
+};
+assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
+
source

pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+
source

pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are array references and do not overlap. If N does not divide the +length of the slice, then the last up to N-1 elements will be omitted and can be +retrieved from the remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
source

pub unsafe fn as_chunks_unchecked_mut<const N: usize>( + &mut self +) -> &mut [[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
§Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
§Examples
+
#![feature(slice_as_chunks)]
+let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &mut [[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[0] = ['L'];
+assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &mut [[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[1] = ['a', 'x', '?'];
+assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
+
source

pub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (chunks, remainder) = v.as_chunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 9]);
+
source

pub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (remainder, chunks) = v.as_rchunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[9, 1, 1, 2, 2]);
+
source

pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable array references and do not overlap. If N does not divide +the length of the slice, then the last up to N-1 elements will be omitted and +can be retrieved from the into_remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact_mut.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.array_chunks_mut() {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>

🔬This is a nightly-only experimental API. (array_windows)

Returns an iterator over overlapping windows of N elements of a slice, +starting at the beginning of the slice.

+

This is the const generic equivalent of windows.

+

If N is greater than the size of the slice, it will return no windows.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and chunks for the same iterator but starting at the beginning +of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and chunks_mut for the same iterator but starting at the +beginning of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[3, 2, 2, 1, 1]);
+
1.31.0 · source

pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +end of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of rchunks.

+

See rchunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and chunks_exact for the same iterator but starting at the beginning of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
+
1.31.0 · source

pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See rchunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and chunks_exact_mut for the same iterator but starting at the beginning +of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[0, 2, 2, 1, 1]);
+
1.77.0 · source

pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
where + F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping runs +of elements using the predicate to separate them.

+

The predicate is called for every pair of consecutive elements, +meaning that it is called on slice[0] and slice[1], +followed by slice[1] and slice[2], and so on.

+
§Examples
+
let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.chunk_by(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.chunk_by(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.77.0 · source

pub fn chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F>
where + F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping mutable +runs of elements using the predicate to separate them.

+

The predicate is called for every pair of consecutive elements, +meaning that it is called on slice[0] and slice[1], +followed by slice[1] and slice[2], and so on.

+
§Examples
+
let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.chunk_by_mut(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&mut [3, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.chunk_by_mut(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.0.0 · source

pub fn split_at(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
§Panics
+

Panics if mid > len. For a non-panicking alternative see +split_at_checked.

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+{
+   let (left, right) = v.split_at(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.0.0 · source

pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
§Panics
+

Panics if mid > len. For a non-panicking alternative see +split_at_mut_checked.

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+let (left, right) = v.split_at_mut(2);
+assert_eq!(left, [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.79.0 · source

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+unsafe {
+   let (left, right) = v.split_at_unchecked(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.79.0 · source

pub unsafe fn split_at_mut_unchecked( + &mut self, + mid: usize +) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at_mut.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+// scoped to restrict the lifetime of the borrows
+unsafe {
+    let (left, right) = v.split_at_mut_unchecked(2);
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.80.0 · source

pub fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])>

Divides one slice into two at an index, returning None if the slice is +too short.

+

If mid ≤ len returns a pair of slices where the first will contain all +indices from [0, mid) (excluding the index mid itself) and the +second will contain all indices from [mid, len) (excluding the index +len itself).

+

Otherwise, if mid > len, returns None.

+
§Examples
+
let v = [1, -2, 3, -4, 5, -6];
+
+{
+   let (left, right) = v.split_at_checked(0).unwrap();
+   assert_eq!(left, []);
+   assert_eq!(right, [1, -2, 3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(2).unwrap();
+    assert_eq!(left, [1, -2]);
+    assert_eq!(right, [3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(6).unwrap();
+    assert_eq!(left, [1, -2, 3, -4, 5, -6]);
+    assert_eq!(right, []);
+}
+
+assert_eq!(None, v.split_at_checked(7));
+
1.80.0 · source

pub fn split_at_mut_checked( + &mut self, + mid: usize +) -> Option<(&mut [T], &mut [T])>

Divides one mutable slice into two at an index, returning None if the +slice is too short.

+

If mid ≤ len returns a pair of slices where the first will contain all +indices from [0, mid) (excluding the index mid itself) and the +second will contain all indices from [mid, len) (excluding the index +len itself).

+

Otherwise, if mid > len, returns None.

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+
+if let Some((left, right)) = v.split_at_mut_checked(2) {
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
+assert_eq!(None, v.split_at_mut_checked(7));
+
1.0.0 · source

pub fn split<F>(&self, pred: F) -> Split<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is not contained in the subslices.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the first element is matched, an empty slice will be the first item +returned by the iterator. Similarly, if the last element in the slice +is matched, an empty slice will be the last item returned by the +iterator:

+ +
let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
+

If two matched elements are directly adjacent, an empty slice will be +present between them:

+ +
let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is not contained in the subslices.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_mut(|num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 1]);
+
1.51.0 · source

pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is contained in the end of the previous +subslice as a terminator.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the last element of the slice is matched, +that element will be considered the terminator of the preceding slice. +That slice will be the last item returned by the iterator.

+ +
let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
+
1.51.0 · source

pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is contained in the previous +subslice as a terminator.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
+    let terminator_idx = group.len()-1;
+    group[terminator_idx] = 1;
+}
+assert_eq!(v, [10, 40, 1, 20, 1, 1]);
+
1.27.0 · source

pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, starting at the end of the slice and working backwards. +The matched element is not contained in the subslices.

+
§Examples
+
let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
+
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
+

As with split(), if the first or last element is matched, an empty +slice will be the first (or last) item returned by the iterator.

+ +
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
+
1.27.0 · source

pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred, starting at the end of the slice and working +backwards. The matched element is not contained in the subslices.

+
§Examples
+
let mut v = [100, 400, 300, 200, 600, 500];
+
+let mut count = 0;
+for group in v.rsplit_mut(|num| *num % 3 == 0) {
+    count += 1;
+    group[0] = count;
+}
+assert_eq!(v, [3, 400, 300, 2, 600, 1]);
+
1.0.0 · source

pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], +[20, 60, 50]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 50]);
+
1.0.0 · source

pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once, starting from the end, by numbers divisible +by 3 (i.e., [50], [10, 40, 30, 20]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+
let mut s = [10, 40, 30, 20, 60, 50];
+
+for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(s, [1, 40, 30, 20, 60, 1]);
+
source

pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the first element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.split_once(|&x| x == 2), Some((
+    &[1][..],
+    &[3, 2, 4][..]
+)));
+assert_eq!(s.split_once(|&x| x == 0), None);
+
source

pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the last element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.rsplit_once(|&x| x == 2), Some((
+    &[1, 2, 3][..],
+    &[4][..]
+)));
+assert_eq!(s.rsplit_once(|&x| x == 0), None);
+
1.0.0 · source

pub fn contains(&self, x: &T) -> bool
where + T: PartialEq,

Returns true if the slice contains an element with the given value.

+

This operation is O(n).

+

Note that if you have a sorted slice, binary_search may be faster.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
+

If you do not have a &T, but some other value that you can compare +with one (for example, String implements PartialEq<str>), you can +use iter().any:

+ +
let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
+
1.0.0 · source

pub fn starts_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a prefix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(v.starts_with(&v));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
+
1.0.0 · source

pub fn ends_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a suffix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(v.ends_with(&v));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
+
1.51.0 · source

pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the prefix removed.

+

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. +If prefix is empty, simply returns the original slice. If prefix is equal to the +original slice, returns an empty slice.

+

If the slice does not start with prefix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
+
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+           Some(b"llo".as_ref()));
+
1.51.0 · source

pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the suffix removed.

+

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. +If suffix is empty, simply returns the original slice. If suffix is equal to the +original slice, returns an empty slice.

+

If the slice does not end with suffix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
+

Binary searches this slice for a given element. +If the slice is not sorted, the returned result is unspecified and +meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search_by, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+assert_eq!(s.binary_search(&13),  Ok(9));
+assert_eq!(s.binary_search(&4),   Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

If you want to find that whole range of matching items, rather than +an arbitrary matching one, that can be done using partition_point:

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
+

If you want to insert an item to a sorted vector, while maintaining +sort order, consider using partition_point:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+// If `num` is unique, `s.partition_point(|&x| x < num)` (with `<`) is equivalent to
+// `s.binary_search(&num).unwrap_or_else(|x| x)`, but using `<=` will allow `insert`
+// to shift less elements.
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
1.0.0 · source

pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
where + F: FnMut(&'a T) -> Ordering,

Binary searches this slice with a comparator function.

+

The comparator function should return an order code that indicates +whether its argument is Less, Equal or Greater the desired +target. +If the slice is not sorted or if the comparator function does not +implement an order consistent with the sort order of the underlying +slice, the returned result is unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.10.0 · source

pub fn binary_search_by_key<'a, B, F>( + &'a self, + b: &B, + f: F +) -> Result<usize, usize>
where + F: FnMut(&'a T) -> B, + B: Ord,

Binary searches this slice with a key extraction function.

+

Assumes that the slice is sorted by the key, for instance with +sort_by_key using the same key extraction function. +If the slice is not sorted by the key, the returned result is +unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by, and partition_point.

+
§Examples
+

Looks up a series of four elements in a slice of pairs sorted by +their second elements. The first is found, with a uniquely +determined position; the second and third are not found; the +fourth could match any position in [1, 4].

+ +
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+         (1, 21), (2, 34), (4, 55)];
+
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.20.0 · source

pub fn sort_unstable(&mut self)
where + T: Ord,

Sorts the slice, but might not preserve the order of equal elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
§Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort_unstable();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.20.0 · source

pub fn sort_unstable_by<F>(&mut self, compare: F)
where + F: FnMut(&T, &T) -> Ordering,

Sorts the slice with a comparator function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
§Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_unstable_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_unstable_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.20.0 · source

pub fn sort_unstable_by_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(m * n * log(n)) worst-case, where the key function is +O(m).

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

Due to its key calling strategy, sort_unstable_by_key +is likely to be slower than sort_by_cached_key in +cases where the key function is expensive.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_unstable_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.49.0 · source

pub fn select_nth_unstable( + &mut self, + index: usize +) -> (&mut [T], &mut T, &mut [T])
where + T: Ord,

Reorder the slice such that the element at index after the reordering is at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index. Additionally, this reordering is +unstable (i.e. any number of equal elements may end up at position index), in-place +(i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from the reordered slice: +the subslice prior to index, the element at index, and the subslice after index; +accordingly, the values in those two subslices will respectively all be less-than-or-equal-to +and greater-than-or-equal-to the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 2, -3, 1];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median.
+let (lesser, median, greater) = v.select_nth_unstable(2);
+
+assert!(lesser == [-3, -5] || lesser == [-5, -3]);
+assert_eq!(median, &mut 1);
+assert!(greater == [4, 2] || greater == [2, 4]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [-3, -5, 1, 2, 4] ||
+        v == [-5, -3, 1, 2, 4] ||
+        v == [-3, -5, 1, 4, 2] ||
+        v == [-5, -3, 1, 4, 2]);
+
1.49.0 · source

pub fn select_nth_unstable_by<F>( + &mut self, + index: usize, + compare: F +) -> (&mut [T], &mut T, &mut [T])
where + F: FnMut(&T, &T) -> Ordering,

Reorder the slice with a comparator function such that the element at index after the reordering is at +its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the comparator function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided comparator function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 2, -3, 1];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median as if the slice were sorted in descending order.
+let (lesser, median, greater) = v.select_nth_unstable_by(2, |a, b| b.cmp(a));
+
+assert!(lesser == [4, 2] || lesser == [2, 4]);
+assert_eq!(median, &mut 1);
+assert!(greater == [-3, -5] || greater == [-5, -3]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [2, 4, 1, -5, -3] ||
+        v == [2, 4, 1, -3, -5] ||
+        v == [4, 2, 1, -5, -3] ||
+        v == [4, 2, 1, -3, -5]);
+
1.49.0 · source

pub fn select_nth_unstable_by_key<K, F>( + &mut self, + index: usize, + f: F +) -> (&mut [T], &mut T, &mut [T])
where + F: FnMut(&T) -> K, + K: Ord,

Reorder the slice with a key extraction function such that the element at index after the reordering is +at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the key extraction function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided key extraction function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median as if the slice were sorted according to absolute value.
+let (lesser, median, greater) = v.select_nth_unstable_by_key(2, |a| a.abs());
+
+assert!(lesser == [1, 2] || lesser == [2, 1]);
+assert_eq!(median, &mut -3);
+assert!(greater == [4, -5] || greater == [-5, 4]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [1, 2, -3, 4, -5] ||
+        v == [1, 2, -3, -5, 4] ||
+        v == [2, 1, -3, 4, -5] ||
+        v == [2, 1, -3, -5, 4]);
+
source

pub fn partition_dedup(&mut self) -> (&mut [T], &mut [T])
where + T: PartialEq,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all consecutive repeated elements to the end of the slice according to the +PartialEq trait implementation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
+
+let (dedup, duplicates) = slice.partition_dedup();
+
+assert_eq!(dedup, [1, 2, 3, 2, 1]);
+assert_eq!(duplicates, [2, 3, 1]);
+
source

pub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T])
where + F: FnMut(&mut T, &mut T) -> bool,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice satisfying +a given equality relation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

The same_bucket function is passed references to two elements from the slice and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is moved +at the end of the slice.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
+
+let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
+assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
+
source

pub fn partition_dedup_by_key<K, F>(&mut self, key: F) -> (&mut [T], &mut [T])
where + F: FnMut(&mut T) -> K, + K: PartialEq,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice that resolve +to the same key.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
+
+let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
+
+assert_eq!(dedup, [10, 20, 30, 20, 11]);
+assert_eq!(duplicates, [21, 30, 13]);
+
1.26.0 · source

pub fn rotate_left(&mut self, mid: usize)

Rotates the slice in-place such that the first mid elements of the +slice move to the end while the last self.len() - mid elements move to +the front. After calling rotate_left, the element previously at index +mid will become the first element in the slice.

+
§Panics
+

This function will panic if mid is greater than the length of the +slice. Note that mid == self.len() does not panic and is a no-op +rotation.

+
§Complexity
+

Takes linear (in self.len()) time.

+
§Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_left(2);
+assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_left(1);
+assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+
1.26.0 · source

pub fn rotate_right(&mut self, k: usize)

Rotates the slice in-place such that the first self.len() - k +elements of the slice move to the end while the last k elements move +to the front. After calling rotate_right, the element previously at +index self.len() - k will become the first element in the slice.

+
§Panics
+

This function will panic if k is greater than the length of the +slice. Note that k == self.len() does not panic and is a no-op +rotation.

+
§Complexity
+

Takes linear (in self.len()) time.

+
§Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_right(2);
+assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_right(1);
+assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
+
1.50.0 · source

pub fn fill(&mut self, value: T)
where + T: Clone,

Fills self with elements by cloning value.

+
§Examples
+
let mut buf = vec![0; 10];
+buf.fill(1);
+assert_eq!(buf, vec![1; 10]);
+
1.51.0 · source

pub fn fill_with<F>(&mut self, f: F)
where + F: FnMut() -> T,

Fills self with elements returned by calling a closure repeatedly.

+

This method uses a closure to create new values. If you’d rather +Clone a given value, use fill. If you want to use the Default +trait to generate values, you can pass Default::default as the +argument.

+
§Examples
+
let mut buf = vec![1; 10];
+buf.fill_with(Default::default);
+assert_eq!(buf, vec![0; 10]);
+
1.7.0 · source

pub fn clone_from_slice(&mut self, src: &[T])
where + T: Clone,

Copies the elements from src into self.

+

The length of src must be the same as self.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Examples
+

Cloning two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.clone_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use clone_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].clone_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.clone_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.9.0 · source

pub fn copy_from_slice(&mut self, src: &[T])
where + T: Copy,

Copies all elements from src into self, using a memcpy.

+

The length of src must be the same as self.

+

If T does not implement Copy, use clone_from_slice.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Examples
+

Copying two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.copy_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use copy_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].copy_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.copy_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.37.0 · source

pub fn copy_within<R>(&mut self, src: R, dest: usize)
where + R: RangeBounds<usize>, + T: Copy,

Copies elements from one part of the slice to another part of itself, +using a memmove.

+

src is the range within self to copy from. dest is the starting +index of the range within self to copy to, which will have the same +length as src. The two ranges may overlap. The ends of the two ranges +must be less than or equal to self.len().

+
§Panics
+

This function will panic if either range exceeds the end of the slice, +or if the end of src is before the start.

+
§Examples
+

Copying four bytes within a slice:

+ +
let mut bytes = *b"Hello, World!";
+
+bytes.copy_within(1..5, 8);
+
+assert_eq!(&bytes, b"Hello, Wello!");
+
1.27.0 · source

pub fn swap_with_slice(&mut self, other: &mut [T])

Swaps all elements in self with those in other.

+

The length of other must be the same as self.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Example
+

Swapping two elements across slices:

+ +
let mut slice1 = [0, 0];
+let mut slice2 = [1, 2, 3, 4];
+
+slice1.swap_with_slice(&mut slice2[2..]);
+
+assert_eq!(slice1, [3, 4]);
+assert_eq!(slice2, [1, 2, 0, 0]);
+

Rust enforces that there can only be one mutable reference to a +particular piece of data in a particular scope. Because of this, +attempting to use swap_with_slice on a single slice will result in +a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +mutable sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.swap_with_slice(&mut right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 1, 2]);
+
1.30.0 · source

pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

Transmute the slice to a slice of another type, ensuring alignment of the types is +maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The middle part will be as big as possible under +the given alignment constraint and element size.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
§Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
§Examples
+

Basic usage:

+ +
unsafe {
+    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
1.30.0 · source

pub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T])

Transmute the mutable slice to a mutable slice of another type, ensuring alignment of the +types is maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The middle part will be as big as possible under +the given alignment constraint and element size.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
§Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
§Examples
+

Basic usage:

+ +
unsafe {
+    let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
source

pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
where + Simd<T, LANES>: AsRef<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.

+

This is a safe wrapper around slice::align_to, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+
§Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
§Examples
+
#![feature(portable_simd)]
+use core::simd::prelude::*;
+
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
+
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+
+fn basic_simd_sum(x: &[f32]) -> f32 {
+    use std::ops::Add;
+    let (prefix, middle, suffix) = x.as_simd();
+    let sums = f32x4::from_array([
+        prefix.iter().copied().sum(),
+        0.0,
+        0.0,
+        suffix.iter().copied().sum(),
+    ]);
+    let sums = middle.iter().copied().fold(sums, f32x4::add);
+    sums.reduce_sum()
+}
+
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+
source

pub fn as_simd_mut<const LANES: usize>( + &mut self +) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T])
where + Simd<T, LANES>: AsMut<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a mutable slice into a mutable prefix, a middle of aligned SIMD types, +and a mutable suffix.

+

This is a safe wrapper around slice::align_to_mut, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+

This is the mutable version of slice::as_simd; see that for examples.

+
§Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
source

pub fn is_sorted(&self) -> bool
where + T: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted.

+

That is, for each element a and its following element b, a <= b must hold. If the +slice yields exactly zero or one element, true is returned.

+

Note that if Self::Item is only PartialOrd, but not Ord, the above definition +implies that this function returns false if any two consecutive items are not +comparable.

+
§Examples
+
#![feature(is_sorted)]
+let empty: [i32; 0] = [];
+
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
+
source

pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> bool
where + F: FnMut(&'a T, &'a T) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given comparator function.

+

Instead of using PartialOrd::partial_cmp, this function uses the given compare +function to determine whether two elements are to be considered in sorted order.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!([1, 2, 2, 9].is_sorted_by(|a, b| a <= b));
+assert!(![1, 2, 2, 9].is_sorted_by(|a, b| a < b));
+
+assert!([0].is_sorted_by(|a, b| true));
+assert!([0].is_sorted_by(|a, b| false));
+
+let empty: [i32; 0] = [];
+assert!(empty.is_sorted_by(|a, b| false));
+assert!(empty.is_sorted_by(|a, b| true));
+
source

pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
where + F: FnMut(&'a T) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given key extraction function.

+

Instead of comparing the slice’s elements directly, this function compares the keys of the +elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its +documentation for more information.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+
1.52.0 · source

pub fn partition_point<P>(&self, pred: P) -> usize
where + P: FnMut(&T) -> bool,

Returns the index of the partition point according to the given predicate +(the index of the first element of the second partition).

+

The slice is assumed to be partitioned according to the given predicate. +This means that all elements for which the predicate returns true are at the start of the slice +and all elements for which the predicate returns false are at the end. +For example, [7, 15, 3, 5, 4, 12, 6] is partitioned under the predicate x % 2 != 0 +(all odd numbers are at the start, all even at the end).

+

If this slice is not partitioned, the returned result is unspecified and meaningless, +as this method performs a kind of binary search.

+

See also binary_search, binary_search_by, and binary_search_by_key.

+
§Examples
+
let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
+
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
+

If all elements of the slice match the predicate, including if the slice +is empty, then the length of the slice will be returned:

+ +
let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
+

If you want to insert an item to a sorted vector, while maintaining +sort order:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
source

pub fn take<'a, R>(self: &mut &'a [T], range: R) -> Option<&'a [T]>
where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
§Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut first_three = slice.take(..3).unwrap();
+
+assert_eq!(slice, &['d']);
+assert_eq!(first_three, &['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut tail = slice.take(2..).unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(tail, &['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take(5..));
+assert_eq!(None, slice.take(..5));
+assert_eq!(None, slice.take(..=4));
+let expected: &[char] = &['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take(..4));
+
source

pub fn take_mut<'a, R>(self: &mut &'a mut [T], range: R) -> Option<&'a mut [T]>
where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a mutable reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
§Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut first_three = slice.take_mut(..3).unwrap();
+
+assert_eq!(slice, &mut ['d']);
+assert_eq!(first_three, &mut ['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut tail = slice.take_mut(2..).unwrap();
+
+assert_eq!(slice, &mut ['a', 'b']);
+assert_eq!(tail, &mut ['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take_mut(5..));
+assert_eq!(None, slice.take_mut(..5));
+assert_eq!(None, slice.take_mut(..=4));
+let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take_mut(..4));
+
source

pub fn take_first<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let first = slice.take_first().unwrap();
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'a');
+
source

pub fn take_first_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let first = slice.take_first_mut().unwrap();
+*first = 'd';
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'d');
+
source

pub fn take_last<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let last = slice.take_last().unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'c');
+
source

pub fn take_last_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let last = slice.take_last_mut().unwrap();
+*last = 'd';
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'d');
+
source

pub unsafe fn get_many_unchecked_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> [&mut T; N]

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once, without doing any checks.

+

For a safe alternative see get_many_mut.

+
§Safety
+

Calling this method with overlapping or out-of-bounds indices is undefined behavior +even if the resulting references are not used.

+
§Examples
+
#![feature(get_many_mut)]
+
+let x = &mut [1, 2, 4];
+
+unsafe {
+    let [a, b] = x.get_many_unchecked_mut([0, 2]);
+    *a *= 10;
+    *b *= 100;
+}
+assert_eq!(x, &[10, 2, 400]);
+
source

pub fn get_many_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> Result<[&mut T; N], GetManyMutError<N>>

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once.

+

Returns an error if any index is out-of-bounds, or if the same index was +passed more than once.

+
§Examples
+
#![feature(get_many_mut)]
+
+let v = &mut [1, 2, 3];
+if let Ok([a, b]) = v.get_many_mut([0, 2]) {
+    *a = 413;
+    *b = 612;
+}
+assert_eq!(v, &[413, 2, 612]);
+
1.79.0 · source

pub fn utf8_chunks(&self) -> Utf8Chunks<'_>

Creates an iterator over the contiguous valid UTF-8 ranges of this +slice, and the non-UTF-8 fragments in between.

+
§Examples
+

This function formats arbitrary but mostly-UTF-8 bytes into Rust source +code in the form of a C-string literal (c"...").

+ +
use std::fmt::Write as _;
+
+pub fn cstr_literal(bytes: &[u8]) -> String {
+    let mut repr = String::new();
+    repr.push_str("c\"");
+    for chunk in bytes.utf8_chunks() {
+        for ch in chunk.valid().chars() {
+            // Escapes \0, \t, \r, \n, \\, \', \", and uses \u{...} for non-printable characters.
+            write!(repr, "{}", ch.escape_debug()).unwrap();
+        }
+        for byte in chunk.invalid() {
+            write!(repr, "\\x{:02X}", byte).unwrap();
+        }
+    }
+    repr.push('"');
+    repr
+}
+
+fn main() {
+    let lit = cstr_literal(b"\xferris the \xf0\x9f\xa6\x80\x07");
+    let expected = stringify!(c"\xFErris the 🦀\u{7}");
+    assert_eq!(lit, expected);
+}
+
1.23.0 · source

pub fn is_ascii(&self) -> bool

Checks if all bytes in this slice are within the ASCII range.

+
source

pub fn as_ascii(&self) -> Option<&[AsciiChar]>

🔬This is a nightly-only experimental API. (ascii_char)

If this slice is_ascii, returns it as a slice of +ASCII characters, otherwise returns None.

+
source

pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]

🔬This is a nightly-only experimental API. (ascii_char)

Converts this slice of bytes into a slice of ASCII characters, +without checking whether they’re valid.

+
§Safety
+

Every byte in the slice must be in 0..=127, or else this is UB.

+
1.23.0 · source

pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool

Checks that two slices are an ASCII case-insensitive match.

+

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), +but without allocating and copying temporaries.

+
1.23.0 · source

pub fn make_ascii_uppercase(&mut self)

Converts this slice to its ASCII upper case equivalent in-place.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To return a new uppercased value without modifying the existing one, use +to_ascii_uppercase.

+
1.23.0 · source

pub fn make_ascii_lowercase(&mut self)

Converts this slice to its ASCII lower case equivalent in-place.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To return a new lowercased value without modifying the existing one, use +to_ascii_lowercase.

+
1.60.0 · source

pub fn escape_ascii(&self) -> EscapeAscii<'_>

Returns an iterator that produces an escaped version of this slice, +treating it as an ASCII string.

+
§Examples
+

+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
+
1.80.0 · source

pub fn trim_ascii_start(&self) -> &[u8]

Returns a byte slice with leading ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b"  ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
+
1.80.0 · source

pub fn trim_ascii_end(&self) -> &[u8]

Returns a byte slice with trailing ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b"  ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
+
1.80.0 · source

pub fn trim_ascii(&self) -> &[u8]

Returns a byte slice with leading and trailing ASCII whitespace bytes +removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b"  ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f64::total_cmp.

+
§Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
§Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
source

pub fn as_str(&self) -> &str

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a UTF-8 str.

+
source

pub fn as_bytes(&self) -> &[u8]

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a slice of u8 bytes.

+
1.0.0 · source

pub fn sort(&mut self)
where + T: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.0.0 · source

pub fn sort_by<F>(&mut self, compare: F)
where + F: FnMut(&T, &T) -> Ordering,

Available on non-no_global_oom_handling only.

Sorts the slice with a comparator function.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.7.0 · source

pub fn sort_by_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n * log(n)) +worst-case, where the key function is O(m).

+

For expensive key functions (e.g. functions that are not simple property accesses or +basic operations), sort_by_cached_key is likely to be +significantly faster, as it does not recompute element keys.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by_key.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.34.0 · source

pub fn sort_by_cached_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

During sorting, the key function is called at most once per element, by using +temporary storage to remember the results of key evaluation. +The order of calls to the key function is unspecified and may change in future versions +of the standard library.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n + n * log(n)) +worst-case, where the key function is O(m).

+

For simple key functions (e.g., functions that are property accesses or +basic operations), sort_by_key is likely to be +faster.

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

In the worst case, the algorithm allocates temporary storage in a Vec<(K, usize)> the +length of the slice.

+
§Examples
+
let mut v = [-5i32, 4, 32, -3, 2];
+
+v.sort_by_cached_key(|k| k.to_string());
+assert!(v == [-3, -5, 2, 32, 4]);
+
1.0.0 · source

pub fn to_vec(&self) -> Vec<T>
where + T: Clone,

Available on non-no_global_oom_handling only.

Copies self into a new Vec.

+
§Examples
+
let s = [10, 40, 30];
+let x = s.to_vec();
+// Here, `s` and `x` can be modified independently.
+
source

pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>
where + A: Allocator, + T: Clone,

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Copies self into a new Vec with an allocator.

+
§Examples
+
#![feature(allocator_api)]
+
+use std::alloc::System;
+
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
+// Here, `s` and `x` can be modified independently.
+
1.40.0 · source

pub fn repeat(&self, n: usize) -> Vec<T>
where + T: Copy,

Available on non-no_global_oom_handling only.

Creates a vector by copying a slice n times.

+
§Panics
+

This function will panic if the capacity would overflow.

+
§Examples
+

Basic usage:

+ +
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
+

A panic upon overflow:

+ +
// this will panic at runtime
+b"0123456789abcdef".repeat(usize::MAX);
+
1.0.0 · source

pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output
where + [T]: Concat<Item>, + Item: ?Sized,

Flattens a slice of T into a single value Self::Output.

+
§Examples
+
assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+
1.3.0 · source

pub fn join<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+
1.0.0 · source

pub fn connect<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

👎Deprecated since 1.3.0: renamed to join

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+
1.23.0 · source

pub fn to_ascii_uppercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII upper case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To uppercase the value in-place, use make_ascii_uppercase.

+
1.23.0 · source

pub fn to_ascii_lowercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII lower case equivalent.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To lowercase the value in-place, use make_ascii_lowercase.

+

Trait Implementations§

source§

impl Clone for Allow

source§

fn clone(&self) -> Allow

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Allow

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for Allow

§

type Target = Vec<Method>

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for Allow

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl Display for Allow

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for Allow

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for Allow

source§

fn eq(&self, other: &Allow) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for Allow

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for Allow

source§

impl StructuralPartialEq for Allow

Auto Trait Implementations§

§

impl Freeze for Allow

§

impl RefUnwindSafe for Allow

§

impl Send for Allow

§

impl Sync for Allow

§

impl Unpin for Allow

§

impl UnwindSafe for Allow

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.CacheControl.html b/actix_web/http/header/struct.CacheControl.html new file mode 100644 index 000000000..19f850704 --- /dev/null +++ b/actix_web/http/header/struct.CacheControl.html @@ -0,0 +1,3133 @@ +CacheControl in actix_web::http::header - Rust

Struct actix_web::http::header::CacheControl

source ·
pub struct CacheControl(pub Vec<CacheDirective>);
Expand description

Cache-Control header, defined +in RFC 7234 §5.2.

+

The Cache-Control header field is used to specify directives for +caches along the request/response chain. Such cache directives are +unidirectional in that the presence of a directive in a request does +not imply that the same directive is to be given in the response.

+

§ABNF

Cache-Control   = 1#cache-directive
+cache-directive = token [ "=" ( token / quoted-string ) ]
+

§Example Values

+
    +
  • no-cache
  • +
  • private, community="UCI"
  • +
  • max-age=30
  • +
+

§Examples

+
use actix_web::HttpResponse;
+use actix_web::http::header::{CacheControl, CacheDirective};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(CacheControl(vec![CacheDirective::MaxAge(86400u32)]));
+ +
use actix_web::HttpResponse;
+use actix_web::http::header::{CacheControl, CacheDirective};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(CacheControl(vec![
+    CacheDirective::NoCache,
+    CacheDirective::Private,
+    CacheDirective::MaxAge(360u32),
+    CacheDirective::Extension("foo".to_owned(), Some("bar".to_owned())),
+]));
+

Tuple Fields§

§0: Vec<CacheDirective>

Methods from Deref<Target = Vec<CacheDirective>>§

1.0.0 · source

pub fn capacity(&self) -> usize

Returns the total number of elements the vector can hold without +reallocating.

+
§Examples
+
let mut vec: Vec<i32> = Vec::with_capacity(10);
+vec.push(42);
+assert!(vec.capacity() >= 10);
+
1.0.0 · source

pub fn reserve(&mut self, additional: usize)

Available on non-no_global_oom_handling only.

Reserves capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to +speculatively avoid frequent reallocations. After calling reserve, +capacity will be greater than or equal to self.len() + additional. +Does nothing if capacity is already sufficient.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1];
+vec.reserve(10);
+assert!(vec.capacity() >= 11);
+
1.0.0 · source

pub fn reserve_exact(&mut self, additional: usize)

Available on non-no_global_oom_handling only.

Reserves the minimum capacity for at least additional more elements to +be inserted in the given Vec<T>. Unlike reserve, this will not +deliberately over-allocate to speculatively avoid frequent allocations. +After calling reserve_exact, capacity will be greater than or equal to +self.len() + additional. Does nothing if the capacity is already +sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer reserve if future insertions are expected.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1];
+vec.reserve_exact(10);
+assert!(vec.capacity() >= 11);
+
1.57.0 · source

pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>

Tries to reserve capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to speculatively avoid +frequent reallocations. After calling try_reserve, capacity will be +greater than or equal to self.len() + additional if it returns +Ok(()). Does nothing if capacity is already sufficient. This method +preserves the contents even if an error occurs.

+
§Errors
+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+
§Examples
+
use std::collections::TryReserveError;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+
1.57.0 · source

pub fn try_reserve_exact( + &mut self, + additional: usize +) -> Result<(), TryReserveError>

Tries to reserve the minimum capacity for at least additional +elements to be inserted in the given Vec<T>. Unlike try_reserve, +this will not deliberately over-allocate to speculatively avoid frequent +allocations. After calling try_reserve_exact, capacity will be greater +than or equal to self.len() + additional if it returns Ok(()). +Does nothing if the capacity is already sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer try_reserve if future insertions are expected.

+
§Errors
+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+
§Examples
+
use std::collections::TryReserveError;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve_exact(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+
1.0.0 · source

pub fn shrink_to_fit(&mut self)

Available on non-no_global_oom_handling only.

Shrinks the capacity of the vector as much as possible.

+

The behavior of this method depends on the allocator, which may either shrink the vector +in-place or reallocate. The resulting vector might still have some excess capacity, just as +is the case for with_capacity. See Allocator::shrink for more details.

+
§Examples
+
let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3]);
+assert!(vec.capacity() >= 10);
+vec.shrink_to_fit();
+assert!(vec.capacity() >= 3);
+
1.56.0 · source

pub fn shrink_to(&mut self, min_capacity: usize)

Available on non-no_global_oom_handling only.

Shrinks the capacity of the vector with a lower bound.

+

The capacity will remain at least as large as both the length +and the supplied value.

+

If the current capacity is less than the lower limit, this is a no-op.

+
§Examples
+
let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3]);
+assert!(vec.capacity() >= 10);
+vec.shrink_to(4);
+assert!(vec.capacity() >= 4);
+vec.shrink_to(0);
+assert!(vec.capacity() >= 3);
+
1.0.0 · source

pub fn truncate(&mut self, len: usize)

Shortens the vector, keeping the first len elements and dropping +the rest.

+

If len is greater or equal to the vector’s current length, this has +no effect.

+

The drain method can emulate truncate, but causes the excess +elements to be returned instead of dropped.

+

Note that this method has no effect on the allocated capacity +of the vector.

+
§Examples
+

Truncating a five element vector to two elements:

+ +
let mut vec = vec![1, 2, 3, 4, 5];
+vec.truncate(2);
+assert_eq!(vec, [1, 2]);
+

No truncation occurs when len is greater than the vector’s current +length:

+ +
let mut vec = vec![1, 2, 3];
+vec.truncate(8);
+assert_eq!(vec, [1, 2, 3]);
+

Truncating when len == 0 is equivalent to calling the clear +method.

+ +
let mut vec = vec![1, 2, 3];
+vec.truncate(0);
+assert_eq!(vec, []);
+
1.7.0 · source

pub fn as_slice(&self) -> &[T]

Extracts a slice containing the entire vector.

+

Equivalent to &s[..].

+
§Examples
+
use std::io::{self, Write};
+let buffer = vec![1, 2, 3, 5, 8];
+io::sink().write(buffer.as_slice()).unwrap();
+
1.7.0 · source

pub fn as_mut_slice(&mut self) -> &mut [T]

Extracts a mutable slice of the entire vector.

+

Equivalent to &mut s[..].

+
§Examples
+
use std::io::{self, Read};
+let mut buffer = vec![0; 3];
+io::repeat(0b101).read_exact(buffer.as_mut_slice()).unwrap();
+
1.37.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the vector’s buffer, or a dangling raw pointer +valid for zero sized reads if the vector didn’t allocate.

+

The caller must ensure that the vector outlives the pointer this +function returns, or else it will end up pointing to garbage. +Modifying the vector may cause its buffer to be reallocated, +which would also make any pointers to it invalid.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

This method guarantees that for the purpose of the aliasing model, this method +does not materialize a reference to the underlying slice, and thus the returned pointer +will remain valid when mixed with other calls to as_ptr and as_mut_ptr. +Note that calling other methods that materialize mutable references to the slice, +or mutable references to specific elements you are planning on accessing through this pointer, +as well as writing to those elements, may still invalidate this pointer. +See the second example below for how this guarantee can be used.

+
§Examples
+
let x = vec![1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(*x_ptr.add(i), 1 << i);
+    }
+}
+

Due to the aliasing guarantee, the following code is legal:

+ +
unsafe {
+    let mut v = vec![0, 1, 2];
+    let ptr1 = v.as_ptr();
+    let _ = ptr1.read();
+    let ptr2 = v.as_mut_ptr().offset(2);
+    ptr2.write(2);
+    // Notably, the write to `ptr2` did *not* invalidate `ptr1`
+    // because it mutated a different element:
+    let _ = ptr1.read();
+}
+
1.37.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the vector’s buffer, or a dangling +raw pointer valid for zero sized reads if the vector didn’t allocate.

+

The caller must ensure that the vector outlives the pointer this +function returns, or else it will end up pointing to garbage. +Modifying the vector may cause its buffer to be reallocated, +which would also make any pointers to it invalid.

+

This method guarantees that for the purpose of the aliasing model, this method +does not materialize a reference to the underlying slice, and thus the returned pointer +will remain valid when mixed with other calls to as_ptr and as_mut_ptr. +Note that calling other methods that materialize references to the slice, +or references to specific elements you are planning on accessing through this pointer, +may still invalidate this pointer. +See the second example below for how this guarantee can be used.

+
§Examples
+
// Allocate vector big enough for 4 elements.
+let size = 4;
+let mut x: Vec<i32> = Vec::with_capacity(size);
+let x_ptr = x.as_mut_ptr();
+
+// Initialize elements via raw pointer writes, then set length.
+unsafe {
+    for i in 0..size {
+        *x_ptr.add(i) = i as i32;
+    }
+    x.set_len(size);
+}
+assert_eq!(&*x, &[0, 1, 2, 3]);
+

Due to the aliasing guarantee, the following code is legal:

+ +
unsafe {
+    let mut v = vec![0];
+    let ptr1 = v.as_mut_ptr();
+    ptr1.write(1);
+    let ptr2 = v.as_mut_ptr();
+    ptr2.write(2);
+    // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
+    ptr1.write(3);
+}
+
source

pub fn allocator(&self) -> &A

🔬This is a nightly-only experimental API. (allocator_api)

Returns a reference to the underlying allocator.

+
1.0.0 · source

pub unsafe fn set_len(&mut self, new_len: usize)

Forces the length of the vector to new_len.

+

This is a low-level operation that maintains none of the normal +invariants of the type. Normally changing the length of a vector +is done using one of the safe operations instead, such as +truncate, resize, extend, or clear.

+
§Safety
+
    +
  • new_len must be less than or equal to capacity().
  • +
  • The elements at old_len..new_len must be initialized.
  • +
+
§Examples
+

This method can be useful for situations in which the vector +is serving as a buffer for other code, particularly over FFI:

+ +
pub fn get_dictionary(&self) -> Option<Vec<u8>> {
+    // Per the FFI method's docs, "32768 bytes is always enough".
+    let mut dict = Vec::with_capacity(32_768);
+    let mut dict_length = 0;
+    // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
+    // 1. `dict_length` elements were initialized.
+    // 2. `dict_length` <= the capacity (32_768)
+    // which makes `set_len` safe to call.
+    unsafe {
+        // Make the FFI call...
+        let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
+        if r == Z_OK {
+            // ...and update the length to what was initialized.
+            dict.set_len(dict_length);
+            Some(dict)
+        } else {
+            None
+        }
+    }
+}
+

While the following example is sound, there is a memory leak since +the inner vectors were not freed prior to the set_len call:

+ +
let mut vec = vec![vec![1, 0, 0],
+                   vec![0, 1, 0],
+                   vec![0, 0, 1]];
+// SAFETY:
+// 1. `old_len..0` is empty so no elements need to be initialized.
+// 2. `0 <= capacity` always holds whatever `capacity` is.
+unsafe {
+    vec.set_len(0);
+}
+

Normally, here, one would use clear instead to correctly drop +the contents and thus not leak memory.

+
1.0.0 · source

pub fn swap_remove(&mut self, index: usize) -> T

Removes an element from the vector and returns it.

+

The removed element is replaced by the last element of the vector.

+

This does not preserve ordering of the remaining elements, but is O(1). +If you need to preserve the element order, use remove instead.

+
§Panics
+

Panics if index is out of bounds.

+
§Examples
+
let mut v = vec!["foo", "bar", "baz", "qux"];
+
+assert_eq!(v.swap_remove(1), "bar");
+assert_eq!(v, ["foo", "qux", "baz"]);
+
+assert_eq!(v.swap_remove(0), "foo");
+assert_eq!(v, ["baz", "qux"]);
+
1.0.0 · source

pub fn insert(&mut self, index: usize, element: T)

Available on non-no_global_oom_handling only.

Inserts an element at position index within the vector, shifting all +elements after it to the right.

+
§Panics
+

Panics if index > len.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+vec.insert(1, 4);
+assert_eq!(vec, [1, 4, 2, 3]);
+vec.insert(4, 5);
+assert_eq!(vec, [1, 4, 2, 3, 5]);
+
§Time complexity
+

Takes O(Vec::len) time. All items after the insertion index must be +shifted to the right. In the worst case, all elements are shifted when +the insertion index is 0.

+
1.0.0 · source

pub fn remove(&mut self, index: usize) -> T

Removes and returns the element at position index within the vector, +shifting all elements after it to the left.

+

Note: Because this shifts over the remaining elements, it has a +worst-case performance of O(n). If you don’t need the order of elements +to be preserved, use swap_remove instead. If you’d like to remove +elements from the beginning of the Vec, consider using +VecDeque::pop_front instead.

+
§Panics
+

Panics if index is out of bounds.

+
§Examples
+
let mut v = vec![1, 2, 3];
+assert_eq!(v.remove(1), 2);
+assert_eq!(v, [1, 3]);
+
1.0.0 · source

pub fn retain<F>(&mut self, f: F)
where + F: FnMut(&T) -> bool,

Retains only the elements specified by the predicate.

+

In other words, remove all elements e for which f(&e) returns false. +This method operates in place, visiting each element exactly once in the +original order, and preserves the order of the retained elements.

+
§Examples
+
let mut vec = vec![1, 2, 3, 4];
+vec.retain(|&x| x % 2 == 0);
+assert_eq!(vec, [2, 4]);
+

Because the elements are visited exactly once in the original order, +external state may be used to decide which elements to keep.

+ +
let mut vec = vec![1, 2, 3, 4, 5];
+let keep = [false, true, true, false, true];
+let mut iter = keep.iter();
+vec.retain(|_| *iter.next().unwrap());
+assert_eq!(vec, [2, 3, 5]);
+
1.61.0 · source

pub fn retain_mut<F>(&mut self, f: F)
where + F: FnMut(&mut T) -> bool,

Retains only the elements specified by the predicate, passing a mutable reference to it.

+

In other words, remove all elements e such that f(&mut e) returns false. +This method operates in place, visiting each element exactly once in the +original order, and preserves the order of the retained elements.

+
§Examples
+
let mut vec = vec![1, 2, 3, 4];
+vec.retain_mut(|x| if *x <= 3 {
+    *x += 1;
+    true
+} else {
+    false
+});
+assert_eq!(vec, [2, 3, 4]);
+
1.16.0 · source

pub fn dedup_by_key<F, K>(&mut self, key: F)
where + F: FnMut(&mut T) -> K, + K: PartialEq,

Removes all but the first of consecutive elements in the vector that resolve to the same +key.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec![10, 20, 21, 30, 20];
+
+vec.dedup_by_key(|i| *i / 10);
+
+assert_eq!(vec, [10, 20, 30, 20]);
+
1.16.0 · source

pub fn dedup_by<F>(&mut self, same_bucket: F)
where + F: FnMut(&mut T, &mut T) -> bool,

Removes all but the first of consecutive elements in the vector satisfying a given equality +relation.

+

The same_bucket function is passed references to two elements from the vector and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is removed.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
+
+vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
+
1.0.0 · source

pub fn push(&mut self, value: T)

Available on non-no_global_oom_handling only.

Appends an element to the back of a collection.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1, 2];
+vec.push(3);
+assert_eq!(vec, [1, 2, 3]);
+
§Time complexity
+

Takes amortized O(1) time. If the vector’s length would exceed its +capacity after the push, O(capacity) time is taken to copy the +vector’s elements to a larger allocation. This expensive operation is +offset by the capacity O(1) insertions it allows.

+
source

pub fn push_within_capacity(&mut self, value: T) -> Result<(), T>

🔬This is a nightly-only experimental API. (vec_push_within_capacity)

Appends an element if there is sufficient spare capacity, otherwise an error is returned +with the element.

+

Unlike push this method will not reallocate when there’s insufficient capacity. +The caller should use reserve or try_reserve to ensure that there is enough capacity.

+
§Examples
+

A manual, panic-free alternative to FromIterator:

+ +
#![feature(vec_push_within_capacity)]
+
+use std::collections::TryReserveError;
+fn from_iter_fallible<T>(iter: impl Iterator<Item=T>) -> Result<Vec<T>, TryReserveError> {
+    let mut vec = Vec::new();
+    for value in iter {
+        if let Err(value) = vec.push_within_capacity(value) {
+            vec.try_reserve(1)?;
+            // this cannot fail, the previous line either returned or added at least 1 free slot
+            let _ = vec.push_within_capacity(value);
+        }
+    }
+    Ok(vec)
+}
+assert_eq!(from_iter_fallible(0..100), Ok(Vec::from_iter(0..100)));
+
§Time complexity
+

Takes O(1) time.

+
1.0.0 · source

pub fn pop(&mut self) -> Option<T>

Removes the last element from a vector and returns it, or None if it +is empty.

+

If you’d like to pop the first element, consider using +VecDeque::pop_front instead.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+assert_eq!(vec.pop(), Some(3));
+assert_eq!(vec, [1, 2]);
+
§Time complexity
+

Takes O(1) time.

+
source

pub fn pop_if<F>(&mut self, f: F) -> Option<T>
where + F: FnOnce(&mut T) -> bool,

🔬This is a nightly-only experimental API. (vec_pop_if)

Removes and returns the last element in a vector if the predicate +returns true, or None if the predicate returns false or the vector +is empty.

+
§Examples
+
#![feature(vec_pop_if)]
+
+let mut vec = vec![1, 2, 3, 4];
+let pred = |x: &mut i32| *x % 2 == 0;
+
+assert_eq!(vec.pop_if(pred), Some(4));
+assert_eq!(vec, [1, 2, 3]);
+assert_eq!(vec.pop_if(pred), None);
+
1.4.0 · source

pub fn append(&mut self, other: &mut Vec<T, A>)

Available on non-no_global_oom_handling only.

Moves all the elements of other into self, leaving other empty.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+let mut vec2 = vec![4, 5, 6];
+vec.append(&mut vec2);
+assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
+assert_eq!(vec2, []);
+
1.6.0 · source

pub fn drain<R>(&mut self, range: R) -> Drain<'_, T, A>
where + R: RangeBounds<usize>,

Removes the specified range from the vector in bulk, returning all +removed elements as an iterator. If the iterator is dropped before +being fully consumed, it drops the remaining removed elements.

+

The returned iterator keeps a mutable borrow on the vector to optimize +its implementation.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Leaking
+

If the returned iterator goes out of scope without being dropped (due to +mem::forget, for example), the vector may have lost and leaked +elements arbitrarily, including elements outside the range.

+
§Examples
+
let mut v = vec![1, 2, 3];
+let u: Vec<_> = v.drain(1..).collect();
+assert_eq!(v, &[1]);
+assert_eq!(u, &[2, 3]);
+
+// A full range clears the vector, like `clear()` does
+v.drain(..);
+assert_eq!(v, &[]);
+
1.0.0 · source

pub fn clear(&mut self)

Clears the vector, removing all values.

+

Note that this method has no effect on the allocated capacity +of the vector.

+
§Examples
+
let mut v = vec![1, 2, 3];
+
+v.clear();
+
+assert!(v.is_empty());
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the vector, also referred to +as its ‘length’.

+
§Examples
+
let a = vec![1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the vector contains no elements.

+
§Examples
+
let mut v = Vec::new();
+assert!(v.is_empty());
+
+v.push(1);
+assert!(!v.is_empty());
+
1.4.0 · source

pub fn split_off(&mut self, at: usize) -> Vec<T, A>
where + A: Clone,

Available on non-no_global_oom_handling only.

Splits the collection into two at the given index.

+

Returns a newly allocated vector containing the elements in the range +[at, len). After the call, the original vector will be left containing +the elements [0, at) with its previous capacity unchanged.

+
    +
  • If you want to take ownership of the entire contents and capacity of +the vector, see mem::take or mem::replace.
  • +
  • If you don’t need the returned vector at all, see Vec::truncate.
  • +
  • If you want to take ownership of an arbitrary subslice, or you don’t +necessarily want to store the removed items in a vector, see Vec::drain.
  • +
+
§Panics
+

Panics if at > len.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+let vec2 = vec.split_off(1);
+assert_eq!(vec, [1]);
+assert_eq!(vec2, [2, 3]);
+
1.33.0 · source

pub fn resize_with<F>(&mut self, new_len: usize, f: F)
where + F: FnMut() -> T,

Available on non-no_global_oom_handling only.

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with the result of +calling the closure f. The return values from f will end up +in the Vec in the order they have been generated.

+

If new_len is less than len, the Vec is simply truncated.

+

This method uses a closure to create new values on every push. If +you’d rather Clone a given value, use Vec::resize. If you +want to use the Default trait to generate values, you can +pass Default::default as the second argument.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+vec.resize_with(5, Default::default);
+assert_eq!(vec, [1, 2, 3, 0, 0]);
+
+let mut vec = vec![];
+let mut p = 1;
+vec.resize_with(4, || { p *= 2; p });
+assert_eq!(vec, [2, 4, 8, 16]);
+
1.60.0 · source

pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>]

Returns the remaining spare capacity of the vector as a slice of +MaybeUninit<T>.

+

The returned slice can be used to fill the vector with data (e.g. by +reading from a file) before marking the data as initialized using the +set_len method.

+
§Examples
+
// Allocate vector big enough for 10 elements.
+let mut v = Vec::with_capacity(10);
+
+// Fill in the first 3 elements.
+let uninit = v.spare_capacity_mut();
+uninit[0].write(0);
+uninit[1].write(1);
+uninit[2].write(2);
+
+// Mark the first 3 elements of the vector as being initialized.
+unsafe {
+    v.set_len(3);
+}
+
+assert_eq!(&v, &[0, 1, 2]);
+
source

pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>])

🔬This is a nightly-only experimental API. (vec_split_at_spare)

Returns vector content as a slice of T, along with the remaining spare +capacity of the vector as a slice of MaybeUninit<T>.

+

The returned spare capacity slice can be used to fill the vector with data +(e.g. by reading from a file) before marking the data as initialized using +the set_len method.

+

Note that this is a low-level API, which should be used with care for +optimization purposes. If you need to append data to a Vec +you can use push, extend, extend_from_slice, +extend_from_within, insert, append, resize or +resize_with, depending on your exact needs.

+
§Examples
+
#![feature(vec_split_at_spare)]
+
+let mut v = vec![1, 1, 2];
+
+// Reserve additional space big enough for 10 elements.
+v.reserve(10);
+
+let (init, uninit) = v.split_at_spare_mut();
+let sum = init.iter().copied().sum::<u32>();
+
+// Fill in the next 4 elements.
+uninit[0].write(sum);
+uninit[1].write(sum * 2);
+uninit[2].write(sum * 3);
+uninit[3].write(sum * 4);
+
+// Mark the 4 elements of the vector as being initialized.
+unsafe {
+    let len = v.len();
+    v.set_len(len + 4);
+}
+
+assert_eq!(&v, &[1, 1, 2, 4, 8, 12, 16]);
+
1.5.0 · source

pub fn resize(&mut self, new_len: usize, value: T)

Available on non-no_global_oom_handling only.

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with value. +If new_len is less than len, the Vec is simply truncated.

+

This method requires T to implement Clone, +in order to be able to clone the passed value. +If you need more flexibility (or want to rely on Default instead of +Clone), use Vec::resize_with. +If you only need to resize to a smaller size, use Vec::truncate.

+
§Examples
+
let mut vec = vec!["hello"];
+vec.resize(3, "world");
+assert_eq!(vec, ["hello", "world", "world"]);
+
+let mut vec = vec![1, 2, 3, 4];
+vec.resize(2, 0);
+assert_eq!(vec, [1, 2]);
+
1.6.0 · source

pub fn extend_from_slice(&mut self, other: &[T])

Available on non-no_global_oom_handling only.

Clones and appends all elements in a slice to the Vec.

+

Iterates over the slice other, clones each element, and then appends +it to this Vec. The other slice is traversed in-order.

+

Note that this function is same as extend except that it is +specialized to work with slices instead. If and when Rust gets +specialization this function will likely be deprecated (but still +available).

+
§Examples
+
let mut vec = vec![1];
+vec.extend_from_slice(&[2, 3, 4]);
+assert_eq!(vec, [1, 2, 3, 4]);
+
1.53.0 · source

pub fn extend_from_within<R>(&mut self, src: R)
where + R: RangeBounds<usize>,

Available on non-no_global_oom_handling only.

Copies elements from src range to the end of the vector.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Examples
+
let mut vec = vec![0, 1, 2, 3, 4];
+
+vec.extend_from_within(2..);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
+
+vec.extend_from_within(..2);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
+
+vec.extend_from_within(4..8);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
+
1.0.0 · source

pub fn dedup(&mut self)

Removes consecutive repeated elements in the vector according to the +PartialEq trait implementation.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec![1, 2, 2, 3, 2];
+
+vec.dedup();
+
+assert_eq!(vec, [1, 2, 3, 2]);
+
1.21.0 · source

pub fn splice<R, I>( + &mut self, + range: R, + replace_with: I +) -> Splice<'_, <I as IntoIterator>::IntoIter, A>
where + R: RangeBounds<usize>, + I: IntoIterator<Item = T>,

Available on non-no_global_oom_handling only.

Creates a splicing iterator that replaces the specified range in the vector +with the given replace_with iterator and yields the removed items. +replace_with does not need to be the same length as range.

+

range is removed even if the iterator is not consumed until the end.

+

It is unspecified how many elements are removed from the vector +if the Splice value is leaked.

+

The input iterator replace_with is only consumed when the Splice value is dropped.

+

This is optimal if:

+
    +
  • The tail (elements in the vector after range) is empty,
  • +
  • or replace_with yields fewer or equal elements than range’s length
  • +
  • or the lower bound of its size_hint() is exact.
  • +
+

Otherwise, a temporary vector is allocated and the tail is moved twice.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Examples
+
let mut v = vec![1, 2, 3, 4];
+let new = [7, 8, 9];
+let u: Vec<_> = v.splice(1..3, new).collect();
+assert_eq!(v, &[1, 7, 8, 9, 4]);
+assert_eq!(u, &[2, 3]);
+
source

pub fn extract_if<F>(&mut self, filter: F) -> ExtractIf<'_, T, F, A>
where + F: FnMut(&mut T) -> bool,

🔬This is a nightly-only experimental API. (extract_if)

Creates an iterator which uses a closure to determine if an element should be removed.

+

If the closure returns true, then the element is removed and yielded. +If the closure returns false, the element will remain in the vector and will not be yielded +by the iterator.

+

If the returned ExtractIf is not exhausted, e.g. because it is dropped without iterating +or the iteration short-circuits, then the remaining elements will be retained. +Use retain with a negated predicate if you do not need the returned iterator.

+

Using this method is equivalent to the following code:

+ +
let mut i = 0;
+while i < vec.len() {
+    if some_predicate(&mut vec[i]) {
+        let val = vec.remove(i);
+        // your code here
+    } else {
+        i += 1;
+    }
+}
+
+

But extract_if is easier to use. extract_if is also more efficient, +because it can backshift the elements of the array in bulk.

+

Note that extract_if also lets you mutate every element in the filter closure, +regardless of whether you choose to keep or remove it.

+
§Examples
+

Splitting an array into evens and odds, reusing the original allocation:

+ +
#![feature(extract_if)]
+let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];
+
+let evens = numbers.extract_if(|x| *x % 2 == 0).collect::<Vec<_>>();
+let odds = numbers;
+
+assert_eq!(evens, vec![2, 4, 6, 8, 14]);
+assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]);
+

Methods from Deref<Target = [T]>§

1.80.0 · source

pub fn as_flattened(&self) -> &[T]

Takes a &[[T; N]], and flattens it to a &[T].

+
§Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
§Examples
+
assert_eq!([[1, 2, 3], [4, 5, 6]].as_flattened(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+    [[1, 2, 3], [4, 5, 6]].as_flattened(),
+    [[1, 2], [3, 4], [5, 6]].as_flattened(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.as_flattened().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.as_flattened().is_empty());
+
1.80.0 · source

pub fn as_flattened_mut(&mut self) -> &mut [T]

Takes a &mut [[T; N]], and flattens it to a &mut [T].

+
§Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
§Examples
+
fn add_5_to_all(slice: &mut [i32]) {
+    for i in slice {
+        *i += 5;
+    }
+}
+
+let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
+add_5_to_all(array.as_flattened_mut());
+assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f32::total_cmp.

+
§Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
§Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the slice.

+
§Examples
+
let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the slice has a length of 0.

+
§Examples
+
let a = [1, 2, 3];
+assert!(!a.is_empty());
+
+let b: &[i32] = &[];
+assert!(b.is_empty());
+
1.0.0 · source

pub fn first(&self) -> Option<&T>

Returns the first element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
+
1.0.0 · source

pub fn first_mut(&mut self) -> Option<&mut T>

Returns a mutable pointer to the first element of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_mut() {
+    *first = 5;
+}
+assert_eq!(x, &[5, 1, 2]);
+
+let y: &mut [i32] = &mut [];
+assert_eq!(None, y.first_mut());
+
1.5.0 · source

pub fn split_first(&self) -> Option<(&T, &[T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first() {
+    assert_eq!(first, &0);
+    assert_eq!(elements, &[1, 2]);
+}
+
1.5.0 · source

pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_mut() {
+    *first = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
1.5.0 · source

pub fn split_last(&self) -> Option<(&T, &[T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+    assert_eq!(last, &2);
+    assert_eq!(elements, &[0, 1]);
+}
+
1.5.0 · source

pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_mut() {
+    *last = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[4, 5, 3]);
+
1.0.0 · source

pub fn last(&self) -> Option<&T>

Returns the last element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
+
1.0.0 · source

pub fn last_mut(&mut self) -> Option<&mut T>

Returns a mutable reference to the last item in the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_mut() {
+    *last = 10;
+}
+assert_eq!(x, &[0, 1, 10]);
+
+let y: &mut [i32] = &mut [];
+assert_eq!(None, y.last_mut());
+
1.77.0 · source

pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the first N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.first_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.first_chunk::<0>());
+
1.77.0 · source

pub fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

Return a mutable array reference to the first N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_chunk_mut::<2>() {
+    first[0] = 5;
+    first[1] = 4;
+}
+assert_eq!(x, &[5, 4, 2]);
+
+assert_eq!(None, x.first_chunk_mut::<4>());
+
1.77.0 · source

pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

Return an array reference to the first N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk::<2>() {
+    assert_eq!(first, &[0, 1]);
+    assert_eq!(elements, &[2]);
+}
+
+assert_eq!(None, x.split_first_chunk::<4>());
+
1.77.0 · source

pub fn split_first_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T; N], &mut [T])>

Return a mutable array reference to the first N items in the slice and the remaining +slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk_mut::<2>() {
+    first[0] = 3;
+    first[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
+assert_eq!(None, x.split_first_chunk_mut::<4>());
+
1.77.0 · source

pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>

Return an array reference to the last N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((elements, last)) = x.split_last_chunk::<2>() {
+    assert_eq!(elements, &[0]);
+    assert_eq!(last, &[1, 2]);
+}
+
+assert_eq!(None, x.split_last_chunk::<4>());
+
1.77.0 · source

pub fn split_last_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T], &mut [T; N])>

Return a mutable array reference to the last N items in the slice and the remaining +slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((elements, last)) = x.split_last_chunk_mut::<2>() {
+    last[0] = 3;
+    last[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[5, 3, 4]);
+
+assert_eq!(None, x.split_last_chunk_mut::<4>());
+
1.77.0 · source

pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the last N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.last_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.last_chunk::<0>());
+
1.77.0 · source

pub fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

Return a mutable array reference to the last N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_chunk_mut::<2>() {
+    last[0] = 10;
+    last[1] = 20;
+}
+assert_eq!(x, &[0, 10, 20]);
+
+assert_eq!(None, x.last_chunk_mut::<4>());
+
1.0.0 · source

pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice depending on the type of +index.

+
    +
  • If given a position, returns a reference to the element at that +position or None if out of bounds.
  • +
  • If given a range, returns the subslice corresponding to that range, +or None if out of bounds.
  • +
+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
+
1.0.0 · source

pub fn get_mut<I>( + &mut self, + index: I +) -> Option<&mut <I as SliceIndex<[T]>>::Output>
where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice depending on the +type of index (see get) or None if the index is out of bounds.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(elem) = x.get_mut(1) {
+    *elem = 42;
+}
+assert_eq!(x, &[0, 42, 2]);
+
1.0.0 · source

pub unsafe fn get_unchecked<I>( + &self, + index: I +) -> &<I as SliceIndex<[T]>>::Output
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice, without doing bounds +checking.

+

For a safe alternative see get.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get(index).unwrap_unchecked(). It’s UB +to call .get_unchecked(len), even if you immediately convert to a +pointer. And it’s UB to call .get_unchecked(..len + 1), +.get_unchecked(..=len), or similar.

+
§Examples
+
let x = &[1, 2, 4];
+
+unsafe {
+    assert_eq!(x.get_unchecked(1), &2);
+}
+
1.0.0 · source

pub unsafe fn get_unchecked_mut<I>( + &mut self, + index: I +) -> &mut <I as SliceIndex<[T]>>::Output
where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice, without doing +bounds checking.

+

For a safe alternative see get_mut.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get_mut(index).unwrap_unchecked(). It’s +UB to call .get_unchecked_mut(len), even if you immediately convert +to a pointer. And it’s UB to call .get_unchecked_mut(..len + 1), +.get_unchecked_mut(..=len), or similar.

+
§Examples
+
let x = &mut [1, 2, 4];
+
+unsafe {
+    let elem = x.get_unchecked_mut(1);
+    *elem = 13;
+}
+assert_eq!(x, &[1, 13, 4]);
+
1.0.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
§Examples
+
let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+    }
+}
+
1.0.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
§Examples
+
let x = &mut [1, 2, 4];
+let x_ptr = x.as_mut_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        *x_ptr.add(i) += 2;
+    }
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.48.0 · source

pub fn as_ptr_range(&self) -> Range<*const T>

Returns the two raw pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_ptr for warnings on using these pointers. The end pointer +requires extra caution, as it does not point to a valid element in the +slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+

It can also be useful to check if a pointer to an element refers to an +element of this slice:

+ +
let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
+
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
+
1.48.0 · source

pub fn as_mut_ptr_range(&mut self) -> Range<*mut T>

Returns the two unsafe mutable pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_mut_ptr for warnings on using these pointers. The end +pointer requires extra caution, as it does not point to a valid element +in the slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+
1.0.0 · source

pub fn swap(&mut self, a: usize, b: usize)

Swaps two elements in the slice.

+

If a equals to b, it’s guaranteed that elements won’t change value.

+
§Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
§Panics
+

Panics if a or b are out of bounds.

+
§Examples
+
let mut v = ["a", "b", "c", "d", "e"];
+v.swap(2, 4);
+assert!(v == ["a", "b", "e", "d", "c"]);
+
source

pub unsafe fn swap_unchecked(&mut self, a: usize, b: usize)

🔬This is a nightly-only experimental API. (slice_swap_unchecked)

Swaps two elements in the slice, without doing bounds checking.

+

For a safe alternative see swap.

+
§Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior. +The caller has to ensure that a < self.len() and b < self.len().

+
§Examples
+
#![feature(slice_swap_unchecked)]
+
+let mut v = ["a", "b", "c", "d"];
+// SAFETY: we know that 1 and 3 are both indices of the slice
+unsafe { v.swap_unchecked(1, 3) };
+assert!(v == ["a", "d", "c", "b"]);
+
1.0.0 · source

pub fn reverse(&mut self)

Reverses the order of elements in the slice, in place.

+
§Examples
+
let mut v = [1, 2, 3];
+v.reverse();
+assert!(v == [3, 2, 1]);
+
1.0.0 · source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the slice.

+

The iterator yields all items from start to end.

+
§Examples
+
let x = &[1, 2, 4];
+let mut iterator = x.iter();
+
+assert_eq!(iterator.next(), Some(&1));
+assert_eq!(iterator.next(), Some(&2));
+assert_eq!(iterator.next(), Some(&4));
+assert_eq!(iterator.next(), None);
+
1.0.0 · source

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Returns an iterator that allows modifying each value.

+

The iterator yields all items from start to end.

+
§Examples
+
let x = &mut [1, 2, 4];
+for elem in x.iter_mut() {
+    *elem += 2;
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.0.0 · source

pub fn windows(&self, size: usize) -> Windows<'_, T>

Returns an iterator over all contiguous windows of length +size. The windows overlap. If the slice is shorter than +size, the iterator returns no values.

+
§Panics
+

Panics if size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.windows(3);
+assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']);
+assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']);
+assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']);
+assert!(iter.next().is_none());
+

If the slice is shorter than size:

+ +
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
+

There’s no windows_mut, as that existing would let safe code violate the +“only one &mut at a time to the same thing” rule. However, you can sometimes +use Cell::as_slice_of_cells in +conjunction with windows to accomplish something similar:

+ +
use std::cell::Cell;
+
+let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
+let slice = &mut array[..];
+let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
+for w in slice_of_cells.windows(3) {
+    Cell::swap(&w[0], &w[2]);
+}
+assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
+
1.0.0 · source

pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See chunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and rchunks for the same iterator but starting at the end of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See chunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and rchunks_mut for the same iterator but starting at +the end of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 3]);
+
1.31.0 · source

pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks.

+

See chunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
1.31.0 · source

pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See chunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and rchunks_exact_mut for the same iterator but starting at the end of +the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
§Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
§Examples
+
#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+
source

pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
+

If you expect the slice to be an exact multiple, you can combine +let-else with an empty slice pattern:

+ +
#![feature(slice_as_chunks)]
+let slice = ['R', 'u', 's', 't'];
+let (chunks, []) = slice.as_chunks::<2>() else {
+    panic!("slice didn't have even length")
+};
+assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
+
source

pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+
source

pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are array references and do not overlap. If N does not divide the +length of the slice, then the last up to N-1 elements will be omitted and can be +retrieved from the remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
source

pub unsafe fn as_chunks_unchecked_mut<const N: usize>( + &mut self +) -> &mut [[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
§Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
§Examples
+
#![feature(slice_as_chunks)]
+let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &mut [[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[0] = ['L'];
+assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &mut [[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[1] = ['a', 'x', '?'];
+assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
+
source

pub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (chunks, remainder) = v.as_chunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 9]);
+
source

pub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (remainder, chunks) = v.as_rchunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[9, 1, 1, 2, 2]);
+
source

pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable array references and do not overlap. If N does not divide +the length of the slice, then the last up to N-1 elements will be omitted and +can be retrieved from the into_remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact_mut.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.array_chunks_mut() {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>

🔬This is a nightly-only experimental API. (array_windows)

Returns an iterator over overlapping windows of N elements of a slice, +starting at the beginning of the slice.

+

This is the const generic equivalent of windows.

+

If N is greater than the size of the slice, it will return no windows.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and chunks for the same iterator but starting at the beginning +of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and chunks_mut for the same iterator but starting at the +beginning of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[3, 2, 2, 1, 1]);
+
1.31.0 · source

pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +end of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of rchunks.

+

See rchunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and chunks_exact for the same iterator but starting at the beginning of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
+
1.31.0 · source

pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See rchunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and chunks_exact_mut for the same iterator but starting at the beginning +of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[0, 2, 2, 1, 1]);
+
1.77.0 · source

pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
where + F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping runs +of elements using the predicate to separate them.

+

The predicate is called for every pair of consecutive elements, +meaning that it is called on slice[0] and slice[1], +followed by slice[1] and slice[2], and so on.

+
§Examples
+
let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.chunk_by(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.chunk_by(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.77.0 · source

pub fn chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F>
where + F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping mutable +runs of elements using the predicate to separate them.

+

The predicate is called for every pair of consecutive elements, +meaning that it is called on slice[0] and slice[1], +followed by slice[1] and slice[2], and so on.

+
§Examples
+
let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.chunk_by_mut(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&mut [3, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.chunk_by_mut(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.0.0 · source

pub fn split_at(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
§Panics
+

Panics if mid > len. For a non-panicking alternative see +split_at_checked.

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+{
+   let (left, right) = v.split_at(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.0.0 · source

pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
§Panics
+

Panics if mid > len. For a non-panicking alternative see +split_at_mut_checked.

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+let (left, right) = v.split_at_mut(2);
+assert_eq!(left, [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.79.0 · source

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+unsafe {
+   let (left, right) = v.split_at_unchecked(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.79.0 · source

pub unsafe fn split_at_mut_unchecked( + &mut self, + mid: usize +) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at_mut.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+// scoped to restrict the lifetime of the borrows
+unsafe {
+    let (left, right) = v.split_at_mut_unchecked(2);
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.80.0 · source

pub fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])>

Divides one slice into two at an index, returning None if the slice is +too short.

+

If mid ≤ len returns a pair of slices where the first will contain all +indices from [0, mid) (excluding the index mid itself) and the +second will contain all indices from [mid, len) (excluding the index +len itself).

+

Otherwise, if mid > len, returns None.

+
§Examples
+
let v = [1, -2, 3, -4, 5, -6];
+
+{
+   let (left, right) = v.split_at_checked(0).unwrap();
+   assert_eq!(left, []);
+   assert_eq!(right, [1, -2, 3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(2).unwrap();
+    assert_eq!(left, [1, -2]);
+    assert_eq!(right, [3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(6).unwrap();
+    assert_eq!(left, [1, -2, 3, -4, 5, -6]);
+    assert_eq!(right, []);
+}
+
+assert_eq!(None, v.split_at_checked(7));
+
1.80.0 · source

pub fn split_at_mut_checked( + &mut self, + mid: usize +) -> Option<(&mut [T], &mut [T])>

Divides one mutable slice into two at an index, returning None if the +slice is too short.

+

If mid ≤ len returns a pair of slices where the first will contain all +indices from [0, mid) (excluding the index mid itself) and the +second will contain all indices from [mid, len) (excluding the index +len itself).

+

Otherwise, if mid > len, returns None.

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+
+if let Some((left, right)) = v.split_at_mut_checked(2) {
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
+assert_eq!(None, v.split_at_mut_checked(7));
+
1.0.0 · source

pub fn split<F>(&self, pred: F) -> Split<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is not contained in the subslices.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the first element is matched, an empty slice will be the first item +returned by the iterator. Similarly, if the last element in the slice +is matched, an empty slice will be the last item returned by the +iterator:

+ +
let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
+

If two matched elements are directly adjacent, an empty slice will be +present between them:

+ +
let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is not contained in the subslices.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_mut(|num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 1]);
+
1.51.0 · source

pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is contained in the end of the previous +subslice as a terminator.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the last element of the slice is matched, +that element will be considered the terminator of the preceding slice. +That slice will be the last item returned by the iterator.

+ +
let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
+
1.51.0 · source

pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is contained in the previous +subslice as a terminator.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
+    let terminator_idx = group.len()-1;
+    group[terminator_idx] = 1;
+}
+assert_eq!(v, [10, 40, 1, 20, 1, 1]);
+
1.27.0 · source

pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, starting at the end of the slice and working backwards. +The matched element is not contained in the subslices.

+
§Examples
+
let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
+
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
+

As with split(), if the first or last element is matched, an empty +slice will be the first (or last) item returned by the iterator.

+ +
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
+
1.27.0 · source

pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred, starting at the end of the slice and working +backwards. The matched element is not contained in the subslices.

+
§Examples
+
let mut v = [100, 400, 300, 200, 600, 500];
+
+let mut count = 0;
+for group in v.rsplit_mut(|num| *num % 3 == 0) {
+    count += 1;
+    group[0] = count;
+}
+assert_eq!(v, [3, 400, 300, 2, 600, 1]);
+
1.0.0 · source

pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], +[20, 60, 50]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 50]);
+
1.0.0 · source

pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once, starting from the end, by numbers divisible +by 3 (i.e., [50], [10, 40, 30, 20]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+
let mut s = [10, 40, 30, 20, 60, 50];
+
+for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(s, [1, 40, 30, 20, 60, 1]);
+
source

pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the first element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.split_once(|&x| x == 2), Some((
+    &[1][..],
+    &[3, 2, 4][..]
+)));
+assert_eq!(s.split_once(|&x| x == 0), None);
+
source

pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the last element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.rsplit_once(|&x| x == 2), Some((
+    &[1, 2, 3][..],
+    &[4][..]
+)));
+assert_eq!(s.rsplit_once(|&x| x == 0), None);
+
1.0.0 · source

pub fn contains(&self, x: &T) -> bool
where + T: PartialEq,

Returns true if the slice contains an element with the given value.

+

This operation is O(n).

+

Note that if you have a sorted slice, binary_search may be faster.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
+

If you do not have a &T, but some other value that you can compare +with one (for example, String implements PartialEq<str>), you can +use iter().any:

+ +
let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
+
1.0.0 · source

pub fn starts_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a prefix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(v.starts_with(&v));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
+
1.0.0 · source

pub fn ends_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a suffix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(v.ends_with(&v));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
+
1.51.0 · source

pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the prefix removed.

+

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. +If prefix is empty, simply returns the original slice. If prefix is equal to the +original slice, returns an empty slice.

+

If the slice does not start with prefix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
+
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+           Some(b"llo".as_ref()));
+
1.51.0 · source

pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the suffix removed.

+

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. +If suffix is empty, simply returns the original slice. If suffix is equal to the +original slice, returns an empty slice.

+

If the slice does not end with suffix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
+

Binary searches this slice for a given element. +If the slice is not sorted, the returned result is unspecified and +meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search_by, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+assert_eq!(s.binary_search(&13),  Ok(9));
+assert_eq!(s.binary_search(&4),   Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

If you want to find that whole range of matching items, rather than +an arbitrary matching one, that can be done using partition_point:

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
+

If you want to insert an item to a sorted vector, while maintaining +sort order, consider using partition_point:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+// If `num` is unique, `s.partition_point(|&x| x < num)` (with `<`) is equivalent to
+// `s.binary_search(&num).unwrap_or_else(|x| x)`, but using `<=` will allow `insert`
+// to shift less elements.
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
1.0.0 · source

pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
where + F: FnMut(&'a T) -> Ordering,

Binary searches this slice with a comparator function.

+

The comparator function should return an order code that indicates +whether its argument is Less, Equal or Greater the desired +target. +If the slice is not sorted or if the comparator function does not +implement an order consistent with the sort order of the underlying +slice, the returned result is unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.10.0 · source

pub fn binary_search_by_key<'a, B, F>( + &'a self, + b: &B, + f: F +) -> Result<usize, usize>
where + F: FnMut(&'a T) -> B, + B: Ord,

Binary searches this slice with a key extraction function.

+

Assumes that the slice is sorted by the key, for instance with +sort_by_key using the same key extraction function. +If the slice is not sorted by the key, the returned result is +unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by, and partition_point.

+
§Examples
+

Looks up a series of four elements in a slice of pairs sorted by +their second elements. The first is found, with a uniquely +determined position; the second and third are not found; the +fourth could match any position in [1, 4].

+ +
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+         (1, 21), (2, 34), (4, 55)];
+
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.20.0 · source

pub fn sort_unstable(&mut self)
where + T: Ord,

Sorts the slice, but might not preserve the order of equal elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
§Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort_unstable();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.20.0 · source

pub fn sort_unstable_by<F>(&mut self, compare: F)
where + F: FnMut(&T, &T) -> Ordering,

Sorts the slice with a comparator function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
§Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_unstable_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_unstable_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.20.0 · source

pub fn sort_unstable_by_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(m * n * log(n)) worst-case, where the key function is +O(m).

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

Due to its key calling strategy, sort_unstable_by_key +is likely to be slower than sort_by_cached_key in +cases where the key function is expensive.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_unstable_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.49.0 · source

pub fn select_nth_unstable( + &mut self, + index: usize +) -> (&mut [T], &mut T, &mut [T])
where + T: Ord,

Reorder the slice such that the element at index after the reordering is at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index. Additionally, this reordering is +unstable (i.e. any number of equal elements may end up at position index), in-place +(i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from the reordered slice: +the subslice prior to index, the element at index, and the subslice after index; +accordingly, the values in those two subslices will respectively all be less-than-or-equal-to +and greater-than-or-equal-to the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 2, -3, 1];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median.
+let (lesser, median, greater) = v.select_nth_unstable(2);
+
+assert!(lesser == [-3, -5] || lesser == [-5, -3]);
+assert_eq!(median, &mut 1);
+assert!(greater == [4, 2] || greater == [2, 4]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [-3, -5, 1, 2, 4] ||
+        v == [-5, -3, 1, 2, 4] ||
+        v == [-3, -5, 1, 4, 2] ||
+        v == [-5, -3, 1, 4, 2]);
+
1.49.0 · source

pub fn select_nth_unstable_by<F>( + &mut self, + index: usize, + compare: F +) -> (&mut [T], &mut T, &mut [T])
where + F: FnMut(&T, &T) -> Ordering,

Reorder the slice with a comparator function such that the element at index after the reordering is at +its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the comparator function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided comparator function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 2, -3, 1];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median as if the slice were sorted in descending order.
+let (lesser, median, greater) = v.select_nth_unstable_by(2, |a, b| b.cmp(a));
+
+assert!(lesser == [4, 2] || lesser == [2, 4]);
+assert_eq!(median, &mut 1);
+assert!(greater == [-3, -5] || greater == [-5, -3]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [2, 4, 1, -5, -3] ||
+        v == [2, 4, 1, -3, -5] ||
+        v == [4, 2, 1, -5, -3] ||
+        v == [4, 2, 1, -3, -5]);
+
1.49.0 · source

pub fn select_nth_unstable_by_key<K, F>( + &mut self, + index: usize, + f: F +) -> (&mut [T], &mut T, &mut [T])
where + F: FnMut(&T) -> K, + K: Ord,

Reorder the slice with a key extraction function such that the element at index after the reordering is +at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the key extraction function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided key extraction function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median as if the slice were sorted according to absolute value.
+let (lesser, median, greater) = v.select_nth_unstable_by_key(2, |a| a.abs());
+
+assert!(lesser == [1, 2] || lesser == [2, 1]);
+assert_eq!(median, &mut -3);
+assert!(greater == [4, -5] || greater == [-5, 4]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [1, 2, -3, 4, -5] ||
+        v == [1, 2, -3, -5, 4] ||
+        v == [2, 1, -3, 4, -5] ||
+        v == [2, 1, -3, -5, 4]);
+
source

pub fn partition_dedup(&mut self) -> (&mut [T], &mut [T])
where + T: PartialEq,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all consecutive repeated elements to the end of the slice according to the +PartialEq trait implementation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
+
+let (dedup, duplicates) = slice.partition_dedup();
+
+assert_eq!(dedup, [1, 2, 3, 2, 1]);
+assert_eq!(duplicates, [2, 3, 1]);
+
source

pub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T])
where + F: FnMut(&mut T, &mut T) -> bool,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice satisfying +a given equality relation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

The same_bucket function is passed references to two elements from the slice and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is moved +at the end of the slice.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
+
+let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
+assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
+
source

pub fn partition_dedup_by_key<K, F>(&mut self, key: F) -> (&mut [T], &mut [T])
where + F: FnMut(&mut T) -> K, + K: PartialEq,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice that resolve +to the same key.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
+
+let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
+
+assert_eq!(dedup, [10, 20, 30, 20, 11]);
+assert_eq!(duplicates, [21, 30, 13]);
+
1.26.0 · source

pub fn rotate_left(&mut self, mid: usize)

Rotates the slice in-place such that the first mid elements of the +slice move to the end while the last self.len() - mid elements move to +the front. After calling rotate_left, the element previously at index +mid will become the first element in the slice.

+
§Panics
+

This function will panic if mid is greater than the length of the +slice. Note that mid == self.len() does not panic and is a no-op +rotation.

+
§Complexity
+

Takes linear (in self.len()) time.

+
§Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_left(2);
+assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_left(1);
+assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+
1.26.0 · source

pub fn rotate_right(&mut self, k: usize)

Rotates the slice in-place such that the first self.len() - k +elements of the slice move to the end while the last k elements move +to the front. After calling rotate_right, the element previously at +index self.len() - k will become the first element in the slice.

+
§Panics
+

This function will panic if k is greater than the length of the +slice. Note that k == self.len() does not panic and is a no-op +rotation.

+
§Complexity
+

Takes linear (in self.len()) time.

+
§Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_right(2);
+assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_right(1);
+assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
+
1.50.0 · source

pub fn fill(&mut self, value: T)
where + T: Clone,

Fills self with elements by cloning value.

+
§Examples
+
let mut buf = vec![0; 10];
+buf.fill(1);
+assert_eq!(buf, vec![1; 10]);
+
1.51.0 · source

pub fn fill_with<F>(&mut self, f: F)
where + F: FnMut() -> T,

Fills self with elements returned by calling a closure repeatedly.

+

This method uses a closure to create new values. If you’d rather +Clone a given value, use fill. If you want to use the Default +trait to generate values, you can pass Default::default as the +argument.

+
§Examples
+
let mut buf = vec![1; 10];
+buf.fill_with(Default::default);
+assert_eq!(buf, vec![0; 10]);
+
1.7.0 · source

pub fn clone_from_slice(&mut self, src: &[T])
where + T: Clone,

Copies the elements from src into self.

+

The length of src must be the same as self.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Examples
+

Cloning two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.clone_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use clone_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].clone_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.clone_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.9.0 · source

pub fn copy_from_slice(&mut self, src: &[T])
where + T: Copy,

Copies all elements from src into self, using a memcpy.

+

The length of src must be the same as self.

+

If T does not implement Copy, use clone_from_slice.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Examples
+

Copying two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.copy_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use copy_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].copy_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.copy_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.37.0 · source

pub fn copy_within<R>(&mut self, src: R, dest: usize)
where + R: RangeBounds<usize>, + T: Copy,

Copies elements from one part of the slice to another part of itself, +using a memmove.

+

src is the range within self to copy from. dest is the starting +index of the range within self to copy to, which will have the same +length as src. The two ranges may overlap. The ends of the two ranges +must be less than or equal to self.len().

+
§Panics
+

This function will panic if either range exceeds the end of the slice, +or if the end of src is before the start.

+
§Examples
+

Copying four bytes within a slice:

+ +
let mut bytes = *b"Hello, World!";
+
+bytes.copy_within(1..5, 8);
+
+assert_eq!(&bytes, b"Hello, Wello!");
+
1.27.0 · source

pub fn swap_with_slice(&mut self, other: &mut [T])

Swaps all elements in self with those in other.

+

The length of other must be the same as self.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Example
+

Swapping two elements across slices:

+ +
let mut slice1 = [0, 0];
+let mut slice2 = [1, 2, 3, 4];
+
+slice1.swap_with_slice(&mut slice2[2..]);
+
+assert_eq!(slice1, [3, 4]);
+assert_eq!(slice2, [1, 2, 0, 0]);
+

Rust enforces that there can only be one mutable reference to a +particular piece of data in a particular scope. Because of this, +attempting to use swap_with_slice on a single slice will result in +a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +mutable sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.swap_with_slice(&mut right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 1, 2]);
+
1.30.0 · source

pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

Transmute the slice to a slice of another type, ensuring alignment of the types is +maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The middle part will be as big as possible under +the given alignment constraint and element size.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
§Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
§Examples
+

Basic usage:

+ +
unsafe {
+    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
1.30.0 · source

pub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T])

Transmute the mutable slice to a mutable slice of another type, ensuring alignment of the +types is maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The middle part will be as big as possible under +the given alignment constraint and element size.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
§Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
§Examples
+

Basic usage:

+ +
unsafe {
+    let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
source

pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
where + Simd<T, LANES>: AsRef<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.

+

This is a safe wrapper around slice::align_to, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+
§Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
§Examples
+
#![feature(portable_simd)]
+use core::simd::prelude::*;
+
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
+
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+
+fn basic_simd_sum(x: &[f32]) -> f32 {
+    use std::ops::Add;
+    let (prefix, middle, suffix) = x.as_simd();
+    let sums = f32x4::from_array([
+        prefix.iter().copied().sum(),
+        0.0,
+        0.0,
+        suffix.iter().copied().sum(),
+    ]);
+    let sums = middle.iter().copied().fold(sums, f32x4::add);
+    sums.reduce_sum()
+}
+
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+
source

pub fn as_simd_mut<const LANES: usize>( + &mut self +) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T])
where + Simd<T, LANES>: AsMut<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a mutable slice into a mutable prefix, a middle of aligned SIMD types, +and a mutable suffix.

+

This is a safe wrapper around slice::align_to_mut, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+

This is the mutable version of slice::as_simd; see that for examples.

+
§Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
source

pub fn is_sorted(&self) -> bool
where + T: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted.

+

That is, for each element a and its following element b, a <= b must hold. If the +slice yields exactly zero or one element, true is returned.

+

Note that if Self::Item is only PartialOrd, but not Ord, the above definition +implies that this function returns false if any two consecutive items are not +comparable.

+
§Examples
+
#![feature(is_sorted)]
+let empty: [i32; 0] = [];
+
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
+
source

pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> bool
where + F: FnMut(&'a T, &'a T) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given comparator function.

+

Instead of using PartialOrd::partial_cmp, this function uses the given compare +function to determine whether two elements are to be considered in sorted order.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!([1, 2, 2, 9].is_sorted_by(|a, b| a <= b));
+assert!(![1, 2, 2, 9].is_sorted_by(|a, b| a < b));
+
+assert!([0].is_sorted_by(|a, b| true));
+assert!([0].is_sorted_by(|a, b| false));
+
+let empty: [i32; 0] = [];
+assert!(empty.is_sorted_by(|a, b| false));
+assert!(empty.is_sorted_by(|a, b| true));
+
source

pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
where + F: FnMut(&'a T) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given key extraction function.

+

Instead of comparing the slice’s elements directly, this function compares the keys of the +elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its +documentation for more information.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+
1.52.0 · source

pub fn partition_point<P>(&self, pred: P) -> usize
where + P: FnMut(&T) -> bool,

Returns the index of the partition point according to the given predicate +(the index of the first element of the second partition).

+

The slice is assumed to be partitioned according to the given predicate. +This means that all elements for which the predicate returns true are at the start of the slice +and all elements for which the predicate returns false are at the end. +For example, [7, 15, 3, 5, 4, 12, 6] is partitioned under the predicate x % 2 != 0 +(all odd numbers are at the start, all even at the end).

+

If this slice is not partitioned, the returned result is unspecified and meaningless, +as this method performs a kind of binary search.

+

See also binary_search, binary_search_by, and binary_search_by_key.

+
§Examples
+
let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
+
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
+

If all elements of the slice match the predicate, including if the slice +is empty, then the length of the slice will be returned:

+ +
let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
+

If you want to insert an item to a sorted vector, while maintaining +sort order:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
source

pub fn take<'a, R>(self: &mut &'a [T], range: R) -> Option<&'a [T]>
where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
§Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut first_three = slice.take(..3).unwrap();
+
+assert_eq!(slice, &['d']);
+assert_eq!(first_three, &['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut tail = slice.take(2..).unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(tail, &['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take(5..));
+assert_eq!(None, slice.take(..5));
+assert_eq!(None, slice.take(..=4));
+let expected: &[char] = &['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take(..4));
+
source

pub fn take_mut<'a, R>(self: &mut &'a mut [T], range: R) -> Option<&'a mut [T]>
where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a mutable reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
§Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut first_three = slice.take_mut(..3).unwrap();
+
+assert_eq!(slice, &mut ['d']);
+assert_eq!(first_three, &mut ['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut tail = slice.take_mut(2..).unwrap();
+
+assert_eq!(slice, &mut ['a', 'b']);
+assert_eq!(tail, &mut ['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take_mut(5..));
+assert_eq!(None, slice.take_mut(..5));
+assert_eq!(None, slice.take_mut(..=4));
+let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take_mut(..4));
+
source

pub fn take_first<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let first = slice.take_first().unwrap();
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'a');
+
source

pub fn take_first_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let first = slice.take_first_mut().unwrap();
+*first = 'd';
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'d');
+
source

pub fn take_last<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let last = slice.take_last().unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'c');
+
source

pub fn take_last_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let last = slice.take_last_mut().unwrap();
+*last = 'd';
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'d');
+
source

pub unsafe fn get_many_unchecked_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> [&mut T; N]

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once, without doing any checks.

+

For a safe alternative see get_many_mut.

+
§Safety
+

Calling this method with overlapping or out-of-bounds indices is undefined behavior +even if the resulting references are not used.

+
§Examples
+
#![feature(get_many_mut)]
+
+let x = &mut [1, 2, 4];
+
+unsafe {
+    let [a, b] = x.get_many_unchecked_mut([0, 2]);
+    *a *= 10;
+    *b *= 100;
+}
+assert_eq!(x, &[10, 2, 400]);
+
source

pub fn get_many_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> Result<[&mut T; N], GetManyMutError<N>>

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once.

+

Returns an error if any index is out-of-bounds, or if the same index was +passed more than once.

+
§Examples
+
#![feature(get_many_mut)]
+
+let v = &mut [1, 2, 3];
+if let Ok([a, b]) = v.get_many_mut([0, 2]) {
+    *a = 413;
+    *b = 612;
+}
+assert_eq!(v, &[413, 2, 612]);
+
1.79.0 · source

pub fn utf8_chunks(&self) -> Utf8Chunks<'_>

Creates an iterator over the contiguous valid UTF-8 ranges of this +slice, and the non-UTF-8 fragments in between.

+
§Examples
+

This function formats arbitrary but mostly-UTF-8 bytes into Rust source +code in the form of a C-string literal (c"...").

+ +
use std::fmt::Write as _;
+
+pub fn cstr_literal(bytes: &[u8]) -> String {
+    let mut repr = String::new();
+    repr.push_str("c\"");
+    for chunk in bytes.utf8_chunks() {
+        for ch in chunk.valid().chars() {
+            // Escapes \0, \t, \r, \n, \\, \', \", and uses \u{...} for non-printable characters.
+            write!(repr, "{}", ch.escape_debug()).unwrap();
+        }
+        for byte in chunk.invalid() {
+            write!(repr, "\\x{:02X}", byte).unwrap();
+        }
+    }
+    repr.push('"');
+    repr
+}
+
+fn main() {
+    let lit = cstr_literal(b"\xferris the \xf0\x9f\xa6\x80\x07");
+    let expected = stringify!(c"\xFErris the 🦀\u{7}");
+    assert_eq!(lit, expected);
+}
+
1.23.0 · source

pub fn is_ascii(&self) -> bool

Checks if all bytes in this slice are within the ASCII range.

+
source

pub fn as_ascii(&self) -> Option<&[AsciiChar]>

🔬This is a nightly-only experimental API. (ascii_char)

If this slice is_ascii, returns it as a slice of +ASCII characters, otherwise returns None.

+
source

pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]

🔬This is a nightly-only experimental API. (ascii_char)

Converts this slice of bytes into a slice of ASCII characters, +without checking whether they’re valid.

+
§Safety
+

Every byte in the slice must be in 0..=127, or else this is UB.

+
1.23.0 · source

pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool

Checks that two slices are an ASCII case-insensitive match.

+

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), +but without allocating and copying temporaries.

+
1.23.0 · source

pub fn make_ascii_uppercase(&mut self)

Converts this slice to its ASCII upper case equivalent in-place.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To return a new uppercased value without modifying the existing one, use +to_ascii_uppercase.

+
1.23.0 · source

pub fn make_ascii_lowercase(&mut self)

Converts this slice to its ASCII lower case equivalent in-place.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To return a new lowercased value without modifying the existing one, use +to_ascii_lowercase.

+
1.60.0 · source

pub fn escape_ascii(&self) -> EscapeAscii<'_>

Returns an iterator that produces an escaped version of this slice, +treating it as an ASCII string.

+
§Examples
+

+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
+
1.80.0 · source

pub fn trim_ascii_start(&self) -> &[u8]

Returns a byte slice with leading ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b"  ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
+
1.80.0 · source

pub fn trim_ascii_end(&self) -> &[u8]

Returns a byte slice with trailing ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b"  ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
+
1.80.0 · source

pub fn trim_ascii(&self) -> &[u8]

Returns a byte slice with leading and trailing ASCII whitespace bytes +removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b"  ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f64::total_cmp.

+
§Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
§Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
source

pub fn as_str(&self) -> &str

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a UTF-8 str.

+
source

pub fn as_bytes(&self) -> &[u8]

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a slice of u8 bytes.

+
1.0.0 · source

pub fn sort(&mut self)
where + T: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.0.0 · source

pub fn sort_by<F>(&mut self, compare: F)
where + F: FnMut(&T, &T) -> Ordering,

Available on non-no_global_oom_handling only.

Sorts the slice with a comparator function.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.7.0 · source

pub fn sort_by_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n * log(n)) +worst-case, where the key function is O(m).

+

For expensive key functions (e.g. functions that are not simple property accesses or +basic operations), sort_by_cached_key is likely to be +significantly faster, as it does not recompute element keys.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by_key.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.34.0 · source

pub fn sort_by_cached_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

During sorting, the key function is called at most once per element, by using +temporary storage to remember the results of key evaluation. +The order of calls to the key function is unspecified and may change in future versions +of the standard library.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n + n * log(n)) +worst-case, where the key function is O(m).

+

For simple key functions (e.g., functions that are property accesses or +basic operations), sort_by_key is likely to be +faster.

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

In the worst case, the algorithm allocates temporary storage in a Vec<(K, usize)> the +length of the slice.

+
§Examples
+
let mut v = [-5i32, 4, 32, -3, 2];
+
+v.sort_by_cached_key(|k| k.to_string());
+assert!(v == [-3, -5, 2, 32, 4]);
+
1.0.0 · source

pub fn to_vec(&self) -> Vec<T>
where + T: Clone,

Available on non-no_global_oom_handling only.

Copies self into a new Vec.

+
§Examples
+
let s = [10, 40, 30];
+let x = s.to_vec();
+// Here, `s` and `x` can be modified independently.
+
source

pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>
where + A: Allocator, + T: Clone,

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Copies self into a new Vec with an allocator.

+
§Examples
+
#![feature(allocator_api)]
+
+use std::alloc::System;
+
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
+// Here, `s` and `x` can be modified independently.
+
1.40.0 · source

pub fn repeat(&self, n: usize) -> Vec<T>
where + T: Copy,

Available on non-no_global_oom_handling only.

Creates a vector by copying a slice n times.

+
§Panics
+

This function will panic if the capacity would overflow.

+
§Examples
+

Basic usage:

+ +
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
+

A panic upon overflow:

+ +
// this will panic at runtime
+b"0123456789abcdef".repeat(usize::MAX);
+
1.0.0 · source

pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output
where + [T]: Concat<Item>, + Item: ?Sized,

Flattens a slice of T into a single value Self::Output.

+
§Examples
+
assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+
1.3.0 · source

pub fn join<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+
1.0.0 · source

pub fn connect<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

👎Deprecated since 1.3.0: renamed to join

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+
1.23.0 · source

pub fn to_ascii_uppercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII upper case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To uppercase the value in-place, use make_ascii_uppercase.

+
1.23.0 · source

pub fn to_ascii_lowercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII lower case equivalent.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To lowercase the value in-place, use make_ascii_lowercase.

+

Trait Implementations§

source§

impl Clone for CacheControl

source§

fn clone(&self) -> CacheControl

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for CacheControl

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for CacheControl

§

type Target = Vec<CacheDirective>

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for CacheControl

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl Display for CacheControl

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for CacheControl

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for CacheControl

source§

fn eq(&self, other: &CacheControl) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for CacheControl

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for CacheControl

source§

impl StructuralPartialEq for CacheControl

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.ContentDisposition.html b/actix_web/http/header/struct.ContentDisposition.html new file mode 100644 index 000000000..2d4b0bd7f --- /dev/null +++ b/actix_web/http/header/struct.ContentDisposition.html @@ -0,0 +1,138 @@ +ContentDisposition in actix_web::http::header - Rust

Struct actix_web::http::header::ContentDisposition

source ·
pub struct ContentDisposition {
+    pub disposition: DispositionType,
+    pub parameters: Vec<DispositionParam>,
+}
Expand description

A Content-Disposition header. It is compatible to be used either as +a response header for the main body +as (re)defined in RFC 6266, or as +a header for a multipart body +as (re)defined in RFC 7587.

+

In a regular HTTP response, the Content-Disposition response header is a header indicating if +the content is expected to be displayed inline in the browser, that is, as a Web page or as +part of a Web page, or as an attachment, that is downloaded and saved locally, and also can be +used to attach additional metadata, such as the filename to use when saving the response payload +locally.

+

In a multipart/form-data body, the HTTP Content-Disposition general header is a header that +can be used on the subpart of a multipart body to give information about the field it applies to. +The subpart is delimited by the boundary defined in the Content-Type header. Used on the body +itself, Content-Disposition has no effect.

+

§ABNF

content-disposition = "Content-Disposition" ":"
+                      disposition-type *( ";" disposition-parm )
+
+disposition-type    = "inline" | "attachment" | disp-ext-type
+                      ; case-insensitive
+
+disp-ext-type       = token
+
+disposition-parm    = filename-parm | disp-ext-parm
+
+filename-parm       = "filename" "=" value
+                    | "filename*" "=" ext-value
+
+disp-ext-parm       = token "=" value
+                    | ext-token "=" ext-value
+
+ext-token           = <the characters in token, followed by "*">
+

§Note

+

filename is not supposed to +contain any non-ASCII characters when used in a Content-Disposition HTTP response header, +where filename* with charset UTF-8 may be used instead in case there are Unicode characters in +file names. Filename is acceptable +to be UTF-8 encoded directly in a Content-Disposition header for +multipart/form-data, though.

+

filename must not be used within +multipart/form-data.

+

§Examples

+
use actix_web::http::header::{
+    Charset, ContentDisposition, DispositionParam, DispositionType,
+    ExtendedValue,
+};
+
+let cd1 = ContentDisposition {
+    disposition: DispositionType::Attachment,
+    parameters: vec![DispositionParam::FilenameExt(ExtendedValue {
+        charset: Charset::Iso_8859_1, // The character set for the bytes of the filename
+        language_tag: None, // The optional language tag (see `language-tag` crate)
+        value: b"\xa9 Copyright 1989.txt".to_vec(), // the actual bytes of the filename
+    })],
+};
+assert!(cd1.is_attachment());
+assert!(cd1.get_filename_ext().is_some());
+
+let cd2 = ContentDisposition {
+    disposition: DispositionType::FormData,
+    parameters: vec![
+        DispositionParam::Name(String::from("file")),
+        DispositionParam::Filename(String::from("bill.odt")),
+    ],
+};
+assert_eq!(cd2.get_name(), Some("file")); // field name
+assert_eq!(cd2.get_filename(), Some("bill.odt"));
+
+// HTTP response header with Unicode characters in file names
+let cd3 = ContentDisposition {
+    disposition: DispositionType::Attachment,
+    parameters: vec![
+        DispositionParam::FilenameExt(ExtendedValue {
+            charset: Charset::Ext(String::from("UTF-8")),
+            language_tag: None,
+            value: String::from("\u{1f600}.svg").into_bytes(),
+        }),
+        // fallback for better compatibility
+        DispositionParam::Filename(String::from("Grinning-Face-Emoji.svg"))
+    ],
+};
+assert_eq!(cd3.get_filename_ext().map(|ev| ev.value.as_ref()),
+           Some("\u{1f600}.svg".as_bytes()));
+

§Security Note

+

If “filename” parameter is supplied, do not use the file name blindly, check and possibly +change to match local file system conventions if applicable, and do not use directory path +information that may be present. +See RFC 2183 §2.3.

+

Fields§

§disposition: DispositionType

The disposition type

+
§parameters: Vec<DispositionParam>

Disposition parameters

+

Implementations§

source§

impl ContentDisposition

source

pub fn attachment(filename: impl Into<String>) -> Self

Constructs a Content-Disposition header suitable for downloads.

+
§Examples
+
use actix_web::http::header::{ContentDisposition, TryIntoHeaderValue as _};
+
+let cd = ContentDisposition::attachment("files.zip");
+
+let cd_val = cd.try_into_value().unwrap();
+assert_eq!(cd_val, "attachment; filename=\"files.zip\"");
+
source

pub fn from_raw(hv: &HeaderValue) -> Result<Self, ParseError>

Parse a raw Content-Disposition header value.

+
source

pub fn is_inline(&self) -> bool

Returns true if type is Inline.

+
source

pub fn is_attachment(&self) -> bool

Returns true if type is Attachment.

+
source

pub fn is_form_data(&self) -> bool

Returns true if type is FormData.

+
source

pub fn is_ext(&self, disp_type: impl AsRef<str>) -> bool

Returns true if type is Ext and the disp_type matches.

+
source

pub fn get_name(&self) -> Option<&str>

Return the value of name if exists.

+
source

pub fn get_filename(&self) -> Option<&str>

Return the value of filename if exists.

+
source

pub fn get_filename_ext(&self) -> Option<&ExtendedValue>

Return the value of filename* if exists.

+
source

pub fn get_unknown(&self, name: impl AsRef<str>) -> Option<&str>

Return the value of the parameter which the name matches.

+
source

pub fn get_unknown_ext(&self, name: impl AsRef<str>) -> Option<&ExtendedValue>

Return the value of the extended parameter which the name matches.

+

Trait Implementations§

source§

impl Clone for ContentDisposition

source§

fn clone(&self) -> ContentDisposition

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ContentDisposition

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for ContentDisposition

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for ContentDisposition

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<T: HttpMessage>(msg: &T) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for ContentDisposition

source§

fn eq(&self, other: &ContentDisposition) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for ContentDisposition

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for ContentDisposition

source§

impl StructuralPartialEq for ContentDisposition

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.ContentLanguage.html b/actix_web/http/header/struct.ContentLanguage.html new file mode 100644 index 000000000..055a41ff3 --- /dev/null +++ b/actix_web/http/header/struct.ContentLanguage.html @@ -0,0 +1,3135 @@ +ContentLanguage in actix_web::http::header - Rust

Struct actix_web::http::header::ContentLanguage

source ·
pub struct ContentLanguage(pub Vec<QualityItem<LanguageTag>>);
Expand description

Content-Language header, defined +in RFC 7231 §3.1.3.2

+

The Content-Language header field describes the natural language(s) +of the intended audience for the representation. Note that this +might not be equivalent to all the languages used within the +representation.

+

§ABNF

Content-Language = 1#language-tag
+

§Example Values

+
    +
  • da
  • +
  • mi, en
  • +
+

§Examples

+
use actix_web::HttpResponse;
+use actix_web::http::header::{ContentLanguage, LanguageTag, QualityItem};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    ContentLanguage(vec![
+        QualityItem::max(LanguageTag::parse("en").unwrap()),
+    ])
+);
+ +
use actix_web::HttpResponse;
+use actix_web::http::header::{ContentLanguage, LanguageTag, QualityItem};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    ContentLanguage(vec![
+        QualityItem::max(LanguageTag::parse("da").unwrap()),
+        QualityItem::max(LanguageTag::parse("en-GB").unwrap()),
+    ])
+);
+

Tuple Fields§

§0: Vec<QualityItem<LanguageTag>>

Methods from Deref<Target = Vec<QualityItem<LanguageTag>>>§

1.0.0 · source

pub fn capacity(&self) -> usize

Returns the total number of elements the vector can hold without +reallocating.

+
§Examples
+
let mut vec: Vec<i32> = Vec::with_capacity(10);
+vec.push(42);
+assert!(vec.capacity() >= 10);
+
1.0.0 · source

pub fn reserve(&mut self, additional: usize)

Available on non-no_global_oom_handling only.

Reserves capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to +speculatively avoid frequent reallocations. After calling reserve, +capacity will be greater than or equal to self.len() + additional. +Does nothing if capacity is already sufficient.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1];
+vec.reserve(10);
+assert!(vec.capacity() >= 11);
+
1.0.0 · source

pub fn reserve_exact(&mut self, additional: usize)

Available on non-no_global_oom_handling only.

Reserves the minimum capacity for at least additional more elements to +be inserted in the given Vec<T>. Unlike reserve, this will not +deliberately over-allocate to speculatively avoid frequent allocations. +After calling reserve_exact, capacity will be greater than or equal to +self.len() + additional. Does nothing if the capacity is already +sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer reserve if future insertions are expected.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1];
+vec.reserve_exact(10);
+assert!(vec.capacity() >= 11);
+
1.57.0 · source

pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>

Tries to reserve capacity for at least additional more elements to be inserted +in the given Vec<T>. The collection may reserve more space to speculatively avoid +frequent reallocations. After calling try_reserve, capacity will be +greater than or equal to self.len() + additional if it returns +Ok(()). Does nothing if capacity is already sufficient. This method +preserves the contents even if an error occurs.

+
§Errors
+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+
§Examples
+
use std::collections::TryReserveError;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+
1.57.0 · source

pub fn try_reserve_exact( + &mut self, + additional: usize +) -> Result<(), TryReserveError>

Tries to reserve the minimum capacity for at least additional +elements to be inserted in the given Vec<T>. Unlike try_reserve, +this will not deliberately over-allocate to speculatively avoid frequent +allocations. After calling try_reserve_exact, capacity will be greater +than or equal to self.len() + additional if it returns Ok(()). +Does nothing if the capacity is already sufficient.

+

Note that the allocator may give the collection more space than it +requests. Therefore, capacity can not be relied upon to be precisely +minimal. Prefer try_reserve if future insertions are expected.

+
§Errors
+

If the capacity overflows, or the allocator reports a failure, then an error +is returned.

+
§Examples
+
use std::collections::TryReserveError;
+
+fn process_data(data: &[u32]) -> Result<Vec<u32>, TryReserveError> {
+    let mut output = Vec::new();
+
+    // Pre-reserve the memory, exiting if we can't
+    output.try_reserve_exact(data.len())?;
+
+    // Now we know this can't OOM in the middle of our complex work
+    output.extend(data.iter().map(|&val| {
+        val * 2 + 5 // very complicated
+    }));
+
+    Ok(output)
+}
+
1.0.0 · source

pub fn shrink_to_fit(&mut self)

Available on non-no_global_oom_handling only.

Shrinks the capacity of the vector as much as possible.

+

The behavior of this method depends on the allocator, which may either shrink the vector +in-place or reallocate. The resulting vector might still have some excess capacity, just as +is the case for with_capacity. See Allocator::shrink for more details.

+
§Examples
+
let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3]);
+assert!(vec.capacity() >= 10);
+vec.shrink_to_fit();
+assert!(vec.capacity() >= 3);
+
1.56.0 · source

pub fn shrink_to(&mut self, min_capacity: usize)

Available on non-no_global_oom_handling only.

Shrinks the capacity of the vector with a lower bound.

+

The capacity will remain at least as large as both the length +and the supplied value.

+

If the current capacity is less than the lower limit, this is a no-op.

+
§Examples
+
let mut vec = Vec::with_capacity(10);
+vec.extend([1, 2, 3]);
+assert!(vec.capacity() >= 10);
+vec.shrink_to(4);
+assert!(vec.capacity() >= 4);
+vec.shrink_to(0);
+assert!(vec.capacity() >= 3);
+
1.0.0 · source

pub fn truncate(&mut self, len: usize)

Shortens the vector, keeping the first len elements and dropping +the rest.

+

If len is greater or equal to the vector’s current length, this has +no effect.

+

The drain method can emulate truncate, but causes the excess +elements to be returned instead of dropped.

+

Note that this method has no effect on the allocated capacity +of the vector.

+
§Examples
+

Truncating a five element vector to two elements:

+ +
let mut vec = vec![1, 2, 3, 4, 5];
+vec.truncate(2);
+assert_eq!(vec, [1, 2]);
+

No truncation occurs when len is greater than the vector’s current +length:

+ +
let mut vec = vec![1, 2, 3];
+vec.truncate(8);
+assert_eq!(vec, [1, 2, 3]);
+

Truncating when len == 0 is equivalent to calling the clear +method.

+ +
let mut vec = vec![1, 2, 3];
+vec.truncate(0);
+assert_eq!(vec, []);
+
1.7.0 · source

pub fn as_slice(&self) -> &[T]

Extracts a slice containing the entire vector.

+

Equivalent to &s[..].

+
§Examples
+
use std::io::{self, Write};
+let buffer = vec![1, 2, 3, 5, 8];
+io::sink().write(buffer.as_slice()).unwrap();
+
1.7.0 · source

pub fn as_mut_slice(&mut self) -> &mut [T]

Extracts a mutable slice of the entire vector.

+

Equivalent to &mut s[..].

+
§Examples
+
use std::io::{self, Read};
+let mut buffer = vec![0; 3];
+io::repeat(0b101).read_exact(buffer.as_mut_slice()).unwrap();
+
1.37.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the vector’s buffer, or a dangling raw pointer +valid for zero sized reads if the vector didn’t allocate.

+

The caller must ensure that the vector outlives the pointer this +function returns, or else it will end up pointing to garbage. +Modifying the vector may cause its buffer to be reallocated, +which would also make any pointers to it invalid.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

This method guarantees that for the purpose of the aliasing model, this method +does not materialize a reference to the underlying slice, and thus the returned pointer +will remain valid when mixed with other calls to as_ptr and as_mut_ptr. +Note that calling other methods that materialize mutable references to the slice, +or mutable references to specific elements you are planning on accessing through this pointer, +as well as writing to those elements, may still invalidate this pointer. +See the second example below for how this guarantee can be used.

+
§Examples
+
let x = vec![1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(*x_ptr.add(i), 1 << i);
+    }
+}
+

Due to the aliasing guarantee, the following code is legal:

+ +
unsafe {
+    let mut v = vec![0, 1, 2];
+    let ptr1 = v.as_ptr();
+    let _ = ptr1.read();
+    let ptr2 = v.as_mut_ptr().offset(2);
+    ptr2.write(2);
+    // Notably, the write to `ptr2` did *not* invalidate `ptr1`
+    // because it mutated a different element:
+    let _ = ptr1.read();
+}
+
1.37.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the vector’s buffer, or a dangling +raw pointer valid for zero sized reads if the vector didn’t allocate.

+

The caller must ensure that the vector outlives the pointer this +function returns, or else it will end up pointing to garbage. +Modifying the vector may cause its buffer to be reallocated, +which would also make any pointers to it invalid.

+

This method guarantees that for the purpose of the aliasing model, this method +does not materialize a reference to the underlying slice, and thus the returned pointer +will remain valid when mixed with other calls to as_ptr and as_mut_ptr. +Note that calling other methods that materialize references to the slice, +or references to specific elements you are planning on accessing through this pointer, +may still invalidate this pointer. +See the second example below for how this guarantee can be used.

+
§Examples
+
// Allocate vector big enough for 4 elements.
+let size = 4;
+let mut x: Vec<i32> = Vec::with_capacity(size);
+let x_ptr = x.as_mut_ptr();
+
+// Initialize elements via raw pointer writes, then set length.
+unsafe {
+    for i in 0..size {
+        *x_ptr.add(i) = i as i32;
+    }
+    x.set_len(size);
+}
+assert_eq!(&*x, &[0, 1, 2, 3]);
+

Due to the aliasing guarantee, the following code is legal:

+ +
unsafe {
+    let mut v = vec![0];
+    let ptr1 = v.as_mut_ptr();
+    ptr1.write(1);
+    let ptr2 = v.as_mut_ptr();
+    ptr2.write(2);
+    // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
+    ptr1.write(3);
+}
+
source

pub fn allocator(&self) -> &A

🔬This is a nightly-only experimental API. (allocator_api)

Returns a reference to the underlying allocator.

+
1.0.0 · source

pub unsafe fn set_len(&mut self, new_len: usize)

Forces the length of the vector to new_len.

+

This is a low-level operation that maintains none of the normal +invariants of the type. Normally changing the length of a vector +is done using one of the safe operations instead, such as +truncate, resize, extend, or clear.

+
§Safety
+
    +
  • new_len must be less than or equal to capacity().
  • +
  • The elements at old_len..new_len must be initialized.
  • +
+
§Examples
+

This method can be useful for situations in which the vector +is serving as a buffer for other code, particularly over FFI:

+ +
pub fn get_dictionary(&self) -> Option<Vec<u8>> {
+    // Per the FFI method's docs, "32768 bytes is always enough".
+    let mut dict = Vec::with_capacity(32_768);
+    let mut dict_length = 0;
+    // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
+    // 1. `dict_length` elements were initialized.
+    // 2. `dict_length` <= the capacity (32_768)
+    // which makes `set_len` safe to call.
+    unsafe {
+        // Make the FFI call...
+        let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
+        if r == Z_OK {
+            // ...and update the length to what was initialized.
+            dict.set_len(dict_length);
+            Some(dict)
+        } else {
+            None
+        }
+    }
+}
+

While the following example is sound, there is a memory leak since +the inner vectors were not freed prior to the set_len call:

+ +
let mut vec = vec![vec![1, 0, 0],
+                   vec![0, 1, 0],
+                   vec![0, 0, 1]];
+// SAFETY:
+// 1. `old_len..0` is empty so no elements need to be initialized.
+// 2. `0 <= capacity` always holds whatever `capacity` is.
+unsafe {
+    vec.set_len(0);
+}
+

Normally, here, one would use clear instead to correctly drop +the contents and thus not leak memory.

+
1.0.0 · source

pub fn swap_remove(&mut self, index: usize) -> T

Removes an element from the vector and returns it.

+

The removed element is replaced by the last element of the vector.

+

This does not preserve ordering of the remaining elements, but is O(1). +If you need to preserve the element order, use remove instead.

+
§Panics
+

Panics if index is out of bounds.

+
§Examples
+
let mut v = vec!["foo", "bar", "baz", "qux"];
+
+assert_eq!(v.swap_remove(1), "bar");
+assert_eq!(v, ["foo", "qux", "baz"]);
+
+assert_eq!(v.swap_remove(0), "foo");
+assert_eq!(v, ["baz", "qux"]);
+
1.0.0 · source

pub fn insert(&mut self, index: usize, element: T)

Available on non-no_global_oom_handling only.

Inserts an element at position index within the vector, shifting all +elements after it to the right.

+
§Panics
+

Panics if index > len.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+vec.insert(1, 4);
+assert_eq!(vec, [1, 4, 2, 3]);
+vec.insert(4, 5);
+assert_eq!(vec, [1, 4, 2, 3, 5]);
+
§Time complexity
+

Takes O(Vec::len) time. All items after the insertion index must be +shifted to the right. In the worst case, all elements are shifted when +the insertion index is 0.

+
1.0.0 · source

pub fn remove(&mut self, index: usize) -> T

Removes and returns the element at position index within the vector, +shifting all elements after it to the left.

+

Note: Because this shifts over the remaining elements, it has a +worst-case performance of O(n). If you don’t need the order of elements +to be preserved, use swap_remove instead. If you’d like to remove +elements from the beginning of the Vec, consider using +VecDeque::pop_front instead.

+
§Panics
+

Panics if index is out of bounds.

+
§Examples
+
let mut v = vec![1, 2, 3];
+assert_eq!(v.remove(1), 2);
+assert_eq!(v, [1, 3]);
+
1.0.0 · source

pub fn retain<F>(&mut self, f: F)
where + F: FnMut(&T) -> bool,

Retains only the elements specified by the predicate.

+

In other words, remove all elements e for which f(&e) returns false. +This method operates in place, visiting each element exactly once in the +original order, and preserves the order of the retained elements.

+
§Examples
+
let mut vec = vec![1, 2, 3, 4];
+vec.retain(|&x| x % 2 == 0);
+assert_eq!(vec, [2, 4]);
+

Because the elements are visited exactly once in the original order, +external state may be used to decide which elements to keep.

+ +
let mut vec = vec![1, 2, 3, 4, 5];
+let keep = [false, true, true, false, true];
+let mut iter = keep.iter();
+vec.retain(|_| *iter.next().unwrap());
+assert_eq!(vec, [2, 3, 5]);
+
1.61.0 · source

pub fn retain_mut<F>(&mut self, f: F)
where + F: FnMut(&mut T) -> bool,

Retains only the elements specified by the predicate, passing a mutable reference to it.

+

In other words, remove all elements e such that f(&mut e) returns false. +This method operates in place, visiting each element exactly once in the +original order, and preserves the order of the retained elements.

+
§Examples
+
let mut vec = vec![1, 2, 3, 4];
+vec.retain_mut(|x| if *x <= 3 {
+    *x += 1;
+    true
+} else {
+    false
+});
+assert_eq!(vec, [2, 3, 4]);
+
1.16.0 · source

pub fn dedup_by_key<F, K>(&mut self, key: F)
where + F: FnMut(&mut T) -> K, + K: PartialEq,

Removes all but the first of consecutive elements in the vector that resolve to the same +key.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec![10, 20, 21, 30, 20];
+
+vec.dedup_by_key(|i| *i / 10);
+
+assert_eq!(vec, [10, 20, 30, 20]);
+
1.16.0 · source

pub fn dedup_by<F>(&mut self, same_bucket: F)
where + F: FnMut(&mut T, &mut T) -> bool,

Removes all but the first of consecutive elements in the vector satisfying a given equality +relation.

+

The same_bucket function is passed references to two elements from the vector and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is removed.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
+
+vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
+
1.0.0 · source

pub fn push(&mut self, value: T)

Available on non-no_global_oom_handling only.

Appends an element to the back of a collection.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1, 2];
+vec.push(3);
+assert_eq!(vec, [1, 2, 3]);
+
§Time complexity
+

Takes amortized O(1) time. If the vector’s length would exceed its +capacity after the push, O(capacity) time is taken to copy the +vector’s elements to a larger allocation. This expensive operation is +offset by the capacity O(1) insertions it allows.

+
source

pub fn push_within_capacity(&mut self, value: T) -> Result<(), T>

🔬This is a nightly-only experimental API. (vec_push_within_capacity)

Appends an element if there is sufficient spare capacity, otherwise an error is returned +with the element.

+

Unlike push this method will not reallocate when there’s insufficient capacity. +The caller should use reserve or try_reserve to ensure that there is enough capacity.

+
§Examples
+

A manual, panic-free alternative to FromIterator:

+ +
#![feature(vec_push_within_capacity)]
+
+use std::collections::TryReserveError;
+fn from_iter_fallible<T>(iter: impl Iterator<Item=T>) -> Result<Vec<T>, TryReserveError> {
+    let mut vec = Vec::new();
+    for value in iter {
+        if let Err(value) = vec.push_within_capacity(value) {
+            vec.try_reserve(1)?;
+            // this cannot fail, the previous line either returned or added at least 1 free slot
+            let _ = vec.push_within_capacity(value);
+        }
+    }
+    Ok(vec)
+}
+assert_eq!(from_iter_fallible(0..100), Ok(Vec::from_iter(0..100)));
+
§Time complexity
+

Takes O(1) time.

+
1.0.0 · source

pub fn pop(&mut self) -> Option<T>

Removes the last element from a vector and returns it, or None if it +is empty.

+

If you’d like to pop the first element, consider using +VecDeque::pop_front instead.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+assert_eq!(vec.pop(), Some(3));
+assert_eq!(vec, [1, 2]);
+
§Time complexity
+

Takes O(1) time.

+
source

pub fn pop_if<F>(&mut self, f: F) -> Option<T>
where + F: FnOnce(&mut T) -> bool,

🔬This is a nightly-only experimental API. (vec_pop_if)

Removes and returns the last element in a vector if the predicate +returns true, or None if the predicate returns false or the vector +is empty.

+
§Examples
+
#![feature(vec_pop_if)]
+
+let mut vec = vec![1, 2, 3, 4];
+let pred = |x: &mut i32| *x % 2 == 0;
+
+assert_eq!(vec.pop_if(pred), Some(4));
+assert_eq!(vec, [1, 2, 3]);
+assert_eq!(vec.pop_if(pred), None);
+
1.4.0 · source

pub fn append(&mut self, other: &mut Vec<T, A>)

Available on non-no_global_oom_handling only.

Moves all the elements of other into self, leaving other empty.

+
§Panics
+

Panics if the new capacity exceeds isize::MAX bytes.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+let mut vec2 = vec![4, 5, 6];
+vec.append(&mut vec2);
+assert_eq!(vec, [1, 2, 3, 4, 5, 6]);
+assert_eq!(vec2, []);
+
1.6.0 · source

pub fn drain<R>(&mut self, range: R) -> Drain<'_, T, A>
where + R: RangeBounds<usize>,

Removes the specified range from the vector in bulk, returning all +removed elements as an iterator. If the iterator is dropped before +being fully consumed, it drops the remaining removed elements.

+

The returned iterator keeps a mutable borrow on the vector to optimize +its implementation.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Leaking
+

If the returned iterator goes out of scope without being dropped (due to +mem::forget, for example), the vector may have lost and leaked +elements arbitrarily, including elements outside the range.

+
§Examples
+
let mut v = vec![1, 2, 3];
+let u: Vec<_> = v.drain(1..).collect();
+assert_eq!(v, &[1]);
+assert_eq!(u, &[2, 3]);
+
+// A full range clears the vector, like `clear()` does
+v.drain(..);
+assert_eq!(v, &[]);
+
1.0.0 · source

pub fn clear(&mut self)

Clears the vector, removing all values.

+

Note that this method has no effect on the allocated capacity +of the vector.

+
§Examples
+
let mut v = vec![1, 2, 3];
+
+v.clear();
+
+assert!(v.is_empty());
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the vector, also referred to +as its ‘length’.

+
§Examples
+
let a = vec![1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the vector contains no elements.

+
§Examples
+
let mut v = Vec::new();
+assert!(v.is_empty());
+
+v.push(1);
+assert!(!v.is_empty());
+
1.4.0 · source

pub fn split_off(&mut self, at: usize) -> Vec<T, A>
where + A: Clone,

Available on non-no_global_oom_handling only.

Splits the collection into two at the given index.

+

Returns a newly allocated vector containing the elements in the range +[at, len). After the call, the original vector will be left containing +the elements [0, at) with its previous capacity unchanged.

+
    +
  • If you want to take ownership of the entire contents and capacity of +the vector, see mem::take or mem::replace.
  • +
  • If you don’t need the returned vector at all, see Vec::truncate.
  • +
  • If you want to take ownership of an arbitrary subslice, or you don’t +necessarily want to store the removed items in a vector, see Vec::drain.
  • +
+
§Panics
+

Panics if at > len.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+let vec2 = vec.split_off(1);
+assert_eq!(vec, [1]);
+assert_eq!(vec2, [2, 3]);
+
1.33.0 · source

pub fn resize_with<F>(&mut self, new_len: usize, f: F)
where + F: FnMut() -> T,

Available on non-no_global_oom_handling only.

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with the result of +calling the closure f. The return values from f will end up +in the Vec in the order they have been generated.

+

If new_len is less than len, the Vec is simply truncated.

+

This method uses a closure to create new values on every push. If +you’d rather Clone a given value, use Vec::resize. If you +want to use the Default trait to generate values, you can +pass Default::default as the second argument.

+
§Examples
+
let mut vec = vec![1, 2, 3];
+vec.resize_with(5, Default::default);
+assert_eq!(vec, [1, 2, 3, 0, 0]);
+
+let mut vec = vec![];
+let mut p = 1;
+vec.resize_with(4, || { p *= 2; p });
+assert_eq!(vec, [2, 4, 8, 16]);
+
1.60.0 · source

pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>]

Returns the remaining spare capacity of the vector as a slice of +MaybeUninit<T>.

+

The returned slice can be used to fill the vector with data (e.g. by +reading from a file) before marking the data as initialized using the +set_len method.

+
§Examples
+
// Allocate vector big enough for 10 elements.
+let mut v = Vec::with_capacity(10);
+
+// Fill in the first 3 elements.
+let uninit = v.spare_capacity_mut();
+uninit[0].write(0);
+uninit[1].write(1);
+uninit[2].write(2);
+
+// Mark the first 3 elements of the vector as being initialized.
+unsafe {
+    v.set_len(3);
+}
+
+assert_eq!(&v, &[0, 1, 2]);
+
source

pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>])

🔬This is a nightly-only experimental API. (vec_split_at_spare)

Returns vector content as a slice of T, along with the remaining spare +capacity of the vector as a slice of MaybeUninit<T>.

+

The returned spare capacity slice can be used to fill the vector with data +(e.g. by reading from a file) before marking the data as initialized using +the set_len method.

+

Note that this is a low-level API, which should be used with care for +optimization purposes. If you need to append data to a Vec +you can use push, extend, extend_from_slice, +extend_from_within, insert, append, resize or +resize_with, depending on your exact needs.

+
§Examples
+
#![feature(vec_split_at_spare)]
+
+let mut v = vec![1, 1, 2];
+
+// Reserve additional space big enough for 10 elements.
+v.reserve(10);
+
+let (init, uninit) = v.split_at_spare_mut();
+let sum = init.iter().copied().sum::<u32>();
+
+// Fill in the next 4 elements.
+uninit[0].write(sum);
+uninit[1].write(sum * 2);
+uninit[2].write(sum * 3);
+uninit[3].write(sum * 4);
+
+// Mark the 4 elements of the vector as being initialized.
+unsafe {
+    let len = v.len();
+    v.set_len(len + 4);
+}
+
+assert_eq!(&v, &[1, 1, 2, 4, 8, 12, 16]);
+
1.5.0 · source

pub fn resize(&mut self, new_len: usize, value: T)

Available on non-no_global_oom_handling only.

Resizes the Vec in-place so that len is equal to new_len.

+

If new_len is greater than len, the Vec is extended by the +difference, with each additional slot filled with value. +If new_len is less than len, the Vec is simply truncated.

+

This method requires T to implement Clone, +in order to be able to clone the passed value. +If you need more flexibility (or want to rely on Default instead of +Clone), use Vec::resize_with. +If you only need to resize to a smaller size, use Vec::truncate.

+
§Examples
+
let mut vec = vec!["hello"];
+vec.resize(3, "world");
+assert_eq!(vec, ["hello", "world", "world"]);
+
+let mut vec = vec![1, 2, 3, 4];
+vec.resize(2, 0);
+assert_eq!(vec, [1, 2]);
+
1.6.0 · source

pub fn extend_from_slice(&mut self, other: &[T])

Available on non-no_global_oom_handling only.

Clones and appends all elements in a slice to the Vec.

+

Iterates over the slice other, clones each element, and then appends +it to this Vec. The other slice is traversed in-order.

+

Note that this function is same as extend except that it is +specialized to work with slices instead. If and when Rust gets +specialization this function will likely be deprecated (but still +available).

+
§Examples
+
let mut vec = vec![1];
+vec.extend_from_slice(&[2, 3, 4]);
+assert_eq!(vec, [1, 2, 3, 4]);
+
1.53.0 · source

pub fn extend_from_within<R>(&mut self, src: R)
where + R: RangeBounds<usize>,

Available on non-no_global_oom_handling only.

Copies elements from src range to the end of the vector.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Examples
+
let mut vec = vec![0, 1, 2, 3, 4];
+
+vec.extend_from_within(2..);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4]);
+
+vec.extend_from_within(..2);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1]);
+
+vec.extend_from_within(4..8);
+assert_eq!(vec, [0, 1, 2, 3, 4, 2, 3, 4, 0, 1, 4, 2, 3, 4]);
+
1.0.0 · source

pub fn dedup(&mut self)

Removes consecutive repeated elements in the vector according to the +PartialEq trait implementation.

+

If the vector is sorted, this removes all duplicates.

+
§Examples
+
let mut vec = vec![1, 2, 2, 3, 2];
+
+vec.dedup();
+
+assert_eq!(vec, [1, 2, 3, 2]);
+
1.21.0 · source

pub fn splice<R, I>( + &mut self, + range: R, + replace_with: I +) -> Splice<'_, <I as IntoIterator>::IntoIter, A>
where + R: RangeBounds<usize>, + I: IntoIterator<Item = T>,

Available on non-no_global_oom_handling only.

Creates a splicing iterator that replaces the specified range in the vector +with the given replace_with iterator and yields the removed items. +replace_with does not need to be the same length as range.

+

range is removed even if the iterator is not consumed until the end.

+

It is unspecified how many elements are removed from the vector +if the Splice value is leaked.

+

The input iterator replace_with is only consumed when the Splice value is dropped.

+

This is optimal if:

+
    +
  • The tail (elements in the vector after range) is empty,
  • +
  • or replace_with yields fewer or equal elements than range’s length
  • +
  • or the lower bound of its size_hint() is exact.
  • +
+

Otherwise, a temporary vector is allocated and the tail is moved twice.

+
§Panics
+

Panics if the starting point is greater than the end point or if +the end point is greater than the length of the vector.

+
§Examples
+
let mut v = vec![1, 2, 3, 4];
+let new = [7, 8, 9];
+let u: Vec<_> = v.splice(1..3, new).collect();
+assert_eq!(v, &[1, 7, 8, 9, 4]);
+assert_eq!(u, &[2, 3]);
+
source

pub fn extract_if<F>(&mut self, filter: F) -> ExtractIf<'_, T, F, A>
where + F: FnMut(&mut T) -> bool,

🔬This is a nightly-only experimental API. (extract_if)

Creates an iterator which uses a closure to determine if an element should be removed.

+

If the closure returns true, then the element is removed and yielded. +If the closure returns false, the element will remain in the vector and will not be yielded +by the iterator.

+

If the returned ExtractIf is not exhausted, e.g. because it is dropped without iterating +or the iteration short-circuits, then the remaining elements will be retained. +Use retain with a negated predicate if you do not need the returned iterator.

+

Using this method is equivalent to the following code:

+ +
let mut i = 0;
+while i < vec.len() {
+    if some_predicate(&mut vec[i]) {
+        let val = vec.remove(i);
+        // your code here
+    } else {
+        i += 1;
+    }
+}
+
+

But extract_if is easier to use. extract_if is also more efficient, +because it can backshift the elements of the array in bulk.

+

Note that extract_if also lets you mutate every element in the filter closure, +regardless of whether you choose to keep or remove it.

+
§Examples
+

Splitting an array into evens and odds, reusing the original allocation:

+ +
#![feature(extract_if)]
+let mut numbers = vec![1, 2, 3, 4, 5, 6, 8, 9, 11, 13, 14, 15];
+
+let evens = numbers.extract_if(|x| *x % 2 == 0).collect::<Vec<_>>();
+let odds = numbers;
+
+assert_eq!(evens, vec![2, 4, 6, 8, 14]);
+assert_eq!(odds, vec![1, 3, 5, 9, 11, 13, 15]);
+

Methods from Deref<Target = [T]>§

1.80.0 · source

pub fn as_flattened(&self) -> &[T]

Takes a &[[T; N]], and flattens it to a &[T].

+
§Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
§Examples
+
assert_eq!([[1, 2, 3], [4, 5, 6]].as_flattened(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+    [[1, 2, 3], [4, 5, 6]].as_flattened(),
+    [[1, 2], [3, 4], [5, 6]].as_flattened(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.as_flattened().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.as_flattened().is_empty());
+
1.80.0 · source

pub fn as_flattened_mut(&mut self) -> &mut [T]

Takes a &mut [[T; N]], and flattens it to a &mut [T].

+
§Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
§Examples
+
fn add_5_to_all(slice: &mut [i32]) {
+    for i in slice {
+        *i += 5;
+    }
+}
+
+let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
+add_5_to_all(array.as_flattened_mut());
+assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f32::total_cmp.

+
§Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
§Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the slice.

+
§Examples
+
let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the slice has a length of 0.

+
§Examples
+
let a = [1, 2, 3];
+assert!(!a.is_empty());
+
+let b: &[i32] = &[];
+assert!(b.is_empty());
+
1.0.0 · source

pub fn first(&self) -> Option<&T>

Returns the first element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
+
1.0.0 · source

pub fn first_mut(&mut self) -> Option<&mut T>

Returns a mutable pointer to the first element of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_mut() {
+    *first = 5;
+}
+assert_eq!(x, &[5, 1, 2]);
+
+let y: &mut [i32] = &mut [];
+assert_eq!(None, y.first_mut());
+
1.5.0 · source

pub fn split_first(&self) -> Option<(&T, &[T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first() {
+    assert_eq!(first, &0);
+    assert_eq!(elements, &[1, 2]);
+}
+
1.5.0 · source

pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_mut() {
+    *first = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
1.5.0 · source

pub fn split_last(&self) -> Option<(&T, &[T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+    assert_eq!(last, &2);
+    assert_eq!(elements, &[0, 1]);
+}
+
1.5.0 · source

pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_mut() {
+    *last = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[4, 5, 3]);
+
1.0.0 · source

pub fn last(&self) -> Option<&T>

Returns the last element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
+
1.0.0 · source

pub fn last_mut(&mut self) -> Option<&mut T>

Returns a mutable reference to the last item in the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_mut() {
+    *last = 10;
+}
+assert_eq!(x, &[0, 1, 10]);
+
+let y: &mut [i32] = &mut [];
+assert_eq!(None, y.last_mut());
+
1.77.0 · source

pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the first N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.first_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.first_chunk::<0>());
+
1.77.0 · source

pub fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

Return a mutable array reference to the first N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_chunk_mut::<2>() {
+    first[0] = 5;
+    first[1] = 4;
+}
+assert_eq!(x, &[5, 4, 2]);
+
+assert_eq!(None, x.first_chunk_mut::<4>());
+
1.77.0 · source

pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

Return an array reference to the first N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk::<2>() {
+    assert_eq!(first, &[0, 1]);
+    assert_eq!(elements, &[2]);
+}
+
+assert_eq!(None, x.split_first_chunk::<4>());
+
1.77.0 · source

pub fn split_first_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T; N], &mut [T])>

Return a mutable array reference to the first N items in the slice and the remaining +slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk_mut::<2>() {
+    first[0] = 3;
+    first[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
+assert_eq!(None, x.split_first_chunk_mut::<4>());
+
1.77.0 · source

pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>

Return an array reference to the last N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((elements, last)) = x.split_last_chunk::<2>() {
+    assert_eq!(elements, &[0]);
+    assert_eq!(last, &[1, 2]);
+}
+
+assert_eq!(None, x.split_last_chunk::<4>());
+
1.77.0 · source

pub fn split_last_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T], &mut [T; N])>

Return a mutable array reference to the last N items in the slice and the remaining +slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((elements, last)) = x.split_last_chunk_mut::<2>() {
+    last[0] = 3;
+    last[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[5, 3, 4]);
+
+assert_eq!(None, x.split_last_chunk_mut::<4>());
+
1.77.0 · source

pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the last N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.last_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.last_chunk::<0>());
+
1.77.0 · source

pub fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

Return a mutable array reference to the last N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_chunk_mut::<2>() {
+    last[0] = 10;
+    last[1] = 20;
+}
+assert_eq!(x, &[0, 10, 20]);
+
+assert_eq!(None, x.last_chunk_mut::<4>());
+
1.0.0 · source

pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice depending on the type of +index.

+
    +
  • If given a position, returns a reference to the element at that +position or None if out of bounds.
  • +
  • If given a range, returns the subslice corresponding to that range, +or None if out of bounds.
  • +
+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
+
1.0.0 · source

pub fn get_mut<I>( + &mut self, + index: I +) -> Option<&mut <I as SliceIndex<[T]>>::Output>
where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice depending on the +type of index (see get) or None if the index is out of bounds.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(elem) = x.get_mut(1) {
+    *elem = 42;
+}
+assert_eq!(x, &[0, 42, 2]);
+
1.0.0 · source

pub unsafe fn get_unchecked<I>( + &self, + index: I +) -> &<I as SliceIndex<[T]>>::Output
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice, without doing bounds +checking.

+

For a safe alternative see get.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get(index).unwrap_unchecked(). It’s UB +to call .get_unchecked(len), even if you immediately convert to a +pointer. And it’s UB to call .get_unchecked(..len + 1), +.get_unchecked(..=len), or similar.

+
§Examples
+
let x = &[1, 2, 4];
+
+unsafe {
+    assert_eq!(x.get_unchecked(1), &2);
+}
+
1.0.0 · source

pub unsafe fn get_unchecked_mut<I>( + &mut self, + index: I +) -> &mut <I as SliceIndex<[T]>>::Output
where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice, without doing +bounds checking.

+

For a safe alternative see get_mut.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get_mut(index).unwrap_unchecked(). It’s +UB to call .get_unchecked_mut(len), even if you immediately convert +to a pointer. And it’s UB to call .get_unchecked_mut(..len + 1), +.get_unchecked_mut(..=len), or similar.

+
§Examples
+
let x = &mut [1, 2, 4];
+
+unsafe {
+    let elem = x.get_unchecked_mut(1);
+    *elem = 13;
+}
+assert_eq!(x, &[1, 13, 4]);
+
1.0.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
§Examples
+
let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+    }
+}
+
1.0.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
§Examples
+
let x = &mut [1, 2, 4];
+let x_ptr = x.as_mut_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        *x_ptr.add(i) += 2;
+    }
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.48.0 · source

pub fn as_ptr_range(&self) -> Range<*const T>

Returns the two raw pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_ptr for warnings on using these pointers. The end pointer +requires extra caution, as it does not point to a valid element in the +slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+

It can also be useful to check if a pointer to an element refers to an +element of this slice:

+ +
let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
+
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
+
1.48.0 · source

pub fn as_mut_ptr_range(&mut self) -> Range<*mut T>

Returns the two unsafe mutable pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_mut_ptr for warnings on using these pointers. The end +pointer requires extra caution, as it does not point to a valid element +in the slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+
1.0.0 · source

pub fn swap(&mut self, a: usize, b: usize)

Swaps two elements in the slice.

+

If a equals to b, it’s guaranteed that elements won’t change value.

+
§Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
§Panics
+

Panics if a or b are out of bounds.

+
§Examples
+
let mut v = ["a", "b", "c", "d", "e"];
+v.swap(2, 4);
+assert!(v == ["a", "b", "e", "d", "c"]);
+
source

pub unsafe fn swap_unchecked(&mut self, a: usize, b: usize)

🔬This is a nightly-only experimental API. (slice_swap_unchecked)

Swaps two elements in the slice, without doing bounds checking.

+

For a safe alternative see swap.

+
§Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior. +The caller has to ensure that a < self.len() and b < self.len().

+
§Examples
+
#![feature(slice_swap_unchecked)]
+
+let mut v = ["a", "b", "c", "d"];
+// SAFETY: we know that 1 and 3 are both indices of the slice
+unsafe { v.swap_unchecked(1, 3) };
+assert!(v == ["a", "d", "c", "b"]);
+
1.0.0 · source

pub fn reverse(&mut self)

Reverses the order of elements in the slice, in place.

+
§Examples
+
let mut v = [1, 2, 3];
+v.reverse();
+assert!(v == [3, 2, 1]);
+
1.0.0 · source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the slice.

+

The iterator yields all items from start to end.

+
§Examples
+
let x = &[1, 2, 4];
+let mut iterator = x.iter();
+
+assert_eq!(iterator.next(), Some(&1));
+assert_eq!(iterator.next(), Some(&2));
+assert_eq!(iterator.next(), Some(&4));
+assert_eq!(iterator.next(), None);
+
1.0.0 · source

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Returns an iterator that allows modifying each value.

+

The iterator yields all items from start to end.

+
§Examples
+
let x = &mut [1, 2, 4];
+for elem in x.iter_mut() {
+    *elem += 2;
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.0.0 · source

pub fn windows(&self, size: usize) -> Windows<'_, T>

Returns an iterator over all contiguous windows of length +size. The windows overlap. If the slice is shorter than +size, the iterator returns no values.

+
§Panics
+

Panics if size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.windows(3);
+assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']);
+assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']);
+assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']);
+assert!(iter.next().is_none());
+

If the slice is shorter than size:

+ +
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
+

There’s no windows_mut, as that existing would let safe code violate the +“only one &mut at a time to the same thing” rule. However, you can sometimes +use Cell::as_slice_of_cells in +conjunction with windows to accomplish something similar:

+ +
use std::cell::Cell;
+
+let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
+let slice = &mut array[..];
+let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
+for w in slice_of_cells.windows(3) {
+    Cell::swap(&w[0], &w[2]);
+}
+assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
+
1.0.0 · source

pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See chunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and rchunks for the same iterator but starting at the end of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See chunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and rchunks_mut for the same iterator but starting at +the end of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 3]);
+
1.31.0 · source

pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks.

+

See chunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
1.31.0 · source

pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See chunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and rchunks_exact_mut for the same iterator but starting at the end of +the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
§Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
§Examples
+
#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+
source

pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
+

If you expect the slice to be an exact multiple, you can combine +let-else with an empty slice pattern:

+ +
#![feature(slice_as_chunks)]
+let slice = ['R', 'u', 's', 't'];
+let (chunks, []) = slice.as_chunks::<2>() else {
+    panic!("slice didn't have even length")
+};
+assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
+
source

pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+
source

pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are array references and do not overlap. If N does not divide the +length of the slice, then the last up to N-1 elements will be omitted and can be +retrieved from the remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
source

pub unsafe fn as_chunks_unchecked_mut<const N: usize>( + &mut self +) -> &mut [[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
§Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
§Examples
+
#![feature(slice_as_chunks)]
+let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &mut [[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[0] = ['L'];
+assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &mut [[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[1] = ['a', 'x', '?'];
+assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
+
source

pub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (chunks, remainder) = v.as_chunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 9]);
+
source

pub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (remainder, chunks) = v.as_rchunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[9, 1, 1, 2, 2]);
+
source

pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable array references and do not overlap. If N does not divide +the length of the slice, then the last up to N-1 elements will be omitted and +can be retrieved from the into_remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact_mut.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.array_chunks_mut() {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>

🔬This is a nightly-only experimental API. (array_windows)

Returns an iterator over overlapping windows of N elements of a slice, +starting at the beginning of the slice.

+

This is the const generic equivalent of windows.

+

If N is greater than the size of the slice, it will return no windows.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and chunks for the same iterator but starting at the beginning +of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and chunks_mut for the same iterator but starting at the +beginning of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[3, 2, 2, 1, 1]);
+
1.31.0 · source

pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +end of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of rchunks.

+

See rchunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and chunks_exact for the same iterator but starting at the beginning of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
+
1.31.0 · source

pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See rchunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and chunks_exact_mut for the same iterator but starting at the beginning +of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[0, 2, 2, 1, 1]);
+
1.77.0 · source

pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
where + F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping runs +of elements using the predicate to separate them.

+

The predicate is called for every pair of consecutive elements, +meaning that it is called on slice[0] and slice[1], +followed by slice[1] and slice[2], and so on.

+
§Examples
+
let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.chunk_by(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.chunk_by(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.77.0 · source

pub fn chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F>
where + F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping mutable +runs of elements using the predicate to separate them.

+

The predicate is called for every pair of consecutive elements, +meaning that it is called on slice[0] and slice[1], +followed by slice[1] and slice[2], and so on.

+
§Examples
+
let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.chunk_by_mut(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&mut [3, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.chunk_by_mut(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.0.0 · source

pub fn split_at(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
§Panics
+

Panics if mid > len. For a non-panicking alternative see +split_at_checked.

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+{
+   let (left, right) = v.split_at(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.0.0 · source

pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
§Panics
+

Panics if mid > len. For a non-panicking alternative see +split_at_mut_checked.

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+let (left, right) = v.split_at_mut(2);
+assert_eq!(left, [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.79.0 · source

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+unsafe {
+   let (left, right) = v.split_at_unchecked(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.79.0 · source

pub unsafe fn split_at_mut_unchecked( + &mut self, + mid: usize +) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at_mut.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+// scoped to restrict the lifetime of the borrows
+unsafe {
+    let (left, right) = v.split_at_mut_unchecked(2);
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.80.0 · source

pub fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])>

Divides one slice into two at an index, returning None if the slice is +too short.

+

If mid ≤ len returns a pair of slices where the first will contain all +indices from [0, mid) (excluding the index mid itself) and the +second will contain all indices from [mid, len) (excluding the index +len itself).

+

Otherwise, if mid > len, returns None.

+
§Examples
+
let v = [1, -2, 3, -4, 5, -6];
+
+{
+   let (left, right) = v.split_at_checked(0).unwrap();
+   assert_eq!(left, []);
+   assert_eq!(right, [1, -2, 3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(2).unwrap();
+    assert_eq!(left, [1, -2]);
+    assert_eq!(right, [3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(6).unwrap();
+    assert_eq!(left, [1, -2, 3, -4, 5, -6]);
+    assert_eq!(right, []);
+}
+
+assert_eq!(None, v.split_at_checked(7));
+
1.80.0 · source

pub fn split_at_mut_checked( + &mut self, + mid: usize +) -> Option<(&mut [T], &mut [T])>

Divides one mutable slice into two at an index, returning None if the +slice is too short.

+

If mid ≤ len returns a pair of slices where the first will contain all +indices from [0, mid) (excluding the index mid itself) and the +second will contain all indices from [mid, len) (excluding the index +len itself).

+

Otherwise, if mid > len, returns None.

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+
+if let Some((left, right)) = v.split_at_mut_checked(2) {
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
+assert_eq!(None, v.split_at_mut_checked(7));
+
1.0.0 · source

pub fn split<F>(&self, pred: F) -> Split<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is not contained in the subslices.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the first element is matched, an empty slice will be the first item +returned by the iterator. Similarly, if the last element in the slice +is matched, an empty slice will be the last item returned by the +iterator:

+ +
let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
+

If two matched elements are directly adjacent, an empty slice will be +present between them:

+ +
let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is not contained in the subslices.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_mut(|num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 1]);
+
1.51.0 · source

pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is contained in the end of the previous +subslice as a terminator.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the last element of the slice is matched, +that element will be considered the terminator of the preceding slice. +That slice will be the last item returned by the iterator.

+ +
let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
+
1.51.0 · source

pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is contained in the previous +subslice as a terminator.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
+    let terminator_idx = group.len()-1;
+    group[terminator_idx] = 1;
+}
+assert_eq!(v, [10, 40, 1, 20, 1, 1]);
+
1.27.0 · source

pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, starting at the end of the slice and working backwards. +The matched element is not contained in the subslices.

+
§Examples
+
let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
+
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
+

As with split(), if the first or last element is matched, an empty +slice will be the first (or last) item returned by the iterator.

+ +
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
+
1.27.0 · source

pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred, starting at the end of the slice and working +backwards. The matched element is not contained in the subslices.

+
§Examples
+
let mut v = [100, 400, 300, 200, 600, 500];
+
+let mut count = 0;
+for group in v.rsplit_mut(|num| *num % 3 == 0) {
+    count += 1;
+    group[0] = count;
+}
+assert_eq!(v, [3, 400, 300, 2, 600, 1]);
+
1.0.0 · source

pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], +[20, 60, 50]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 50]);
+
1.0.0 · source

pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once, starting from the end, by numbers divisible +by 3 (i.e., [50], [10, 40, 30, 20]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+
let mut s = [10, 40, 30, 20, 60, 50];
+
+for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(s, [1, 40, 30, 20, 60, 1]);
+
source

pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the first element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.split_once(|&x| x == 2), Some((
+    &[1][..],
+    &[3, 2, 4][..]
+)));
+assert_eq!(s.split_once(|&x| x == 0), None);
+
source

pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the last element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.rsplit_once(|&x| x == 2), Some((
+    &[1, 2, 3][..],
+    &[4][..]
+)));
+assert_eq!(s.rsplit_once(|&x| x == 0), None);
+
1.0.0 · source

pub fn contains(&self, x: &T) -> bool
where + T: PartialEq,

Returns true if the slice contains an element with the given value.

+

This operation is O(n).

+

Note that if you have a sorted slice, binary_search may be faster.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
+

If you do not have a &T, but some other value that you can compare +with one (for example, String implements PartialEq<str>), you can +use iter().any:

+ +
let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
+
1.0.0 · source

pub fn starts_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a prefix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(v.starts_with(&v));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
+
1.0.0 · source

pub fn ends_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a suffix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(v.ends_with(&v));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
+
1.51.0 · source

pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the prefix removed.

+

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. +If prefix is empty, simply returns the original slice. If prefix is equal to the +original slice, returns an empty slice.

+

If the slice does not start with prefix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
+
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+           Some(b"llo".as_ref()));
+
1.51.0 · source

pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the suffix removed.

+

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. +If suffix is empty, simply returns the original slice. If suffix is equal to the +original slice, returns an empty slice.

+

If the slice does not end with suffix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
+

Binary searches this slice for a given element. +If the slice is not sorted, the returned result is unspecified and +meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search_by, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+assert_eq!(s.binary_search(&13),  Ok(9));
+assert_eq!(s.binary_search(&4),   Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

If you want to find that whole range of matching items, rather than +an arbitrary matching one, that can be done using partition_point:

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
+

If you want to insert an item to a sorted vector, while maintaining +sort order, consider using partition_point:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+// If `num` is unique, `s.partition_point(|&x| x < num)` (with `<`) is equivalent to
+// `s.binary_search(&num).unwrap_or_else(|x| x)`, but using `<=` will allow `insert`
+// to shift less elements.
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
1.0.0 · source

pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
where + F: FnMut(&'a T) -> Ordering,

Binary searches this slice with a comparator function.

+

The comparator function should return an order code that indicates +whether its argument is Less, Equal or Greater the desired +target. +If the slice is not sorted or if the comparator function does not +implement an order consistent with the sort order of the underlying +slice, the returned result is unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.10.0 · source

pub fn binary_search_by_key<'a, B, F>( + &'a self, + b: &B, + f: F +) -> Result<usize, usize>
where + F: FnMut(&'a T) -> B, + B: Ord,

Binary searches this slice with a key extraction function.

+

Assumes that the slice is sorted by the key, for instance with +sort_by_key using the same key extraction function. +If the slice is not sorted by the key, the returned result is +unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by, and partition_point.

+
§Examples
+

Looks up a series of four elements in a slice of pairs sorted by +their second elements. The first is found, with a uniquely +determined position; the second and third are not found; the +fourth could match any position in [1, 4].

+ +
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+         (1, 21), (2, 34), (4, 55)];
+
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.20.0 · source

pub fn sort_unstable(&mut self)
where + T: Ord,

Sorts the slice, but might not preserve the order of equal elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
§Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort_unstable();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.20.0 · source

pub fn sort_unstable_by<F>(&mut self, compare: F)
where + F: FnMut(&T, &T) -> Ordering,

Sorts the slice with a comparator function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
§Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_unstable_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_unstable_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.20.0 · source

pub fn sort_unstable_by_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(m * n * log(n)) worst-case, where the key function is +O(m).

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

Due to its key calling strategy, sort_unstable_by_key +is likely to be slower than sort_by_cached_key in +cases where the key function is expensive.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_unstable_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.49.0 · source

pub fn select_nth_unstable( + &mut self, + index: usize +) -> (&mut [T], &mut T, &mut [T])
where + T: Ord,

Reorder the slice such that the element at index after the reordering is at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index. Additionally, this reordering is +unstable (i.e. any number of equal elements may end up at position index), in-place +(i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from the reordered slice: +the subslice prior to index, the element at index, and the subslice after index; +accordingly, the values in those two subslices will respectively all be less-than-or-equal-to +and greater-than-or-equal-to the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 2, -3, 1];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median.
+let (lesser, median, greater) = v.select_nth_unstable(2);
+
+assert!(lesser == [-3, -5] || lesser == [-5, -3]);
+assert_eq!(median, &mut 1);
+assert!(greater == [4, 2] || greater == [2, 4]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [-3, -5, 1, 2, 4] ||
+        v == [-5, -3, 1, 2, 4] ||
+        v == [-3, -5, 1, 4, 2] ||
+        v == [-5, -3, 1, 4, 2]);
+
1.49.0 · source

pub fn select_nth_unstable_by<F>( + &mut self, + index: usize, + compare: F +) -> (&mut [T], &mut T, &mut [T])
where + F: FnMut(&T, &T) -> Ordering,

Reorder the slice with a comparator function such that the element at index after the reordering is at +its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the comparator function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided comparator function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 2, -3, 1];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median as if the slice were sorted in descending order.
+let (lesser, median, greater) = v.select_nth_unstable_by(2, |a, b| b.cmp(a));
+
+assert!(lesser == [4, 2] || lesser == [2, 4]);
+assert_eq!(median, &mut 1);
+assert!(greater == [-3, -5] || greater == [-5, -3]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [2, 4, 1, -5, -3] ||
+        v == [2, 4, 1, -3, -5] ||
+        v == [4, 2, 1, -5, -3] ||
+        v == [4, 2, 1, -3, -5]);
+
1.49.0 · source

pub fn select_nth_unstable_by_key<K, F>( + &mut self, + index: usize, + f: F +) -> (&mut [T], &mut T, &mut [T])
where + F: FnMut(&T) -> K, + K: Ord,

Reorder the slice with a key extraction function such that the element at index after the reordering is +at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the key extraction function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided key extraction function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median as if the slice were sorted according to absolute value.
+let (lesser, median, greater) = v.select_nth_unstable_by_key(2, |a| a.abs());
+
+assert!(lesser == [1, 2] || lesser == [2, 1]);
+assert_eq!(median, &mut -3);
+assert!(greater == [4, -5] || greater == [-5, 4]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [1, 2, -3, 4, -5] ||
+        v == [1, 2, -3, -5, 4] ||
+        v == [2, 1, -3, 4, -5] ||
+        v == [2, 1, -3, -5, 4]);
+
source

pub fn partition_dedup(&mut self) -> (&mut [T], &mut [T])
where + T: PartialEq,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all consecutive repeated elements to the end of the slice according to the +PartialEq trait implementation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
+
+let (dedup, duplicates) = slice.partition_dedup();
+
+assert_eq!(dedup, [1, 2, 3, 2, 1]);
+assert_eq!(duplicates, [2, 3, 1]);
+
source

pub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T])
where + F: FnMut(&mut T, &mut T) -> bool,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice satisfying +a given equality relation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

The same_bucket function is passed references to two elements from the slice and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is moved +at the end of the slice.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
+
+let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
+assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
+
source

pub fn partition_dedup_by_key<K, F>(&mut self, key: F) -> (&mut [T], &mut [T])
where + F: FnMut(&mut T) -> K, + K: PartialEq,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice that resolve +to the same key.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
+
+let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
+
+assert_eq!(dedup, [10, 20, 30, 20, 11]);
+assert_eq!(duplicates, [21, 30, 13]);
+
1.26.0 · source

pub fn rotate_left(&mut self, mid: usize)

Rotates the slice in-place such that the first mid elements of the +slice move to the end while the last self.len() - mid elements move to +the front. After calling rotate_left, the element previously at index +mid will become the first element in the slice.

+
§Panics
+

This function will panic if mid is greater than the length of the +slice. Note that mid == self.len() does not panic and is a no-op +rotation.

+
§Complexity
+

Takes linear (in self.len()) time.

+
§Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_left(2);
+assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_left(1);
+assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+
1.26.0 · source

pub fn rotate_right(&mut self, k: usize)

Rotates the slice in-place such that the first self.len() - k +elements of the slice move to the end while the last k elements move +to the front. After calling rotate_right, the element previously at +index self.len() - k will become the first element in the slice.

+
§Panics
+

This function will panic if k is greater than the length of the +slice. Note that k == self.len() does not panic and is a no-op +rotation.

+
§Complexity
+

Takes linear (in self.len()) time.

+
§Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_right(2);
+assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_right(1);
+assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
+
1.50.0 · source

pub fn fill(&mut self, value: T)
where + T: Clone,

Fills self with elements by cloning value.

+
§Examples
+
let mut buf = vec![0; 10];
+buf.fill(1);
+assert_eq!(buf, vec![1; 10]);
+
1.51.0 · source

pub fn fill_with<F>(&mut self, f: F)
where + F: FnMut() -> T,

Fills self with elements returned by calling a closure repeatedly.

+

This method uses a closure to create new values. If you’d rather +Clone a given value, use fill. If you want to use the Default +trait to generate values, you can pass Default::default as the +argument.

+
§Examples
+
let mut buf = vec![1; 10];
+buf.fill_with(Default::default);
+assert_eq!(buf, vec![0; 10]);
+
1.7.0 · source

pub fn clone_from_slice(&mut self, src: &[T])
where + T: Clone,

Copies the elements from src into self.

+

The length of src must be the same as self.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Examples
+

Cloning two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.clone_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use clone_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].clone_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.clone_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.9.0 · source

pub fn copy_from_slice(&mut self, src: &[T])
where + T: Copy,

Copies all elements from src into self, using a memcpy.

+

The length of src must be the same as self.

+

If T does not implement Copy, use clone_from_slice.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Examples
+

Copying two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.copy_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use copy_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].copy_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.copy_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.37.0 · source

pub fn copy_within<R>(&mut self, src: R, dest: usize)
where + R: RangeBounds<usize>, + T: Copy,

Copies elements from one part of the slice to another part of itself, +using a memmove.

+

src is the range within self to copy from. dest is the starting +index of the range within self to copy to, which will have the same +length as src. The two ranges may overlap. The ends of the two ranges +must be less than or equal to self.len().

+
§Panics
+

This function will panic if either range exceeds the end of the slice, +or if the end of src is before the start.

+
§Examples
+

Copying four bytes within a slice:

+ +
let mut bytes = *b"Hello, World!";
+
+bytes.copy_within(1..5, 8);
+
+assert_eq!(&bytes, b"Hello, Wello!");
+
1.27.0 · source

pub fn swap_with_slice(&mut self, other: &mut [T])

Swaps all elements in self with those in other.

+

The length of other must be the same as self.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Example
+

Swapping two elements across slices:

+ +
let mut slice1 = [0, 0];
+let mut slice2 = [1, 2, 3, 4];
+
+slice1.swap_with_slice(&mut slice2[2..]);
+
+assert_eq!(slice1, [3, 4]);
+assert_eq!(slice2, [1, 2, 0, 0]);
+

Rust enforces that there can only be one mutable reference to a +particular piece of data in a particular scope. Because of this, +attempting to use swap_with_slice on a single slice will result in +a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +mutable sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.swap_with_slice(&mut right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 1, 2]);
+
1.30.0 · source

pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

Transmute the slice to a slice of another type, ensuring alignment of the types is +maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The middle part will be as big as possible under +the given alignment constraint and element size.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
§Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
§Examples
+

Basic usage:

+ +
unsafe {
+    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
1.30.0 · source

pub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T])

Transmute the mutable slice to a mutable slice of another type, ensuring alignment of the +types is maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The middle part will be as big as possible under +the given alignment constraint and element size.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
§Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
§Examples
+

Basic usage:

+ +
unsafe {
+    let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
source

pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
where + Simd<T, LANES>: AsRef<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.

+

This is a safe wrapper around slice::align_to, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+
§Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
§Examples
+
#![feature(portable_simd)]
+use core::simd::prelude::*;
+
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
+
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+
+fn basic_simd_sum(x: &[f32]) -> f32 {
+    use std::ops::Add;
+    let (prefix, middle, suffix) = x.as_simd();
+    let sums = f32x4::from_array([
+        prefix.iter().copied().sum(),
+        0.0,
+        0.0,
+        suffix.iter().copied().sum(),
+    ]);
+    let sums = middle.iter().copied().fold(sums, f32x4::add);
+    sums.reduce_sum()
+}
+
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+
source

pub fn as_simd_mut<const LANES: usize>( + &mut self +) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T])
where + Simd<T, LANES>: AsMut<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a mutable slice into a mutable prefix, a middle of aligned SIMD types, +and a mutable suffix.

+

This is a safe wrapper around slice::align_to_mut, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+

This is the mutable version of slice::as_simd; see that for examples.

+
§Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
source

pub fn is_sorted(&self) -> bool
where + T: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted.

+

That is, for each element a and its following element b, a <= b must hold. If the +slice yields exactly zero or one element, true is returned.

+

Note that if Self::Item is only PartialOrd, but not Ord, the above definition +implies that this function returns false if any two consecutive items are not +comparable.

+
§Examples
+
#![feature(is_sorted)]
+let empty: [i32; 0] = [];
+
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
+
source

pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> bool
where + F: FnMut(&'a T, &'a T) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given comparator function.

+

Instead of using PartialOrd::partial_cmp, this function uses the given compare +function to determine whether two elements are to be considered in sorted order.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!([1, 2, 2, 9].is_sorted_by(|a, b| a <= b));
+assert!(![1, 2, 2, 9].is_sorted_by(|a, b| a < b));
+
+assert!([0].is_sorted_by(|a, b| true));
+assert!([0].is_sorted_by(|a, b| false));
+
+let empty: [i32; 0] = [];
+assert!(empty.is_sorted_by(|a, b| false));
+assert!(empty.is_sorted_by(|a, b| true));
+
source

pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
where + F: FnMut(&'a T) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given key extraction function.

+

Instead of comparing the slice’s elements directly, this function compares the keys of the +elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its +documentation for more information.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+
1.52.0 · source

pub fn partition_point<P>(&self, pred: P) -> usize
where + P: FnMut(&T) -> bool,

Returns the index of the partition point according to the given predicate +(the index of the first element of the second partition).

+

The slice is assumed to be partitioned according to the given predicate. +This means that all elements for which the predicate returns true are at the start of the slice +and all elements for which the predicate returns false are at the end. +For example, [7, 15, 3, 5, 4, 12, 6] is partitioned under the predicate x % 2 != 0 +(all odd numbers are at the start, all even at the end).

+

If this slice is not partitioned, the returned result is unspecified and meaningless, +as this method performs a kind of binary search.

+

See also binary_search, binary_search_by, and binary_search_by_key.

+
§Examples
+
let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
+
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
+

If all elements of the slice match the predicate, including if the slice +is empty, then the length of the slice will be returned:

+ +
let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
+

If you want to insert an item to a sorted vector, while maintaining +sort order:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
source

pub fn take<'a, R>(self: &mut &'a [T], range: R) -> Option<&'a [T]>
where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
§Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut first_three = slice.take(..3).unwrap();
+
+assert_eq!(slice, &['d']);
+assert_eq!(first_three, &['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut tail = slice.take(2..).unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(tail, &['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take(5..));
+assert_eq!(None, slice.take(..5));
+assert_eq!(None, slice.take(..=4));
+let expected: &[char] = &['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take(..4));
+
source

pub fn take_mut<'a, R>(self: &mut &'a mut [T], range: R) -> Option<&'a mut [T]>
where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a mutable reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
§Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut first_three = slice.take_mut(..3).unwrap();
+
+assert_eq!(slice, &mut ['d']);
+assert_eq!(first_three, &mut ['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut tail = slice.take_mut(2..).unwrap();
+
+assert_eq!(slice, &mut ['a', 'b']);
+assert_eq!(tail, &mut ['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take_mut(5..));
+assert_eq!(None, slice.take_mut(..5));
+assert_eq!(None, slice.take_mut(..=4));
+let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take_mut(..4));
+
source

pub fn take_first<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let first = slice.take_first().unwrap();
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'a');
+
source

pub fn take_first_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let first = slice.take_first_mut().unwrap();
+*first = 'd';
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'d');
+
source

pub fn take_last<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let last = slice.take_last().unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'c');
+
source

pub fn take_last_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let last = slice.take_last_mut().unwrap();
+*last = 'd';
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'d');
+
source

pub unsafe fn get_many_unchecked_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> [&mut T; N]

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once, without doing any checks.

+

For a safe alternative see get_many_mut.

+
§Safety
+

Calling this method with overlapping or out-of-bounds indices is undefined behavior +even if the resulting references are not used.

+
§Examples
+
#![feature(get_many_mut)]
+
+let x = &mut [1, 2, 4];
+
+unsafe {
+    let [a, b] = x.get_many_unchecked_mut([0, 2]);
+    *a *= 10;
+    *b *= 100;
+}
+assert_eq!(x, &[10, 2, 400]);
+
source

pub fn get_many_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> Result<[&mut T; N], GetManyMutError<N>>

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once.

+

Returns an error if any index is out-of-bounds, or if the same index was +passed more than once.

+
§Examples
+
#![feature(get_many_mut)]
+
+let v = &mut [1, 2, 3];
+if let Ok([a, b]) = v.get_many_mut([0, 2]) {
+    *a = 413;
+    *b = 612;
+}
+assert_eq!(v, &[413, 2, 612]);
+
1.79.0 · source

pub fn utf8_chunks(&self) -> Utf8Chunks<'_>

Creates an iterator over the contiguous valid UTF-8 ranges of this +slice, and the non-UTF-8 fragments in between.

+
§Examples
+

This function formats arbitrary but mostly-UTF-8 bytes into Rust source +code in the form of a C-string literal (c"...").

+ +
use std::fmt::Write as _;
+
+pub fn cstr_literal(bytes: &[u8]) -> String {
+    let mut repr = String::new();
+    repr.push_str("c\"");
+    for chunk in bytes.utf8_chunks() {
+        for ch in chunk.valid().chars() {
+            // Escapes \0, \t, \r, \n, \\, \', \", and uses \u{...} for non-printable characters.
+            write!(repr, "{}", ch.escape_debug()).unwrap();
+        }
+        for byte in chunk.invalid() {
+            write!(repr, "\\x{:02X}", byte).unwrap();
+        }
+    }
+    repr.push('"');
+    repr
+}
+
+fn main() {
+    let lit = cstr_literal(b"\xferris the \xf0\x9f\xa6\x80\x07");
+    let expected = stringify!(c"\xFErris the 🦀\u{7}");
+    assert_eq!(lit, expected);
+}
+
1.23.0 · source

pub fn is_ascii(&self) -> bool

Checks if all bytes in this slice are within the ASCII range.

+
source

pub fn as_ascii(&self) -> Option<&[AsciiChar]>

🔬This is a nightly-only experimental API. (ascii_char)

If this slice is_ascii, returns it as a slice of +ASCII characters, otherwise returns None.

+
source

pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]

🔬This is a nightly-only experimental API. (ascii_char)

Converts this slice of bytes into a slice of ASCII characters, +without checking whether they’re valid.

+
§Safety
+

Every byte in the slice must be in 0..=127, or else this is UB.

+
1.23.0 · source

pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool

Checks that two slices are an ASCII case-insensitive match.

+

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), +but without allocating and copying temporaries.

+
1.23.0 · source

pub fn make_ascii_uppercase(&mut self)

Converts this slice to its ASCII upper case equivalent in-place.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To return a new uppercased value without modifying the existing one, use +to_ascii_uppercase.

+
1.23.0 · source

pub fn make_ascii_lowercase(&mut self)

Converts this slice to its ASCII lower case equivalent in-place.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To return a new lowercased value without modifying the existing one, use +to_ascii_lowercase.

+
1.60.0 · source

pub fn escape_ascii(&self) -> EscapeAscii<'_>

Returns an iterator that produces an escaped version of this slice, +treating it as an ASCII string.

+
§Examples
+

+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
+
1.80.0 · source

pub fn trim_ascii_start(&self) -> &[u8]

Returns a byte slice with leading ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b"  ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
+
1.80.0 · source

pub fn trim_ascii_end(&self) -> &[u8]

Returns a byte slice with trailing ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b"  ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
+
1.80.0 · source

pub fn trim_ascii(&self) -> &[u8]

Returns a byte slice with leading and trailing ASCII whitespace bytes +removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b"  ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f64::total_cmp.

+
§Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
§Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
source

pub fn as_str(&self) -> &str

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a UTF-8 str.

+
source

pub fn as_bytes(&self) -> &[u8]

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a slice of u8 bytes.

+
1.0.0 · source

pub fn sort(&mut self)
where + T: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.0.0 · source

pub fn sort_by<F>(&mut self, compare: F)
where + F: FnMut(&T, &T) -> Ordering,

Available on non-no_global_oom_handling only.

Sorts the slice with a comparator function.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.7.0 · source

pub fn sort_by_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n * log(n)) +worst-case, where the key function is O(m).

+

For expensive key functions (e.g. functions that are not simple property accesses or +basic operations), sort_by_cached_key is likely to be +significantly faster, as it does not recompute element keys.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by_key.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.34.0 · source

pub fn sort_by_cached_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

During sorting, the key function is called at most once per element, by using +temporary storage to remember the results of key evaluation. +The order of calls to the key function is unspecified and may change in future versions +of the standard library.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n + n * log(n)) +worst-case, where the key function is O(m).

+

For simple key functions (e.g., functions that are property accesses or +basic operations), sort_by_key is likely to be +faster.

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

In the worst case, the algorithm allocates temporary storage in a Vec<(K, usize)> the +length of the slice.

+
§Examples
+
let mut v = [-5i32, 4, 32, -3, 2];
+
+v.sort_by_cached_key(|k| k.to_string());
+assert!(v == [-3, -5, 2, 32, 4]);
+
1.0.0 · source

pub fn to_vec(&self) -> Vec<T>
where + T: Clone,

Available on non-no_global_oom_handling only.

Copies self into a new Vec.

+
§Examples
+
let s = [10, 40, 30];
+let x = s.to_vec();
+// Here, `s` and `x` can be modified independently.
+
source

pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>
where + A: Allocator, + T: Clone,

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Copies self into a new Vec with an allocator.

+
§Examples
+
#![feature(allocator_api)]
+
+use std::alloc::System;
+
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
+// Here, `s` and `x` can be modified independently.
+
1.40.0 · source

pub fn repeat(&self, n: usize) -> Vec<T>
where + T: Copy,

Available on non-no_global_oom_handling only.

Creates a vector by copying a slice n times.

+
§Panics
+

This function will panic if the capacity would overflow.

+
§Examples
+

Basic usage:

+ +
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
+

A panic upon overflow:

+ +
// this will panic at runtime
+b"0123456789abcdef".repeat(usize::MAX);
+
1.0.0 · source

pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output
where + [T]: Concat<Item>, + Item: ?Sized,

Flattens a slice of T into a single value Self::Output.

+
§Examples
+
assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+
1.3.0 · source

pub fn join<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+
1.0.0 · source

pub fn connect<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

👎Deprecated since 1.3.0: renamed to join

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+
1.23.0 · source

pub fn to_ascii_uppercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII upper case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To uppercase the value in-place, use make_ascii_uppercase.

+
1.23.0 · source

pub fn to_ascii_lowercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII lower case equivalent.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To lowercase the value in-place, use make_ascii_lowercase.

+

Trait Implementations§

source§

impl Clone for ContentLanguage

source§

fn clone(&self) -> ContentLanguage

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ContentLanguage

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for ContentLanguage

§

type Target = Vec<QualityItem<LanguageTag>>

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for ContentLanguage

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl Display for ContentLanguage

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for ContentLanguage

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for ContentLanguage

source§

fn eq(&self, other: &ContentLanguage) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for ContentLanguage

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for ContentLanguage

source§

impl StructuralPartialEq for ContentLanguage

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.ContentLength.html b/actix_web/http/header/struct.ContentLength.html new file mode 100644 index 000000000..d3387a1d3 --- /dev/null +++ b/actix_web/http/header/struct.ContentLength.html @@ -0,0 +1,59 @@ +ContentLength in actix_web::http::header - Rust

Struct actix_web::http::header::ContentLength

source ·
pub struct ContentLength(pub usize);
Expand description

Content-Length header, defined in RFC 9110 §8.6.

+

The Content-Length

+

§ABNF

Content-Length = 1*DIGIT
+

§Example Values

+
    +
  • 0
  • +
  • 3495
  • +
+

§Examples

+
use actix_web::{http::header::ContentLength, HttpResponse};
+
+let res_empty = HttpResponse::Ok()
+    .insert_header(ContentLength(0));
+
+let res_fake_cl = HttpResponse::Ok()
+    .insert_header(ContentLength(3_495));
+

Tuple Fields§

§0: usize

Implementations§

source§

impl ContentLength

source

pub fn into_inner(&self) -> usize

Returns Content-Length value.

+

Methods from Deref<Target = usize>§

1.43.0 · source

pub const MIN: usize = 0usize

1.43.0 · source

pub const MAX: usize = 18_446_744_073_709_551_615usize

1.53.0 · source

pub const BITS: u32 = 64u32

Trait Implementations§

source§

impl Clone for ContentLength

source§

fn clone(&self) -> ContentLength

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ContentLength

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for ContentLength

§

type Target = usize

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for ContentLength

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl From<ContentLength> for usize

source§

fn from(ContentLength: ContentLength) -> Self

Converts to this type from the input type.
source§

impl From<usize> for ContentLength

source§

fn from(len: usize) -> Self

Converts to this type from the input type.
source§

impl FromStr for ContentLength

§

type Err = <usize as FromStr>::Err

The associated error which can be returned from parsing.
source§

fn from_str(val: &str) -> Result<Self, Self::Err>

Parses a string s to return a value of this type. Read more
source§

impl Header for ContentLength

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl Ord for ContentLength

source§

fn cmp(&self, other: &ContentLength) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq<ContentLength> for usize

source§

fn eq(&self, other: &ContentLength) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<usize> for ContentLength

source§

fn eq(&self, other: &usize) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for ContentLength

source§

fn eq(&self, other: &ContentLength) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd<ContentLength> for usize

source§

fn partial_cmp(&self, other: &ContentLength) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<usize> for ContentLength

source§

fn partial_cmp(&self, other: &usize) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for ContentLength

source§

fn partial_cmp(&self, other: &ContentLength) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl TryIntoHeaderValue for ContentLength

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for ContentLength

source§

impl StructuralPartialEq for ContentLength

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.ContentRange.html b/actix_web/http/header/struct.ContentRange.html new file mode 100644 index 000000000..dd1ac05a2 --- /dev/null +++ b/actix_web/http/header/struct.ContentRange.html @@ -0,0 +1,30 @@ +ContentRange in actix_web::http::header - Rust

Struct actix_web::http::header::ContentRange

source ·
pub struct ContentRange(pub ContentRangeSpec);
Expand description

Content-Range header, defined +in RFC 7233 §4.2

+

Tuple Fields§

§0: ContentRangeSpec

Trait Implementations§

source§

impl Clone for ContentRange

source§

fn clone(&self) -> ContentRange

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ContentRange

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for ContentRange

§

type Target = ContentRangeSpec

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for ContentRange

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl Display for ContentRange

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for ContentRange

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for ContentRange

source§

fn eq(&self, other: &ContentRange) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for ContentRange

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for ContentRange

source§

impl StructuralPartialEq for ContentRange

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.ContentType.html b/actix_web/http/header/struct.ContentType.html new file mode 100644 index 000000000..3fcf01dd6 --- /dev/null +++ b/actix_web/http/header/struct.ContentType.html @@ -0,0 +1,90 @@ +ContentType in actix_web::http::header - Rust

Struct actix_web::http::header::ContentType

source ·
pub struct ContentType(pub Mime);
Expand description

Content-Type header, defined in RFC 9110 §8.3.

+

The Content-Type header field indicates the media type of the associated representation: +either the representation enclosed in the message payload or the selected representation, +as determined by the message semantics. The indicated media type defines both the data +format and how that data is intended to be processed by a recipient, within the scope of the +received message semantics, after any content codings indicated by Content-Encoding are +decoded.

+

Although the mime crate allows the mime options to be any slice, this crate forces the use +of Vec. This is to make sure the same header can’t have more than 1 type. If this is an +issue, it’s possible to implement Header on a custom struct.

+

§ABNF

Content-Type = media-type
+

§Example Values

+
    +
  • text/html; charset=utf-8
  • +
  • application/json
  • +
+

§Examples

+
use actix_web::{http::header::ContentType, HttpResponse};
+
+let res_json = HttpResponse::Ok()
+    .insert_header(ContentType::json());
+
+let res_html = HttpResponse::Ok()
+    .insert_header(ContentType(mime::TEXT_HTML));
+

Tuple Fields§

§0: Mime

Implementations§

source§

impl ContentType

source

pub fn json() -> ContentType

Constructs a Content-Type: application/json header.

+
source

pub fn plaintext() -> ContentType

Constructs a Content-Type: text/plain; charset=utf-8 header.

+
source

pub fn html() -> ContentType

Constructs a Content-Type: text/html; charset=utf-8 header.

+
source

pub fn xml() -> ContentType

Constructs a Content-Type: text/xml header.

+
source

pub fn form_url_encoded() -> ContentType

Constructs a Content-Type: application/www-form-url-encoded header.

+
source

pub fn jpeg() -> ContentType

Constructs a Content-Type: image/jpeg header.

+
source

pub fn png() -> ContentType

Constructs a Content-Type: image/png header.

+
source

pub fn octet_stream() -> ContentType

Constructs a Content-Type: application/octet-stream header.

+

Methods from Deref<Target = Mime>§

source

pub fn type_(&self) -> Name<'_>

Get the top level media type for this Mime.

+
§Example
+
let mime = mime::TEXT_PLAIN;
+assert_eq!(mime.type_(), "text");
+assert_eq!(mime.type_(), mime::TEXT);
+
source

pub fn subtype(&self) -> Name<'_>

Get the subtype of this Mime.

+
§Example
+
let mime = mime::TEXT_PLAIN;
+assert_eq!(mime.subtype(), "plain");
+assert_eq!(mime.subtype(), mime::PLAIN);
+
source

pub fn suffix(&self) -> Option<Name<'_>>

Get an optional +suffix for this Mime.

+
§Example
+
let svg = "image/svg+xml".parse::<mime::Mime>().unwrap();
+assert_eq!(svg.suffix(), Some(mime::XML));
+assert_eq!(svg.suffix().unwrap(), "xml");
+
+
+assert!(mime::TEXT_PLAIN.suffix().is_none());
+
source

pub fn get_param<'a, N>(&'a self, attr: N) -> Option<Name<'a>>
where + N: PartialEq<Name<'a>>,

Look up a parameter by name.

+
§Example
+
let mime = mime::TEXT_PLAIN_UTF_8;
+assert_eq!(mime.get_param(mime::CHARSET), Some(mime::UTF_8));
+assert_eq!(mime.get_param("charset").unwrap(), "utf-8");
+assert!(mime.get_param("boundary").is_none());
+
+let mime = "multipart/form-data; boundary=ABCDEFG".parse::<mime::Mime>().unwrap();
+assert_eq!(mime.get_param(mime::BOUNDARY).unwrap(), "ABCDEFG");
+
source

pub fn params<'a>(&'a self) -> Params<'a>

Returns an iterator over the parameters.

+
source

pub fn essence_str(&self) -> &str

Return a &str of the Mime’s “essence”.

+

Trait Implementations§

source§

impl Clone for ContentType

source§

fn clone(&self) -> ContentType

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ContentType

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for ContentType

§

type Target = Mime

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for ContentType

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl Display for ContentType

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for ContentType

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for ContentType

source§

fn eq(&self, other: &ContentType) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for ContentType

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for ContentType

source§

impl StructuralPartialEq for ContentType

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.Date.html b/actix_web/http/header/struct.Date.html new file mode 100644 index 000000000..01c27cbfd --- /dev/null +++ b/actix_web/http/header/struct.Date.html @@ -0,0 +1,47 @@ +Date in actix_web::http::header - Rust

Struct actix_web::http::header::Date

source ·
pub struct Date(pub HttpDate);
Expand description

Date header, defined +in RFC 7231 §7.1.1.2

+

The Date header field represents the date and time at which the +message was originated.

+

§ABNF

Date = HTTP-date
+

§Example Values

+
    +
  • Tue, 15 Nov 1994 08:12:31 GMT
  • +
+

§Examples

+
use std::time::SystemTime;
+use actix_web::HttpResponse;
+use actix_web::http::header::Date;
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    Date(SystemTime::now().into())
+);
+

Tuple Fields§

§0: HttpDate

Implementations§

source§

impl Date

source

pub fn now() -> Date

Create a date instance set to the current system time

+

Trait Implementations§

source§

impl Clone for Date

source§

fn clone(&self) -> Date

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Date

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for Date

§

type Target = HttpDate

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for Date

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl Display for Date

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for Date

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for Date

source§

fn eq(&self, other: &Date) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for Date

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for Date

source§

impl StructuralPartialEq for Date

Auto Trait Implementations§

§

impl Freeze for Date

§

impl RefUnwindSafe for Date

§

impl Send for Date

§

impl Sync for Date

§

impl Unpin for Date

§

impl UnwindSafe for Date

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.ETag.html b/actix_web/http/header/struct.ETag.html new file mode 100644 index 000000000..8f8a23a8e --- /dev/null +++ b/actix_web/http/header/struct.ETag.html @@ -0,0 +1,72 @@ +ETag in actix_web::http::header - Rust

Struct actix_web::http::header::ETag

source ·
pub struct ETag(pub EntityTag);
Expand description

ETag header, defined in +RFC 7232 §2.3

+

The ETag header field in a response provides the current entity-tag +for the selected representation, as determined at the conclusion of +handling the request. An entity-tag is an opaque validator for +differentiating between multiple representations of the same +resource, regardless of whether those multiple representations are +due to resource state changes over time, content negotiation +resulting in multiple representations being valid at the same time, +or both. An entity-tag consists of an opaque quoted string, possibly +prefixed by a weakness indicator.

+

§ABNF

ETag       = entity-tag
+

§Example Values

+
    +
  • "xyzzy"
  • +
  • W/"xyzzy"
  • +
  • ""
  • +
+

§Examples

+
use actix_web::HttpResponse;
+use actix_web::http::header::{ETag, EntityTag};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    ETag(EntityTag::new_strong("xyzzy".to_owned()))
+);
+ +
use actix_web::HttpResponse;
+use actix_web::http::header::{ETag, EntityTag};
+
+let mut builder = HttpResponse::Ok();
+builder.insert_header(
+    ETag(EntityTag::new_weak("xyzzy".to_owned()))
+);
+

Tuple Fields§

§0: EntityTag

Methods from Deref<Target = EntityTag>§

source

pub fn tag(&self) -> &str

Returns tag.

+
source

pub fn set_tag(&mut self, tag: impl Into<String>)

Sets tag.

+
§Panics
+

If the tag contains invalid characters.

+
source

pub fn strong_eq(&self, other: &EntityTag) -> bool

For strong comparison two entity-tags are equivalent if both are not weak and their +opaque-tags match character-by-character.

+
source

pub fn weak_eq(&self, other: &EntityTag) -> bool

For weak comparison two entity-tags are equivalent if their opaque-tags match +character-by-character, regardless of either or both being tagged as “weak”.

+
source

pub fn strong_ne(&self, other: &EntityTag) -> bool

Returns the inverse of strong_eq().

+
source

pub fn weak_ne(&self, other: &EntityTag) -> bool

Returns inverse of weak_eq().

+

Trait Implementations§

source§

impl Clone for ETag

source§

fn clone(&self) -> ETag

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ETag

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for ETag

§

type Target = EntityTag

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for ETag

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl Display for ETag

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for ETag

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for ETag

source§

fn eq(&self, other: &ETag) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for ETag

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for ETag

source§

impl StructuralPartialEq for ETag

Auto Trait Implementations§

§

impl Freeze for ETag

§

impl RefUnwindSafe for ETag

§

impl Send for ETag

§

impl Sync for ETag

§

impl Unpin for ETag

§

impl UnwindSafe for ETag

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.EntityTag.html b/actix_web/http/header/struct.EntityTag.html new file mode 100644 index 000000000..3d6e29c2f --- /dev/null +++ b/actix_web/http/header/struct.EntityTag.html @@ -0,0 +1,72 @@ +EntityTag in actix_web::http::header - Rust

Struct actix_web::http::header::EntityTag

source ·
pub struct EntityTag {
+    pub weak: bool,
+    /* private fields */
+}
Expand description

An entity tag, defined in [RFC 7232 §2.3].

+

An entity tag consists of a string enclosed by two literal double quotes. +Preceding the first double quote is an optional weakness indicator, +which always looks like W/. Examples for valid tags are "xyzzy" and +W/"xyzzy".

+

§ABNF

entity-tag = [ weak ] opaque-tag
+weak       = %x57.2F ; "W/", case-sensitive
+opaque-tag = DQUOTE *etagc DQUOTE
+etagc      = %x21 / %x23-7E / obs-text
+           ; VCHAR except double quotes, plus obs-text
+

§Comparison

+

To check if two entity tags are equivalent in an application always use the +strong_eq or weak_eq methods based on the context of the Tag. Only use +== to check if two tags are identical.

+

The example below shows the results for a set of entity-tag pairs and +both the weak and strong comparison function results:

+
+ + + + +
ETag 1ETag 2Strong ComparisonWeak Comparison
W/"1"W/"1"no matchmatch
W/"1"W/"2"no matchno match
W/"1""1"no matchmatch
"1""1"matchmatch
+
+

RFC 7232 §2.3

+

Fields§

§weak: bool

Weakness indicator for the tag

+

Implementations§

source§

impl EntityTag

source

pub fn new(weak: bool, tag: String) -> EntityTag

Constructs a new EntityTag.

+
§Panics
+

If the tag contains invalid characters.

+
source

pub fn new_weak(tag: String) -> EntityTag

Constructs a new weak EntityTag.

+
§Panics
+

If the tag contains invalid characters.

+
source

pub fn weak(tag: String) -> EntityTag

👎Deprecated since 3.0.0: Renamed to new_weak.
source

pub fn new_strong(tag: String) -> EntityTag

Constructs a new strong EntityTag.

+
§Panics
+

If the tag contains invalid characters.

+
source

pub fn strong(tag: String) -> EntityTag

👎Deprecated since 3.0.0: Renamed to new_strong.
source

pub fn tag(&self) -> &str

Returns tag.

+
source

pub fn set_tag(&mut self, tag: impl Into<String>)

Sets tag.

+
§Panics
+

If the tag contains invalid characters.

+
source

pub fn strong_eq(&self, other: &EntityTag) -> bool

For strong comparison two entity-tags are equivalent if both are not weak and their +opaque-tags match character-by-character.

+
source

pub fn weak_eq(&self, other: &EntityTag) -> bool

For weak comparison two entity-tags are equivalent if their opaque-tags match +character-by-character, regardless of either or both being tagged as “weak”.

+
source

pub fn strong_ne(&self, other: &EntityTag) -> bool

Returns the inverse of strong_eq().

+
source

pub fn weak_ne(&self, other: &EntityTag) -> bool

Returns inverse of weak_eq().

+

Trait Implementations§

source§

impl Clone for EntityTag

source§

fn clone(&self) -> EntityTag

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for EntityTag

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for EntityTag

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl FromStr for EntityTag

§

type Err = ParseError

The associated error which can be returned from parsing.
source§

fn from_str(slice: &str) -> Result<EntityTag, ParseError>

Parses a string s to return a value of this type. Read more
source§

impl PartialEq for EntityTag

source§

fn eq(&self, other: &EntityTag) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for EntityTag

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for EntityTag

source§

impl StructuralPartialEq for EntityTag

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.Expires.html b/actix_web/http/header/struct.Expires.html new file mode 100644 index 000000000..1dc09321a --- /dev/null +++ b/actix_web/http/header/struct.Expires.html @@ -0,0 +1,50 @@ +Expires in actix_web::http::header - Rust

Struct actix_web::http::header::Expires

source ·
pub struct Expires(pub HttpDate);
Expand description

Expires header, defined +in RFC 7234 §5.3

+

The Expires header field gives the date/time after which the +response is considered stale.

+

The presence of an Expires field does not imply that the original +resource will change or cease to exist at, before, or after that +time.

+

§ABNF

Expires = HTTP-date
+

§Example Values

+
    +
  • Thu, 01 Dec 1994 16:00:00 GMT
  • +
+

§Examples

+
use std::time::{SystemTime, Duration};
+use actix_web::HttpResponse;
+use actix_web::http::header::Expires;
+
+let mut builder = HttpResponse::Ok();
+let expiration = SystemTime::now() + Duration::from_secs(60 * 60 * 24);
+builder.insert_header(
+    Expires(expiration.into())
+);
+

Tuple Fields§

§0: HttpDate

Trait Implementations§

source§

impl Clone for Expires

source§

fn clone(&self) -> Expires

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Expires

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for Expires

§

type Target = HttpDate

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for Expires

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl Display for Expires

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for Expires

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for Expires

source§

fn eq(&self, other: &Expires) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for Expires

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for Expires

source§

impl StructuralPartialEq for Expires

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.ExtendedValue.html b/actix_web/http/header/struct.ExtendedValue.html new file mode 100644 index 000000000..9b12434d5 --- /dev/null +++ b/actix_web/http/header/struct.ExtendedValue.html @@ -0,0 +1,39 @@ +ExtendedValue in actix_web::http::header - Rust

Struct actix_web::http::header::ExtendedValue

source ·
pub struct ExtendedValue {
+    pub charset: Charset,
+    pub language_tag: Option<LanguageTag>,
+    pub value: Vec<u8>,
+}
Expand description

The value part of an extended parameter consisting of three parts:

+
    +
  • The REQUIRED character set name (charset).
  • +
  • The OPTIONAL language information (language_tag).
  • +
  • A character sequence representing the actual value (value), separated by single quotes.
  • +
+

It is defined in RFC 5987 §3.2.

+

Fields§

§charset: Charset

The character set that is used to encode the value to a string.

+
§language_tag: Option<LanguageTag>

The human language details of the value, if available.

+
§value: Vec<u8>

The parameter value, as expressed in octets.

+

Trait Implementations§

source§

impl Clone for ExtendedValue

source§

fn clone(&self) -> ExtendedValue

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for ExtendedValue

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for ExtendedValue

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl PartialEq for ExtendedValue

source§

fn eq(&self, other: &ExtendedValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for ExtendedValue

source§

impl StructuralPartialEq for ExtendedValue

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.HeaderMap.html b/actix_web/http/header/struct.HeaderMap.html new file mode 100644 index 000000000..d70b5cbec --- /dev/null +++ b/actix_web/http/header/struct.HeaderMap.html @@ -0,0 +1,330 @@ +HeaderMap in actix_web::http::header - Rust

Struct actix_web::http::header::HeaderMap

source ·
pub struct HeaderMap { /* private fields */ }
Expand description

A multi-map of HTTP headers.

+

HeaderMap is a “multi-map” of HeaderName to one or more HeaderValues.

+

§Examples

+
use actix_http::header::{self, HeaderMap, HeaderValue};
+
+let mut map = HeaderMap::new();
+
+map.insert(header::CONTENT_TYPE, HeaderValue::from_static("text/plain"));
+map.insert(header::ORIGIN, HeaderValue::from_static("example.com"));
+
+assert!(map.contains_key(header::CONTENT_TYPE));
+assert!(map.contains_key(header::ORIGIN));
+
+let mut removed = map.remove(header::ORIGIN);
+assert_eq!(removed.next().unwrap(), "example.com");
+
+assert!(!map.contains_key(header::ORIGIN));
+

Implementations§

source§

impl HeaderMap

source

pub fn new() -> HeaderMap

Create an empty HeaderMap.

+

The map will be created without any capacity; this function will not allocate.

+
§Examples
+
let map = HeaderMap::new();
+
+assert!(map.is_empty());
+assert_eq!(0, map.capacity());
+
source

pub fn with_capacity(capacity: usize) -> HeaderMap

Create an empty HeaderMap with the specified capacity.

+

The map will be able to hold at least capacity elements without needing to reallocate. +If capacity is 0, the map will be created without allocating.

+
§Examples
+
let map = HeaderMap::with_capacity(16);
+
+assert!(map.is_empty());
+assert!(map.capacity() >= 16);
+
source

pub fn len(&self) -> usize

Returns the number of values stored in the map.

+

See also: len_keys.

+
§Examples
+
let mut map = HeaderMap::new();
+assert_eq!(map.len(), 0);
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+assert_eq!(map.len(), 2);
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+assert_eq!(map.len(), 3);
+
source

pub fn len_keys(&self) -> usize

Returns the number of keys stored in the map.

+

The number of values stored will be at least this number. See also: Self::len.

+
§Examples
+
let mut map = HeaderMap::new();
+assert_eq!(map.len_keys(), 0);
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+assert_eq!(map.len_keys(), 2);
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+assert_eq!(map.len_keys(), 2);
+
source

pub fn is_empty(&self) -> bool

Returns true if the map contains no elements.

+
§Examples
+
let mut map = HeaderMap::new();
+assert!(map.is_empty());
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(!map.is_empty());
+
source

pub fn clear(&mut self)

Clears the map, removing all name-value pairs.

+

Keeps the allocated memory for reuse.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+assert_eq!(map.len(), 2);
+
+map.clear();
+assert!(map.is_empty());
+
source

pub fn get(&self, key: impl AsHeaderName) -> Option<&HeaderValue>

Returns a reference to the first value associated with a header name.

+

Returns None if there is no value associated with the key.

+

Even when multiple values are associated with the key, the “first” one is returned but is +not guaranteed to be chosen with any particular order; though, the returned item will be +consistent for each call to get if the map has not changed.

+

See also: get_all.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+
+let cookie = map.get(header::SET_COOKIE).unwrap();
+assert_eq!(cookie, "one=1");
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+assert_eq!(map.get(header::SET_COOKIE).unwrap(), "one=1");
+
+assert_eq!(map.get(header::SET_COOKIE), map.get("set-cookie"));
+assert_eq!(map.get(header::SET_COOKIE), map.get("Set-Cookie"));
+
+assert!(map.get(header::HOST).is_none());
+assert!(map.get("INVALID HEADER NAME").is_none());
+
source

pub fn get_mut(&mut self, key: impl AsHeaderName) -> Option<&mut HeaderValue>

Returns a mutable reference to the first value associated a header name.

+

Returns None if there is no value associated with the key.

+

Even when multiple values are associated with the key, the “first” one is returned but is +not guaranteed to be chosen with any particular order; though, the returned item will be +consistent for each call to get_mut if the map has not changed.

+

See also: get_all.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+
+let mut cookie = map.get_mut(header::SET_COOKIE).unwrap();
+assert_eq!(cookie, "one=1");
+
+*cookie = HeaderValue::from_static("three=3");
+assert_eq!(map.get(header::SET_COOKIE).unwrap(), "three=3");
+
+assert!(map.get(header::HOST).is_none());
+assert!(map.get("INVALID HEADER NAME").is_none());
+
source

pub fn get_all(&self, key: impl AsHeaderName) -> Iter<'_, HeaderValue>

Returns an iterator over all values associated with a header name.

+

The returned iterator does not incur any allocations and will yield no items if there are no +values associated with the key. Iteration order is guaranteed to be the same as +insertion order.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut none_iter = map.get_all(header::ORIGIN);
+assert!(none_iter.next().is_none());
+
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let mut set_cookies_iter = map.get_all(header::SET_COOKIE);
+assert_eq!(set_cookies_iter.next().unwrap(), "one=1");
+assert_eq!(set_cookies_iter.next().unwrap(), "two=2");
+assert!(set_cookies_iter.next().is_none());
+
source

pub fn contains_key(&self, key: impl AsHeaderName) -> bool

Returns true if the map contains a value for the specified key.

+

Invalid header names will simply return false.

+
§Examples
+
let mut map = HeaderMap::new();
+assert!(!map.contains_key(header::ACCEPT));
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(map.contains_key(header::ACCEPT));
+
source

pub fn insert(&mut self, key: HeaderName, val: HeaderValue) -> Removed

Inserts (overrides) a name-value pair in the map.

+

If the map already contained this key, the new value is associated with the key and all +previous values are removed and returned as a Removed iterator. The key is not updated; +this matters for types that can be == without being identical.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(map.contains_key(header::ACCEPT));
+assert_eq!(map.len(), 1);
+
+let mut removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/csv"));
+assert_eq!(removed.next().unwrap(), "text/plain");
+assert!(removed.next().is_none());
+
+assert_eq!(map.len(), 1);
+

A convenience method is provided on the returned iterator to check if the insertion replaced +any values.

+ +
let mut map = HeaderMap::new();
+
+let removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(removed.is_empty());
+
+let removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/html"));
+assert!(!removed.is_empty());
+
source

pub fn append(&mut self, key: HeaderName, value: HeaderValue)

Appends a name-value pair to the map.

+

If the map already contained this key, the new value is added to the list of values +currently associated with the key. The key is not updated; this matters for types that can +be == without being identical.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.append(header::HOST, HeaderValue::from_static("example.com"));
+assert_eq!(map.len(), 1);
+
+map.append(header::ACCEPT, HeaderValue::from_static("text/csv"));
+assert_eq!(map.len(), 2);
+
+map.append(header::ACCEPT, HeaderValue::from_static("text/html"));
+assert_eq!(map.len(), 3);
+
source

pub fn remove(&mut self, key: impl AsHeaderName) -> Removed

Removes all headers for a particular header name from the map.

+

Providing an invalid header names (as a string argument) will have no effect and return +without error.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=2"));
+
+assert_eq!(map.len(), 2);
+
+let mut removed = map.remove(header::SET_COOKIE);
+assert_eq!(removed.next().unwrap(), "one=1");
+assert_eq!(removed.next().unwrap(), "one=2");
+assert!(removed.next().is_none());
+
+assert!(map.is_empty());
+

A convenience method is provided on the returned iterator to check if the remove call +actually removed any values.

+ +
let mut map = HeaderMap::new();
+
+let removed = map.remove("accept");
+assert!(removed.is_empty());
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/html"));
+let removed = map.remove("accept");
+assert!(!removed.is_empty());
+
source

pub fn capacity(&self) -> usize

Returns the number of single-value headers the map can hold without needing to reallocate.

+

Since this is a multi-value map, the actual capacity is much larger when considering +each header name can be associated with an arbitrary number of values. The effect is that +the size of len may be greater than capacity since it counts all the values. +Conversely, len_keys will never be larger than capacity.

+
§Examples
+
let map = HeaderMap::with_capacity(16);
+
+assert!(map.is_empty());
+assert!(map.capacity() >= 16);
+
source

pub fn reserve(&mut self, additional: usize)

Reserves capacity for at least additional more headers to be inserted in the map.

+

The header map may reserve more space to avoid frequent reallocations. Additional capacity +only considers single-value headers.

+
§Panics
+

Panics if the new allocation size overflows usize.

+
§Examples
+
let mut map = HeaderMap::with_capacity(2);
+assert!(map.capacity() >= 2);
+
+map.reserve(100);
+assert!(map.capacity() >= 102);
+
+assert!(map.is_empty());
+
source

pub fn iter(&self) -> Iter<'_>

An iterator over all name-value pairs.

+

Names will be yielded for each associated value. So, if a key has 3 associated values, it +will be yielded 3 times. The iteration order should be considered arbitrary.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut iter = map.iter();
+assert!(iter.next().is_none());
+
+map.append(header::HOST, HeaderValue::from_static("duck.com"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let mut iter = map.iter();
+assert!(iter.next().is_some());
+assert!(iter.next().is_some());
+assert!(iter.next().is_some());
+assert!(iter.next().is_none());
+
+let pairs = map.iter().collect::<Vec<_>>();
+assert!(pairs.contains(&(&header::HOST, &HeaderValue::from_static("duck.com"))));
+assert!(pairs.contains(&(&header::SET_COOKIE, &HeaderValue::from_static("one=1"))));
+assert!(pairs.contains(&(&header::SET_COOKIE, &HeaderValue::from_static("two=2"))));
+
source

pub fn keys(&self) -> Keys<'_>

An iterator over all contained header names.

+

Each name will only be yielded once even if it has multiple associated values. The iteration +order should be considered arbitrary.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut iter = map.keys();
+assert!(iter.next().is_none());
+
+map.append(header::HOST, HeaderValue::from_static("duck.com"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let keys = map.keys().cloned().collect::<Vec<_>>();
+assert_eq!(keys.len(), 2);
+assert!(keys.contains(&header::HOST));
+assert!(keys.contains(&header::SET_COOKIE));
+
source

pub fn retain<F>(&mut self, retain_fn: F)
where + F: FnMut(&HeaderName, &mut HeaderValue) -> bool,

Retains only the headers specified by the predicate.

+

In other words, removes all headers (name, val) for which retain_fn(&name, &mut val) +returns false.

+

The order in which headers are visited should be considered arbitrary.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.append(header::HOST, HeaderValue::from_static("duck.com"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+map.retain(|name, val| val.as_bytes().starts_with(b"one"));
+
+assert_eq!(map.len(), 1);
+assert!(map.contains_key(&header::SET_COOKIE));
+
source

pub fn drain(&mut self) -> Drain<'_>

Clears the map, returning all name-value sets as an iterator.

+

Header names will only be yielded for the first value in each set. All items that are +yielded without a name and after an item with a name are associated with that same name. +The first item will always contain a name.

+

Keeps the allocated memory for reuse.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut iter = map.drain();
+assert!(iter.next().is_none());
+drop(iter);
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let mut iter = map.drain();
+assert_eq!(iter.next().unwrap(), (Some(header::SET_COOKIE), HeaderValue::from_static("one=1")));
+assert_eq!(iter.next().unwrap(), (None, HeaderValue::from_static("two=2")));
+drop(iter);
+
+assert!(map.is_empty());
+

Trait Implementations§

source§

impl Clone for HeaderMap

source§

fn clone(&self) -> HeaderMap

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for HeaderMap

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for HeaderMap

source§

fn default() -> HeaderMap

Returns the “default value” for a type. Read more
source§

impl From<HeaderMap> for HeaderMap

Convert a http::HeaderMap to our HeaderMap.

+
source§

fn from(map: HeaderMap) -> HeaderMap

Converts to this type from the input type.
source§

impl<'a> IntoIterator for &'a HeaderMap

§

type Item = (&'a HeaderName, &'a HeaderValue)

The type of the elements being iterated over.
§

type IntoIter = Iter<'a>

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> <&'a HeaderMap as IntoIterator>::IntoIter

Creates an iterator from a value. Read more
source§

impl IntoIterator for HeaderMap

Note that this implementation will clone a HeaderName for each value. Consider using +drain to control header name cloning.

+
§

type Item = (HeaderName, HeaderValue)

The type of the elements being iterated over.
§

type IntoIter = IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> <HeaderMap as IntoIterator>::IntoIter

Creates an iterator from a value. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.HeaderName.html b/actix_web/http/header/struct.HeaderName.html new file mode 100644 index 000000000..2cb1ba940 --- /dev/null +++ b/actix_web/http/header/struct.HeaderName.html @@ -0,0 +1,136 @@ +HeaderName in actix_web::http::header - Rust

Struct actix_web::http::header::HeaderName

source ·
pub struct HeaderName { /* private fields */ }
Expand description

Represents an HTTP header field name

+

Header field names identify the header. Header sets may include multiple +headers with the same name. The HTTP specification defines a number of +standard headers, but HTTP messages may include non-standard header names as +well as long as they adhere to the specification.

+

HeaderName is used as the HeaderMap key. Constants are available for +all standard header names in the header module.

+

§Representation

+

HeaderName represents standard header names using an enum, as such they +will not require an allocation for storage. All custom header names are +lower cased upon conversion to a HeaderName value. This avoids the +overhead of dynamically doing lower case conversion during the hash code +computation and the comparison operation.

+

Implementations§

source§

impl HeaderName

source

pub fn from_bytes(src: &[u8]) -> Result<HeaderName, InvalidHeaderName>

Converts a slice of bytes to an HTTP header name.

+

This function normalizes the input.

+
source

pub fn from_lowercase(src: &[u8]) -> Result<HeaderName, InvalidHeaderName>

Converts a slice of bytes to an HTTP header name.

+

This function expects the input to only contain lowercase characters. +This is useful when decoding HTTP/2.0 or HTTP/3.0 headers. Both +require that all headers be represented in lower case.

+
§Examples
+

+// Parsing a lower case header
+let hdr = HeaderName::from_lowercase(b"content-length").unwrap();
+assert_eq!(CONTENT_LENGTH, hdr);
+
+// Parsing a header that contains uppercase characters
+assert!(HeaderName::from_lowercase(b"Content-Length").is_err());
+
source

pub const fn from_static(src: &'static str) -> HeaderName

Converts a static string to a HTTP header name.

+

This function requires the static string to only contain lowercase +characters, numerals and symbols, as per the HTTP/2.0 specification +and header names internal representation within this library.

+
§Panics
+

This function panics when the static string is a invalid header.

+

Until Allow panicking in constants +makes its way into stable, the panic message at compile-time is +going to look cryptic, but should at least point at your header value:

+
error: any use of this value will cause an error
+    --> http/src/header/name.rs:1241:13
+     |
+1241 |             ([] as [u8; 0])[0]; // Invalid header name
+     |             ^^^^^^^^^^^^^^^^^^
+     |             |
+     |             index out of bounds: the length is 0 but the index is 0
+     |             inside `http::HeaderName::from_static` at http/src/header/name.rs:1241:13
+     |             inside `INVALID_NAME` at src/main.rs:3:34
+     |
+    ::: src/main.rs:3:1
+     |
+3    | const INVALID_NAME: HeaderName = HeaderName::from_static("Capitalized");
+     | ------------------------------------------------------------------------
+
§Examples
+
// Parsing a standard header
+let hdr = HeaderName::from_static("content-length");
+assert_eq!(CONTENT_LENGTH, hdr);
+
+// Parsing a custom header
+let CUSTOM_HEADER: &'static str = "custom-header";
+
+let a = HeaderName::from_lowercase(b"custom-header").unwrap();
+let b = HeaderName::from_static(CUSTOM_HEADER);
+assert_eq!(a, b);
+ +
// Parsing a header that contains invalid symbols(s):
+HeaderName::from_static("content{}{}length"); // This line panics!
+
+// Parsing a header that contains invalid uppercase characters.
+let a = HeaderName::from_static("foobar");
+let b = HeaderName::from_static("FOOBAR"); // This line panics!
+
source

pub fn as_str(&self) -> &str

Returns a str representation of the header.

+

The returned string will always be lower case.

+

Trait Implementations§

source§

impl AsRef<[u8]> for HeaderName

source§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl AsRef<str> for HeaderName

source§

fn as_ref(&self) -> &str

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Borrow<str> for HeaderName

source§

fn borrow(&self) -> &str

Immutably borrows from an owned value. Read more
source§

impl Clone for HeaderName

source§

fn clone(&self) -> HeaderName

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for HeaderName

source§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for HeaderName

source§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a HeaderName> for HeaderName

source§

fn from(src: &'a HeaderName) -> HeaderName

Converts to this type from the input type.
source§

impl From<HeaderName> for HeaderValue

source§

fn from(h: HeaderName) -> HeaderValue

Converts to this type from the input type.
source§

impl FromStr for HeaderName

§

type Err = InvalidHeaderName

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<HeaderName, InvalidHeaderName>

Parses a string s to return a value of this type. Read more
source§

impl Hash for HeaderName

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<'a> PartialEq<&'a HeaderName> for HeaderName

source§

fn eq(&self, other: &&'a HeaderName) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<&'a str> for HeaderName

source§

fn eq(&self, other: &&'a str) -> bool

Performs a case-insensitive comparison of the string against the header +name

+
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<HeaderName> for &'a HeaderName

source§

fn eq(&self, other: &HeaderName) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<HeaderName> for &'a str

source§

fn eq(&self, other: &HeaderName) -> bool

Performs a case-insensitive comparison of the string against the header +name

+
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<HeaderName> for str

source§

fn eq(&self, other: &HeaderName) -> bool

Performs a case-insensitive comparison of the string against the header +name

+
§Examples
+
use http::header::CONTENT_LENGTH;
+
+assert_eq!(CONTENT_LENGTH, "content-length");
+assert_eq!(CONTENT_LENGTH, "Content-Length");
+assert_ne!(CONTENT_LENGTH, "content length");
+
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for HeaderName

source§

fn eq(&self, other: &str) -> bool

Performs a case-insensitive comparison of the string against the header +name

+
§Examples
+
use http::header::CONTENT_LENGTH;
+
+assert_eq!(CONTENT_LENGTH, "content-length");
+assert_eq!(CONTENT_LENGTH, "Content-Length");
+assert_ne!(CONTENT_LENGTH, "content length");
+
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for HeaderName

source§

fn eq(&self, other: &HeaderName) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> TryFrom<&'a [u8]> for HeaderName

§

type Error = InvalidHeaderName

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a [u8] +) -> Result<HeaderName, <HeaderName as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a String> for HeaderName

§

type Error = InvalidHeaderName

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a String +) -> Result<HeaderName, <HeaderName as TryFrom<&'a String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for HeaderName

§

type Error = InvalidHeaderName

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a str +) -> Result<HeaderName, <HeaderName as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for HeaderName

§

type Error = InvalidHeaderName

The type returned in the event of a conversion error.
source§

fn try_from( + s: String +) -> Result<HeaderName, <HeaderName as TryFrom<String>>::Error>

Performs the conversion.
source§

impl TryFrom<Vec<u8>> for HeaderName

§

type Error = InvalidHeaderName

The type returned in the event of a conversion error.
source§

fn try_from( + vec: Vec<u8> +) -> Result<HeaderName, <HeaderName as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
source§

impl AsHeaderName for &HeaderName

source§

impl<'a> AsHeaderName for &'a HeaderName

source§

impl AsHeaderName for HeaderName

source§

impl AsHeaderName for HeaderName

source§

impl Eq for HeaderName

source§

impl<'a> IntoHeaderName for &'a HeaderName

source§

impl IntoHeaderName for HeaderName

source§

impl StructuralPartialEq for HeaderName

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.HeaderValue.html b/actix_web/http/header/struct.HeaderValue.html new file mode 100644 index 000000000..8405cae7e --- /dev/null +++ b/actix_web/http/header/struct.HeaderValue.html @@ -0,0 +1,208 @@ +HeaderValue in actix_web::http::header - Rust

Struct actix_web::http::header::HeaderValue

source ·
pub struct HeaderValue { /* private fields */ }
Expand description

Represents an HTTP header field value.

+

In practice, HTTP header field values are usually valid ASCII. However, the +HTTP spec allows for a header value to contain opaque bytes as well. In this +case, the header field value is not able to be represented as a string.

+

To handle this, the HeaderValue is useable as a type and can be compared +with strings and implements Debug. A to_str fn is provided that returns +an Err if the header value contains non visible ascii characters.

+

Implementations§

source§

impl HeaderValue

source

pub const fn from_static(src: &'static str) -> HeaderValue

Convert a static string to a HeaderValue.

+

This function will not perform any copying, however the string is +checked to ensure that no invalid characters are present. Only visible +ASCII characters (32-127) are permitted.

+
§Panics
+

This function panics if the argument contains invalid header value +characters.

+

Until Allow panicking in constants +makes its way into stable, the panic message at compile-time is +going to look cryptic, but should at least point at your header value:

+
error: any use of this value will cause an error
+  --> http/src/header/value.rs:67:17
+   |
+67 |                 ([] as [u8; 0])[0]; // Invalid header value
+   |                 ^^^^^^^^^^^^^^^^^^
+   |                 |
+   |                 index out of bounds: the length is 0 but the index is 0
+   |                 inside `HeaderValue::from_static` at http/src/header/value.rs:67:17
+   |                 inside `INVALID_HEADER` at src/main.rs:73:33
+   |
+  ::: src/main.rs:73:1
+   |
+73 | const INVALID_HEADER: HeaderValue = HeaderValue::from_static("жsome value");
+   | ----------------------------------------------------------------------------
+
§Examples
+
let val = HeaderValue::from_static("hello");
+assert_eq!(val, "hello");
+
source

pub fn from_str(src: &str) -> Result<HeaderValue, InvalidHeaderValue>

Attempt to convert a string to a HeaderValue.

+

If the argument contains invalid header value characters, an error is +returned. Only visible ASCII characters (32-127) are permitted. Use +from_bytes to create a HeaderValue that includes opaque octets +(128-255).

+

This function is intended to be replaced in the future by a TryFrom +implementation once the trait is stabilized in std.

+
§Examples
+
let val = HeaderValue::from_str("hello").unwrap();
+assert_eq!(val, "hello");
+

An invalid value

+ +
let val = HeaderValue::from_str("\n");
+assert!(val.is_err());
+
source

pub fn from_name(name: HeaderName) -> HeaderValue

Converts a HeaderName into a HeaderValue

+

Since every valid HeaderName is a valid HeaderValue this is done infallibly.

+
§Examples
+
let val = HeaderValue::from_name(ACCEPT);
+assert_eq!(val, HeaderValue::from_bytes(b"accept").unwrap());
+
source

pub fn from_bytes(src: &[u8]) -> Result<HeaderValue, InvalidHeaderValue>

Attempt to convert a byte slice to a HeaderValue.

+

If the argument contains invalid header value bytes, an error is +returned. Only byte values between 32 and 255 (inclusive) are permitted, +excluding byte 127 (DEL).

+

This function is intended to be replaced in the future by a TryFrom +implementation once the trait is stabilized in std.

+
§Examples
+
let val = HeaderValue::from_bytes(b"hello\xfa").unwrap();
+assert_eq!(val, &b"hello\xfa"[..]);
+

An invalid value

+ +
let val = HeaderValue::from_bytes(b"\n");
+assert!(val.is_err());
+
source

pub fn from_maybe_shared<T>(src: T) -> Result<HeaderValue, InvalidHeaderValue>
where + T: AsRef<[u8]> + 'static,

Attempt to convert a Bytes buffer to a HeaderValue.

+

This will try to prevent a copy if the type passed is the type used +internally, and will copy the data if it is not.

+
source

pub unsafe fn from_maybe_shared_unchecked<T>(src: T) -> HeaderValue
where + T: AsRef<[u8]> + 'static,

Convert a Bytes directly into a HeaderValue without validating.

+

This function does NOT validate that illegal bytes are not contained +within the buffer.

+
source

pub fn to_str(&self) -> Result<&str, ToStrError>

Yields a &str slice if the HeaderValue only contains visible ASCII +chars.

+

This function will perform a scan of the header value, checking all the +characters.

+
§Examples
+
let val = HeaderValue::from_static("hello");
+assert_eq!(val.to_str().unwrap(), "hello");
+
source

pub fn len(&self) -> usize

Returns the length of self.

+

This length is in bytes.

+
§Examples
+
let val = HeaderValue::from_static("hello");
+assert_eq!(val.len(), 5);
+
source

pub fn is_empty(&self) -> bool

Returns true if the HeaderValue has a length of zero bytes.

+
§Examples
+
let val = HeaderValue::from_static("");
+assert!(val.is_empty());
+
+let val = HeaderValue::from_static("hello");
+assert!(!val.is_empty());
+
source

pub fn as_bytes(&self) -> &[u8]

Converts a HeaderValue to a byte slice.

+
§Examples
+
let val = HeaderValue::from_static("hello");
+assert_eq!(val.as_bytes(), b"hello");
+
source

pub fn set_sensitive(&mut self, val: bool)

Mark that the header value represents sensitive information.

+
§Examples
+
let mut val = HeaderValue::from_static("my secret");
+
+val.set_sensitive(true);
+assert!(val.is_sensitive());
+
+val.set_sensitive(false);
+assert!(!val.is_sensitive());
+
source

pub fn is_sensitive(&self) -> bool

Returns true if the value represents sensitive data.

+

Sensitive data could represent passwords or other data that should not +be stored on disk or in memory. By marking header values as sensitive, +components using this crate can be instructed to treat them with special +care for security reasons. For example, caches can avoid storing +sensitive values, and HPACK encoders used by HTTP/2.0 implementations +can choose not to compress them.

+

Additionally, sensitive values will be masked by the Debug +implementation of HeaderValue.

+

Note that sensitivity is not factored into equality or ordering.

+
§Examples
+
let mut val = HeaderValue::from_static("my secret");
+
+val.set_sensitive(true);
+assert!(val.is_sensitive());
+
+val.set_sensitive(false);
+assert!(!val.is_sensitive());
+

Trait Implementations§

source§

impl AsRef<[u8]> for HeaderValue

source§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for HeaderValue

source§

fn clone(&self) -> HeaderValue

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for HeaderValue

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a HeaderValue> for HeaderValue

source§

fn from(t: &'a HeaderValue) -> HeaderValue

Converts to this type from the input type.
source§

impl From<HeaderName> for HeaderValue

source§

fn from(h: HeaderName) -> HeaderValue

Converts to this type from the input type.
source§

impl From<i16> for HeaderValue

source§

fn from(num: i16) -> HeaderValue

Converts to this type from the input type.
source§

impl From<i32> for HeaderValue

source§

fn from(num: i32) -> HeaderValue

Converts to this type from the input type.
source§

impl From<i64> for HeaderValue

source§

fn from(num: i64) -> HeaderValue

Converts to this type from the input type.
source§

impl From<isize> for HeaderValue

source§

fn from(num: isize) -> HeaderValue

Converts to this type from the input type.
source§

impl From<u16> for HeaderValue

source§

fn from(num: u16) -> HeaderValue

Converts to this type from the input type.
source§

impl From<u32> for HeaderValue

source§

fn from(num: u32) -> HeaderValue

Converts to this type from the input type.
source§

impl From<u64> for HeaderValue

source§

fn from(num: u64) -> HeaderValue

Converts to this type from the input type.
source§

impl From<usize> for HeaderValue

source§

fn from(num: usize) -> HeaderValue

Converts to this type from the input type.
source§

impl FromStr for HeaderValue

§

type Err = InvalidHeaderValue

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<HeaderValue, <HeaderValue as FromStr>::Err>

Parses a string s to return a value of this type. Read more
source§

impl Hash for HeaderValue

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for HeaderValue

source§

fn cmp(&self, other: &HeaderValue) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl<'a, T> PartialEq<&'a T> for HeaderValue
where + HeaderValue: PartialEq<T>, + T: ?Sized,

source§

fn eq(&self, other: &&'a T) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<[u8]> for HeaderValue

source§

fn eq(&self, other: &[u8]) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<HeaderValue> for &'a HeaderValue

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<HeaderValue> for &'a str

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<HeaderValue> for [u8]

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<HeaderValue> for str

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<String> for HeaderValue

source§

fn eq(&self, other: &String) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for HeaderValue

source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for HeaderValue

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a, T> PartialOrd<&'a T> for HeaderValue
where + HeaderValue: PartialOrd<T>, + T: ?Sized,

source§

fn partial_cmp(&self, other: &&'a T) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<[u8]> for HeaderValue

source§

fn partial_cmp(&self, other: &[u8]) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> PartialOrd<HeaderValue> for &'a HeaderValue

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> PartialOrd<HeaderValue> for &'a str

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<HeaderValue> for [u8]

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<HeaderValue> for str

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<String> for HeaderValue

source§

fn partial_cmp(&self, other: &String) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<str> for HeaderValue

source§

fn partial_cmp(&self, other: &str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for HeaderValue

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> TryFrom<&'a [u8]> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + t: &'a [u8] +) -> Result<HeaderValue, <HeaderValue as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a String> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a String +) -> Result<HeaderValue, <HeaderValue as TryFrom<&'a String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + t: &'a str +) -> Result<HeaderValue, <HeaderValue as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + t: String +) -> Result<HeaderValue, <HeaderValue as TryFrom<String>>::Error>

Performs the conversion.
source§

impl TryFrom<Vec<u8>> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + vec: Vec<u8> +) -> Result<HeaderValue, <HeaderValue as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
source§

impl TryIntoHeaderValue for &HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value( + self +) -> Result<HeaderValue, <&HeaderValue as TryIntoHeaderValue>::Error>

Try to convert value to a HeaderValue.
source§

impl TryIntoHeaderValue for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value( + self +) -> Result<HeaderValue, <HeaderValue as TryIntoHeaderValue>::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for HeaderValue

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.HttpDate.html b/actix_web/http/header/struct.HttpDate.html new file mode 100644 index 000000000..ce7fc867c --- /dev/null +++ b/actix_web/http/header/struct.HttpDate.html @@ -0,0 +1,35 @@ +HttpDate in actix_web::http::header - Rust

Struct actix_web::http::header::HttpDate

source ·
pub struct HttpDate(/* private fields */);
Expand description

A timestamp with HTTP-style formatting and parsing.

+

Trait Implementations§

source§

impl Clone for HttpDate

source§

fn clone(&self) -> HttpDate

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for HttpDate

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for HttpDate

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl From<SystemTime> for HttpDate

source§

fn from(sys_time: SystemTime) -> HttpDate

Converts to this type from the input type.
source§

impl FromStr for HttpDate

§

type Err = ParseError

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<HttpDate, ParseError>

Parses a string s to return a value of this type. Read more
source§

impl Ord for HttpDate

source§

fn cmp(&self, other: &HttpDate) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq for HttpDate

source§

fn eq(&self, other: &HttpDate) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for HttpDate

source§

fn partial_cmp(&self, other: &HttpDate) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl TryIntoHeaderValue for HttpDate

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value( + self +) -> Result<HeaderValue, <HttpDate as TryIntoHeaderValue>::Error>

Try to convert value to a HeaderValue.
source§

impl Copy for HttpDate

source§

impl Eq for HttpDate

source§

impl StructuralPartialEq for HttpDate

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.IfModifiedSince.html b/actix_web/http/header/struct.IfModifiedSince.html new file mode 100644 index 000000000..c1c012edc --- /dev/null +++ b/actix_web/http/header/struct.IfModifiedSince.html @@ -0,0 +1,50 @@ +IfModifiedSince in actix_web::http::header - Rust

Struct actix_web::http::header::IfModifiedSince

source ·
pub struct IfModifiedSince(pub HttpDate);
Expand description

If-Modified-Since header, defined +in RFC 7232 §3.3

+

The If-Modified-Since header field makes a GET or HEAD request +method conditional on the selected representation’s modification date +being more recent than the date provided in the field-value. +Transfer of the selected representation’s data is avoided if that +data has not changed.

+

§ABNF

If-Unmodified-Since = HTTP-date
+

§Example Values

+
    +
  • Sat, 29 Oct 1994 19:43:31 GMT
  • +
+

§Examples

+
use std::time::{SystemTime, Duration};
+use actix_web::HttpResponse;
+use actix_web::http::header::IfModifiedSince;
+
+let mut builder = HttpResponse::Ok();
+let modified = SystemTime::now() - Duration::from_secs(60 * 60 * 24);
+builder.insert_header(
+    IfModifiedSince(modified.into())
+);
+

Tuple Fields§

§0: HttpDate

Trait Implementations§

source§

impl Clone for IfModifiedSince

source§

fn clone(&self) -> IfModifiedSince

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for IfModifiedSince

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for IfModifiedSince

§

type Target = HttpDate

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for IfModifiedSince

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl Display for IfModifiedSince

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for IfModifiedSince

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for IfModifiedSince

source§

fn eq(&self, other: &IfModifiedSince) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for IfModifiedSince

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for IfModifiedSince

source§

impl StructuralPartialEq for IfModifiedSince

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.IfUnmodifiedSince.html b/actix_web/http/header/struct.IfUnmodifiedSince.html new file mode 100644 index 000000000..dd6bf6362 --- /dev/null +++ b/actix_web/http/header/struct.IfUnmodifiedSince.html @@ -0,0 +1,50 @@ +IfUnmodifiedSince in actix_web::http::header - Rust

Struct actix_web::http::header::IfUnmodifiedSince

source ·
pub struct IfUnmodifiedSince(pub HttpDate);
Expand description

If-Unmodified-Since header, defined +in RFC 7232 §3.4

+

The If-Unmodified-Since header field makes the request method +conditional on the selected representation’s last modification date +being earlier than or equal to the date provided in the field-value. +This field accomplishes the same purpose as If-Match for cases where +the user agent does not have an entity-tag for the representation.

+

§ABNF

If-Unmodified-Since = HTTP-date
+

§Example Values

+
    +
  • Sat, 29 Oct 1994 19:43:31 GMT
  • +
+

§Examples

+
use std::time::{SystemTime, Duration};
+use actix_web::HttpResponse;
+use actix_web::http::header::IfUnmodifiedSince;
+
+let mut builder = HttpResponse::Ok();
+let modified = SystemTime::now() - Duration::from_secs(60 * 60 * 24);
+builder.insert_header(
+    IfUnmodifiedSince(modified.into())
+);
+

Tuple Fields§

§0: HttpDate

Trait Implementations§

source§

impl Clone for IfUnmodifiedSince

source§

fn clone(&self) -> IfUnmodifiedSince

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for IfUnmodifiedSince

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for IfUnmodifiedSince

§

type Target = HttpDate

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for IfUnmodifiedSince

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl Display for IfUnmodifiedSince

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for IfUnmodifiedSince

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for IfUnmodifiedSince

source§

fn eq(&self, other: &IfUnmodifiedSince) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for IfUnmodifiedSince

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for IfUnmodifiedSince

source§

impl StructuralPartialEq for IfUnmodifiedSince

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.InvalidHeaderName.html b/actix_web/http/header/struct.InvalidHeaderName.html new file mode 100644 index 000000000..6160bac98 --- /dev/null +++ b/actix_web/http/header/struct.InvalidHeaderName.html @@ -0,0 +1,19 @@ +InvalidHeaderName in actix_web::http::header - Rust

Struct actix_web::http::header::InvalidHeaderName

source ·
pub struct InvalidHeaderName { /* private fields */ }
Expand description

A possible error when converting a HeaderName from another type.

+

Trait Implementations§

source§

impl Debug for InvalidHeaderName

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for InvalidHeaderName

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for InvalidHeaderName

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<InvalidHeaderName> for Error

source§

fn from(err: InvalidHeaderName) -> Error

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.InvalidHeaderValue.html b/actix_web/http/header/struct.InvalidHeaderValue.html new file mode 100644 index 000000000..3c0570c8e --- /dev/null +++ b/actix_web/http/header/struct.InvalidHeaderValue.html @@ -0,0 +1,20 @@ +InvalidHeaderValue in actix_web::http::header - Rust

Struct actix_web::http::header::InvalidHeaderValue

source ·
pub struct InvalidHeaderValue { /* private fields */ }
Expand description

A possible error when converting a HeaderValue from a string or byte +slice.

+

Trait Implementations§

source§

impl Debug for InvalidHeaderValue

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for InvalidHeaderValue

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for InvalidHeaderValue

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<InvalidHeaderValue> for Error

source§

fn from(err: InvalidHeaderValue) -> Error

Converts to this type from the input type.
source§

impl ResponseError for InvalidHeaderValue

source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
source§

fn error_response(&self) -> HttpResponse<BoxBody>

Creates full response for error. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.LanguageTag.html b/actix_web/http/header/struct.LanguageTag.html new file mode 100644 index 000000000..baa180c90 --- /dev/null +++ b/actix_web/http/header/struct.LanguageTag.html @@ -0,0 +1,177 @@ +LanguageTag in actix_web::http::header - Rust

Struct actix_web::http::header::LanguageTag

pub struct LanguageTag { /* private fields */ }
Expand description

A language tag as described in RFC 5646.

+

Language tags are used to help identify languages, whether spoken, +written, signed, or otherwise signaled, for the purpose of +communication. This includes constructed and artificial languages +but excludes languages not intended primarily for human +communication, such as programming languages.

+

Implementations§

§

impl LanguageTag

pub fn as_str(&self) -> &str

Return the serialization of this language tag.

+

This is fast since that serialization is already stored in the LanguageTag struct.

+

pub fn into_string(self) -> String

Return the serialization of this language tag.

+

This consumes the LanguageTag and takes ownership of the String stored in it.

+

pub fn primary_language(&self) -> &str

Return the primary language subtag.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.primary_language(), "zh");
+

pub fn extended_language(&self) -> Option<&str>

Return the extended language subtags.

+

Valid language tags have at most one extended language.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.extended_language(), Some("cmn"));
+

pub fn extended_language_subtags(&self) -> impl Iterator<Item = &str>

Iterate on the extended language subtags.

+

Valid language tags have at most one extended language.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.extended_language_subtags().collect::<Vec<_>>(), vec!["cmn"]);
+

pub fn full_language(&self) -> &str

Return the primary language subtag +and its extended language subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.full_language(), "zh-cmn");
+

pub fn script(&self) -> Option<&str>

Return the script subtag.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.script(), Some("Hans"));
+

pub fn region(&self) -> Option<&str>

Return the region subtag.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.region(), Some("CN"));
+

pub fn variant(&self) -> Option<&str>

Return the variant subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-Latn-TW-pinyin").unwrap();
+assert_eq!(language_tag.variant(), Some("pinyin"));
+

pub fn variant_subtags(&self) -> impl Iterator<Item = &str>

Iterate on the variant subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-Latn-TW-pinyin").unwrap();
+assert_eq!(language_tag.variant_subtags().collect::<Vec<_>>(), vec!["pinyin"]);
+

pub fn extension(&self) -> Option<&str>

Return the extension subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("de-DE-u-co-phonebk").unwrap();
+assert_eq!(language_tag.extension(), Some("u-co-phonebk"));
+

pub fn extension_subtags(&self) -> impl Iterator<Item = (char, &str)>

Iterate on the extension subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("de-DE-u-co-phonebk").unwrap();
+assert_eq!(language_tag.extension_subtags().collect::<Vec<_>>(), vec![('u', "co-phonebk")]);
+

pub fn private_use(&self) -> Option<&str>

Return the private use subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("de-x-foo-bar").unwrap();
+assert_eq!(language_tag.private_use(), Some("x-foo-bar"));
+

pub fn private_use_subtags(&self) -> impl Iterator<Item = &str>

Iterate on the private use subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("de-x-foo-bar").unwrap();
+assert_eq!(language_tag.private_use_subtags().collect::<Vec<_>>(), vec!["foo", "bar"]);
+

pub fn parse(input: &str) -> Result<LanguageTag, ParseError>

Create a LanguageTag from its serialization.

+

This parser accepts the language tags that are “well-formed” according to +RFC 5646. +Full validation could be done with the validate method.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("en-us").unwrap();
+assert_eq!(language_tag.into_string(), "en-US")
+
§Errors
+

If the language tag is not “well-formed” a ParseError variant will be returned.

+

pub fn validate(&self) -> Result<(), ValidationError>

Check if the language tag is “valid” according to +RFC 5646.

+

It applies the following steps:

+
    +
  • grandfathereds and private use tags are valid
  • +
  • There should be no more than one extended language subtag +(c.f. errata 5457).
  • +
  • Primary language, extended language, script, region and variants should appear +in the IANA Language Subtag Registry.
  • +
  • Extended language and variants should have a correct prefix as set +in the IANA Language Subtag Registry.
  • +
  • There should be no duplicate variant and singleton (extension) subtags.
  • +
+
§Errors
+

If the language tag is not “valid” a ValidationError variant will be returned.

+

pub fn is_valid(&self) -> bool

Check if the language tag is valid according to +RFC 5646.

+

pub fn canonicalize(&self) -> Result<LanguageTag, ValidationError>

Returns the canonical version of the language tag following +RFC 5646 4.5.

+

It currently applies the following steps:

+
    +
  • Grandfathered tags are replaced with the canonical version if possible.
  • +
  • Redundant tags are replaced with the canonical version if possible.
  • +
  • Extension languages are promoted to primary language.
  • +
  • Deprecated languages, scripts, regions and variants are replaced with modern equivalents.
  • +
  • Suppress-Script is applied to remove default script for a language (e.g. “en-Latn” is canonicalized as “en”).
  • +
  • Variants are deduplicated
  • +
+
§Errors
+

If there is not a unique way to canonicalize the language tag +a ValidationError variant will be returned.

+

pub fn matches(&self, other: &LanguageTag) -> bool

Matches language tags. The first language acts as a language range, the second one is used +as a normal language tag. None fields in the language range are ignored. If the language +tag has more extlangs than the range these extlangs are ignored. Matches are +case-insensitive.

+

For example the range en-GB matches only en-GB and en-Arab-GB but not en. +The range en matches all language tags starting with en including en, en-GB, +en-Arab and en-Arab-GB.

+
§Panics
+

If the language range has extensions or private use tags.

+
§Examples
+
use language_tags::LanguageTag;
+
+let range_italian = LanguageTag::parse("it").unwrap();
+let tag_german = LanguageTag::parse("de").unwrap();
+let tag_italian_switzerland = LanguageTag::parse("it-CH").unwrap();
+assert!(!range_italian.matches(&tag_german));
+assert!(range_italian.matches(&tag_italian_switzerland));
+
+let range_spanish_brazil = LanguageTag::parse("es-BR").unwrap();
+let tag_spanish = LanguageTag::parse("es").unwrap();
+assert!(!range_spanish_brazil.matches(&tag_spanish));
+

pub fn is_language_range(&self) -> bool

Checks if it is a language range, meaning that there are no extension and privateuse tags.

+

Trait Implementations§

§

impl Clone for LanguageTag

§

fn clone(&self) -> LanguageTag

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for LanguageTag

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for LanguageTag

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl FromStr for LanguageTag

§

type Err = ParseError

The associated error which can be returned from parsing.
§

fn from_str(input: &str) -> Result<LanguageTag, ParseError>

Parses a string s to return a value of this type. Read more
§

impl Hash for LanguageTag

§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl PartialEq for LanguageTag

§

fn eq(&self, other: &LanguageTag) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Eq for LanguageTag

§

impl StructuralPartialEq for LanguageTag

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.LastModified.html b/actix_web/http/header/struct.LastModified.html new file mode 100644 index 000000000..d496210fe --- /dev/null +++ b/actix_web/http/header/struct.LastModified.html @@ -0,0 +1,49 @@ +LastModified in actix_web::http::header - Rust

Struct actix_web::http::header::LastModified

source ·
pub struct LastModified(pub HttpDate);
Expand description

Last-Modified header, defined +in RFC 7232 §2.2

+

The Last-Modified header field in a response provides a timestamp +indicating the date and time at which the origin server believes the +selected representation was last modified, as determined at the +conclusion of handling the request.

+

§ABNF

Expires = HTTP-date
+

§Example Values

+
    +
  • Sat, 29 Oct 1994 19:43:31 GMT
  • +
+

§Examples

+
use std::time::{SystemTime, Duration};
+use actix_web::HttpResponse;
+use actix_web::http::header::LastModified;
+
+let mut builder = HttpResponse::Ok();
+let modified = SystemTime::now() - Duration::from_secs(60 * 60 * 24);
+builder.insert_header(
+    LastModified(modified.into())
+);
+

Tuple Fields§

§0: HttpDate

Trait Implementations§

source§

impl Clone for LastModified

source§

fn clone(&self) -> LastModified

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for LastModified

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Deref for LastModified

§

type Target = HttpDate

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl DerefMut for LastModified

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl Display for LastModified

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Header for LastModified

source§

fn name() -> HeaderName

Returns the name of the header field.
source§

fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>

Parse the header from a HTTP message.
source§

impl PartialEq for LastModified

source§

fn eq(&self, other: &LastModified) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl TryIntoHeaderValue for LastModified

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for LastModified

source§

impl StructuralPartialEq for LastModified

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.Quality.html b/actix_web/http/header/struct.Quality.html new file mode 100644 index 000000000..87c8d3517 --- /dev/null +++ b/actix_web/http/header/struct.Quality.html @@ -0,0 +1,52 @@ +Quality in actix_web::http::header - Rust

Struct actix_web::http::header::Quality

source ·
pub struct Quality(/* private fields */);
Expand description

Represents a quality used in q-factor values.

+

The default value is equivalent to q=1.0 (the max value).

+

§Implementation notes

+

The quality value is defined as a number between 0.0 and 1.0 with three decimal places. +This means there are 1001 possible values. Since floating point numbers are not exact and the +smallest floating point data type (f32) consumes four bytes, we use an u16 value to store +the quality internally.

+

RFC 7231 §5.3.1 gives more information on quality values in HTTP header fields.

+

§Examples

+
use actix_http::header::{Quality, q};
+assert_eq!(q(1.0), Quality::MAX);
+
+assert_eq!(q(0.42).to_string(), "0.42");
+assert_eq!(q(1.0).to_string(), "1");
+assert_eq!(Quality::MIN.to_string(), "0.001");
+assert_eq!(Quality::ZERO.to_string(), "0");
+

Implementations§

source§

impl Quality

source

pub const MAX: Quality = _

The maximum quality value, equivalent to q=1.0.

+
source

pub const MIN: Quality = _

The minimum, non-zero quality value, equivalent to q=0.001.

+
source

pub const ZERO: Quality = _

The zero quality value, equivalent to q=0.0.

+

Trait Implementations§

source§

impl Clone for Quality

source§

fn clone(&self) -> Quality

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Quality

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Quality

The default value is Quality::MAX.

+
source§

fn default() -> Quality

Returns the “default value” for a type. Read more
source§

impl Display for Quality

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Ord for Quality

source§

fn cmp(&self, other: &Quality) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq for Quality

source§

fn eq(&self, other: &Quality) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for Quality

source§

fn partial_cmp(&self, other: &Quality) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl TryFrom<f32> for Quality

§

type Error = QualityOutOfBounds

The type returned in the event of a conversion error.
source§

fn try_from(value: f32) -> Result<Quality, <Quality as TryFrom<f32>>::Error>

Performs the conversion.
source§

impl Copy for Quality

source§

impl Eq for Quality

source§

impl StructuralPartialEq for Quality

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.QualityItem.html b/actix_web/http/header/struct.QualityItem.html new file mode 100644 index 000000000..ed9476e98 --- /dev/null +++ b/actix_web/http/header/struct.QualityItem.html @@ -0,0 +1,74 @@ +QualityItem in actix_web::http::header - Rust

Struct actix_web::http::header::QualityItem

source ·
pub struct QualityItem<T> {
+    pub item: T,
+    pub quality: Quality,
+}
Expand description

Represents an item with a quality value as defined +in RFC 7231 §5.3.1.

+

§Parsing and Formatting

+

This wrapper be used to parse header value items that have a q-factor annotation as well as +serialize items with a their q-factor.

+

§Ordering

+

Since this context of use for this type is header value items, ordering is defined for +QualityItems but only considers the item’s quality. Order of appearance should be used as +the secondary sorting parameter; i.e., a stable sort over the quality values will produce a +correctly sorted sequence.

+

§Examples

+
let q_item: QualityItem<String> = "hello;q=0.3".parse().unwrap();
+assert_eq!(&q_item.item, "hello");
+assert_eq!(q_item.quality, q(0.3));
+
+// note that format is normalized compared to parsed item
+assert_eq!(q_item.to_string(), "hello; q=0.3");
+
+// item with q=0.3 is greater than item with q=0.1
+let q_item_fallback: QualityItem<String> = "abc;q=0.1".parse().unwrap();
+assert!(q_item > q_item_fallback);
+

Fields§

§item: T

The wrapped contents of the field.

+
§quality: Quality

The quality (client or server preference) for the value.

+

Implementations§

source§

impl<T> QualityItem<T>

source

pub fn new(item: T, quality: Quality) -> QualityItem<T>

Constructs a new QualityItem from an item and a quality value.

+

The item can be of any type. The quality should be a value in the range [0, 1].

+
source

pub fn max(item: T) -> QualityItem<T>

Constructs a new QualityItem from an item, using the maximum q-value.

+
source

pub fn min(item: T) -> QualityItem<T>

Constructs a new QualityItem from an item, using the minimum, non-zero q-value.

+
source

pub fn zero(item: T) -> QualityItem<T>

Constructs a new QualityItem from an item, using zero q-value of zero.

+

Trait Implementations§

source§

impl<T> Clone for QualityItem<T>
where + T: Clone,

source§

fn clone(&self) -> QualityItem<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T> Debug for QualityItem<T>
where + T: Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<T> Display for QualityItem<T>
where + T: Display,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<T> FromStr for QualityItem<T>
where + T: FromStr,

§

type Err = ParseError

The associated error which can be returned from parsing.
source§

fn from_str( + q_item_str: &str +) -> Result<QualityItem<T>, <QualityItem<T> as FromStr>::Err>

Parses a string s to return a value of this type. Read more
source§

impl<T> PartialEq for QualityItem<T>
where + T: PartialEq,

source§

fn eq(&self, other: &QualityItem<T>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<T> PartialOrd for QualityItem<T>
where + T: PartialEq,

source§

fn partial_cmp(&self, other: &QualityItem<T>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<T> Copy for QualityItem<T>
where + T: Copy,

source§

impl<T> Eq for QualityItem<T>
where + T: Eq,

source§

impl<T> StructuralPartialEq for QualityItem<T>

Auto Trait Implementations§

§

impl<T> Freeze for QualityItem<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for QualityItem<T>
where + T: RefUnwindSafe,

§

impl<T> Send for QualityItem<T>
where + T: Send,

§

impl<T> Sync for QualityItem<T>
where + T: Sync,

§

impl<T> Unpin for QualityItem<T>
where + T: Unpin,

§

impl<T> UnwindSafe for QualityItem<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/struct.ToStrError.html b/actix_web/http/header/struct.ToStrError.html new file mode 100644 index 000000000..4f5e728ae --- /dev/null +++ b/actix_web/http/header/struct.ToStrError.html @@ -0,0 +1,21 @@ +ToStrError in actix_web::http::header - Rust

Struct actix_web::http::header::ToStrError

source ·
pub struct ToStrError { /* private fields */ }
Expand description

A possible error when converting a HeaderValue to a string representation.

+

Header field values may contain opaque bytes, in which case it is not +possible to represent the value as a string.

+

Trait Implementations§

source§

impl Debug for ToStrError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for ToStrError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for ToStrError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/header/trait.AsHeaderName.html b/actix_web/http/header/trait.AsHeaderName.html new file mode 100644 index 000000000..6424e1c4d --- /dev/null +++ b/actix_web/http/header/trait.AsHeaderName.html @@ -0,0 +1,2 @@ +AsHeaderName in actix_web::http::header - Rust

Trait actix_web::http::header::AsHeaderName

source ·
pub trait AsHeaderName: Sealed { }
Expand description

Sealed trait implemented for types that can be effectively borrowed as a HeaderValue.

+

Implementations on Foreign Types§

source§

impl AsHeaderName for &str

source§

impl AsHeaderName for &String

source§

impl AsHeaderName for String

Implementors§

\ No newline at end of file diff --git a/actix_web/http/header/trait.Header.html b/actix_web/http/header/trait.Header.html new file mode 100644 index 000000000..360b83edd --- /dev/null +++ b/actix_web/http/header/trait.Header.html @@ -0,0 +1,10 @@ +Header in actix_web::http::header - Rust

Trait actix_web::http::header::Header

source ·
pub trait Header: TryIntoHeaderValue {
+    // Required methods
+    fn name() -> HeaderName;
+    fn parse<M>(msg: &M) -> Result<Self, ParseError>
+       where M: HttpMessage;
+}
Expand description

An interface for types that already represent a valid header.

+

Required Methods§

source

fn name() -> HeaderName

Returns the name of the header field.

+
source

fn parse<M>(msg: &M) -> Result<Self, ParseError>
where + M: HttpMessage,

Parse the header from a HTTP message.

+

Object Safety§

This trait is not object safe.

Implementors§

\ No newline at end of file diff --git a/actix_web/http/header/trait.TryIntoHeaderPair.html b/actix_web/http/header/trait.TryIntoHeaderPair.html new file mode 100644 index 000000000..7e9506467 --- /dev/null +++ b/actix_web/http/header/trait.TryIntoHeaderPair.html @@ -0,0 +1,29 @@ +TryIntoHeaderPair in actix_web::http::header - Rust

Trait actix_web::http::header::TryIntoHeaderPair

source ·
pub trait TryIntoHeaderPair: Sized {
+    type Error: Into<Error>;
+
+    // Required method
+    fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error>;
+}
Expand description

An interface for types that can be converted into a HeaderName + HeaderValue pair for +insertion into a HeaderMap.

+

Required Associated Types§

Required Methods§

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<V> TryIntoHeaderPair for (&str, V)

§

type Error = InvalidHeaderPart

source§

fn try_into_pair( + self +) -> Result<(HeaderName, HeaderValue), <(&str, V) as TryIntoHeaderPair>::Error>

source§

impl<V> TryIntoHeaderPair for (&HeaderName, V)

§

type Error = InvalidHeaderPart

source§

fn try_into_pair( + self +) -> Result<(HeaderName, HeaderValue), <(&HeaderName, V) as TryIntoHeaderPair>::Error>

source§

impl<V> TryIntoHeaderPair for (&[u8], V)

§

type Error = InvalidHeaderPart

source§

fn try_into_pair( + self +) -> Result<(HeaderName, HeaderValue), <(&[u8], V) as TryIntoHeaderPair>::Error>

source§

impl<V> TryIntoHeaderPair for (String, V)

§

type Error = InvalidHeaderPart

source§

fn try_into_pair( + self +) -> Result<(HeaderName, HeaderValue), <(String, V) as TryIntoHeaderPair>::Error>

source§

impl<V> TryIntoHeaderPair for (HeaderName, V)

§

type Error = InvalidHeaderPart

source§

fn try_into_pair( + self +) -> Result<(HeaderName, HeaderValue), <(HeaderName, V) as TryIntoHeaderPair>::Error>

Implementors§

source§

impl<T> TryIntoHeaderPair for T
where + T: Header,

\ No newline at end of file diff --git a/actix_web/http/header/trait.TryIntoHeaderValue.html b/actix_web/http/header/trait.TryIntoHeaderValue.html new file mode 100644 index 000000000..62cfb9cdb --- /dev/null +++ b/actix_web/http/header/trait.TryIntoHeaderValue.html @@ -0,0 +1,29 @@ +TryIntoHeaderValue in actix_web::http::header - Rust

Trait actix_web::http::header::TryIntoHeaderValue

source ·
pub trait TryIntoHeaderValue: Sized {
+    type Error: Into<Error>;
+
+    // Required method
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error>;
+}
Expand description

An interface for types that can be converted into a HeaderValue.

+

Required Associated Types§

source

type Error: Into<Error>

The type returned in the event of a conversion error.

+

Required Methods§

source

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.

+

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl TryIntoHeaderValue for &str

source§

impl TryIntoHeaderValue for &[u8]

source§

impl TryIntoHeaderValue for i32

source§

impl TryIntoHeaderValue for i64

source§

impl TryIntoHeaderValue for u32

source§

impl TryIntoHeaderValue for u64

source§

impl TryIntoHeaderValue for usize

source§

impl TryIntoHeaderValue for String

source§

impl TryIntoHeaderValue for Vec<u8>

source§

impl TryIntoHeaderValue for Mime

Implementors§

source§

impl TryIntoHeaderValue for &HeaderValue

source§

impl TryIntoHeaderValue for ContentEncoding

source§

impl TryIntoHeaderValue for ContentRangeSpec

source§

impl TryIntoHeaderValue for IfMatch

source§

impl TryIntoHeaderValue for IfNoneMatch

source§

impl TryIntoHeaderValue for IfRange

source§

impl TryIntoHeaderValue for Range

source§

impl TryIntoHeaderValue for Bytes

source§

impl TryIntoHeaderValue for Accept

source§

impl TryIntoHeaderValue for AcceptCharset

source§

impl TryIntoHeaderValue for AcceptEncoding

source§

impl TryIntoHeaderValue for AcceptLanguage

source§

impl TryIntoHeaderValue for Allow

source§

impl TryIntoHeaderValue for CacheControl

source§

impl TryIntoHeaderValue for ContentDisposition

source§

impl TryIntoHeaderValue for ContentLanguage

source§

impl TryIntoHeaderValue for ContentLength

source§

impl TryIntoHeaderValue for ContentRange

source§

impl TryIntoHeaderValue for ContentType

source§

impl TryIntoHeaderValue for Date

source§

impl TryIntoHeaderValue for ETag

source§

impl TryIntoHeaderValue for EntityTag

source§

impl TryIntoHeaderValue for Expires

source§

impl TryIntoHeaderValue for HeaderValue

source§

impl TryIntoHeaderValue for HttpDate

source§

impl TryIntoHeaderValue for IfModifiedSince

source§

impl TryIntoHeaderValue for IfUnmodifiedSince

source§

impl TryIntoHeaderValue for LastModified

\ No newline at end of file diff --git a/actix_web/http/index.html b/actix_web/http/index.html new file mode 100644 index 000000000..14c629545 --- /dev/null +++ b/actix_web/http/index.html @@ -0,0 +1,2 @@ +actix_web::http - Rust

Module actix_web::http

source ·
Expand description

Various HTTP related types.

+

Modules§

  • A Collection of Header implementations for common HTTP Headers.
  • URI component of request and response lines

Structs§

  • The Request Method (VERB)
  • An HTTP status code (status-code in RFC 7230 et al.).
  • The URI component of a request.
  • Represents a version of the HTTP spec.

Enums§

\ No newline at end of file diff --git a/actix_web/http/sidebar-items.js b/actix_web/http/sidebar-items.js new file mode 100644 index 000000000..01a261dea --- /dev/null +++ b/actix_web/http/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["ConnectionType","KeepAlive"],"mod":["header","uri"],"struct":["Error","Method","StatusCode","Uri","Version"]}; \ No newline at end of file diff --git a/actix_web/http/struct.Error.html b/actix_web/http/struct.Error.html new file mode 100644 index 000000000..85b3ffbba --- /dev/null +++ b/actix_web/http/struct.Error.html @@ -0,0 +1,18 @@ +Error in actix_web::http - Rust

Struct actix_web::http::Error

source ·
pub struct Error { /* private fields */ }

Trait Implementations§

source§

impl Debug for Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for Error

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<EncoderError> for Error

source§

fn from(err: EncoderError) -> Error

Converts to this type from the input type.
source§

impl From<Error> for Response<BoxBody>

source§

fn from(err: Error) -> Response<BoxBody>

Converts to this type from the input type.
source§

impl From<HandshakeError> for Error

Available on crate feature ws only.
source§

fn from(err: HandshakeError) -> Error

Converts to this type from the input type.
source§

impl From<Error> for Error

source§

fn from(err: Error) -> Error

Converts to this type from the input type.
source§

impl From<Infallible> for Error

source§

fn from(err: Infallible) -> Error

Converts to this type from the input type.
source§

impl From<ParseError> for Error

source§

fn from(err: ParseError) -> Error

Converts to this type from the input type.
source§

impl From<PayloadError> for Error

source§

fn from(err: PayloadError) -> Error

Converts to this type from the input type.
source§

impl From<ProtocolError> for Error

Available on crate feature ws only.
source§

fn from(err: ProtocolError) -> Error

Converts to this type from the input type.
source§

impl ResponseError for Error

source§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
source§

fn error_response(&self) -> HttpResponse<BoxBody>

Creates full response for error. Read more

Auto Trait Implementations§

§

impl Freeze for Error

§

impl !RefUnwindSafe for Error

§

impl !Send for Error

§

impl !Sync for Error

§

impl Unpin for Error

§

impl !UnwindSafe for Error

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/struct.Method.html b/actix_web/http/struct.Method.html new file mode 100644 index 000000000..969ff243a --- /dev/null +++ b/actix_web/http/struct.Method.html @@ -0,0 +1,80 @@ +Method in actix_web::http - Rust

Struct actix_web::http::Method

source ·
pub struct Method(/* private fields */);
Expand description

The Request Method (VERB)

+

This type also contains constants for a number of common HTTP methods such +as GET, POST, etc.

+

Currently includes 8 variants representing the 8 methods defined in +RFC 7230, plus PATCH, +and an Extension variant for all extensions.

+

§Examples

+
use http::Method;
+
+assert_eq!(Method::GET, Method::from_bytes(b"GET").unwrap());
+assert!(Method::GET.is_idempotent());
+assert_eq!(Method::POST.as_str(), "POST");
+

Implementations§

source§

impl Method

source

pub const GET: Method = _

GET

+
source

pub const POST: Method = _

POST

+
source

pub const PUT: Method = _

PUT

+
source

pub const DELETE: Method = _

DELETE

+
source

pub const HEAD: Method = _

HEAD

+
source

pub const OPTIONS: Method = _

OPTIONS

+
source

pub const CONNECT: Method = _

CONNECT

+
source

pub const PATCH: Method = _

PATCH

+
source

pub const TRACE: Method = _

TRACE

+
source

pub fn from_bytes(src: &[u8]) -> Result<Method, InvalidMethod>

Converts a slice of bytes to an HTTP method.

+
source

pub fn is_safe(&self) -> bool

Whether a method is considered “safe”, meaning the request is +essentially read-only.

+

See the spec +for more words.

+
source

pub fn is_idempotent(&self) -> bool

Whether a method is considered “idempotent”, meaning the request has +the same result if executed multiple times.

+

See the spec for +more words.

+
source

pub fn as_str(&self) -> &str

Return a &str representation of the HTTP method

+

Trait Implementations§

source§

impl AsRef<str> for Method

source§

fn as_ref(&self) -> &str

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for Method

source§

fn clone(&self) -> Method

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Method

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Method

source§

fn default() -> Method

Returns the “default value” for a type. Read more
source§

impl Display for Method

source§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a Method> for Method

source§

fn from(t: &'a Method) -> Method

Converts to this type from the input type.
source§

impl FromRequest for Method

Extract the request’s method.

+

§Examples

+
use actix_web::{http::Method, web, App, Responder};
+
+async fn handler(method: Method) -> impl Responder {
+    format!("Request method: {}", method)
+}
+
+let app = App::new().default_service(web::to(handler));
+
§

type Error = Infallible

The associated error which can be returned.
§

type Future = Ready<Result<Method, <Method as FromRequest>::Error>>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more
source§

impl FromStr for Method

§

type Err = InvalidMethod

The associated error which can be returned from parsing.
source§

fn from_str(t: &str) -> Result<Method, <Method as FromStr>::Err>

Parses a string s to return a value of this type. Read more
source§

impl Hash for Method

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<'a> PartialEq<&'a Method> for Method

source§

fn eq(&self, other: &&'a Method) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<&'a str> for Method

source§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<Method> for &'a Method

source§

fn eq(&self, other: &Method) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<Method> for &'a str

source§

fn eq(&self, other: &Method) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Method> for str

source§

fn eq(&self, other: &Method) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for Method

source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Method

source§

fn eq(&self, other: &Method) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> TryFrom<&'a [u8]> for Method

§

type Error = InvalidMethod

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a [u8]) -> Result<Method, <Method as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for Method

§

type Error = InvalidMethod

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a str) -> Result<Method, <Method as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl Eq for Method

source§

impl StructuralPartialEq for Method

Auto Trait Implementations§

§

impl Freeze for Method

§

impl RefUnwindSafe for Method

§

impl Send for Method

§

impl Sync for Method

§

impl Unpin for Method

§

impl UnwindSafe for Method

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/struct.StatusCode.html b/actix_web/http/struct.StatusCode.html new file mode 100644 index 000000000..68b61f293 --- /dev/null +++ b/actix_web/http/struct.StatusCode.html @@ -0,0 +1,221 @@ +StatusCode in actix_web::http - Rust

Struct actix_web::http::StatusCode

source ·
pub struct StatusCode(/* private fields */);
Expand description

An HTTP status code (status-code in RFC 7230 et al.).

+

Constants are provided for known status codes, including those in the IANA +HTTP Status Code Registry.

+

Status code values in the range 100-999 (inclusive) are supported by this +type. Values in the range 100-599 are semantically classified by the most +significant digit. See StatusCode::is_success, etc. Values above 599 +are unclassified but allowed for legacy compatibility, though their use is +discouraged. Applications may interpret such values as protocol errors.

+

§Examples

+
use http::StatusCode;
+
+assert_eq!(StatusCode::from_u16(200).unwrap(), StatusCode::OK);
+assert_eq!(StatusCode::NOT_FOUND.as_u16(), 404);
+assert!(StatusCode::OK.is_success());
+

Implementations§

source§

impl StatusCode

source

pub fn from_u16(src: u16) -> Result<StatusCode, InvalidStatusCode>

Converts a u16 to a status code.

+

The function validates the correctness of the supplied u16. It must be +greater or equal to 100 and less than 1000.

+
§Example
+
use http::StatusCode;
+
+let ok = StatusCode::from_u16(200).unwrap();
+assert_eq!(ok, StatusCode::OK);
+
+let err = StatusCode::from_u16(99);
+assert!(err.is_err());
+
source

pub fn from_bytes(src: &[u8]) -> Result<StatusCode, InvalidStatusCode>

Converts a &u8 to a status code

+
source

pub fn as_u16(&self) -> u16

Returns the u16 corresponding to this StatusCode.

+
§Note
+

This is the same as the From<StatusCode> implementation, but +included as an inherent method because that implementation doesn’t +appear in rustdocs, as well as a way to force the type instead of +relying on inference.

+
§Example
+
let status = http::StatusCode::OK;
+assert_eq!(status.as_u16(), 200);
+
source

pub fn as_str(&self) -> &str

Returns a &str representation of the StatusCode

+

The return value only includes a numerical representation of the +status code. The canonical reason is not included.

+
§Example
+
let status = http::StatusCode::OK;
+assert_eq!(status.as_str(), "200");
+
source

pub fn canonical_reason(&self) -> Option<&'static str>

Get the standardised reason-phrase for this status code.

+

This is mostly here for servers writing responses, but could potentially have application +at other times.

+

The reason phrase is defined as being exclusively for human readers. You should avoid +deriving any meaning from it at all costs.

+

Bear in mind also that in HTTP/2.0 and HTTP/3.0 the reason phrase is abolished from +transmission, and so this canonical reason phrase really is the only reason phrase you’ll +find.

+
§Example
+
let status = http::StatusCode::OK;
+assert_eq!(status.canonical_reason(), Some("OK"));
+
source

pub fn is_informational(&self) -> bool

Check if status is within 100-199.

+
source

pub fn is_success(&self) -> bool

Check if status is within 200-299.

+
source

pub fn is_redirection(&self) -> bool

Check if status is within 300-399.

+
source

pub fn is_client_error(&self) -> bool

Check if status is within 400-499.

+
source

pub fn is_server_error(&self) -> bool

Check if status is within 500-599.

+
source§

impl StatusCode

source

pub const CONTINUE: StatusCode = _

100 Continue +[RFC7231, Section 6.2.1]

+
source

pub const SWITCHING_PROTOCOLS: StatusCode = _

101 Switching Protocols +[RFC7231, Section 6.2.2]

+
source

pub const PROCESSING: StatusCode = _

102 Processing +[RFC2518]

+
source

pub const OK: StatusCode = _

source

pub const CREATED: StatusCode = _

201 Created +[RFC7231, Section 6.3.2]

+
source

pub const ACCEPTED: StatusCode = _

202 Accepted +[RFC7231, Section 6.3.3]

+
source

pub const NON_AUTHORITATIVE_INFORMATION: StatusCode = _

203 Non-Authoritative Information +[RFC7231, Section 6.3.4]

+
source

pub const NO_CONTENT: StatusCode = _

204 No Content +[RFC7231, Section 6.3.5]

+
source

pub const RESET_CONTENT: StatusCode = _

205 Reset Content +[RFC7231, Section 6.3.6]

+
source

pub const PARTIAL_CONTENT: StatusCode = _

206 Partial Content +[RFC7233, Section 4.1]

+
source

pub const MULTI_STATUS: StatusCode = _

207 Multi-Status +[RFC4918]

+
source

pub const ALREADY_REPORTED: StatusCode = _

208 Already Reported +[RFC5842]

+
source

pub const IM_USED: StatusCode = _

226 IM Used +[RFC3229]

+
source

pub const MULTIPLE_CHOICES: StatusCode = _

300 Multiple Choices +[RFC7231, Section 6.4.1]

+
source

pub const MOVED_PERMANENTLY: StatusCode = _

301 Moved Permanently +[RFC7231, Section 6.4.2]

+
source

pub const FOUND: StatusCode = _

302 Found +[RFC7231, Section 6.4.3]

+
source

pub const SEE_OTHER: StatusCode = _

303 See Other +[RFC7231, Section 6.4.4]

+
source

pub const NOT_MODIFIED: StatusCode = _

304 Not Modified +[RFC7232, Section 4.1]

+
source

pub const USE_PROXY: StatusCode = _

305 Use Proxy +[RFC7231, Section 6.4.5]

+
source

pub const TEMPORARY_REDIRECT: StatusCode = _

307 Temporary Redirect +[RFC7231, Section 6.4.7]

+
source

pub const PERMANENT_REDIRECT: StatusCode = _

308 Permanent Redirect +[RFC7238]

+
source

pub const BAD_REQUEST: StatusCode = _

400 Bad Request +[RFC7231, Section 6.5.1]

+
source

pub const UNAUTHORIZED: StatusCode = _

401 Unauthorized +[RFC7235, Section 3.1]

+
source

pub const PAYMENT_REQUIRED: StatusCode = _

402 Payment Required +[RFC7231, Section 6.5.2]

+
source

pub const FORBIDDEN: StatusCode = _

403 Forbidden +[RFC7231, Section 6.5.3]

+
source

pub const NOT_FOUND: StatusCode = _

404 Not Found +[RFC7231, Section 6.5.4]

+
source

pub const METHOD_NOT_ALLOWED: StatusCode = _

405 Method Not Allowed +[RFC7231, Section 6.5.5]

+
source

pub const NOT_ACCEPTABLE: StatusCode = _

406 Not Acceptable +[RFC7231, Section 6.5.6]

+
source

pub const PROXY_AUTHENTICATION_REQUIRED: StatusCode = _

407 Proxy Authentication Required +[RFC7235, Section 3.2]

+
source

pub const REQUEST_TIMEOUT: StatusCode = _

408 Request Timeout +[RFC7231, Section 6.5.7]

+
source

pub const CONFLICT: StatusCode = _

409 Conflict +[RFC7231, Section 6.5.8]

+
source

pub const GONE: StatusCode = _

source

pub const LENGTH_REQUIRED: StatusCode = _

411 Length Required +[RFC7231, Section 6.5.10]

+
source

pub const PRECONDITION_FAILED: StatusCode = _

412 Precondition Failed +[RFC7232, Section 4.2]

+
source

pub const PAYLOAD_TOO_LARGE: StatusCode = _

413 Payload Too Large +[RFC7231, Section 6.5.11]

+
source

pub const URI_TOO_LONG: StatusCode = _

414 URI Too Long +[RFC7231, Section 6.5.12]

+
source

pub const UNSUPPORTED_MEDIA_TYPE: StatusCode = _

415 Unsupported Media Type +[RFC7231, Section 6.5.13]

+
source

pub const RANGE_NOT_SATISFIABLE: StatusCode = _

416 Range Not Satisfiable +[RFC7233, Section 4.4]

+
source

pub const EXPECTATION_FAILED: StatusCode = _

417 Expectation Failed +[RFC7231, Section 6.5.14]

+
source

pub const IM_A_TEAPOT: StatusCode = _

418 I’m a teapot +[curiously not registered by IANA but RFC2324]

+
source

pub const MISDIRECTED_REQUEST: StatusCode = _

421 Misdirected Request +RFC7540, Section 9.1.2

+
source

pub const UNPROCESSABLE_ENTITY: StatusCode = _

422 Unprocessable Entity +[RFC4918]

+
source

pub const LOCKED: StatusCode = _

423 Locked +[RFC4918]

+
source

pub const FAILED_DEPENDENCY: StatusCode = _

424 Failed Dependency +[RFC4918]

+
source

pub const UPGRADE_REQUIRED: StatusCode = _

426 Upgrade Required +[RFC7231, Section 6.5.15]

+
source

pub const PRECONDITION_REQUIRED: StatusCode = _

428 Precondition Required +[RFC6585]

+
source

pub const TOO_MANY_REQUESTS: StatusCode = _

429 Too Many Requests +[RFC6585]

+
source

pub const REQUEST_HEADER_FIELDS_TOO_LARGE: StatusCode = _

431 Request Header Fields Too Large +[RFC6585]

+

451 Unavailable For Legal Reasons +[RFC7725]

+
source

pub const INTERNAL_SERVER_ERROR: StatusCode = _

500 Internal Server Error +[RFC7231, Section 6.6.1]

+
source

pub const NOT_IMPLEMENTED: StatusCode = _

501 Not Implemented +[RFC7231, Section 6.6.2]

+
source

pub const BAD_GATEWAY: StatusCode = _

502 Bad Gateway +[RFC7231, Section 6.6.3]

+
source

pub const SERVICE_UNAVAILABLE: StatusCode = _

503 Service Unavailable +[RFC7231, Section 6.6.4]

+
source

pub const GATEWAY_TIMEOUT: StatusCode = _

504 Gateway Timeout +[RFC7231, Section 6.6.5]

+
source

pub const HTTP_VERSION_NOT_SUPPORTED: StatusCode = _

505 HTTP Version Not Supported +[RFC7231, Section 6.6.6]

+
source

pub const VARIANT_ALSO_NEGOTIATES: StatusCode = _

506 Variant Also Negotiates +[RFC2295]

+
source

pub const INSUFFICIENT_STORAGE: StatusCode = _

507 Insufficient Storage +[RFC4918]

+
source

pub const LOOP_DETECTED: StatusCode = _

508 Loop Detected +[RFC5842]

+
source

pub const NOT_EXTENDED: StatusCode = _

510 Not Extended +[RFC2774]

+
source

pub const NETWORK_AUTHENTICATION_REQUIRED: StatusCode = _

511 Network Authentication Required +[RFC6585]

+

Trait Implementations§

source§

impl Clone for StatusCode

source§

fn clone(&self) -> StatusCode

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for StatusCode

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for StatusCode

source§

fn default() -> StatusCode

Returns the “default value” for a type. Read more
source§

impl Display for StatusCode

Formats the status code, including the canonical reason.

+

§Example

+
assert_eq!(format!("{}", StatusCode::OK), "200 OK");
+
source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a StatusCode> for StatusCode

source§

fn from(t: &'a StatusCode) -> StatusCode

Converts to this type from the input type.
source§

impl FromStr for StatusCode

§

type Err = InvalidStatusCode

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<StatusCode, InvalidStatusCode>

Parses a string s to return a value of this type. Read more
source§

impl Hash for StatusCode

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for StatusCode

source§

fn cmp(&self, other: &StatusCode) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq<u16> for StatusCode

source§

fn eq(&self, other: &u16) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for StatusCode

source§

fn eq(&self, other: &StatusCode) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for StatusCode

source§

fn partial_cmp(&self, other: &StatusCode) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> TryFrom<&'a [u8]> for StatusCode

§

type Error = InvalidStatusCode

The type returned in the event of a conversion error.
source§

fn try_from( + t: &'a [u8] +) -> Result<StatusCode, <StatusCode as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for StatusCode

§

type Error = InvalidStatusCode

The type returned in the event of a conversion error.
source§

fn try_from( + t: &'a str +) -> Result<StatusCode, <StatusCode as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<u16> for StatusCode

§

type Error = InvalidStatusCode

The type returned in the event of a conversion error.
source§

fn try_from(t: u16) -> Result<StatusCode, <StatusCode as TryFrom<u16>>::Error>

Performs the conversion.
source§

impl Copy for StatusCode

source§

impl Eq for StatusCode

source§

impl StructuralPartialEq for StatusCode

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/struct.Uri.html b/actix_web/http/struct.Uri.html new file mode 100644 index 000000000..8511ef1bd --- /dev/null +++ b/actix_web/http/struct.Uri.html @@ -0,0 +1,293 @@ +Uri in actix_web::http - Rust

Struct actix_web::http::Uri

source ·
pub struct Uri { /* private fields */ }
Expand description

The URI component of a request.

+

For HTTP 1, this is included as part of the request line. From Section 5.3, +Request Target:

+
+

Once an inbound connection is obtained, the client sends an HTTP +request message (Section 3) with a request-target derived from the +target URI. There are four distinct formats for the request-target, +depending on both the method being requested and whether the request +is to a proxy.

+
request-target = origin-form
+               / absolute-form
+               / authority-form
+               / asterisk-form
+
+

The URI is structured as follows:

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+|-|   |-------------------------------||--------| |-------------------| |-----|
+ |                  |                       |               |              |
+scheme          authority                 path            query         fragment
+
+

For HTTP 2.0, the URI is encoded using pseudoheaders.

+

§Examples

+
use http::Uri;
+
+let uri = "/foo/bar?baz".parse::<Uri>().unwrap();
+assert_eq!(uri.path(), "/foo/bar");
+assert_eq!(uri.query(), Some("baz"));
+assert_eq!(uri.host(), None);
+
+let uri = "https://www.rust-lang.org/install.html".parse::<Uri>().unwrap();
+assert_eq!(uri.scheme_str(), Some("https"));
+assert_eq!(uri.host(), Some("www.rust-lang.org"));
+assert_eq!(uri.path(), "/install.html");
+

Implementations§

source§

impl Uri

source

pub fn builder() -> Builder

Creates a new builder-style object to manufacture a Uri.

+

This method returns an instance of Builder which can be usd to +create a Uri.

+
§Examples
+
use http::Uri;
+
+let uri = Uri::builder()
+    .scheme("https")
+    .authority("hyper.rs")
+    .path_and_query("/")
+    .build()
+    .unwrap();
+
source

pub fn from_parts(src: Parts) -> Result<Uri, InvalidUriParts>

Attempt to convert a Parts into a Uri.

+
§Examples
+

Relative URI

+ +
let mut parts = Parts::default();
+parts.path_and_query = Some("/foo".parse().unwrap());
+
+let uri = Uri::from_parts(parts).unwrap();
+
+assert_eq!(uri.path(), "/foo");
+
+assert!(uri.scheme().is_none());
+assert!(uri.authority().is_none());
+

Absolute URI

+ +
let mut parts = Parts::default();
+parts.scheme = Some("http".parse().unwrap());
+parts.authority = Some("foo.com".parse().unwrap());
+parts.path_and_query = Some("/foo".parse().unwrap());
+
+let uri = Uri::from_parts(parts).unwrap();
+
+assert_eq!(uri.scheme().unwrap().as_str(), "http");
+assert_eq!(uri.authority().unwrap(), "foo.com");
+assert_eq!(uri.path(), "/foo");
+
source

pub fn from_maybe_shared<T>(src: T) -> Result<Uri, InvalidUri>
where + T: AsRef<[u8]> + 'static,

Attempt to convert a Bytes buffer to a Uri.

+

This will try to prevent a copy if the type passed is the type used +internally, and will copy the data if it is not.

+
source

pub fn from_static(src: &'static str) -> Uri

Convert a Uri from a static string.

+

This function will not perform any copying, however the string is +checked to ensure that it is valid.

+
§Panics
+

This function panics if the argument is an invalid URI.

+
§Examples
+
let uri = Uri::from_static("http://example.com/foo");
+
+assert_eq!(uri.host().unwrap(), "example.com");
+assert_eq!(uri.path(), "/foo");
+
source

pub fn into_parts(self) -> Parts

Convert a Uri into Parts.

+
§Note
+

This is just an inherent method providing the same functionality as +let parts: Parts = uri.into()

+
§Examples
+
let uri: Uri = "/foo".parse().unwrap();
+
+let parts = uri.into_parts();
+
+assert_eq!(parts.path_and_query.unwrap(), "/foo");
+
+assert!(parts.scheme.is_none());
+assert!(parts.authority.is_none());
+
source

pub fn path_and_query(&self) -> Option<&PathAndQuery>

Returns the path & query components of the Uri

+
source

pub fn path(&self) -> &str

Get the path of this Uri.

+

Both relative and absolute URIs contain a path component, though it +might be the empty string. The path component is case sensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                       |--------|
+                                            |
+                                          path
+
+

If the URI is * then the path component is equal to *.

+
§Examples
+

A relative URI

+ +

+let uri: Uri = "/hello/world".parse().unwrap();
+
+assert_eq!(uri.path(), "/hello/world");
+

An absolute URI

+ +
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.path(), "/hello/world");
+
source

pub fn scheme(&self) -> Option<&Scheme>

Get the scheme of this Uri.

+

The URI scheme refers to a specification for assigning identifiers +within that scheme. Only absolute URIs contain a scheme component, but +not all absolute URIs will contain a scheme component. Although scheme +names are case-insensitive, the canonical form is lowercase.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+|-|
+ |
+scheme
+
§Examples
+

Absolute URI

+ +
use http::uri::{Scheme, Uri};
+
+let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.scheme(), Some(&Scheme::HTTP));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.scheme().is_none());
+
source

pub fn scheme_str(&self) -> Option<&str>

Get the scheme of this Uri as a &str.

+
§Example
+
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.scheme_str(), Some("http"));
+
source

pub fn authority(&self) -> Option<&Authority>

Get the authority of this Uri.

+

The authority is a hierarchical element for naming authority such that +the remainder of the URI is delegated to that authority. For HTTP, the +authority consists of the host and port. The host portion of the +authority is case-insensitive.

+

The authority also includes a username:password component, however +the use of this is deprecated and should be avoided.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+      |-------------------------------|
+                    |
+                authority
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.authority().map(|a| a.as_str()), Some("example.org:80"));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.authority().is_none());
+
source

pub fn host(&self) -> Option<&str>

Get the host of this Uri.

+

The host subcomponent of authority is identified by an IP literal +encapsulated within square brackets, an IPv4 address in dotted- decimal +form, or a registered name. The host subcomponent is case-insensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                        |---------|
+                             |
+                            host
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.host(), Some("example.org"));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.host().is_none());
+
source

pub fn port(&self) -> Option<Port<&str>>

Get the port part of this Uri.

+

The port subcomponent of authority is designated by an optional port +number following the host and delimited from it by a single colon (“:”) +character. It can be turned into a decimal port number with the as_u16 +method or as a str with the as_str method.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                    |-|
+                                     |
+                                    port
+
§Examples
+

Absolute URI with port

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+let port = uri.port().unwrap();
+assert_eq!(port.as_u16(), 80);
+

Absolute URI without port

+ +
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert!(uri.port().is_none());
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.port().is_none());
+
source

pub fn port_u16(&self) -> Option<u16>

Get the port of this Uri as a u16.

+
§Example
+
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.port_u16(), Some(80));
+
source

pub fn query(&self) -> Option<&str>

Get the query string of this Uri, starting after the ?.

+

The query component contains non-hierarchical data that, along with data +in the path component, serves to identify a resource within the scope of +the URI’s scheme and naming authority (if any). The query component is +indicated by the first question mark (“?”) character and terminated by a +number sign (“#”) character or by the end of the URI.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                                  |-------------------|
+                                                            |
+                                                          query
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org/hello/world?key=value".parse().unwrap();
+
+assert_eq!(uri.query(), Some("key=value"));
+

Relative URI with a query string component

+ +
let uri: Uri = "/hello/world?key=value&foo=bar".parse().unwrap();
+
+assert_eq!(uri.query(), Some("key=value&foo=bar"));
+

Relative URI without a query string component

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.query().is_none());
+

Trait Implementations§

source§

impl Clone for Uri

source§

fn clone(&self) -> Uri

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Uri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Uri

Returns a Uri representing /

+
source§

fn default() -> Uri

Returns the “default value” for a type. Read more
source§

impl Display for Uri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl From<Authority> for Uri

Convert an Authority into a Uri.

+
source§

fn from(authority: Authority) -> Uri

Converts to this type from the input type.
source§

impl From<PathAndQuery> for Uri

Convert a PathAndQuery into a Uri.

+
source§

fn from(path_and_query: PathAndQuery) -> Uri

Converts to this type from the input type.
source§

impl From<Uri> for Parts

Convert a Uri into Parts

+
source§

fn from(src: Uri) -> Parts

Converts to this type from the input type.
source§

impl FromRequest for Uri

Extract the request’s URI.

+

§Examples

+
use actix_web::{http::Uri, web, App, Responder};
+
+async fn handler(uri: Uri) -> impl Responder {
+    format!("Requested path: {}", uri.path())
+}
+
+let app = App::new().default_service(web::to(handler));
+
§

type Error = Infallible

The associated error which can be returned.
§

type Future = Ready<Result<Uri, <Uri as FromRequest>::Error>>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more
source§

impl FromStr for Uri

§

type Err = InvalidUri

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Uri, InvalidUri>

Parses a string s to return a value of this type. Read more
source§

impl Hash for Uri

source§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl Host for Uri

§

fn hostname(&self) -> &str

Extract hostname.
§

fn port(&self) -> Option<u16>

Extract optional port.
source§

impl<'a> PartialEq<&'a str> for Uri

source§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<Uri> for &'a str

source§

fn eq(&self, uri: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Uri> for str

source§

fn eq(&self, uri: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for Uri

source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Uri

source§

fn eq(&self, other: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl ResourcePath for Uri

Available on crate feature http only.
source§

fn path(&self) -> &str

source§

impl<'a> TryFrom<&'a [u8]> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a [u8]) -> Result<Uri, <Uri as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a String> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a String) -> Result<Uri, <Uri as TryFrom<&'a String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a Uri> for Uri

§

type Error = Error

The type returned in the event of a conversion error.
source§

fn try_from(src: &'a Uri) -> Result<Uri, <Uri as TryFrom<&'a Uri>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a str) -> Result<Uri, <Uri as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<Parts> for Uri

§

type Error = InvalidUriParts

The type returned in the event of a conversion error.
source§

fn try_from(src: Parts) -> Result<Uri, <Uri as TryFrom<Parts>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: String) -> Result<Uri, <Uri as TryFrom<String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<Vec<u8>> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(vec: Vec<u8>) -> Result<Uri, <Uri as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
source§

impl Eq for Uri

Auto Trait Implementations§

§

impl !Freeze for Uri

§

impl RefUnwindSafe for Uri

§

impl Send for Uri

§

impl Sync for Uri

§

impl Unpin for Uri

§

impl UnwindSafe for Uri

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/struct.Version.html b/actix_web/http/struct.Version.html new file mode 100644 index 000000000..6553f9016 --- /dev/null +++ b/actix_web/http/struct.Version.html @@ -0,0 +1,40 @@ +Version in actix_web::http - Rust

Struct actix_web::http::Version

source ·
pub struct Version(/* private fields */);
Expand description

Represents a version of the HTTP spec.

+

Implementations§

source§

impl Version

source

pub const HTTP_09: Version = _

HTTP/0.9

+
source

pub const HTTP_10: Version = _

HTTP/1.0

+
source

pub const HTTP_11: Version = _

HTTP/1.1

+
source

pub const HTTP_2: Version = _

HTTP/2.0

+
source

pub const HTTP_3: Version = _

HTTP/3.0

+

Trait Implementations§

source§

impl Clone for Version

source§

fn clone(&self) -> Version

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Version

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Version

source§

fn default() -> Version

Returns the “default value” for a type. Read more
source§

impl Hash for Version

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for Version

source§

fn cmp(&self, other: &Version) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq for Version

source§

fn eq(&self, other: &Version) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for Version

source§

fn partial_cmp(&self, other: &Version) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl Copy for Version

source§

impl Eq for Version

source§

impl StructuralPartialEq for Version

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/uri/index.html b/actix_web/http/uri/index.html new file mode 100644 index 000000000..cb6ee0792 --- /dev/null +++ b/actix_web/http/uri/index.html @@ -0,0 +1,19 @@ +actix_web::http::uri - Rust

Module actix_web::http::uri

source ·
Expand description

URI component of request and response lines

+

This module primarily contains the Uri type which is a component of all +HTTP requests and also reexports this type at the root of the crate. A URI +is not always a “full URL” in the sense of something you’d type into a web +browser, but HTTP requests may only have paths on servers but may have full +schemes and hostnames on clients.

+

§Examples

+
use http::Uri;
+
+let uri = "/foo/bar?baz".parse::<Uri>().unwrap();
+assert_eq!(uri.path(), "/foo/bar");
+assert_eq!(uri.query(), Some("baz"));
+assert_eq!(uri.host(), None);
+
+let uri = "https://www.rust-lang.org/install.html".parse::<Uri>().unwrap();
+assert_eq!(uri.scheme_str(), Some("https"));
+assert_eq!(uri.host(), Some("www.rust-lang.org"));
+assert_eq!(uri.path(), "/install.html");
+

Structs§

  • Represents the authority component of a URI.
  • A builder for Uris.
  • An error resulting from a failed attempt to construct a URI.
  • An error resulting from a failed attempt to construct a URI.
  • The various parts of a URI.
  • Represents the path component of a URI
  • The port component of a URI.
  • Represents the scheme component of a URI
  • The URI component of a request.
\ No newline at end of file diff --git a/actix_web/http/uri/sidebar-items.js b/actix_web/http/uri/sidebar-items.js new file mode 100644 index 000000000..0b4e597bc --- /dev/null +++ b/actix_web/http/uri/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Authority","Builder","InvalidUri","InvalidUriParts","Parts","PathAndQuery","Port","Scheme","Uri"]}; \ No newline at end of file diff --git a/actix_web/http/uri/struct.Authority.html b/actix_web/http/uri/struct.Authority.html new file mode 100644 index 000000000..39c0cc98d --- /dev/null +++ b/actix_web/http/uri/struct.Authority.html @@ -0,0 +1,138 @@ +Authority in actix_web::http::uri - Rust

Struct actix_web::http::uri::Authority

source ·
pub struct Authority { /* private fields */ }
Expand description

Represents the authority component of a URI.

+

Implementations§

source§

impl Authority

source

pub fn from_static(src: &'static str) -> Authority

Attempt to convert an Authority from a static string.

+

This function will not perform any copying, and the string will be +checked if it is empty or contains an invalid character.

+
§Panics
+

This function panics if the argument contains invalid characters or +is empty.

+
§Examples
+
let authority = Authority::from_static("example.com");
+assert_eq!(authority.host(), "example.com");
+
source

pub fn from_maybe_shared<T>(src: T) -> Result<Authority, InvalidUri>
where + T: AsRef<[u8]> + 'static,

Attempt to convert a Bytes buffer to a Authority.

+

This will try to prevent a copy if the type passed is the type used +internally, and will copy the data if it is not.

+
source

pub fn host(&self) -> &str

Get the host of this Authority.

+

The host subcomponent of authority is identified by an IP literal +encapsulated within square brackets, an IPv4 address in dotted- decimal +form, or a registered name. The host subcomponent is case-insensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                        |---------|
+                             |
+                            host
+
§Examples
+
let authority: Authority = "example.org:80".parse().unwrap();
+
+assert_eq!(authority.host(), "example.org");
+
source

pub fn port(&self) -> Option<Port<&str>>

Get the port part of this Authority.

+

The port subcomponent of authority is designated by an optional port +number following the host and delimited from it by a single colon (“:”) +character. It can be turned into a decimal port number with the as_u16 +method or as a str with the as_str method.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                    |-|
+                                     |
+                                    port
+
§Examples
+

Authority with port

+ +
let authority: Authority = "example.org:80".parse().unwrap();
+
+let port = authority.port().unwrap();
+assert_eq!(port.as_u16(), 80);
+assert_eq!(port.as_str(), "80");
+

Authority without port

+ +
let authority: Authority = "example.org".parse().unwrap();
+
+assert!(authority.port().is_none());
+
source

pub fn port_u16(&self) -> Option<u16>

Get the port of this Authority as a u16.

+
§Example
+
let authority: Authority = "example.org:80".parse().unwrap();
+
+assert_eq!(authority.port_u16(), Some(80));
+
source

pub fn as_str(&self) -> &str

Return a str representation of the authority

+

Trait Implementations§

source§

impl AsRef<str> for Authority

source§

fn as_ref(&self) -> &str

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for Authority

source§

fn clone(&self) -> Authority

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Authority

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for Authority

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl From<Authority> for Uri

Convert an Authority into a Uri.

+
source§

fn from(authority: Authority) -> Uri

Converts to this type from the input type.
source§

impl FromStr for Authority

§

type Err = InvalidUri

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Authority, InvalidUri>

Parses a string s to return a value of this type. Read more
source§

impl Hash for Authority

Case-insensitive hashing

+

§Examples

+

+let a: Authority = "HELLO.com".parse().unwrap();
+let b: Authority = "hello.coM".parse().unwrap();
+
+let mut s = DefaultHasher::new();
+a.hash(&mut s);
+let a = s.finish();
+
+let mut s = DefaultHasher::new();
+b.hash(&mut s);
+let b = s.finish();
+
+assert_eq!(a, b);
+
source§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<'a> PartialEq<&'a str> for Authority

source§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<Authority> for &'a str

source§

fn eq(&self, other: &Authority) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Authority> for str

source§

fn eq(&self, other: &Authority) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<String> for Authority

source§

fn eq(&self, other: &String) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for Authority

Case-insensitive equality

+

§Examples

+
let authority: Authority = "HELLO.com".parse().unwrap();
+assert_eq!(authority, "hello.coM");
+assert_eq!("hello.com", authority);
+
source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Authority

source§

fn eq(&self, other: &Authority) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialOrd<&'a str> for Authority

source§

fn partial_cmp(&self, other: &&'a str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> PartialOrd<Authority> for &'a str

source§

fn partial_cmp(&self, other: &Authority) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<Authority> for str

source§

fn partial_cmp(&self, other: &Authority) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<String> for Authority

source§

fn partial_cmp(&self, other: &String) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<str> for Authority

source§

fn partial_cmp(&self, other: &str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for Authority

Case-insensitive ordering

+

§Examples

+
let authority: Authority = "DEF.com".parse().unwrap();
+assert!(authority < "ghi.com");
+assert!(authority > "abc.com");
+
source§

fn partial_cmp(&self, other: &Authority) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> TryFrom<&'a [u8]> for Authority

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a [u8] +) -> Result<Authority, <Authority as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for Authority

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a str +) -> Result<Authority, <Authority as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for Authority

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + t: String +) -> Result<Authority, <Authority as TryFrom<String>>::Error>

Performs the conversion.
source§

impl TryFrom<Vec<u8>> for Authority

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + vec: Vec<u8> +) -> Result<Authority, <Authority as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
source§

impl Eq for Authority

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/uri/struct.Builder.html b/actix_web/http/uri/struct.Builder.html new file mode 100644 index 000000000..8706e383b --- /dev/null +++ b/actix_web/http/uri/struct.Builder.html @@ -0,0 +1,70 @@ +Builder in actix_web::http::uri - Rust

Struct actix_web::http::uri::Builder

source ·
pub struct Builder { /* private fields */ }
Expand description

A builder for Uris.

+

This type can be used to construct an instance of Uri +through a builder pattern.

+

Implementations§

source§

impl Builder

source

pub fn new() -> Builder

Creates a new default instance of Builder to construct a Uri.

+
§Examples
+

+let uri = uri::Builder::new()
+    .scheme("https")
+    .authority("hyper.rs")
+    .path_and_query("/")
+    .build()
+    .unwrap();
+
source

pub fn scheme<T>(self, scheme: T) -> Builder
where + Scheme: TryFrom<T>, + <Scheme as TryFrom<T>>::Error: Into<Error>,

Set the Scheme for this URI.

+
§Examples
+

+let mut builder = uri::Builder::new();
+builder.scheme("https");
+
source

pub fn authority<T>(self, auth: T) -> Builder
where + Authority: TryFrom<T>, + <Authority as TryFrom<T>>::Error: Into<Error>,

Set the Authority for this URI.

+
§Examples
+

+let uri = uri::Builder::new()
+    .authority("tokio.rs")
+    .build()
+    .unwrap();
+
source

pub fn path_and_query<T>(self, p_and_q: T) -> Builder

Set the PathAndQuery for this URI.

+
§Examples
+

+let uri = uri::Builder::new()
+    .path_and_query("/hello?foo=bar")
+    .build()
+    .unwrap();
+
source

pub fn build(self) -> Result<Uri, Error>

Consumes this builder, and tries to construct a valid Uri from +the configured pieces.

+
§Errors
+

This function may return an error if any previously configured argument +failed to parse or get converted to the internal representation. For +example if an invalid scheme was specified via scheme("!@#%/^") +the error will be returned when this function is called rather than +when scheme was called.

+

Additionally, the various forms of URI require certain combinations of +parts to be set to be valid. If the parts don’t fit into any of the +valid forms of URI, a new error is returned.

+
§Examples
+

+let uri = Uri::builder()
+    .build()
+    .unwrap();
+

Trait Implementations§

source§

impl Debug for Builder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Builder

source§

fn default() -> Builder

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/uri/struct.InvalidUri.html b/actix_web/http/uri/struct.InvalidUri.html new file mode 100644 index 000000000..2e24a78c5 --- /dev/null +++ b/actix_web/http/uri/struct.InvalidUri.html @@ -0,0 +1,19 @@ +InvalidUri in actix_web::http::uri - Rust

Struct actix_web::http::uri::InvalidUri

source ·
pub struct InvalidUri(/* private fields */);
Expand description

An error resulting from a failed attempt to construct a URI.

+

Trait Implementations§

source§

impl Debug for InvalidUri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for InvalidUri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for InvalidUri

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<ErrorKind> for InvalidUri

source§

fn from(src: ErrorKind) -> InvalidUri

Converts to this type from the input type.
source§

impl From<InvalidUri> for Error

source§

fn from(err: InvalidUri) -> Error

Converts to this type from the input type.
source§

impl From<InvalidUri> for ParseError

source§

fn from(err: InvalidUri) -> ParseError

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/uri/struct.InvalidUriParts.html b/actix_web/http/uri/struct.InvalidUriParts.html new file mode 100644 index 000000000..13ab95b04 --- /dev/null +++ b/actix_web/http/uri/struct.InvalidUriParts.html @@ -0,0 +1,19 @@ +InvalidUriParts in actix_web::http::uri - Rust

Struct actix_web::http::uri::InvalidUriParts

source ·
pub struct InvalidUriParts(/* private fields */);
Expand description

An error resulting from a failed attempt to construct a URI.

+

Trait Implementations§

source§

impl Debug for InvalidUriParts

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for InvalidUriParts

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for InvalidUriParts

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<ErrorKind> for InvalidUriParts

source§

fn from(src: ErrorKind) -> InvalidUriParts

Converts to this type from the input type.
source§

impl From<InvalidUriParts> for Error

source§

fn from(err: InvalidUriParts) -> Error

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/uri/struct.Parts.html b/actix_web/http/uri/struct.Parts.html new file mode 100644 index 000000000..c46315d83 --- /dev/null +++ b/actix_web/http/uri/struct.Parts.html @@ -0,0 +1,28 @@ +Parts in actix_web::http::uri - Rust

Struct actix_web::http::uri::Parts

source ·
pub struct Parts {
+    pub scheme: Option<Scheme>,
+    pub authority: Option<Authority>,
+    pub path_and_query: Option<PathAndQuery>,
+    /* private fields */
+}
Expand description

The various parts of a URI.

+

This struct is used to provide to and retrieve from a URI.

+

Fields§

§scheme: Option<Scheme>

The scheme component of a URI

+
§authority: Option<Authority>

The authority component of a URI

+
§path_and_query: Option<PathAndQuery>

The origin-form component of a URI

+

Trait Implementations§

source§

impl Debug for Parts

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Parts

source§

fn default() -> Parts

Returns the “default value” for a type. Read more
source§

impl From<Uri> for Parts

Convert a Uri into Parts

+
source§

fn from(src: Uri) -> Parts

Converts to this type from the input type.
source§

impl TryFrom<Parts> for Uri

§

type Error = InvalidUriParts

The type returned in the event of a conversion error.
source§

fn try_from(src: Parts) -> Result<Uri, <Uri as TryFrom<Parts>>::Error>

Performs the conversion.

Auto Trait Implementations§

§

impl !Freeze for Parts

§

impl RefUnwindSafe for Parts

§

impl Send for Parts

§

impl Sync for Parts

§

impl Unpin for Parts

§

impl UnwindSafe for Parts

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/uri/struct.PathAndQuery.html b/actix_web/http/uri/struct.PathAndQuery.html new file mode 100644 index 000000000..41affa122 --- /dev/null +++ b/actix_web/http/uri/struct.PathAndQuery.html @@ -0,0 +1,122 @@ +PathAndQuery in actix_web::http::uri - Rust

Struct actix_web::http::uri::PathAndQuery

source ·
pub struct PathAndQuery { /* private fields */ }
Expand description

Represents the path component of a URI

+

Implementations§

source§

impl PathAndQuery

source

pub fn from_static(src: &'static str) -> PathAndQuery

Convert a PathAndQuery from a static string.

+

This function will not perform any copying, however the string is +checked to ensure that it is valid.

+
§Panics
+

This function panics if the argument is an invalid path and query.

+
§Examples
+
let v = PathAndQuery::from_static("/hello?world");
+
+assert_eq!(v.path(), "/hello");
+assert_eq!(v.query(), Some("world"));
+
source

pub fn from_maybe_shared<T>(src: T) -> Result<PathAndQuery, InvalidUri>
where + T: AsRef<[u8]> + 'static,

Attempt to convert a Bytes buffer to a PathAndQuery.

+

This will try to prevent a copy if the type passed is the type used +internally, and will copy the data if it is not.

+
source

pub fn path(&self) -> &str

Returns the path component

+

The path component is case sensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                       |--------|
+                                            |
+                                          path
+
+

If the URI is * then the path component is equal to *.

+
§Examples
+

+let path_and_query: PathAndQuery = "/hello/world".parse().unwrap();
+
+assert_eq!(path_and_query.path(), "/hello/world");
+
source

pub fn query(&self) -> Option<&str>

Returns the query string component

+

The query component contains non-hierarchical data that, along with data +in the path component, serves to identify a resource within the scope of +the URI’s scheme and naming authority (if any). The query component is +indicated by the first question mark (“?”) character and terminated by a +number sign (“#”) character or by the end of the URI.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                                  |-------------------|
+                                                            |
+                                                          query
+
§Examples
+

With a query string component

+ +
let path_and_query: PathAndQuery = "/hello/world?key=value&foo=bar".parse().unwrap();
+
+assert_eq!(path_and_query.query(), Some("key=value&foo=bar"));
+

Without a query string component

+ +
let path_and_query: PathAndQuery = "/hello/world".parse().unwrap();
+
+assert!(path_and_query.query().is_none());
+
source

pub fn as_str(&self) -> &str

Returns the path and query as a string component.

+
§Examples
+

With a query string component

+ +
let path_and_query: PathAndQuery = "/hello/world?key=value&foo=bar".parse().unwrap();
+
+assert_eq!(path_and_query.as_str(), "/hello/world?key=value&foo=bar");
+

Without a query string component

+ +
let path_and_query: PathAndQuery = "/hello/world".parse().unwrap();
+
+assert_eq!(path_and_query.as_str(), "/hello/world");
+

Trait Implementations§

source§

impl Clone for PathAndQuery

source§

fn clone(&self) -> PathAndQuery

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for PathAndQuery

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for PathAndQuery

source§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl From<PathAndQuery> for Uri

Convert a PathAndQuery into a Uri.

+
source§

fn from(path_and_query: PathAndQuery) -> Uri

Converts to this type from the input type.
source§

impl FromStr for PathAndQuery

§

type Err = InvalidUri

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<PathAndQuery, InvalidUri>

Parses a string s to return a value of this type. Read more
source§

impl Hash for PathAndQuery

source§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<'a> PartialEq<&'a str> for PathAndQuery

source§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<PathAndQuery> for &'a str

source§

fn eq(&self, other: &PathAndQuery) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<PathAndQuery> for str

source§

fn eq(&self, other: &PathAndQuery) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<String> for PathAndQuery

source§

fn eq(&self, other: &String) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for PathAndQuery

source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for PathAndQuery

source§

fn eq(&self, other: &PathAndQuery) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialOrd<&'a str> for PathAndQuery

source§

fn partial_cmp(&self, other: &&'a str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> PartialOrd<PathAndQuery> for &'a str

source§

fn partial_cmp(&self, other: &PathAndQuery) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<PathAndQuery> for str

source§

fn partial_cmp(&self, other: &PathAndQuery) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<String> for PathAndQuery

source§

fn partial_cmp(&self, other: &String) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<str> for PathAndQuery

source§

fn partial_cmp(&self, other: &str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for PathAndQuery

source§

fn partial_cmp(&self, other: &PathAndQuery) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> TryFrom<&'a [u8]> for PathAndQuery

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a [u8] +) -> Result<PathAndQuery, <PathAndQuery as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl TryFrom<&String> for PathAndQuery

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: &String +) -> Result<PathAndQuery, <PathAndQuery as TryFrom<&String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for PathAndQuery

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a str +) -> Result<PathAndQuery, <PathAndQuery as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for PathAndQuery

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: String +) -> Result<PathAndQuery, <PathAndQuery as TryFrom<String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<Vec<u8>> for PathAndQuery

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + vec: Vec<u8> +) -> Result<PathAndQuery, <PathAndQuery as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
source§

impl Eq for PathAndQuery

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/uri/struct.Port.html b/actix_web/http/uri/struct.Port.html new file mode 100644 index 000000000..42c620c21 --- /dev/null +++ b/actix_web/http/uri/struct.Port.html @@ -0,0 +1,48 @@ +Port in actix_web::http::uri - Rust

Struct actix_web::http::uri::Port

source ·
pub struct Port<T> { /* private fields */ }
Expand description

The port component of a URI.

+

Implementations§

source§

impl<T> Port<T>

source

pub fn as_u16(&self) -> u16

Returns the port number as a u16.

+
§Examples
+

Port as u16.

+ +
let authority: Authority = "example.org:80".parse().unwrap();
+
+let port = authority.port().unwrap();
+assert_eq!(port.as_u16(), 80);
+
source§

impl<T> Port<T>
where + T: AsRef<str>,

source

pub fn as_str(&self) -> &str

Returns the port number as a str.

+
§Examples
+

Port as str.

+ +
let authority: Authority = "example.org:80".parse().unwrap();
+
+let port = authority.port().unwrap();
+assert_eq!(port.as_str(), "80");
+

Trait Implementations§

source§

impl<T> AsRef<str> for Port<T>
where + T: AsRef<str>,

source§

fn as_ref(&self) -> &str

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl<T> Debug for Port<T>
where + T: Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<T> Display for Port<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<T, U> PartialEq<Port<U>> for Port<T>

source§

fn eq(&self, other: &Port<U>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<T> PartialEq<u16> for Port<T>

source§

fn eq(&self, other: &u16) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

§

impl<T> Freeze for Port<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for Port<T>
where + T: RefUnwindSafe,

§

impl<T> Send for Port<T>
where + T: Send,

§

impl<T> Sync for Port<T>
where + T: Sync,

§

impl<T> Unpin for Port<T>
where + T: Unpin,

§

impl<T> UnwindSafe for Port<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/uri/struct.Scheme.html b/actix_web/http/uri/struct.Scheme.html new file mode 100644 index 000000000..d228c41ef --- /dev/null +++ b/actix_web/http/uri/struct.Scheme.html @@ -0,0 +1,45 @@ +Scheme in actix_web::http::uri - Rust

Struct actix_web::http::uri::Scheme

source ·
pub struct Scheme { /* private fields */ }
Expand description

Represents the scheme component of a URI

+

Implementations§

source§

impl Scheme

source

pub const HTTP: Scheme = _

HTTP protocol scheme

+
source

pub const HTTPS: Scheme = _

HTTP protocol over TLS.

+
source

pub fn as_str(&self) -> &str

Return a str representation of the scheme

+
§Examples
+
let scheme: Scheme = "http".parse().unwrap();
+assert_eq!(scheme.as_str(), "http");
+

Trait Implementations§

source§

impl AsRef<str> for Scheme

source§

fn as_ref(&self) -> &str

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for Scheme

source§

fn clone(&self) -> Scheme

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Scheme

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for Scheme

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl FromStr for Scheme

§

type Err = InvalidUri

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Scheme, <Scheme as FromStr>::Err>

Parses a string s to return a value of this type. Read more
source§

impl Hash for Scheme

Case-insensitive hashing

+
source§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq<Scheme> for str

Case-insensitive equality

+
source§

fn eq(&self, other: &Scheme) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for Scheme

Case-insensitive equality

+

§Examples

+
let scheme: Scheme = "HTTP".parse().unwrap();
+assert_eq!(scheme, *"http");
+
source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Scheme

source§

fn eq(&self, other: &Scheme) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> TryFrom<&'a [u8]> for Scheme

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(s: &'a [u8]) -> Result<Scheme, <Scheme as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for Scheme

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(s: &'a str) -> Result<Scheme, <Scheme as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl Eq for Scheme

Auto Trait Implementations§

§

impl Freeze for Scheme

§

impl RefUnwindSafe for Scheme

§

impl Send for Scheme

§

impl Sync for Scheme

§

impl Unpin for Scheme

§

impl UnwindSafe for Scheme

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/http/uri/struct.Uri.html b/actix_web/http/uri/struct.Uri.html new file mode 100644 index 000000000..6428991b2 --- /dev/null +++ b/actix_web/http/uri/struct.Uri.html @@ -0,0 +1,293 @@ +Uri in actix_web::http::uri - Rust

Struct actix_web::http::uri::Uri

source ·
pub struct Uri { /* private fields */ }
Expand description

The URI component of a request.

+

For HTTP 1, this is included as part of the request line. From Section 5.3, +Request Target:

+
+

Once an inbound connection is obtained, the client sends an HTTP +request message (Section 3) with a request-target derived from the +target URI. There are four distinct formats for the request-target, +depending on both the method being requested and whether the request +is to a proxy.

+
request-target = origin-form
+               / absolute-form
+               / authority-form
+               / asterisk-form
+
+

The URI is structured as follows:

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+|-|   |-------------------------------||--------| |-------------------| |-----|
+ |                  |                       |               |              |
+scheme          authority                 path            query         fragment
+
+

For HTTP 2.0, the URI is encoded using pseudoheaders.

+

§Examples

+
use http::Uri;
+
+let uri = "/foo/bar?baz".parse::<Uri>().unwrap();
+assert_eq!(uri.path(), "/foo/bar");
+assert_eq!(uri.query(), Some("baz"));
+assert_eq!(uri.host(), None);
+
+let uri = "https://www.rust-lang.org/install.html".parse::<Uri>().unwrap();
+assert_eq!(uri.scheme_str(), Some("https"));
+assert_eq!(uri.host(), Some("www.rust-lang.org"));
+assert_eq!(uri.path(), "/install.html");
+

Implementations§

source§

impl Uri

source

pub fn builder() -> Builder

Creates a new builder-style object to manufacture a Uri.

+

This method returns an instance of Builder which can be usd to +create a Uri.

+
§Examples
+
use http::Uri;
+
+let uri = Uri::builder()
+    .scheme("https")
+    .authority("hyper.rs")
+    .path_and_query("/")
+    .build()
+    .unwrap();
+
source

pub fn from_parts(src: Parts) -> Result<Uri, InvalidUriParts>

Attempt to convert a Parts into a Uri.

+
§Examples
+

Relative URI

+ +
let mut parts = Parts::default();
+parts.path_and_query = Some("/foo".parse().unwrap());
+
+let uri = Uri::from_parts(parts).unwrap();
+
+assert_eq!(uri.path(), "/foo");
+
+assert!(uri.scheme().is_none());
+assert!(uri.authority().is_none());
+

Absolute URI

+ +
let mut parts = Parts::default();
+parts.scheme = Some("http".parse().unwrap());
+parts.authority = Some("foo.com".parse().unwrap());
+parts.path_and_query = Some("/foo".parse().unwrap());
+
+let uri = Uri::from_parts(parts).unwrap();
+
+assert_eq!(uri.scheme().unwrap().as_str(), "http");
+assert_eq!(uri.authority().unwrap(), "foo.com");
+assert_eq!(uri.path(), "/foo");
+
source

pub fn from_maybe_shared<T>(src: T) -> Result<Uri, InvalidUri>
where + T: AsRef<[u8]> + 'static,

Attempt to convert a Bytes buffer to a Uri.

+

This will try to prevent a copy if the type passed is the type used +internally, and will copy the data if it is not.

+
source

pub fn from_static(src: &'static str) -> Uri

Convert a Uri from a static string.

+

This function will not perform any copying, however the string is +checked to ensure that it is valid.

+
§Panics
+

This function panics if the argument is an invalid URI.

+
§Examples
+
let uri = Uri::from_static("http://example.com/foo");
+
+assert_eq!(uri.host().unwrap(), "example.com");
+assert_eq!(uri.path(), "/foo");
+
source

pub fn into_parts(self) -> Parts

Convert a Uri into Parts.

+
§Note
+

This is just an inherent method providing the same functionality as +let parts: Parts = uri.into()

+
§Examples
+
let uri: Uri = "/foo".parse().unwrap();
+
+let parts = uri.into_parts();
+
+assert_eq!(parts.path_and_query.unwrap(), "/foo");
+
+assert!(parts.scheme.is_none());
+assert!(parts.authority.is_none());
+
source

pub fn path_and_query(&self) -> Option<&PathAndQuery>

Returns the path & query components of the Uri

+
source

pub fn path(&self) -> &str

Get the path of this Uri.

+

Both relative and absolute URIs contain a path component, though it +might be the empty string. The path component is case sensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                       |--------|
+                                            |
+                                          path
+
+

If the URI is * then the path component is equal to *.

+
§Examples
+

A relative URI

+ +

+let uri: Uri = "/hello/world".parse().unwrap();
+
+assert_eq!(uri.path(), "/hello/world");
+

An absolute URI

+ +
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.path(), "/hello/world");
+
source

pub fn scheme(&self) -> Option<&Scheme>

Get the scheme of this Uri.

+

The URI scheme refers to a specification for assigning identifiers +within that scheme. Only absolute URIs contain a scheme component, but +not all absolute URIs will contain a scheme component. Although scheme +names are case-insensitive, the canonical form is lowercase.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+|-|
+ |
+scheme
+
§Examples
+

Absolute URI

+ +
use http::uri::{Scheme, Uri};
+
+let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.scheme(), Some(&Scheme::HTTP));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.scheme().is_none());
+
source

pub fn scheme_str(&self) -> Option<&str>

Get the scheme of this Uri as a &str.

+
§Example
+
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.scheme_str(), Some("http"));
+
source

pub fn authority(&self) -> Option<&Authority>

Get the authority of this Uri.

+

The authority is a hierarchical element for naming authority such that +the remainder of the URI is delegated to that authority. For HTTP, the +authority consists of the host and port. The host portion of the +authority is case-insensitive.

+

The authority also includes a username:password component, however +the use of this is deprecated and should be avoided.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+      |-------------------------------|
+                    |
+                authority
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.authority().map(|a| a.as_str()), Some("example.org:80"));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.authority().is_none());
+
source

pub fn host(&self) -> Option<&str>

Get the host of this Uri.

+

The host subcomponent of authority is identified by an IP literal +encapsulated within square brackets, an IPv4 address in dotted- decimal +form, or a registered name. The host subcomponent is case-insensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                        |---------|
+                             |
+                            host
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.host(), Some("example.org"));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.host().is_none());
+
source

pub fn port(&self) -> Option<Port<&str>>

Get the port part of this Uri.

+

The port subcomponent of authority is designated by an optional port +number following the host and delimited from it by a single colon (“:”) +character. It can be turned into a decimal port number with the as_u16 +method or as a str with the as_str method.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                    |-|
+                                     |
+                                    port
+
§Examples
+

Absolute URI with port

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+let port = uri.port().unwrap();
+assert_eq!(port.as_u16(), 80);
+

Absolute URI without port

+ +
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert!(uri.port().is_none());
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.port().is_none());
+
source

pub fn port_u16(&self) -> Option<u16>

Get the port of this Uri as a u16.

+
§Example
+
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.port_u16(), Some(80));
+
source

pub fn query(&self) -> Option<&str>

Get the query string of this Uri, starting after the ?.

+

The query component contains non-hierarchical data that, along with data +in the path component, serves to identify a resource within the scope of +the URI’s scheme and naming authority (if any). The query component is +indicated by the first question mark (“?”) character and terminated by a +number sign (“#”) character or by the end of the URI.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                                  |-------------------|
+                                                            |
+                                                          query
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org/hello/world?key=value".parse().unwrap();
+
+assert_eq!(uri.query(), Some("key=value"));
+

Relative URI with a query string component

+ +
let uri: Uri = "/hello/world?key=value&foo=bar".parse().unwrap();
+
+assert_eq!(uri.query(), Some("key=value&foo=bar"));
+

Relative URI without a query string component

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.query().is_none());
+

Trait Implementations§

source§

impl Clone for Uri

source§

fn clone(&self) -> Uri

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Uri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Uri

Returns a Uri representing /

+
source§

fn default() -> Uri

Returns the “default value” for a type. Read more
source§

impl Display for Uri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl From<Authority> for Uri

Convert an Authority into a Uri.

+
source§

fn from(authority: Authority) -> Uri

Converts to this type from the input type.
source§

impl From<PathAndQuery> for Uri

Convert a PathAndQuery into a Uri.

+
source§

fn from(path_and_query: PathAndQuery) -> Uri

Converts to this type from the input type.
source§

impl From<Uri> for Parts

Convert a Uri into Parts

+
source§

fn from(src: Uri) -> Parts

Converts to this type from the input type.
source§

impl FromRequest for Uri

Extract the request’s URI.

+

§Examples

+
use actix_web::{http::Uri, web, App, Responder};
+
+async fn handler(uri: Uri) -> impl Responder {
+    format!("Requested path: {}", uri.path())
+}
+
+let app = App::new().default_service(web::to(handler));
+
§

type Error = Infallible

The associated error which can be returned.
§

type Future = Ready<Result<Uri, <Uri as FromRequest>::Error>>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more
source§

impl FromStr for Uri

§

type Err = InvalidUri

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Uri, InvalidUri>

Parses a string s to return a value of this type. Read more
source§

impl Hash for Uri

source§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl Host for Uri

§

fn hostname(&self) -> &str

Extract hostname.
§

fn port(&self) -> Option<u16>

Extract optional port.
source§

impl<'a> PartialEq<&'a str> for Uri

source§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<Uri> for &'a str

source§

fn eq(&self, uri: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Uri> for str

source§

fn eq(&self, uri: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for Uri

source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Uri

source§

fn eq(&self, other: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl ResourcePath for Uri

Available on crate feature http only.
source§

fn path(&self) -> &str

source§

impl<'a> TryFrom<&'a [u8]> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a [u8]) -> Result<Uri, <Uri as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a String> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a String) -> Result<Uri, <Uri as TryFrom<&'a String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a Uri> for Uri

§

type Error = Error

The type returned in the event of a conversion error.
source§

fn try_from(src: &'a Uri) -> Result<Uri, <Uri as TryFrom<&'a Uri>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a str) -> Result<Uri, <Uri as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<Parts> for Uri

§

type Error = InvalidUriParts

The type returned in the event of a conversion error.
source§

fn try_from(src: Parts) -> Result<Uri, <Uri as TryFrom<Parts>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: String) -> Result<Uri, <Uri as TryFrom<String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<Vec<u8>> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(vec: Vec<u8>) -> Result<Uri, <Uri as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
source§

impl Eq for Uri

Auto Trait Implementations§

§

impl !Freeze for Uri

§

impl RefUnwindSafe for Uri

§

impl Send for Uri

§

impl Sync for Uri

§

impl Unpin for Uri

§

impl UnwindSafe for Uri

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/index.html b/actix_web/index.html new file mode 100644 index 000000000..5aaf43f2f --- /dev/null +++ b/actix_web/index.html @@ -0,0 +1,77 @@ +actix_web - Rust

Crate actix_web

source ·
Expand description

Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust.

+

§Examples

+
use actix_web::{get, web, App, HttpServer, Responder};
+
+#[get("/hello/{name}")]
+async fn greet(name: web::Path<String>) -> impl Responder {
+    format!("Hello {}!", name)
+}
+
+#[actix_web::main] // or #[tokio::main]
+async fn main() -> std::io::Result<()> {
+    HttpServer::new(|| {
+        App::new().service(greet)
+    })
+    .bind(("127.0.0.1", 8080))?
+    .run()
+    .await
+}
+

§Documentation & Community Resources

+

In addition to this API documentation, several other resources are available:

+ +

To get started navigating the API docs, you may consider looking at the following pages first:

+
    +
  • +

    App: This struct represents an Actix Web application and is used to +configure routes and other common application settings.

    +
  • +
  • +

    HttpServer: This struct represents an HTTP server instance and is +used to instantiate and configure servers.

    +
  • +
  • +

    web: This module provides essential types for route registration as well as +common utilities for request handlers.

    +
  • +
  • +

    HttpRequest and HttpResponse: These +structs represent HTTP requests and responses and expose methods for creating, inspecting, +and otherwise utilizing them.

    +
  • +
+

§Features

+
    +
  • Supports HTTP/1.x and HTTP/2
  • +
  • Streaming and pipelining
  • +
  • Powerful request routing with optional macros
  • +
  • Full Tokio compatibility
  • +
  • Keep-alive and slow requests handling
  • +
  • Client/server WebSockets support
  • +
  • Transparent content compression/decompression (br, gzip, deflate, zstd)
  • +
  • Multipart streams
  • +
  • Static assets
  • +
  • SSL support using OpenSSL or Rustls
  • +
  • Middlewares (Logger, Session, CORS, etc)
  • +
  • Integrates with the awc HTTP client
  • +
  • Runs on stable Rust 1.54+
  • +
+

§Crate Features

+
    +
  • cookies - cookies support (enabled by default)
  • +
  • macros - routing and runtime macros (enabled by default)
  • +
  • compress-brotli - brotli content encoding compression support (enabled by default)
  • +
  • compress-gzip - gzip and deflate content encoding compression support (enabled by default)
  • +
  • compress-zstd - zstd content encoding compression support (enabled by default)
  • +
  • openssl - HTTPS support via openssl crate, supports HTTP/2
  • +
  • rustls - HTTPS support via rustls 0.20 crate, supports HTTP/2
  • +
  • rustls-0_21 - HTTPS support via rustls 0.21 crate, supports HTTP/2
  • +
  • rustls-0_22 - HTTPS support via rustls 0.22 crate, supports HTTP/2
  • +
  • rustls-0_23 - HTTPS support via rustls 0.23 crate, supports HTTP/2
  • +
  • secure-cookies - secure cookies support
  • +
+

Re-exports§

Modules§

  • Traits and structures to aid consuming and writing HTTP payloads.
  • cookiecookies
    HTTP cookie parsing and cookie jar management.
  • Lower-level types and re-exports.
  • Error and Result module
  • Route guards.
  • Various HTTP related types.
  • A collection of common middleware.
  • A selection of re-exports from tokio and actix-rt.
  • Various helpers for Actix applications to use during testing.
  • Essentials helper functions and types for application registration.

Macros§

  • Macro to help register different types of services at the same time.

Structs§

Enums§

  • Combines two extractor or responder types into a single type.

Traits§

  • A type that implements FromRequest is called an extractor and can extract data from +the request. Some types that implement this trait are: Json, Header, and Path.
  • The interface for request handlers.
  • Trait that implements general purpose operations on HTTP messages.
  • Trait implemented by types that can be converted to an HTTP response.

Type Aliases§

Attribute Macros§

  • connectmacros
    Creates route handler with actix_web::guard::Connect.
  • deletemacros
    Creates route handler with actix_web::guard::Delete.
  • getmacros
    Creates route handler with actix_web::guard::Get.
  • headmacros
    Creates route handler with actix_web::guard::Head.
  • mainmacros
    Marks async main function as the Actix Web system entry-point.
  • optionsmacros
    Creates route handler with actix_web::guard::Options.
  • patchmacros
    Creates route handler with actix_web::guard::Patch.
  • postmacros
    Creates route handler with actix_web::guard::Post.
  • putmacros
    Creates route handler with actix_web::guard::Put.
  • routemacros
    Creates resource handler, allowing multiple HTTP method guards.
  • routesmacros
    Creates resource handler, allowing multiple HTTP methods and paths.
  • testmacros
    Marks async test functions to use the Actix Web system entry-point.
  • tracemacros
    Creates route handler with actix_web::guard::Trace.
\ No newline at end of file diff --git a/actix_web/info/struct.ConnectionInfo.html b/actix_web/info/struct.ConnectionInfo.html new file mode 100644 index 000000000..52daa0e97 --- /dev/null +++ b/actix_web/info/struct.ConnectionInfo.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/dev/struct.ConnectionInfo.html...

+ + + \ No newline at end of file diff --git a/actix_web/info/struct.PeerAddr.html b/actix_web/info/struct.PeerAddr.html new file mode 100644 index 000000000..78a1391ae --- /dev/null +++ b/actix_web/info/struct.PeerAddr.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/dev/struct.PeerAddr.html...

+ + + \ No newline at end of file diff --git a/actix_web/macro.services!.html b/actix_web/macro.services!.html new file mode 100644 index 000000000..6ed55835f --- /dev/null +++ b/actix_web/macro.services!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.services.html...

+ + + \ No newline at end of file diff --git a/actix_web/macro.services.html b/actix_web/macro.services.html new file mode 100644 index 000000000..c2c458957 --- /dev/null +++ b/actix_web/macro.services.html @@ -0,0 +1,22 @@ +services in actix_web - Rust

Macro actix_web::services

source ·
macro_rules! services {
+    ($($x:expr),+ $(,)?) => { ... };
+}
Expand description

Macro to help register different types of services at the same time.

+

The max number of services that can be grouped together is 12 and all must implement the +HttpServiceFactory trait.

+

§Examples

+
use actix_web::{services, web, App};
+
+let services = services![
+    web::resource("/test2").to(|| async { "test2" }),
+    web::scope("/test3").route("/", web::get().to(|| async { "test3" }))
+];
+
+let app = App::new().service(services);
+
+// services macro just convert multiple services to a tuple.
+// below would also work without importing the macro.
+let app = App::new().service((
+    web::resource("/test2").to(|| async { "test2" }),
+    web::scope("/test3").route("/", web::get().to(|| async { "test3" }))
+));
+
\ No newline at end of file diff --git a/actix_web/middleware/compat/struct.Compat.html b/actix_web/middleware/compat/struct.Compat.html new file mode 100644 index 000000000..7a9ad78a2 --- /dev/null +++ b/actix_web/middleware/compat/struct.Compat.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/middleware/struct.Compat.html...

+ + + \ No newline at end of file diff --git a/actix_web/middleware/compress/struct.Compress.html b/actix_web/middleware/compress/struct.Compress.html new file mode 100644 index 000000000..64ce67728 --- /dev/null +++ b/actix_web/middleware/compress/struct.Compress.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/middleware/struct.Compress.html...

+ + + \ No newline at end of file diff --git a/actix_web/middleware/condition/struct.Condition.html b/actix_web/middleware/condition/struct.Condition.html new file mode 100644 index 000000000..574c09e02 --- /dev/null +++ b/actix_web/middleware/condition/struct.Condition.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/middleware/struct.Condition.html...

+ + + \ No newline at end of file diff --git a/actix_web/middleware/default_headers/struct.DefaultHeaders.html b/actix_web/middleware/default_headers/struct.DefaultHeaders.html new file mode 100644 index 000000000..f5dbd0d05 --- /dev/null +++ b/actix_web/middleware/default_headers/struct.DefaultHeaders.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/middleware/struct.DefaultHeaders.html...

+ + + \ No newline at end of file diff --git a/actix_web/middleware/enum.ErrorHandlerResponse.html b/actix_web/middleware/enum.ErrorHandlerResponse.html new file mode 100644 index 000000000..267484ba3 --- /dev/null +++ b/actix_web/middleware/enum.ErrorHandlerResponse.html @@ -0,0 +1,24 @@ +ErrorHandlerResponse in actix_web::middleware - Rust

Enum actix_web::middleware::ErrorHandlerResponse

source ·
pub enum ErrorHandlerResponse<B> {
+    Response(ServiceResponse<EitherBody<B>>),
+    Future(LocalBoxFuture<'static, Result<ServiceResponse<EitherBody<B>>, Error>>),
+}
Expand description

Return type for ErrorHandlers custom handlers.

+

Variants§

§

Response(ServiceResponse<EitherBody<B>>)

Immediate HTTP response.

+
§

Future(LocalBoxFuture<'static, Result<ServiceResponse<EitherBody<B>>, Error>>)

A future that resolves to an HTTP response.

+

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/middleware/enum.TrailingSlash.html b/actix_web/middleware/enum.TrailingSlash.html new file mode 100644 index 000000000..08a8d58dd --- /dev/null +++ b/actix_web/middleware/enum.TrailingSlash.html @@ -0,0 +1,30 @@ +TrailingSlash in actix_web::middleware - Rust

Enum actix_web::middleware::TrailingSlash

source ·
#[non_exhaustive]
pub enum TrailingSlash { + Trim, + MergeOnly, + Always, +}
Expand description

Determines the behavior of the NormalizePath middleware.

+

The default is TrailingSlash::Trim.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Trim

Trim trailing slashes from the end of the path.

+

Using this will require all routes to omit trailing slashes for them to be accessible.

+
§

MergeOnly

Only merge any present multiple trailing slashes.

+

This option provides the best compatibility with behavior in actix-web v2.0.

+
§

Always

Always add a trailing slash to the end of the path.

+

Using this will require all routes have a trailing slash for them to be accessible.

+

Trait Implementations§

source§

impl Clone for TrailingSlash

source§

fn clone(&self) -> TrailingSlash

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for TrailingSlash

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for TrailingSlash

source§

fn default() -> TrailingSlash

Returns the “default value” for a type. Read more
source§

impl Copy for TrailingSlash

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/middleware/err_handlers/enum.ErrorHandlerResponse.html b/actix_web/middleware/err_handlers/enum.ErrorHandlerResponse.html new file mode 100644 index 000000000..36aa91b05 --- /dev/null +++ b/actix_web/middleware/err_handlers/enum.ErrorHandlerResponse.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/middleware/enum.ErrorHandlerResponse.html...

+ + + \ No newline at end of file diff --git a/actix_web/middleware/err_handlers/struct.ErrorHandlers.html b/actix_web/middleware/err_handlers/struct.ErrorHandlers.html new file mode 100644 index 000000000..63fac7868 --- /dev/null +++ b/actix_web/middleware/err_handlers/struct.ErrorHandlers.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/middleware/struct.ErrorHandlers.html...

+ + + \ No newline at end of file diff --git a/actix_web/middleware/index.html b/actix_web/middleware/index.html new file mode 100644 index 000000000..6f6e1f22e --- /dev/null +++ b/actix_web/middleware/index.html @@ -0,0 +1,165 @@ +actix_web::middleware - Rust

Module actix_web::middleware

source ·
Expand description

A collection of common middleware.

+

§What Is Middleware?

+

Actix Web’s middleware system allows us to add additional behavior to request/response +processing. Middleware can hook into incoming request and outgoing response processes, enabling +us to modify requests and responses as well as halt request processing to return a response +early.

+

Typically, middleware is involved in the following actions:

+ +

Middleware is registered for each App, Scope, or +Resource and executed in opposite order as registration. In general, a +middleware is a pair of types that implements the Service trait and Transform trait, +respectively. The new_transform and call methods must return a Future, though it +can often be an immediately-ready one.

+

§Ordering

+
#[get("/")]
+async fn service(a: ExtractorA, b: ExtractorB) -> impl Responder { "Hello, World!" }
+
+let app = App::new()
+    .wrap(MiddlewareA::default())
+    .wrap(MiddlewareB::default())
+    .wrap(MiddlewareC::default())
+    .service(service);
+
                  Request
+                     ⭣
+╭────────────────────┼────╮
+│ MiddlewareC        │    │
+│ ╭──────────────────┼───╮│
+│ │ MiddlewareB      │   ││
+│ │ ╭────────────────┼──╮││
+│ │ │ MiddlewareA    │  │││
+│ │ │ ╭──────────────┼─╮│││
+│ │ │ │ ExtractorA   │ ││││
+│ │ │ ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┼┈┤│││
+│ │ │ │ ExtractorB   │ ││││
+│ │ │ ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┼┈┤│││
+│ │ │ │ service      │ ││││
+│ │ │ ╰──────────────┼─╯│││
+│ │ ╰────────────────┼──╯││
+│ ╰──────────────────┼───╯│
+╰────────────────────┼────╯
+                     ⭣
+                  Response
+
+

The request first gets processed by the middleware specified last - MiddlewareC. It passes +the request (modified a modified one) to the next middleware - MiddlewareB - or directly +responds to the request (e.g. when the request was invalid or an error occurred). MiddlewareB +processes the request as well and passes it to MiddlewareA, which then passes it to the +Service. In the Service, the extractors will run first. They don’t pass the request on, +but only view it (see FromRequest). After the Service responds to the request, the +response is passed back through MiddlewareA, MiddlewareB, and MiddlewareC.

+

As you register middleware using wrap and wrap_fn +in the App builder, imagine wrapping layers around an inner App. The first middleware +layer exposed to a Request is the outermost layer (i.e., the last registered in the builder +chain, in the example above: MiddlewareC). Consequently, the first middleware registered in +the builder chain is the last to start executing during request processing (MiddlewareA). +Ordering is less obvious when wrapped services also have middleware applied. In this case, +middleware are run in reverse order for App and then in reverse order for the wrapped +service.

+

§Middleware Traits

§Transform<S, Req>

+

The Transform trait is the builder for the actual Services that handle the requests. All +the middleware you pass to the wrap methods implement this trait. During construction, each +thread assembles a chain of Services by calling new_transform and passing the next +Service (S) in the chain. The created Service handles requests of type Req.

+

In the example from the ordering section, the chain would be:

+
MiddlewareCService {
+    next: MiddlewareBService {
+        next: MiddlewareAService { ... }
+    }
+}
+

§Service<Req>

+

A Service S represents an asynchronous operation that turns a request of type Req into a +response of type S::Response or an error of type +S::Error. You can think of the service of being roughly:

+ +
async fn(&self, req: Req) -> Result<S::Response, S::Error>
+

In most cases the Service implementation will, at some point, call the wrapped Service +in its call implementation.

+

Note that the Services created by new_transform don’t need to be Send or Sync.

+

§Example

+
use std::{future::{ready, Ready, Future}, pin::Pin};
+
+use actix_web::{
+    dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform},
+    web, Error,
+};
+
+pub struct SayHi;
+
+// `S` - type of the next service
+// `B` - type of response's body
+impl<S, B> Transform<S, ServiceRequest> for SayHi
+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 = SayHiMiddleware<S>;
+    type Future = Ready<Result<Self::Transform, Self::InitError>>;
+
+    fn new_transform(&self, service: S) -> Self::Future {
+        ready(Ok(SayHiMiddleware { service }))
+    }
+}
+
+pub struct SayHiMiddleware<S> {
+    /// The next service to call
+    service: S,
+}
+
+// This future doesn't have the requirement of being `Send`.
+// See: futures_util::future::LocalBoxFuture
+type LocalBoxFuture<T> = Pin<Box<dyn Future<Output = T> + 'static>>;
+
+// `S`: type of the wrapped service
+// `B`: type of the body - try to be generic over the body where possible
+impl<S, B> Service<ServiceRequest> for SayHiMiddleware<S>
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+    S::Future: 'static,
+    B: 'static,
+{
+    type Response = ServiceResponse<B>;
+    type Error = Error;
+    type Future = LocalBoxFuture<Result<Self::Response, Self::Error>>;
+
+    // This service is ready when its next service is ready
+    forward_ready!(service);
+
+    fn call(&self, req: ServiceRequest) -> Self::Future {
+        println!("Hi from start. You requested: {}", req.path());
+
+        // A more complex middleware, could return an error or an early response here.
+
+        let fut = self.service.call(req);
+
+        Box::pin(async move {
+            let res = fut.await?;
+
+            println!("Hi from response");
+            Ok(res)
+        })
+    }
+}
+
+let app = App::new()
+    .wrap(SayHi)
+    .route("/", web::get().to(|| async { "Hello, middleware!" }));
+

§Simpler Middleware

+

In many cases, you can actually use an async function via a helper that will provide a more +natural flow for your behavior.

+

The experimental actix_web_lab crate provides a from_fn utility which allows +an async fn to be wrapped and used in the same way as other middleware. See the +from_fn docs for more info and examples of it’s use.

+

While from_fn is experimental currently, it’s likely this helper will graduate +to Actix Web in some form, so feedback is appreciated.

+

Structs§

  • Middleware for enabling any middleware to be used in Resource::wrap, +and Condition.
  • Compress__compress
    Middleware for compressing response payloads.
  • Middleware for conditionally enabling other middleware.
  • Middleware for setting default response headers.
  • Middleware for registering custom status code based error handlers.
  • Middleware for logging request and response summaries to the terminal.
  • Middleware for normalizing a request’s path so that routes can be matched more flexibly.

Enums§

\ No newline at end of file diff --git a/actix_web/middleware/logger/struct.Logger.html b/actix_web/middleware/logger/struct.Logger.html new file mode 100644 index 000000000..12fe9406e --- /dev/null +++ b/actix_web/middleware/logger/struct.Logger.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/middleware/struct.Logger.html...

+ + + \ No newline at end of file diff --git a/actix_web/middleware/normalize/enum.TrailingSlash.html b/actix_web/middleware/normalize/enum.TrailingSlash.html new file mode 100644 index 000000000..a5e5fccf2 --- /dev/null +++ b/actix_web/middleware/normalize/enum.TrailingSlash.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/middleware/enum.TrailingSlash.html...

+ + + \ No newline at end of file diff --git a/actix_web/middleware/normalize/struct.NormalizePath.html b/actix_web/middleware/normalize/struct.NormalizePath.html new file mode 100644 index 000000000..480bc2303 --- /dev/null +++ b/actix_web/middleware/normalize/struct.NormalizePath.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/middleware/struct.NormalizePath.html...

+ + + \ No newline at end of file diff --git a/actix_web/middleware/sidebar-items.js b/actix_web/middleware/sidebar-items.js new file mode 100644 index 000000000..689b62dc4 --- /dev/null +++ b/actix_web/middleware/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["ErrorHandlerResponse","TrailingSlash"],"struct":["Compat","Compress","Condition","DefaultHeaders","ErrorHandlers","Logger","NormalizePath"]}; \ No newline at end of file diff --git a/actix_web/middleware/struct.Compat.html b/actix_web/middleware/struct.Compat.html new file mode 100644 index 000000000..f96425fd8 --- /dev/null +++ b/actix_web/middleware/struct.Compat.html @@ -0,0 +1,44 @@ +Compat in actix_web::middleware - Rust

Struct actix_web::middleware::Compat

source ·
pub struct Compat<T> { /* private fields */ }
Expand description

Middleware for enabling any middleware to be used in Resource::wrap, +and Condition.

+

§Examples

+
use actix_web::middleware::{Logger, Compat};
+use actix_web::{App, web};
+
+let logger = Logger::default();
+
+// this would not compile because of incompatible body types
+// let app = App::new()
+//     .service(web::scope("scoped").wrap(logger));
+
+// by using this middleware we can use the logger on a scope
+let app = App::new()
+    .service(web::scope("scoped").wrap(Compat::new(logger)));
+

Implementations§

source§

impl<T> Compat<T>

source

pub fn new(middleware: T) -> Self

Wrap a middleware to give it broader compatibility.

+

Trait Implementations§

source§

impl<S, T, Req> Transform<S, Req> for Compat<T>
where + S: Service<Req>, + T: Transform<S, Req>, + T::Future: 'static, + T::Response: MapServiceResponseBody, + T::Error: Into<Error>,

§

type Response = ServiceResponse

Responses produced by the service.
§

type Error = Error

Errors produced by the service.
§

type Transform = CompatMiddleware<<T as Transform<S, Req>>::Transform>

The TransformService value created by this factory
§

type InitError = <T as Transform<S, Req>>::InitError

Errors produced while building a transform service.
§

type Future = Pin<Box<dyn Future<Output = Result<<Compat<T> as Transform<S, Req>>::Transform, <Compat<T> as Transform<S, Req>>::InitError>>>>

The future response value.
source§

fn new_transform(&self, service: S) -> Self::Future

Creates and returns a new Transform component, asynchronously

Auto Trait Implementations§

§

impl<T> Freeze for Compat<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for Compat<T>
where + T: RefUnwindSafe,

§

impl<T> Send for Compat<T>
where + T: Send,

§

impl<T> Sync for Compat<T>
where + T: Sync,

§

impl<T> Unpin for Compat<T>
where + T: Unpin,

§

impl<T> UnwindSafe for Compat<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/middleware/struct.Compress.html b/actix_web/middleware/struct.Compress.html new file mode 100644 index 000000000..7240d01d7 --- /dev/null +++ b/actix_web/middleware/struct.Compress.html @@ -0,0 +1,57 @@ +Compress in actix_web::middleware - Rust

Struct actix_web::middleware::Compress

source ·
#[non_exhaustive]
pub struct Compress;
Available on crate feature __compress only.
Expand description

Middleware for compressing response payloads.

+

§Encoding Negotiation

+

Compress will read the Accept-Encoding header to negotiate which compression codec to use. +Payloads are not compressed if the header is not sent. The compress-* feature flags are also +considered in this selection process.

+

§Pre-compressed Payload

+

If you are serving some data that is already using a compressed representation (e.g., a gzip +compressed HTML file from disk) you can signal this to Compress by setting an appropriate +Content-Encoding header. In addition to preventing double compressing the payload, this header +is required by the spec when using compressed representations and will inform the client that +the content should be uncompressed.

+

However, it is not advised to unconditionally serve encoded representations of content because +the client may not support it. The AcceptEncoding typed header has some utilities to help +perform manual encoding negotiation, if required. When negotiating content encoding, it is also +required by the spec to send a Vary: Accept-Encoding header.

+

A (naïve) example serving an pre-compressed Gzip file is included below.

+

§Examples

+

To enable automatic payload compression just include Compress as a top-level middleware:

+ +
use actix_web::{middleware, web, App, HttpResponse};
+
+let app = App::new()
+    .wrap(middleware::Compress::default())
+    .default_service(web::to(|| async { HttpResponse::Ok().body("hello world") }));
+

Pre-compressed Gzip file being served from disk with correct headers added to bypass middleware:

+ +
use actix_web::{middleware, http::header, web, App, HttpResponse, Responder};
+
+async fn index_handler() -> actix_web::Result<impl Responder> {
+    Ok(actix_files::NamedFile::open_async("./assets/index.html.gz").await?
+        .customize()
+        .insert_header(header::ContentEncoding::Gzip))
+}
+
+let app = App::new()
+    .wrap(middleware::Compress::default())
+    .default_service(web::to(index_handler));
+

Trait Implementations§

source§

impl Clone for Compress

source§

fn clone(&self) -> Compress

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Compress

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Compress

source§

fn default() -> Compress

Returns the “default value” for a type. Read more
source§

impl<S, B> Transform<S, ServiceRequest> for Compress
where + B: MessageBody, + S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,

§

type Response = ServiceResponse<EitherBody<Encoder<B>>>

Responses produced by the service.
§

type Error = Error

Errors produced by the service.
§

type Transform = CompressMiddleware<S>

The TransformService value created by this factory
§

type InitError = ()

Errors produced while building a transform service.
§

type Future = Ready<Result<<Compress as Transform<S, ServiceRequest>>::Transform, <Compress as Transform<S, ServiceRequest>>::InitError>>

The future response value.
source§

fn new_transform(&self, service: S) -> Self::Future

Creates and returns a new Transform component, asynchronously

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/middleware/struct.Condition.html b/actix_web/middleware/struct.Condition.html new file mode 100644 index 000000000..9523d98dd --- /dev/null +++ b/actix_web/middleware/struct.Condition.html @@ -0,0 +1,36 @@ +Condition in actix_web::middleware - Rust

Struct actix_web::middleware::Condition

source ·
pub struct Condition<T> { /* private fields */ }
Expand description

Middleware for conditionally enabling other middleware.

+

§Examples

+
use actix_web::middleware::{Condition, NormalizePath};
+use actix_web::App;
+
+let enable_normalize = std::env::var("NORMALIZE_PATH").is_ok();
+let app = App::new()
+    .wrap(Condition::new(enable_normalize, NormalizePath::default()));
+

Implementations§

source§

impl<T> Condition<T>

source

pub fn new(enable: bool, transformer: T) -> Self

Trait Implementations§

source§

impl<S, T, Req, BE, BD, Err> Transform<S, Req> for Condition<T>
where + S: Service<Req, Response = ServiceResponse<BD>, Error = Err> + 'static, + T: Transform<S, Req, Response = ServiceResponse<BE>, Error = Err>, + T::Future: 'static, + T::InitError: 'static, + T::Transform: 'static,

§

type Response = ServiceResponse<EitherBody<BE, BD>>

Responses produced by the service.
§

type Error = Err

Errors produced by the service.
§

type Transform = ConditionMiddleware<<T as Transform<S, Req>>::Transform, S>

The TransformService value created by this factory
§

type InitError = <T as Transform<S, Req>>::InitError

Errors produced while building a transform service.
§

type Future = Pin<Box<dyn Future<Output = Result<<Condition<T> as Transform<S, Req>>::Transform, <Condition<T> as Transform<S, Req>>::InitError>>>>

The future response value.
source§

fn new_transform(&self, service: S) -> Self::Future

Creates and returns a new Transform component, asynchronously

Auto Trait Implementations§

§

impl<T> Freeze for Condition<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for Condition<T>
where + T: RefUnwindSafe,

§

impl<T> Send for Condition<T>
where + T: Send,

§

impl<T> Sync for Condition<T>
where + T: Sync,

§

impl<T> Unpin for Condition<T>
where + T: Unpin,

§

impl<T> UnwindSafe for Condition<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/middleware/struct.DefaultHeaders.html b/actix_web/middleware/struct.DefaultHeaders.html new file mode 100644 index 000000000..398350176 --- /dev/null +++ b/actix_web/middleware/struct.DefaultHeaders.html @@ -0,0 +1,38 @@ +DefaultHeaders in actix_web::middleware - Rust

Struct actix_web::middleware::DefaultHeaders

source ·
pub struct DefaultHeaders { /* private fields */ }
Expand description

Middleware for setting default response headers.

+

Headers with the same key that are already set in a response will not be overwritten.

+

§Examples

+
use actix_web::{web, http, middleware, App, HttpResponse};
+
+let app = App::new()
+    .wrap(middleware::DefaultHeaders::new().add(("X-Version", "0.2")))
+    .service(
+        web::resource("/test")
+            .route(web::get().to(|| HttpResponse::Ok()))
+            .route(web::method(http::Method::HEAD).to(|| HttpResponse::MethodNotAllowed()))
+    );
+

Implementations§

source§

impl DefaultHeaders

source

pub fn new() -> DefaultHeaders

Constructs an empty DefaultHeaders middleware.

+
source

pub fn add(self, header: impl TryIntoHeaderPair) -> Self

Adds a header to the default set.

+
§Panics
+

Panics when resolved header name or value is invalid.

+
source

pub fn add_content_type(self) -> Self

Adds a default Content-Type header if response does not contain one.

+

Default is application/octet-stream.

+

Trait Implementations§

source§

impl Clone for DefaultHeaders

source§

fn clone(&self) -> DefaultHeaders

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for DefaultHeaders

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for DefaultHeaders

source§

fn default() -> DefaultHeaders

Returns the “default value” for a type. Read more
source§

impl<S, B> Transform<S, ServiceRequest> for DefaultHeaders
where + S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>, + S::Future: 'static,

§

type Response = ServiceResponse<B>

Responses produced by the service.
§

type Error = Error

Errors produced by the service.
§

type Transform = DefaultHeadersMiddleware<S>

The TransformService value created by this factory
§

type InitError = ()

Errors produced while building a transform service.
§

type Future = Ready<Result<<DefaultHeaders as Transform<S, ServiceRequest>>::Transform, <DefaultHeaders as Transform<S, ServiceRequest>>::InitError>>

The future response value.
source§

fn new_transform(&self, service: S) -> Self::Future

Creates and returns a new Transform component, asynchronously

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/middleware/struct.ErrorHandlers.html b/actix_web/middleware/struct.ErrorHandlers.html new file mode 100644 index 000000000..39268f3ee --- /dev/null +++ b/actix_web/middleware/struct.ErrorHandlers.html @@ -0,0 +1,139 @@ +ErrorHandlers in actix_web::middleware - Rust

Struct actix_web::middleware::ErrorHandlers

source ·
pub struct ErrorHandlers<B> { /* private fields */ }
Expand description

Middleware for registering custom status code based error handlers.

+

Register handlers with the ErrorHandlers::handler() method to register a custom error handler +for a given status code. Handlers can modify existing responses or create completely new ones.

+

To register a default handler, use the ErrorHandlers::default_handler() method. This +handler will be used only if a response has an error status code (400-599) that isn’t covered by +a more specific handler (set with the handler() method). See examples +below.

+

To register a default for only client errors (400-499) or only server errors (500-599), use the +ErrorHandlers::default_handler_client() and ErrorHandlers::default_handler_server() +methods, respectively.

+

Any response with a status code that isn’t covered by a specific handler or a default handler +will pass by unchanged by this middleware.

+

§Examples

+

Adding a header:

+ +
use actix_web::{
+    dev::ServiceResponse,
+    http::{header, StatusCode},
+    middleware::{ErrorHandlerResponse, ErrorHandlers},
+    web, App, HttpResponse, Result,
+};
+
+fn add_error_header<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+    res.response_mut().headers_mut().insert(
+        header::CONTENT_TYPE,
+        header::HeaderValue::from_static("Error"),
+    );
+
+    // body is unchanged, map to "left" slot
+    Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
+}
+
+let app = App::new()
+    .wrap(ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, add_error_header))
+    .service(web::resource("/").route(web::get().to(HttpResponse::InternalServerError)));
+

Modifying response body:

+ +
use actix_web::{
+    dev::ServiceResponse,
+    http::{header, StatusCode},
+    middleware::{ErrorHandlerResponse, ErrorHandlers},
+    web, App, HttpResponse, Result,
+};
+
+fn add_error_body<B>(res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+    // split service response into request and response components
+    let (req, res) = res.into_parts();
+
+    // set body of response to modified body
+    let res = res.set_body("An error occurred.");
+
+    // modified bodies need to be boxed and placed in the "right" slot
+    let res = ServiceResponse::new(req, res)
+        .map_into_boxed_body()
+        .map_into_right_body();
+
+    Ok(ErrorHandlerResponse::Response(res))
+}
+
+let app = App::new()
+    .wrap(ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, add_error_body))
+    .service(web::resource("/").route(web::get().to(HttpResponse::InternalServerError)));
+

Registering default handler:

+ +
fn add_error_header<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+    res.response_mut().headers_mut().insert(
+        header::CONTENT_TYPE,
+        header::HeaderValue::from_static("Error"),
+    );
+
+    // body is unchanged, map to "left" slot
+    Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
+}
+
+fn handle_bad_request<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+    res.response_mut().headers_mut().insert(
+        header::CONTENT_TYPE,
+        header::HeaderValue::from_static("Bad Request Error"),
+    );
+
+    // body is unchanged, map to "left" slot
+    Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
+}
+
+// Bad Request errors will hit `handle_bad_request()`, while all other errors will hit
+// `add_error_header()`. The order in which the methods are called is not meaningful.
+let app = App::new()
+    .wrap(
+        ErrorHandlers::new()
+            .default_handler(add_error_header)
+            .handler(StatusCode::BAD_REQUEST, handle_bad_request)
+    )
+    .service(web::resource("/").route(web::get().to(HttpResponse::InternalServerError)));
+

You can set default handlers for all client (4xx) or all server (5xx) errors:

+ +
// Bad request errors will hit `handle_bad_request()`, other client errors will hit
+// `add_error_header()`, and server errors will pass through unchanged
+let app = App::new()
+    .wrap(
+        ErrorHandlers::new()
+            .default_handler_client(add_error_header) // or .default_handler_server
+            .handler(StatusCode::BAD_REQUEST, handle_bad_request)
+    )
+    .service(web::resource("/").route(web::get().to(HttpResponse::InternalServerError)));
+

Implementations§

source§

impl<B> ErrorHandlers<B>

source

pub fn new() -> Self

Construct new ErrorHandlers instance.

+
source

pub fn handler<F>(self, status: StatusCode, handler: F) -> Self
where + F: Fn(ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> + 'static,

Register error handler for specified status code.

+
source

pub fn default_handler<F>(self, handler: F) -> Self
where + F: Fn(ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> + 'static,

Register a default error handler.

+

Any request with a status code that hasn’t been given a specific other handler (by calling +.handler()) will fall back on this.

+

Note that this will overwrite any default handlers previously set by calling +.default_handler_client() or +.default_handler_server(), but not any set by +calling .handler().

+
source

pub fn default_handler_client<F>(self, handler: F) -> Self
where + F: Fn(ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> + 'static,

Register a handler on which to fall back for client error status codes (400-499).

+
source

pub fn default_handler_server<F>(self, handler: F) -> Self
where + F: Fn(ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> + 'static,

Register a handler on which to fall back for server error status codes (500-599).

+

Trait Implementations§

source§

impl<B> Default for ErrorHandlers<B>

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<S, B> Transform<S, ServiceRequest> for ErrorHandlers<B>
where + S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static, + S::Future: 'static, + B: 'static,

§

type Response = ServiceResponse<EitherBody<B>>

Responses produced by the service.
§

type Error = Error

Errors produced by the service.
§

type Transform = ErrorHandlersMiddleware<S, B>

The TransformService value created by this factory
§

type InitError = ()

Errors produced while building a transform service.
§

type Future = Pin<Box<dyn Future<Output = Result<<ErrorHandlers<B> as Transform<S, ServiceRequest>>::Transform, <ErrorHandlers<B> as Transform<S, ServiceRequest>>::InitError>>>>

The future response value.
source§

fn new_transform(&self, service: S) -> Self::Future

Creates and returns a new Transform component, asynchronously

Auto Trait Implementations§

§

impl<B> Freeze for ErrorHandlers<B>

§

impl<B> !RefUnwindSafe for ErrorHandlers<B>

§

impl<B> !Send for ErrorHandlers<B>

§

impl<B> !Sync for ErrorHandlers<B>

§

impl<B> Unpin for ErrorHandlers<B>

§

impl<B> !UnwindSafe for ErrorHandlers<B>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/middleware/struct.Logger.html b/actix_web/middleware/struct.Logger.html new file mode 100644 index 000000000..8ae3ac22b --- /dev/null +++ b/actix_web/middleware/struct.Logger.html @@ -0,0 +1,104 @@ +Logger in actix_web::middleware - Rust

Struct actix_web::middleware::Logger

source ·
pub struct Logger(/* private fields */);
Expand description

Middleware for logging request and response summaries to the terminal.

+

This middleware uses the log crate to output information. Enable log’s output for the +“actix_web” scope using env_logger or similar crate.

+

§Default Format

+

The default Logger uses the following format:

+
%a "%r" %s %b "%{Referer}i" "%{User-Agent}i" %T
+
+Example Output:
+127.0.0.1:54278 "GET /test HTTP/1.1" 404 20 "-" "HTTPie/2.2.0" 0.001074
+

§Examples

+
use actix_web::{middleware::Logger, App};
+
+// access logs are printed with the INFO level so ensure it is enabled by default
+env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
+
+let app = App::new()
+    // .wrap(Logger::default())
+    .wrap(Logger::new("%a %{User-Agent}i"));
+

§Format

+ + + + + + + + + + + + + + + +
VariableDescription
%%The percent sign
%aPeer IP address (or IP address of reverse proxy if used)
%tTime when the request started processing (in RFC 3339 format)
%rFirst line of request (Example: GET /test HTTP/1.1)
%sResponse status code
%bSize of response in bytes, including HTTP headers
%TTime taken to serve the request, in seconds to 6 decimal places
%DTime taken to serve the request, in milliseconds
%URequest URL
%{r}a“Real IP” remote address *
%{FOO}irequest.headers["FOO"]
%{FOO}oresponse.headers["FOO"]
%{FOO}eenv_var["FOO"]
%{FOO}xiCustom request replacement labelled “FOO”
%{FOO}xoCustom response replacement labelled “FOO”
+

§Security

+

* “Real IP” remote address is calculated using +ConnectionInfo::realip_remote_addr()

+

If you use this value, ensure that all requests come from trusted hosts. Otherwise, it is +trivial for the remote client to falsify their source IP address.

+

Implementations§

source§

impl Logger

source

pub fn new(format: &str) -> Logger

Create Logger middleware with the specified format.

+
source

pub fn exclude<T: Into<String>>(self, path: T) -> Self

Ignore and do not log access info for specified path.

+
source

pub fn exclude_regex<T: Into<String>>(self, path: T) -> Self

Ignore and do not log access info for paths that match regex.

+
source

pub fn log_target(self, target: impl Into<Cow<'static, str>>) -> Self

Sets the logging target to target.

+

By default, the log target is module_path!() of the log call location. In our case, that +would be actix_web::middleware::logger.

+
§Examples
+

Using .log_target("http_log") would have this effect on request logs:

+
- [2015-10-21T07:28:00Z INFO  actix_web::middleware::logger] 127.0.0.1 "GET / HTTP/1.1" 200 88 "-" "dmc/1.0" 0.001985
++ [2015-10-21T07:28:00Z INFO  http_log] 127.0.0.1 "GET / HTTP/1.1" 200 88 "-" "dmc/1.0" 0.001985
+                              ^^^^^^^^
+
source

pub fn custom_request_replace( + self, + label: &str, + f: impl Fn(&ServiceRequest) -> String + 'static +) -> Self

Register a function that receives a ServiceRequest and returns a String for use in the +log line. The label passed as the first argument should match a replacement substring in +the logger format like %{label}xi.

+

It is convention to print “-” to indicate no output instead of an empty string.

+
§Examples
+
Logger::new("example %{JWT_ID}xi")
+    .custom_request_replace("JWT_ID", |req| parse_jwt_id(req.headers().get("Authorization")));
+
source

pub fn custom_response_replace( + self, + label: &str, + f: impl Fn(&ServiceResponse) -> String + 'static +) -> Self

Register a function that receives a ServiceResponse and returns a string for use in the +log line.

+

The label passed as the first argument should match a replacement substring in +the logger format like %{label}xo.

+

It is convention to print “-” to indicate no output instead of an empty string.

+

The replacement function does not have access to the response body.

+
§Examples
+
fn log_if_error(res: &ServiceResponse) -> String {
+    if res.status().as_u16() >= 400 {
+        "ERROR".to_string()
+    } else {
+        "-".to_string()
+    }
+}
+
+Logger::new("example %{ERROR_STATUS}xo")
+    .custom_response_replace("ERROR_STATUS", |res| log_if_error(res) );
+

Trait Implementations§

source§

impl Debug for Logger

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for Logger

source§

fn default() -> Logger

Create Logger middleware with format:

+
%a "%r" %s %b "%{Referer}i" "%{User-Agent}i" %T
+
source§

impl<S, B> Transform<S, ServiceRequest> for Logger
where + S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>, + B: MessageBody,

§

type Response = ServiceResponse<StreamLog<B>>

Responses produced by the service.
§

type Error = Error

Errors produced by the service.
§

type Transform = LoggerMiddleware<S>

The TransformService value created by this factory
§

type InitError = ()

Errors produced while building a transform service.
§

type Future = Ready<Result<<Logger as Transform<S, ServiceRequest>>::Transform, <Logger as Transform<S, ServiceRequest>>::InitError>>

The future response value.
source§

fn new_transform(&self, service: S) -> Self::Future

Creates and returns a new Transform component, asynchronously

Auto Trait Implementations§

§

impl Freeze for Logger

§

impl !RefUnwindSafe for Logger

§

impl !Send for Logger

§

impl !Sync for Logger

§

impl Unpin for Logger

§

impl !UnwindSafe for Logger

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/middleware/struct.NormalizePath.html b/actix_web/middleware/struct.NormalizePath.html new file mode 100644 index 000000000..7f6a6b98e --- /dev/null +++ b/actix_web/middleware/struct.NormalizePath.html @@ -0,0 +1,64 @@ +NormalizePath in actix_web::middleware - Rust

Struct actix_web::middleware::NormalizePath

source ·
pub struct NormalizePath(/* private fields */);
Expand description

Middleware for normalizing a request’s path so that routes can be matched more flexibly.

+

§Normalization Steps

+
    +
  • Merges consecutive slashes into one. (For example, /path//one always becomes /path/one.)
  • +
  • Appends a trailing slash if one is not present, removes one if present, or keeps trailing +slashes as-is, depending on which TrailingSlash variant is supplied +to new.
  • +
+

§Default Behavior

+

The default constructor chooses to strip trailing slashes from the end of paths with them +(TrailingSlash::Trim). The implication is that route definitions should be defined without +trailing slashes or else they will be inaccessible (or vice versa when using the +TrailingSlash::Always behavior), as shown in the example tests below.

+

§Examples

+
use actix_web::{web, middleware, App};
+
+let app = App::new()
+    .wrap(middleware::NormalizePath::trim())
+    .route("/test", web::get().to(|| async { "test" }))
+    .route("/unmatchable/", web::get().to(|| async { "unmatchable" }));
+
+use actix_web::http::StatusCode;
+use actix_web::test::{call_service, init_service, TestRequest};
+
+let app = init_service(app).await;
+
+let req = TestRequest::with_uri("/test").to_request();
+let res = call_service(&app, req).await;
+assert_eq!(res.status(), StatusCode::OK);
+
+let req = TestRequest::with_uri("/test/").to_request();
+let res = call_service(&app, req).await;
+assert_eq!(res.status(), StatusCode::OK);
+
+let req = TestRequest::with_uri("/unmatchable").to_request();
+let res = call_service(&app, req).await;
+assert_eq!(res.status(), StatusCode::NOT_FOUND);
+
+let req = TestRequest::with_uri("/unmatchable/").to_request();
+let res = call_service(&app, req).await;
+assert_eq!(res.status(), StatusCode::NOT_FOUND);
+

Implementations§

source§

impl NormalizePath

source

pub fn new(trailing_slash_style: TrailingSlash) -> Self

Create new NormalizePath middleware with the specified trailing slash style.

+
source

pub fn trim() -> Self

Constructs a new NormalizePath middleware with trim semantics.

+

Use this instead of NormalizePath::default() to avoid deprecation warning.

+

Trait Implementations§

source§

impl Clone for NormalizePath

source§

fn clone(&self) -> NormalizePath

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for NormalizePath

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Default for NormalizePath

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<S, B> Transform<S, ServiceRequest> for NormalizePath
where + S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>, + S::Future: 'static,

§

type Response = ServiceResponse<B>

Responses produced by the service.
§

type Error = Error

Errors produced by the service.
§

type Transform = NormalizePathNormalization<S>

The TransformService value created by this factory
§

type InitError = ()

Errors produced while building a transform service.
§

type Future = Ready<Result<<NormalizePath as Transform<S, ServiceRequest>>::Transform, <NormalizePath as Transform<S, ServiceRequest>>::InitError>>

The future response value.
source§

fn new_transform(&self, service: S) -> Self::Future

Creates and returns a new Transform component, asynchronously
source§

impl Copy for NormalizePath

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/redirect/struct.Redirect.html b/actix_web/redirect/struct.Redirect.html new file mode 100644 index 000000000..f17947d9f --- /dev/null +++ b/actix_web/redirect/struct.Redirect.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/web/struct.Redirect.html...

+ + + \ No newline at end of file diff --git a/actix_web/request/struct.HttpRequest.html b/actix_web/request/struct.HttpRequest.html new file mode 100644 index 000000000..ffa240125 --- /dev/null +++ b/actix_web/request/struct.HttpRequest.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/struct.HttpRequest.html...

+ + + \ No newline at end of file diff --git a/actix_web/request_data/struct.ReqData.html b/actix_web/request_data/struct.ReqData.html new file mode 100644 index 000000000..ed0df2894 --- /dev/null +++ b/actix_web/request_data/struct.ReqData.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/web/struct.ReqData.html...

+ + + \ No newline at end of file diff --git a/actix_web/resource/struct.Resource.html b/actix_web/resource/struct.Resource.html new file mode 100644 index 000000000..77752842a --- /dev/null +++ b/actix_web/resource/struct.Resource.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/struct.Resource.html...

+ + + \ No newline at end of file diff --git a/actix_web/response/builder/struct.HttpResponseBuilder.html b/actix_web/response/builder/struct.HttpResponseBuilder.html new file mode 100644 index 000000000..216a87cfb --- /dev/null +++ b/actix_web/response/builder/struct.HttpResponseBuilder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/struct.HttpResponseBuilder.html...

+ + + \ No newline at end of file diff --git a/actix_web/response/customize_responder/struct.CustomizeResponder.html b/actix_web/response/customize_responder/struct.CustomizeResponder.html new file mode 100644 index 000000000..32f42a306 --- /dev/null +++ b/actix_web/response/customize_responder/struct.CustomizeResponder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/struct.CustomizeResponder.html...

+ + + \ No newline at end of file diff --git a/actix_web/response/responder/trait.Responder.html b/actix_web/response/responder/trait.Responder.html new file mode 100644 index 000000000..798700959 --- /dev/null +++ b/actix_web/response/responder/trait.Responder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/trait.Responder.html...

+ + + \ No newline at end of file diff --git a/actix_web/response/response/struct.HttpResponse.html b/actix_web/response/response/struct.HttpResponse.html new file mode 100644 index 000000000..40fdf9a6b --- /dev/null +++ b/actix_web/response/response/struct.HttpResponse.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/struct.HttpResponse.html...

+ + + \ No newline at end of file diff --git a/actix_web/rmap/struct.ResourceMap.html b/actix_web/rmap/struct.ResourceMap.html new file mode 100644 index 000000000..012e6306f --- /dev/null +++ b/actix_web/rmap/struct.ResourceMap.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/dev/struct.ResourceMap.html...

+ + + \ No newline at end of file diff --git a/actix_web/route/struct.Route.html b/actix_web/route/struct.Route.html new file mode 100644 index 000000000..859af1f29 --- /dev/null +++ b/actix_web/route/struct.Route.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/struct.Route.html...

+ + + \ No newline at end of file diff --git a/actix_web/rt/fn.spawn.html b/actix_web/rt/fn.spawn.html new file mode 100644 index 000000000..9f3e0757a --- /dev/null +++ b/actix_web/rt/fn.spawn.html @@ -0,0 +1,24 @@ +spawn in actix_web::rt - Rust

Function actix_web::rt::spawn

pub fn spawn<Fut>(f: Fut) -> JoinHandle<<Fut as Future>::Output> 
where + Fut: Future + 'static, + <Fut as Future>::Output: 'static,
Expand description

Spawns a future on the current thread as a new task.

+

If not immediately awaited, the task can be cancelled using JoinHandle::abort.

+

The provided future is spawned as a new task; therefore, panics are caught.

+

§Panics

+

Panics if Actix system is not running.

+

§Examples

+
// task resolves successfully
+assert_eq!(actix_rt::spawn(async { 1 }).await.unwrap(), 1);
+
+// task panics
+assert!(actix_rt::spawn(async {
+    panic!("panic is caught at task boundary");
+})
+.await
+.unwrap_err()
+.is_panic());
+
+// task is cancelled before completion
+let handle = actix_rt::spawn(actix_rt::time::sleep(Duration::from_secs(100)));
+handle.abort();
+assert!(handle.await.unwrap_err().is_cancelled());
+
\ No newline at end of file diff --git a/actix_web/rt/index.html b/actix_web/rt/index.html new file mode 100644 index 000000000..c158d37cb --- /dev/null +++ b/actix_web/rt/index.html @@ -0,0 +1,50 @@ +actix_web::rt - Rust

Module actix_web::rt

source ·
Expand description

A selection of re-exports from tokio and actix-rt.

+

Actix Web runs on Tokio, providing full1 compatibility with its huge ecosystem of +crates. Each of the server’s workers uses a single-threaded runtime. Read more about the +architecture in actix-rt’s docs.

+

§Running Actix Web Without Macros

+
use actix_web::{middleware, rt, web, App, HttpRequest, HttpServer};
+
+async fn index(req: HttpRequest) -> &'static str {
+    println!("REQ: {:?}", req);
+    "Hello world!\r\n"
+}
+
+fn main() -> std::io::Result<()> {
+    rt::System::new().block_on(
+        HttpServer::new(|| {
+            App::new().service(web::resource("/").route(web::get().to(index)))
+        })
+        .bind(("127.0.0.1", 8080))?
+        .run()
+    )
+}
+

§Running Actix Web Using #[tokio::main]

+

If you need to run something that uses Tokio’s work stealing functionality alongside Actix Web, +you can run Actix Web under #[tokio::main]. The Server object returned +from HttpServer::run can also be spawned, if preferred.

+

Note that actix actor support (and therefore WebSocket support through actix-web-actors) +still require #[actix_web::main] since they require a System to be set up.

+

Also note that calls to this module’s spawn() re-export require an #[actix_web::main] +runtime (or a manually configured LocalSet) since it makes calls into to the current thread’s +LocalSet, which #[tokio::main] does not set up.

+ +
use actix_web::{get, middleware, rt, web, App, HttpRequest, HttpServer};
+
+#[get("/")]
+async fn index(req: HttpRequest) -> &'static str {
+    println!("REQ: {:?}", req);
+    "Hello world!\r\n"
+}
+
+#[tokio::main]
+async fn main() -> std::io::Result<()> {
+    HttpServer::new(|| {
+        App::new().service(index)
+    })
+    .bind(("127.0.0.1", 8080))?
+    .run()
+    .await
+}
+

  1. Crates that use Tokio’s block_in_place will not work with Actix Web. Fortunately, +the vast majority of Tokio-based crates do not use it. 

Modules§

  • TCP/UDP/Unix bindings (mostly Tokio re-exports).
  • Asynchronous signal handling (Tokio re-exports).
  • Task management (Tokio re-exports).
  • Utilities for tracking time (Tokio re-exports).

Macros§

  • Pins a value on the stack.

Structs§

  • A Tokio-based runtime proxy.
  • A manager for a per-thread distributed async runtime.
  • Runner that keeps a System’s event loop alive until stop message is received.

Functions§

  • Spawns a future on the current thread as a new task.
\ No newline at end of file diff --git a/actix_web/rt/macro.pin!.html b/actix_web/rt/macro.pin!.html new file mode 100644 index 000000000..22b3e8426 --- /dev/null +++ b/actix_web/rt/macro.pin!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.pin.html...

+ + + \ No newline at end of file diff --git a/actix_web/rt/macro.pin.html b/actix_web/rt/macro.pin.html new file mode 100644 index 000000000..a090e4307 --- /dev/null +++ b/actix_web/rt/macro.pin.html @@ -0,0 +1,104 @@ +pin in actix_web::rt - Rust

Macro actix_web::rt::pin

macro_rules! pin {
+    ($($x:ident),*) => { ... };
+    ($(
+            let $x:ident = $init:expr;
+    )*) => { ... };
+}
Expand description

Pins a value on the stack.

+

Calls to async fn return anonymous Future values that are !Unpin. +These values must be pinned before they can be polled. Calling .await will +handle this, but consumes the future. If it is required to call .await on +a &mut _ reference, the caller is responsible for pinning the future.

+

Pinning may be done by allocating with Box::pin or by using the stack +with the pin! macro.

+

The following will fail to compile:

+ +
async fn my_async_fn() {
+    // async logic here
+}
+
+#[tokio::main]
+async fn main() {
+    let mut future = my_async_fn();
+    (&mut future).await;
+}
+

To make this work requires pinning:

+ +
use tokio::pin;
+
+async fn my_async_fn() {
+    // async logic here
+}
+
+#[tokio::main]
+async fn main() {
+    let future = my_async_fn();
+    pin!(future);
+
+    (&mut future).await;
+}
+

Pinning is useful when using select! and stream operators that require T: Stream + Unpin.

+

§Usage

+

The pin! macro takes identifiers as arguments. It does not work +with expressions.

+

The following does not compile as an expression is passed to pin!.

+ +
async fn my_async_fn() {
+    // async logic here
+}
+
+#[tokio::main]
+async fn main() {
+    let mut future = pin!(my_async_fn());
+    (&mut future).await;
+}
+

§Examples

+

Using with select:

+ +
use tokio::{pin, select};
+use tokio_stream::{self as stream, StreamExt};
+
+async fn my_async_fn() {
+    // async logic here
+}
+
+#[tokio::main]
+async fn main() {
+    let mut stream = stream::iter(vec![1, 2, 3, 4]);
+
+    let future = my_async_fn();
+    pin!(future);
+
+    loop {
+        select! {
+            _ = &mut future => {
+                // Stop looping `future` will be polled after completion
+                break;
+            }
+            Some(val) = stream.next() => {
+                println!("got value = {}", val);
+            }
+        }
+    }
+}
+

Because assigning to a variable followed by pinning is common, there is also +a variant of the macro that supports doing both in one go.

+ +
use tokio::{pin, select};
+
+async fn my_async_fn() {
+    // async logic here
+}
+
+#[tokio::main]
+async fn main() {
+    pin! {
+        let future1 = my_async_fn();
+        let future2 = my_async_fn();
+    }
+
+    select! {
+        _ = &mut future1 => {}
+        _ = &mut future2 => {}
+    }
+}
+
\ No newline at end of file diff --git a/actix_web/rt/net/index.html b/actix_web/rt/net/index.html new file mode 100644 index 000000000..bf178b94d --- /dev/null +++ b/actix_web/rt/net/index.html @@ -0,0 +1,3 @@ +actix_web::rt::net - Rust

Module actix_web::rt::net

Expand description

TCP/UDP/Unix bindings (mostly Tokio re-exports).

+

Structs§

  • Describes the readiness state of an I/O resources.
  • A TCP socket server, listening for connections.
  • A TCP socket that has not yet been converted to a TcpStream or +TcpListener.
  • A TCP stream between a local and a remote socket.
  • A UDP socket.
  • UnixDatagramUnix and net
    An I/O object representing a Unix datagram socket.
  • UnixListenerUnix and net
    A Unix socket which can accept connections from other Unix sockets.
  • UnixStreamUnix and net
    A structure representing a connected Unix socket.
\ No newline at end of file diff --git a/actix_web/rt/net/sidebar-items.js b/actix_web/rt/net/sidebar-items.js new file mode 100644 index 000000000..2f29502d3 --- /dev/null +++ b/actix_web/rt/net/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Ready","TcpListener","TcpSocket","TcpStream","UdpSocket","UnixDatagram","UnixListener","UnixStream"]}; \ No newline at end of file diff --git a/actix_web/rt/net/struct.Ready.html b/actix_web/rt/net/struct.Ready.html new file mode 100644 index 000000000..7bfb26939 --- /dev/null +++ b/actix_web/rt/net/struct.Ready.html @@ -0,0 +1,91 @@ +Ready in actix_web::rt::net - Rust

Struct actix_web::rt::net::Ready

pub struct Ready(/* private fields */);
Expand description

Describes the readiness state of an I/O resources.

+

Ready tracks which operation an I/O resource is ready to perform.

+

Implementations§

§

impl Ready

pub const EMPTY: Ready = _

Returns the empty Ready set.

+

pub const READABLE: Ready = _

Returns a Ready representing readable readiness.

+

pub const WRITABLE: Ready = _

Returns a Ready representing writable readiness.

+

pub const READ_CLOSED: Ready = _

Returns a Ready representing read closed readiness.

+

pub const WRITE_CLOSED: Ready = _

Returns a Ready representing write closed readiness.

+

pub const PRIORITY: Ready = _

Available on Linux or Android only.

Returns a Ready representing priority readiness.

+

pub const ERROR: Ready = _

Returns a Ready representing error readiness.

+

pub const ALL: Ready = _

Available on Linux or Android only.

Returns a Ready representing readiness for all operations.

+

pub fn is_empty(self) -> bool

Returns true if Ready is the empty set.

+
§Examples
+
use tokio::io::Ready;
+
+assert!(Ready::EMPTY.is_empty());
+assert!(!Ready::READABLE.is_empty());
+

pub fn is_readable(self) -> bool

Returns true if the value includes readable.

+
§Examples
+
use tokio::io::Ready;
+
+assert!(!Ready::EMPTY.is_readable());
+assert!(Ready::READABLE.is_readable());
+assert!(Ready::READ_CLOSED.is_readable());
+assert!(!Ready::WRITABLE.is_readable());
+

pub fn is_writable(self) -> bool

Returns true if the value includes writable readiness.

+
§Examples
+
use tokio::io::Ready;
+
+assert!(!Ready::EMPTY.is_writable());
+assert!(!Ready::READABLE.is_writable());
+assert!(Ready::WRITABLE.is_writable());
+assert!(Ready::WRITE_CLOSED.is_writable());
+

pub fn is_read_closed(self) -> bool

Returns true if the value includes read-closed readiness.

+
§Examples
+
use tokio::io::Ready;
+
+assert!(!Ready::EMPTY.is_read_closed());
+assert!(!Ready::READABLE.is_read_closed());
+assert!(Ready::READ_CLOSED.is_read_closed());
+

pub fn is_write_closed(self) -> bool

Returns true if the value includes write-closed readiness.

+
§Examples
+
use tokio::io::Ready;
+
+assert!(!Ready::EMPTY.is_write_closed());
+assert!(!Ready::WRITABLE.is_write_closed());
+assert!(Ready::WRITE_CLOSED.is_write_closed());
+

pub fn is_priority(self) -> bool

Available on Linux or Android only.

Returns true if the value includes priority readiness.

+
§Examples
+
use tokio::io::Ready;
+
+assert!(!Ready::EMPTY.is_priority());
+assert!(!Ready::WRITABLE.is_priority());
+assert!(Ready::PRIORITY.is_priority());
+

pub fn is_error(self) -> bool

Returns true if the value includes error readiness.

+
§Examples
+
use tokio::io::Ready;
+
+assert!(!Ready::EMPTY.is_error());
+assert!(!Ready::WRITABLE.is_error());
+assert!(Ready::ERROR.is_error());
+

Trait Implementations§

§

impl BitAnd for Ready

§

type Output = Ready

The resulting type after applying the & operator.
§

fn bitand(self, other: Ready) -> Ready

Performs the & operation. Read more
§

impl BitOr for Ready

§

type Output = Ready

The resulting type after applying the | operator.
§

fn bitor(self, other: Ready) -> Ready

Performs the | operation. Read more
§

impl BitOrAssign for Ready

§

fn bitor_assign(&mut self, other: Ready)

Performs the |= operation. Read more
§

impl Clone for Ready

§

fn clone(&self) -> Ready

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Ready

§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Ord for Ready

§

fn cmp(&self, other: &Ready) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
§

impl PartialEq for Ready

§

fn eq(&self, other: &Ready) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialOrd for Ready

§

fn partial_cmp(&self, other: &Ready) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl Sub for Ready

§

type Output = Ready

The resulting type after applying the - operator.
§

fn sub(self, other: Ready) -> Ready

Performs the - operation. Read more
§

impl Copy for Ready

§

impl Eq for Ready

§

impl StructuralPartialEq for Ready

Auto Trait Implementations§

§

impl Freeze for Ready

§

impl RefUnwindSafe for Ready

§

impl Send for Ready

§

impl Sync for Ready

§

impl Unpin for Ready

§

impl UnwindSafe for Ready

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/net/struct.TcpListener.html b/actix_web/rt/net/struct.TcpListener.html new file mode 100644 index 000000000..5b6aab8b6 --- /dev/null +++ b/actix_web/rt/net/struct.TcpListener.html @@ -0,0 +1,204 @@ +TcpListener in actix_web::rt::net - Rust

Struct actix_web::rt::net::TcpListener

pub struct TcpListener { /* private fields */ }
Available on crate feature net only.
Expand description

A TCP socket server, listening for connections.

+

You can accept a new connection by using the accept +method.

+

A TcpListener can be turned into a Stream with TcpListenerStream.

+

§Errors

+

Note that accepting a connection can lead to various errors and not all +of them are necessarily fatal ‒ for example having too many open file +descriptors or the other side closing the connection while it waits in +an accept queue. These would terminate the stream if not handled in any +way.

+

§Examples

+

Using accept:

+ +
use tokio::net::TcpListener;
+
+use std::io;
+
+async fn process_socket<T>(socket: T) {
+    // do work with socket here
+}
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let listener = TcpListener::bind("127.0.0.1:8080").await?;
+
+    loop {
+        let (socket, _) = listener.accept().await?;
+        process_socket(socket).await;
+    }
+}
+

Implementations§

§

impl TcpListener

pub async fn bind<A>(addr: A) -> Result<TcpListener, Error>
where + A: ToSocketAddrs,

Available on non-WASI only.

Creates a new TcpListener, which will be bound to the specified address.

+

The returned listener is ready for accepting connections.

+

Binding with a port number of 0 will request that the OS assigns a port +to this listener. The port allocated can be queried via the local_addr +method.

+

The address type can be any implementor of the ToSocketAddrs trait. +If addr yields multiple addresses, bind will be attempted with each of +the addresses until one succeeds and returns the listener. If none of +the addresses succeed in creating a listener, the error returned from +the last attempt (the last address) is returned.

+

This function sets the SO_REUSEADDR option on the socket.

+

To configure the socket before binding, you can use the TcpSocket +type.

+
§Examples
+
use tokio::net::TcpListener;
+
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let listener = TcpListener::bind("127.0.0.1:2345").await?;
+
+    // use the listener
+
+    Ok(())
+}
+

pub async fn accept(&self) -> Result<(TcpStream, SocketAddr), Error>

Accepts a new incoming connection from this listener.

+

This function will yield once a new TCP connection is established. When +established, the corresponding TcpStream and the remote peer’s +address will be returned.

+
§Cancel safety
+

This method is cancel safe. If the method is used as the event in a +tokio::select! statement and some other branch +completes first, then it is guaranteed that no new connections were +accepted by this method.

+
§Examples
+
use tokio::net::TcpListener;
+
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let listener = TcpListener::bind("127.0.0.1:8080").await?;
+
+    match listener.accept().await {
+        Ok((_socket, addr)) => println!("new client: {:?}", addr),
+        Err(e) => println!("couldn't get client: {:?}", e),
+    }
+
+    Ok(())
+}
+

pub fn poll_accept( + &self, + cx: &mut Context<'_> +) -> Poll<Result<(TcpStream, SocketAddr), Error>>

Polls to accept a new incoming connection to this listener.

+

If there is no connection to accept, Poll::Pending is returned and the +current task will be notified by a waker. Note that on multiple calls +to poll_accept, only the Waker from the Context passed to the most +recent call is scheduled to receive a wakeup.

+

pub fn from_std(listener: TcpListener) -> Result<TcpListener, Error>

Creates new TcpListener from a std::net::TcpListener.

+

This function is intended to be used to wrap a TCP listener from the +standard library in the Tokio equivalent.

+

This API is typically paired with the socket2 crate and the Socket +type to build up and customize a listener before it’s shipped off to the +backing event loop. This allows configuration of options like +SO_REUSEPORT, binding to multiple addresses, etc.

+
§Notes
+

The caller is responsible for ensuring that the listener is in +non-blocking mode. Otherwise all I/O operations on the listener +will block the thread, which will cause unexpected behavior. +Non-blocking mode can be set using set_nonblocking.

+
§Examples
+
use std::error::Error;
+use tokio::net::TcpListener;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    let std_listener = std::net::TcpListener::bind("127.0.0.1:0")?;
+    std_listener.set_nonblocking(true)?;
+    let listener = TcpListener::from_std(std_listener)?;
+    Ok(())
+}
+
§Panics
+

This function panics if it is not called from within a runtime with +IO enabled.

+

The runtime is usually set implicitly when this function is called +from a future driven by a tokio runtime, otherwise runtime can be set +explicitly with Runtime::enter function.

+

pub fn into_std(self) -> Result<TcpListener, Error>

Turns a tokio::net::TcpListener into a std::net::TcpListener.

+

The returned std::net::TcpListener will have nonblocking mode set as +true. Use set_nonblocking to change the blocking mode if needed.

+
§Examples
+
use std::error::Error;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    let tokio_listener = tokio::net::TcpListener::bind("127.0.0.1:0").await?;
+    let std_listener = tokio_listener.into_std()?;
+    std_listener.set_nonblocking(false)?;
+    Ok(())
+}
+

pub fn local_addr(&self) -> Result<SocketAddr, Error>

Returns the local address that this listener is bound to.

+

This can be useful, for example, when binding to port 0 to figure out +which port was actually bound.

+
§Examples
+
use tokio::net::TcpListener;
+
+use std::io;
+use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let listener = TcpListener::bind("127.0.0.1:8080").await?;
+
+    assert_eq!(listener.local_addr()?,
+               SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)));
+
+    Ok(())
+}
+

pub fn ttl(&self) -> Result<u32, Error>

Gets the value of the IP_TTL option for this socket.

+

For more information about this option, see set_ttl.

+
§Examples
+
use tokio::net::TcpListener;
+
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+   let listener = TcpListener::bind("127.0.0.1:0").await?;
+
+   listener.set_ttl(100).expect("could not set TTL");
+   assert_eq!(listener.ttl()?, 100);
+
+   Ok(())
+}
+

pub fn set_ttl(&self, ttl: u32) -> Result<(), Error>

Sets the value for the IP_TTL option on this socket.

+

This value sets the time-to-live field that is used in every packet sent +from this socket.

+
§Examples
+
use tokio::net::TcpListener;
+
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let listener = TcpListener::bind("127.0.0.1:0").await?;
+
+    listener.set_ttl(100).expect("could not set TTL");
+
+    Ok(())
+}
+

Trait Implementations§

§

impl AsFd for TcpListener

§

fn as_fd(&self) -> BorrowedFd<'_>

Borrows the file descriptor. Read more
§

impl AsRawFd for TcpListener

§

fn as_raw_fd(&self) -> i32

Extracts the raw file descriptor. Read more
§

impl Debug for TcpListener

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl TryFrom<TcpListener> for TcpListener

§

fn try_from( + stream: TcpListener +) -> Result<TcpListener, <TcpListener as TryFrom<TcpListener>>::Error>

Consumes stream, returning the tokio I/O object.

+

This is equivalent to +TcpListener::from_std(stream).

+
§

type Error = Error

The type returned in the event of a conversion error.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/net/struct.TcpSocket.html b/actix_web/rt/net/struct.TcpSocket.html new file mode 100644 index 000000000..770bb1961 --- /dev/null +++ b/actix_web/rt/net/struct.TcpSocket.html @@ -0,0 +1,400 @@ +TcpSocket in actix_web::rt::net - Rust

Struct actix_web::rt::net::TcpSocket

pub struct TcpSocket { /* private fields */ }
Available on crate feature net only.
Expand description

A TCP socket that has not yet been converted to a TcpStream or +TcpListener.

+

TcpSocket wraps an operating system socket and enables the caller to +configure the socket before establishing a TCP connection or accepting +inbound connections. The caller is able to set socket option and explicitly +bind the socket with a socket address.

+

The underlying socket is closed when the TcpSocket value is dropped.

+

TcpSocket should only be used directly if the default configuration used +by TcpStream::connect and TcpListener::bind does not meet the required +use case.

+

Calling TcpStream::connect("127.0.0.1:8080") is equivalent to:

+ +
use tokio::net::TcpSocket;
+
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let addr = "127.0.0.1:8080".parse().unwrap();
+
+    let socket = TcpSocket::new_v4()?;
+    let stream = socket.connect(addr).await?;
+
+    Ok(())
+}
+

Calling TcpListener::bind("127.0.0.1:8080") is equivalent to:

+ +
use tokio::net::TcpSocket;
+
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let addr = "127.0.0.1:8080".parse().unwrap();
+
+    let socket = TcpSocket::new_v4()?;
+    // On platforms with Berkeley-derived sockets, this allows to quickly
+    // rebind a socket, without needing to wait for the OS to clean up the
+    // previous one.
+    //
+    // On Windows, this allows rebinding sockets which are actively in use,
+    // which allows “socket hijacking”, so we explicitly don't set it here.
+    // https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse
+    socket.set_reuseaddr(true)?;
+    socket.bind(addr)?;
+
+    let listener = socket.listen(1024)?;
+
+    Ok(())
+}
+

Setting socket options not explicitly provided by TcpSocket may be done by +accessing the RawFd/RawSocket using AsRawFd/AsRawSocket and +setting the option with a crate like socket2.

+

Implementations§

§

impl TcpSocket

pub fn new_v4() -> Result<TcpSocket, Error>

Creates a new socket configured for IPv4.

+

Calls socket(2) with AF_INET and SOCK_STREAM.

+
§Returns
+

On success, the newly created TcpSocket is returned. If an error is +encountered, it is returned instead.

+
§Examples
+

Create a new IPv4 socket and start listening.

+ +
use tokio::net::TcpSocket;
+
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let addr = "127.0.0.1:8080".parse().unwrap();
+    let socket = TcpSocket::new_v4()?;
+    socket.bind(addr)?;
+
+    let listener = socket.listen(128)?;
+    Ok(())
+}
+

pub fn new_v6() -> Result<TcpSocket, Error>

Creates a new socket configured for IPv6.

+

Calls socket(2) with AF_INET6 and SOCK_STREAM.

+
§Returns
+

On success, the newly created TcpSocket is returned. If an error is +encountered, it is returned instead.

+
§Examples
+

Create a new IPv6 socket and start listening.

+ +
use tokio::net::TcpSocket;
+
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let addr = "[::1]:8080".parse().unwrap();
+    let socket = TcpSocket::new_v6()?;
+    socket.bind(addr)?;
+
+    let listener = socket.listen(128)?;
+    Ok(())
+}
+

pub fn set_keepalive(&self, keepalive: bool) -> Result<(), Error>

Sets value for the SO_KEEPALIVE option on this socket.

+

pub fn keepalive(&self) -> Result<bool, Error>

Gets the value of the SO_KEEPALIVE option on this socket.

+

pub fn set_reuseaddr(&self, reuseaddr: bool) -> Result<(), Error>

Allows the socket to bind to an in-use address.

+

Behavior is platform specific. Refer to the target platform’s +documentation for more details.

+
§Examples
+
use tokio::net::TcpSocket;
+
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let addr = "127.0.0.1:8080".parse().unwrap();
+
+    let socket = TcpSocket::new_v4()?;
+    socket.set_reuseaddr(true)?;
+    socket.bind(addr)?;
+
+    let listener = socket.listen(1024)?;
+
+    Ok(())
+}
+

pub fn reuseaddr(&self) -> Result<bool, Error>

Retrieves the value set for SO_REUSEADDR on this socket.

+
§Examples
+
use tokio::net::TcpSocket;
+
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let addr = "127.0.0.1:8080".parse().unwrap();
+
+    let socket = TcpSocket::new_v4()?;
+    socket.set_reuseaddr(true)?;
+    assert!(socket.reuseaddr().unwrap());
+    socket.bind(addr)?;
+
+    let listener = socket.listen(1024)?;
+    Ok(())
+}
+

pub fn set_reuseport(&self, reuseport: bool) -> Result<(), Error>

Available on Unix and non-Solaris and non-illumos only.

Allows the socket to bind to an in-use port. Only available for unix systems +(excluding Solaris & Illumos).

+

Behavior is platform specific. Refer to the target platform’s +documentation for more details.

+
§Examples
+
use tokio::net::TcpSocket;
+
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let addr = "127.0.0.1:8080".parse().unwrap();
+
+    let socket = TcpSocket::new_v4()?;
+    socket.set_reuseport(true)?;
+    socket.bind(addr)?;
+
+    let listener = socket.listen(1024)?;
+    Ok(())
+}
+

pub fn reuseport(&self) -> Result<bool, Error>

Available on Unix and non-Solaris and non-illumos only.

Allows the socket to bind to an in-use port. Only available for unix systems +(excluding Solaris & Illumos).

+

Behavior is platform specific. Refer to the target platform’s +documentation for more details.

+
§Examples
+
use tokio::net::TcpSocket;
+
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let addr = "127.0.0.1:8080".parse().unwrap();
+
+    let socket = TcpSocket::new_v4()?;
+    socket.set_reuseport(true)?;
+    assert!(socket.reuseport().unwrap());
+    socket.bind(addr)?;
+
+    let listener = socket.listen(1024)?;
+    Ok(())
+}
+

pub fn set_send_buffer_size(&self, size: u32) -> Result<(), Error>

Sets the size of the TCP send buffer on this socket.

+

On most operating systems, this sets the SO_SNDBUF socket option.

+

pub fn send_buffer_size(&self) -> Result<u32, Error>

Returns the size of the TCP send buffer for this socket.

+

On most operating systems, this is the value of the SO_SNDBUF socket +option.

+

Note that if set_send_buffer_size has been called on this socket +previously, the value returned by this function may not be the same as +the argument provided to set_send_buffer_size. This is for the +following reasons:

+
    +
  • Most operating systems have minimum and maximum allowed sizes for the +send buffer, and will clamp the provided value if it is below the +minimum or above the maximum. The minimum and maximum buffer sizes are +OS-dependent.
  • +
  • Linux will double the buffer size to account for internal bookkeeping +data, and returns the doubled value from getsockopt(2). As per man 7 socket: +
    +

    Sets or gets the maximum socket send buffer in bytes. The +kernel doubles this value (to allow space for bookkeeping +overhead) when it is set using setsockopt(2), and this doubled +value is returned by getsockopt(2).

    +
    +
  • +
+

pub fn set_recv_buffer_size(&self, size: u32) -> Result<(), Error>

Sets the size of the TCP receive buffer on this socket.

+

On most operating systems, this sets the SO_RCVBUF socket option.

+

pub fn recv_buffer_size(&self) -> Result<u32, Error>

Returns the size of the TCP receive buffer for this socket.

+

On most operating systems, this is the value of the SO_RCVBUF socket +option.

+

Note that if set_recv_buffer_size has been called on this socket +previously, the value returned by this function may not be the same as +the argument provided to set_send_buffer_size. This is for the +following reasons:

+
    +
  • Most operating systems have minimum and maximum allowed sizes for the +receive buffer, and will clamp the provided value if it is below the +minimum or above the maximum. The minimum and maximum buffer sizes are +OS-dependent.
  • +
  • Linux will double the buffer size to account for internal bookkeeping +data, and returns the doubled value from getsockopt(2). As per man 7 socket: +
    +

    Sets or gets the maximum socket send buffer in bytes. The +kernel doubles this value (to allow space for bookkeeping +overhead) when it is set using setsockopt(2), and this doubled +value is returned by getsockopt(2).

    +
    +
  • +
+

pub fn set_linger(&self, dur: Option<Duration>) -> Result<(), Error>

Sets the linger duration of this socket by setting the SO_LINGER option.

+

This option controls the action taken when a stream has unsent messages and the stream is +closed. If SO_LINGER is set, the system shall block the process until it can transmit the +data or until the time expires.

+

If SO_LINGER is not specified, and the socket is closed, the system handles the call in a +way that allows the process to continue as quickly as possible.

+

pub fn linger(&self) -> Result<Option<Duration>, Error>

Reads the linger duration for this socket by getting the SO_LINGER +option.

+

For more information about this option, see set_linger.

+

pub fn set_nodelay(&self, nodelay: bool) -> Result<(), Error>

Sets the value of the TCP_NODELAY option on this socket.

+

If set, this option disables the Nagle algorithm. This means that segments are always +sent as soon as possible, even if there is only a small amount of data. When not set, +data is buffered until there is a sufficient amount to send out, thereby avoiding +the frequent sending of small packets.

+
§Examples
+
use tokio::net::TcpSocket;
+
+let socket = TcpSocket::new_v4()?;
+
+println!("{:?}", socket.nodelay()?);
+

pub fn nodelay(&self) -> Result<bool, Error>

Gets the value of the TCP_NODELAY option on this socket.

+

For more information about this option, see set_nodelay.

+
§Examples
+
use tokio::net::TcpSocket;
+
+let stream = TcpSocket::new_v4()?;
+
+stream.set_nodelay(true)?;
+

pub fn tos(&self) -> Result<u32, Error>

Available on neither Fuchsia nor Redox nor Solaris nor illumos.

Gets the value of the IP_TOS option for this socket.

+

For more information about this option, see set_tos.

+

NOTE: On Windows, IP_TOS is only supported on Windows 8+ or +Windows Server 2012+.

+

pub fn set_tos(&self, tos: u32) -> Result<(), Error>

Available on neither Fuchsia nor Redox nor Solaris nor illumos.

Sets the value for the IP_TOS option on this socket.

+

This value sets the type-of-service field that is used in every packet +sent from this socket.

+

NOTE: On Windows, IP_TOS is only supported on Windows 8+ or +Windows Server 2012+.

+

pub fn device(&self) -> Result<Option<Vec<u8>>, Error>

Available on Android or Fuchsia or Linux only.

Gets the value for the SO_BINDTODEVICE option on this socket

+

This value gets the socket binded device’s interface name.

+

pub fn bind_device(&self, interface: Option<&[u8]>) -> Result<(), Error>

Available on Android or Fuchsia or Linux only.

Sets the value for the SO_BINDTODEVICE option on this socket

+

If a socket is bound to an interface, only packets received from that +particular interface are processed by the socket. Note that this only +works for some socket types, particularly AF_INET sockets.

+

If interface is None or an empty string it removes the binding.

+

pub fn local_addr(&self) -> Result<SocketAddr, Error>

Gets the local address of this socket.

+

Will fail on windows if called before bind.

+
§Examples
+
use tokio::net::TcpSocket;
+
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let addr = "127.0.0.1:8080".parse().unwrap();
+
+    let socket = TcpSocket::new_v4()?;
+    socket.bind(addr)?;
+    assert_eq!(socket.local_addr().unwrap().to_string(), "127.0.0.1:8080");
+    let listener = socket.listen(1024)?;
+    Ok(())
+}
+

pub fn take_error(&self) -> Result<Option<Error>, Error>

Returns the value of the SO_ERROR option.

+

pub fn bind(&self, addr: SocketAddr) -> Result<(), Error>

Binds the socket to the given address.

+

This calls the bind(2) operating-system function. Behavior is +platform specific. Refer to the target platform’s documentation for more +details.

+
§Examples
+

Bind a socket before listening.

+ +
use tokio::net::TcpSocket;
+
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let addr = "127.0.0.1:8080".parse().unwrap();
+
+    let socket = TcpSocket::new_v4()?;
+    socket.bind(addr)?;
+
+    let listener = socket.listen(1024)?;
+
+    Ok(())
+}
+

pub async fn connect(self, addr: SocketAddr) -> Result<TcpStream, Error>

Establishes a TCP connection with a peer at the specified socket address.

+

The TcpSocket is consumed. Once the connection is established, a +connected TcpStream is returned. If the connection fails, the +encountered error is returned.

+

This calls the connect(2) operating-system function. Behavior is +platform specific. Refer to the target platform’s documentation for more +details.

+
§Examples
+

Connecting to a peer.

+ +
use tokio::net::TcpSocket;
+
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let addr = "127.0.0.1:8080".parse().unwrap();
+
+    let socket = TcpSocket::new_v4()?;
+    let stream = socket.connect(addr).await?;
+
+    Ok(())
+}
+

pub fn listen(self, backlog: u32) -> Result<TcpListener, Error>

Converts the socket into a TcpListener.

+

backlog defines the maximum number of pending connections are queued +by the operating system at any given time. Connection are removed from +the queue with TcpListener::accept. When the queue is full, the +operating-system will start rejecting connections.

+

This calls the listen(2) operating-system function, marking the socket +as a passive socket. Behavior is platform specific. Refer to the target +platform’s documentation for more details.

+
§Examples
+

Create a TcpListener.

+ +
use tokio::net::TcpSocket;
+
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let addr = "127.0.0.1:8080".parse().unwrap();
+
+    let socket = TcpSocket::new_v4()?;
+    socket.bind(addr)?;
+
+    let listener = socket.listen(1024)?;
+
+    Ok(())
+}
+

pub fn from_std_stream(std_stream: TcpStream) -> TcpSocket

Converts a std::net::TcpStream into a TcpSocket. The provided +socket must not have been connected prior to calling this function. This +function is typically used together with crates such as socket2 to +configure socket options that are not available on TcpSocket.

+
§Notes
+

The caller is responsible for ensuring that the socket is in +non-blocking mode. Otherwise all I/O operations on the socket +will block the thread, which will cause unexpected behavior. +Non-blocking mode can be set using set_nonblocking.

+
§Examples
+
use tokio::net::TcpSocket;
+use socket2::{Domain, Socket, Type};
+
+#[tokio::main]
+async fn main() -> std::io::Result<()> {
+    let socket2_socket = Socket::new(Domain::IPV4, Type::STREAM, None)?;
+    socket2_socket.set_nonblocking(true)?;
+
+    let socket = TcpSocket::from_std_stream(socket2_socket.into());
+
+    Ok(())
+}
+

Trait Implementations§

§

impl AsFd for TcpSocket

Available on docsrs or Unix only.
§

fn as_fd(&self) -> BorrowedFd<'_>

Borrows the file descriptor. Read more
§

impl AsRawFd for TcpSocket

Available on docsrs or Unix only.
§

fn as_raw_fd(&self) -> i32

Extracts the raw file descriptor. Read more
§

impl Debug for TcpSocket

§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl FromRawFd for TcpSocket

Available on docsrs or Unix only.
§

unsafe fn from_raw_fd(fd: i32) -> TcpSocket

Converts a RawFd to a TcpSocket.

+
§Notes
+

The caller is responsible for ensuring that the socket is in +non-blocking mode.

+
§

impl IntoRawFd for TcpSocket

Available on docsrs or Unix only.
§

fn into_raw_fd(self) -> i32

Consumes this object, returning the raw underlying file descriptor. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/net/struct.TcpStream.html b/actix_web/rt/net/struct.TcpStream.html new file mode 100644 index 000000000..8f39bdd90 --- /dev/null +++ b/actix_web/rt/net/struct.TcpStream.html @@ -0,0 +1,891 @@ +TcpStream in actix_web::rt::net - Rust

Struct actix_web::rt::net::TcpStream

pub struct TcpStream { /* private fields */ }
Available on crate feature net only.
Expand description

A TCP stream between a local and a remote socket.

+

A TCP stream can either be created by connecting to an endpoint, via the +connect method, or by accepting a connection from a listener. A +TCP stream can also be created via the TcpSocket type.

+

Reading and writing to a TcpStream is usually done using the +convenience methods found on the AsyncReadExt and AsyncWriteExt +traits.

+

§Examples

+
use tokio::net::TcpStream;
+use tokio::io::AsyncWriteExt;
+use std::error::Error;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    // Connect to a peer
+    let mut stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+    // Write some data.
+    stream.write_all(b"hello world!").await?;
+
+    Ok(())
+}
+

The write_all method is defined on the AsyncWriteExt trait.

+

To shut down the stream in the write direction, you can call the +shutdown() method. This will cause the other peer to receive a read of +length 0, indicating that no more data will be sent. This only closes +the stream in one direction.

+

Implementations§

§

impl TcpStream

pub async fn connect<A>(addr: A) -> Result<TcpStream, Error>
where + A: ToSocketAddrs,

Available on non-WASI only.

Opens a TCP connection to a remote host.

+

addr is an address of the remote host. Anything which implements the +ToSocketAddrs trait can be supplied as the address. If addr +yields multiple addresses, connect will be attempted with each of the +addresses until a connection is successful. If none of the addresses +result in a successful connection, the error returned from the last +connection attempt (the last address) is returned.

+

To configure the socket before connecting, you can use the TcpSocket +type.

+
§Examples
+
use tokio::net::TcpStream;
+use tokio::io::AsyncWriteExt;
+use std::error::Error;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    // Connect to a peer
+    let mut stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+    // Write some data.
+    stream.write_all(b"hello world!").await?;
+
+    Ok(())
+}
+

The write_all method is defined on the AsyncWriteExt trait.

+

pub fn from_std(stream: TcpStream) -> Result<TcpStream, Error>

Creates new TcpStream from a std::net::TcpStream.

+

This function is intended to be used to wrap a TCP stream from the +standard library in the Tokio equivalent.

+
§Notes
+

The caller is responsible for ensuring that the stream is in +non-blocking mode. Otherwise all I/O operations on the stream +will block the thread, which will cause unexpected behavior. +Non-blocking mode can be set using set_nonblocking.

+
§Examples
+
use std::error::Error;
+use tokio::net::TcpStream;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    let std_stream = std::net::TcpStream::connect("127.0.0.1:34254")?;
+    std_stream.set_nonblocking(true)?;
+    let stream = TcpStream::from_std(std_stream)?;
+    Ok(())
+}
+
§Panics
+

This function panics if it is not called from within a runtime with +IO enabled.

+

The runtime is usually set implicitly when this function is called +from a future driven by a tokio runtime, otherwise runtime can be set +explicitly with Runtime::enter function.

+

pub fn into_std(self) -> Result<TcpStream, Error>

Turns a tokio::net::TcpStream into a std::net::TcpStream.

+

The returned std::net::TcpStream will have nonblocking mode set as true. +Use set_nonblocking to change the blocking mode if needed.

+
§Examples
+
use std::error::Error;
+use std::io::Read;
+use tokio::net::TcpListener;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    let mut data = [0u8; 12];
+    let listener = TcpListener::bind("127.0.0.1:34254").await?;
+    let (tokio_tcp_stream, _) = listener.accept().await?;
+    let mut std_tcp_stream = tokio_tcp_stream.into_std()?;
+    std_tcp_stream.set_nonblocking(false)?;
+    std_tcp_stream.read_exact(&mut data)?;
+    Ok(())
+}
+

pub fn local_addr(&self) -> Result<SocketAddr, Error>

Returns the local address that this stream is bound to.

+
§Examples
+
use tokio::net::TcpStream;
+
+let stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+println!("{:?}", stream.local_addr()?);
+

pub fn take_error(&self) -> Result<Option<Error>, Error>

Returns the value of the SO_ERROR option.

+

pub fn peer_addr(&self) -> Result<SocketAddr, Error>

Returns the remote address that this stream is connected to.

+
§Examples
+
use tokio::net::TcpStream;
+
+let stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+println!("{:?}", stream.peer_addr()?);
+

pub fn poll_peek( + &self, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_> +) -> Poll<Result<usize, Error>>

Attempts to receive data on the socket, without removing that data from +the queue, registering the current task for wakeup if data is not yet +available.

+

Note that on multiple calls to poll_peek, poll_read or +poll_read_ready, only the Waker from the Context passed to the +most recent call is scheduled to receive a wakeup. (However, +poll_write retains a second, independent waker.)

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if data is not yet available.
  • +
  • Poll::Ready(Ok(n)) if data is available. n is the number of bytes peeked.
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+
§Examples
+
use tokio::io::{self, ReadBuf};
+use tokio::net::TcpStream;
+
+use futures::future::poll_fn;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let stream = TcpStream::connect("127.0.0.1:8000").await?;
+    let mut buf = [0; 10];
+    let mut buf = ReadBuf::new(&mut buf);
+
+    poll_fn(|cx| {
+        stream.poll_peek(cx, &mut buf)
+    }).await?;
+
+    Ok(())
+}
+

pub async fn ready(&self, interest: Interest) -> Result<Ready, Error>

Waits for any of the requested ready states.

+

This function is usually paired with try_read() or try_write(). It +can be used to concurrently read / write to the same socket on a single +task without splitting the socket.

+

The function may complete without the socket being ready. This is a +false-positive and attempting an operation will return with +io::ErrorKind::WouldBlock. The function can also return with an empty +Ready set, so you should always check the returned value and possibly +wait again if the requested states are not set.

+
§Cancel safety
+

This method is cancel safe. Once a readiness event occurs, the method +will continue to return immediately until the readiness event is +consumed by an attempt to read or write that fails with WouldBlock or +Poll::Pending.

+
§Examples
+

Concurrently read and write to the stream on the same task without +splitting.

+ +
use tokio::io::Interest;
+use tokio::net::TcpStream;
+use std::error::Error;
+use std::io;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    let stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+    loop {
+        let ready = stream.ready(Interest::READABLE | Interest::WRITABLE).await?;
+
+        if ready.is_readable() {
+            let mut data = vec![0; 1024];
+            // Try to read data, this may still fail with `WouldBlock`
+            // if the readiness event is a false positive.
+            match stream.try_read(&mut data) {
+                Ok(n) => {
+                    println!("read {} bytes", n);
+                }
+                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                    continue;
+                }
+                Err(e) => {
+                    return Err(e.into());
+                }
+            }
+
+        }
+
+        if ready.is_writable() {
+            // Try to write data, this may still fail with `WouldBlock`
+            // if the readiness event is a false positive.
+            match stream.try_write(b"hello world") {
+                Ok(n) => {
+                    println!("write {} bytes", n);
+                }
+                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                    continue
+                }
+                Err(e) => {
+                    return Err(e.into());
+                }
+            }
+        }
+    }
+}
+

pub async fn readable(&self) -> Result<(), Error>

Waits for the socket to become readable.

+

This function is equivalent to ready(Interest::READABLE) and is usually +paired with try_read().

+
§Cancel safety
+

This method is cancel safe. Once a readiness event occurs, the method +will continue to return immediately until the readiness event is +consumed by an attempt to read that fails with WouldBlock or +Poll::Pending.

+
§Examples
+
use tokio::net::TcpStream;
+use std::error::Error;
+use std::io;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    // Connect to a peer
+    let stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+    let mut msg = vec![0; 1024];
+
+    loop {
+        // Wait for the socket to be readable
+        stream.readable().await?;
+
+        // Try to read data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match stream.try_read(&mut msg) {
+            Ok(n) => {
+                msg.truncate(n);
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e.into());
+            }
+        }
+    }
+
+    println!("GOT = {:?}", msg);
+    Ok(())
+}
+

pub fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Error>>

Polls for read readiness.

+

If the tcp stream is not currently ready for reading, this method will +store a clone of the Waker from the provided Context. When the tcp +stream becomes ready for reading, Waker::wake will be called on the +waker.

+

Note that on multiple calls to poll_read_ready, poll_read or +poll_peek, only the Waker from the Context passed to the most +recent call is scheduled to receive a wakeup. (However, +poll_write_ready retains a second, independent waker.)

+

This function is intended for cases where creating and pinning a future +via readable is not feasible. Where possible, using readable is +preferred, as this supports polling from multiple tasks at once.

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if the tcp stream is not ready for reading.
  • +
  • Poll::Ready(Ok(())) if the tcp stream is ready for reading.
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+

pub fn try_read(&self, buf: &mut [u8]) -> Result<usize, Error>

Tries to read data from the stream into the provided buffer, returning how +many bytes were read.

+

Receives any pending data from the socket but does not wait for new data +to arrive. On success, returns the number of bytes read. Because +try_read() is non-blocking, the buffer does not have to be stored by +the async task and can exist entirely on the stack.

+

Usually, readable() or ready() is used with this function.

+
§Return
+

If data is successfully read, Ok(n) is returned, where n is the +number of bytes read. If n is 0, then it can indicate one of two scenarios:

+
    +
  1. The stream’s read half is closed and will no longer yield data.
  2. +
  3. The specified buffer was 0 bytes in length.
  4. +
+

If the stream is not ready to read data, +Err(io::ErrorKind::WouldBlock) is returned.

+
§Examples
+
use tokio::net::TcpStream;
+use std::error::Error;
+use std::io;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    // Connect to a peer
+    let stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+    loop {
+        // Wait for the socket to be readable
+        stream.readable().await?;
+
+        // Creating the buffer **after** the `await` prevents it from
+        // being stored in the async task.
+        let mut buf = [0; 4096];
+
+        // Try to read data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match stream.try_read(&mut buf) {
+            Ok(0) => break,
+            Ok(n) => {
+                println!("read {} bytes", n);
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e.into());
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn try_read_vectored( + &self, + bufs: &mut [IoSliceMut<'_>] +) -> Result<usize, Error>

Tries to read data from the stream into the provided buffers, returning +how many bytes were read.

+

Data is copied to fill each buffer in order, with the final buffer +written to possibly being only partially filled. This method behaves +equivalently to a single call to try_read() with concatenated +buffers.

+

Receives any pending data from the socket but does not wait for new data +to arrive. On success, returns the number of bytes read. Because +try_read_vectored() is non-blocking, the buffer does not have to be +stored by the async task and can exist entirely on the stack.

+

Usually, readable() or ready() is used with this function.

+
§Return
+

If data is successfully read, Ok(n) is returned, where n is the +number of bytes read. Ok(0) indicates the stream’s read half is closed +and will no longer yield data. If the stream is not ready to read data +Err(io::ErrorKind::WouldBlock) is returned.

+
§Examples
+
use tokio::net::TcpStream;
+use std::error::Error;
+use std::io::{self, IoSliceMut};
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    // Connect to a peer
+    let stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+    loop {
+        // Wait for the socket to be readable
+        stream.readable().await?;
+
+        // Creating the buffer **after** the `await` prevents it from
+        // being stored in the async task.
+        let mut buf_a = [0; 512];
+        let mut buf_b = [0; 1024];
+        let mut bufs = [
+            IoSliceMut::new(&mut buf_a),
+            IoSliceMut::new(&mut buf_b),
+        ];
+
+        // Try to read data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match stream.try_read_vectored(&mut bufs) {
+            Ok(0) => break,
+            Ok(n) => {
+                println!("read {} bytes", n);
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e.into());
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn try_read_buf<B>(&self, buf: &mut B) -> Result<usize, Error>
where + B: BufMut,

Available on crate feature io-util only.

Tries to read data from the stream into the provided buffer, advancing the +buffer’s internal cursor, returning how many bytes were read.

+

Receives any pending data from the socket but does not wait for new data +to arrive. On success, returns the number of bytes read. Because +try_read_buf() is non-blocking, the buffer does not have to be stored by +the async task and can exist entirely on the stack.

+

Usually, readable() or ready() is used with this function.

+
§Return
+

If data is successfully read, Ok(n) is returned, where n is the +number of bytes read. Ok(0) indicates the stream’s read half is closed +and will no longer yield data. If the stream is not ready to read data +Err(io::ErrorKind::WouldBlock) is returned.

+
§Examples
+
use tokio::net::TcpStream;
+use std::error::Error;
+use std::io;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    // Connect to a peer
+    let stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+    loop {
+        // Wait for the socket to be readable
+        stream.readable().await?;
+
+        let mut buf = Vec::with_capacity(4096);
+
+        // Try to read data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match stream.try_read_buf(&mut buf) {
+            Ok(0) => break,
+            Ok(n) => {
+                println!("read {} bytes", n);
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e.into());
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub async fn writable(&self) -> Result<(), Error>

Waits for the socket to become writable.

+

This function is equivalent to ready(Interest::WRITABLE) and is usually +paired with try_write().

+
§Cancel safety
+

This method is cancel safe. Once a readiness event occurs, the method +will continue to return immediately until the readiness event is +consumed by an attempt to write that fails with WouldBlock or +Poll::Pending.

+
§Examples
+
use tokio::net::TcpStream;
+use std::error::Error;
+use std::io;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    // Connect to a peer
+    let stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+    loop {
+        // Wait for the socket to be writable
+        stream.writable().await?;
+
+        // Try to write data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match stream.try_write(b"hello world") {
+            Ok(n) => {
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e.into());
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Error>>

Polls for write readiness.

+

If the tcp stream is not currently ready for writing, this method will +store a clone of the Waker from the provided Context. When the tcp +stream becomes ready for writing, Waker::wake will be called on the +waker.

+

Note that on multiple calls to poll_write_ready or poll_write, only +the Waker from the Context passed to the most recent call is +scheduled to receive a wakeup. (However, poll_read_ready retains a +second, independent waker.)

+

This function is intended for cases where creating and pinning a future +via writable is not feasible. Where possible, using writable is +preferred, as this supports polling from multiple tasks at once.

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if the tcp stream is not ready for writing.
  • +
  • Poll::Ready(Ok(())) if the tcp stream is ready for writing.
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+

pub fn try_write(&self, buf: &[u8]) -> Result<usize, Error>

Try to write a buffer to the stream, returning how many bytes were +written.

+

The function will attempt to write the entire contents of buf, but +only part of the buffer may be written.

+

This function is usually paired with writable().

+
§Return
+

If data is successfully written, Ok(n) is returned, where n is the +number of bytes written. If the stream is not ready to write data, +Err(io::ErrorKind::WouldBlock) is returned.

+
§Examples
+
use tokio::net::TcpStream;
+use std::error::Error;
+use std::io;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    // Connect to a peer
+    let stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+    loop {
+        // Wait for the socket to be writable
+        stream.writable().await?;
+
+        // Try to write data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match stream.try_write(b"hello world") {
+            Ok(n) => {
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e.into());
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn try_write_vectored(&self, bufs: &[IoSlice<'_>]) -> Result<usize, Error>

Tries to write several buffers to the stream, returning how many bytes +were written.

+

Data is written from each buffer in order, with the final buffer read +from possible being only partially consumed. This method behaves +equivalently to a single call to try_write() with concatenated +buffers.

+

This function is usually paired with writable().

+
§Return
+

If data is successfully written, Ok(n) is returned, where n is the +number of bytes written. If the stream is not ready to write data, +Err(io::ErrorKind::WouldBlock) is returned.

+
§Examples
+
use tokio::net::TcpStream;
+use std::error::Error;
+use std::io;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    // Connect to a peer
+    let stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+    let bufs = [io::IoSlice::new(b"hello "), io::IoSlice::new(b"world")];
+
+    loop {
+        // Wait for the socket to be writable
+        stream.writable().await?;
+
+        // Try to write data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match stream.try_write_vectored(&bufs) {
+            Ok(n) => {
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e.into());
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn try_io<R>( + &self, + interest: Interest, + f: impl FnOnce() -> Result<R, Error> +) -> Result<R, Error>

Tries to read or write from the socket using a user-provided IO operation.

+

If the socket is ready, the provided closure is called. The closure +should attempt to perform IO operation on the socket by manually +calling the appropriate syscall. If the operation fails because the +socket is not actually ready, then the closure should return a +WouldBlock error and the readiness flag is cleared. The return value +of the closure is then returned by try_io.

+

If the socket is not ready, then the closure is not called +and a WouldBlock error is returned.

+

The closure should only return a WouldBlock error if it has performed +an IO operation on the socket that failed due to the socket not being +ready. Returning a WouldBlock error in any other situation will +incorrectly clear the readiness flag, which can cause the socket to +behave incorrectly.

+

The closure should not perform the IO operation using any of the methods +defined on the Tokio TcpStream type, as this will mess with the +readiness flag and can cause the socket to behave incorrectly.

+

This method is not intended to be used with combined interests. +The closure should perform only one type of IO operation, so it should not +require more than one ready state. This method may panic or sleep forever +if it is called with a combined interest.

+

Usually, readable(), writable() or ready() is used with this function.

+

pub async fn async_io<R>( + &self, + interest: Interest, + f: impl FnMut() -> Result<R, Error> +) -> Result<R, Error>

Reads or writes from the socket using a user-provided IO operation.

+

The readiness of the socket is awaited and when the socket is ready, +the provided closure is called. The closure should attempt to perform +IO operation on the socket by manually calling the appropriate syscall. +If the operation fails because the socket is not actually ready, +then the closure should return a WouldBlock error. In such case the +readiness flag is cleared and the socket readiness is awaited again. +This loop is repeated until the closure returns an Ok or an error +other than WouldBlock.

+

The closure should only return a WouldBlock error if it has performed +an IO operation on the socket that failed due to the socket not being +ready. Returning a WouldBlock error in any other situation will +incorrectly clear the readiness flag, which can cause the socket to +behave incorrectly.

+

The closure should not perform the IO operation using any of the methods +defined on the Tokio TcpStream type, as this will mess with the +readiness flag and can cause the socket to behave incorrectly.

+

This method is not intended to be used with combined interests. +The closure should perform only one type of IO operation, so it should not +require more than one ready state. This method may panic or sleep forever +if it is called with a combined interest.

+

pub async fn peek(&self, buf: &mut [u8]) -> Result<usize, Error>

Receives data on the socket from the remote address to which it is +connected, without removing that data from the queue. On success, +returns the number of bytes peeked.

+

Successive calls return the same data. This is accomplished by passing +MSG_PEEK as a flag to the underlying recv system call.

+
§Examples
+
use tokio::net::TcpStream;
+use tokio::io::AsyncReadExt;
+use std::error::Error;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    // Connect to a peer
+    let mut stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+    let mut b1 = [0; 10];
+    let mut b2 = [0; 10];
+
+    // Peek at the data
+    let n = stream.peek(&mut b1).await?;
+
+    // Read the data
+    assert_eq!(n, stream.read(&mut b2[..n]).await?);
+    assert_eq!(&b1[..n], &b2[..n]);
+
+    Ok(())
+}
+

The read method is defined on the AsyncReadExt trait.

+

pub fn nodelay(&self) -> Result<bool, Error>

Gets the value of the TCP_NODELAY option on this socket.

+

For more information about this option, see set_nodelay.

+
§Examples
+
use tokio::net::TcpStream;
+
+let stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+println!("{:?}", stream.nodelay()?);
+

pub fn set_nodelay(&self, nodelay: bool) -> Result<(), Error>

Sets the value of the TCP_NODELAY option on this socket.

+

If set, this option disables the Nagle algorithm. This means that +segments are always sent as soon as possible, even if there is only a +small amount of data. When not set, data is buffered until there is a +sufficient amount to send out, thereby avoiding the frequent sending of +small packets.

+
§Examples
+
use tokio::net::TcpStream;
+
+let stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+stream.set_nodelay(true)?;
+

pub fn linger(&self) -> Result<Option<Duration>, Error>

Available on non-WASI only.

Reads the linger duration for this socket by getting the SO_LINGER +option.

+

For more information about this option, see set_linger.

+
§Examples
+
use tokio::net::TcpStream;
+
+let stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+println!("{:?}", stream.linger()?);
+

pub fn set_linger(&self, dur: Option<Duration>) -> Result<(), Error>

Available on non-WASI only.

Sets the linger duration of this socket by setting the SO_LINGER option.

+

This option controls the action taken when a stream has unsent messages and the stream is +closed. If SO_LINGER is set, the system shall block the process until it can transmit the +data or until the time expires.

+

If SO_LINGER is not specified, and the stream is closed, the system handles the call in a +way that allows the process to continue as quickly as possible.

+
§Examples
+
use tokio::net::TcpStream;
+
+let stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+stream.set_linger(None)?;
+

pub fn ttl(&self) -> Result<u32, Error>

Gets the value of the IP_TTL option for this socket.

+

For more information about this option, see set_ttl.

+
§Examples
+
use tokio::net::TcpStream;
+
+let stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+println!("{:?}", stream.ttl()?);
+

pub fn set_ttl(&self, ttl: u32) -> Result<(), Error>

Sets the value for the IP_TTL option on this socket.

+

This value sets the time-to-live field that is used in every packet sent +from this socket.

+
§Examples
+
use tokio::net::TcpStream;
+
+let stream = TcpStream::connect("127.0.0.1:8080").await?;
+
+stream.set_ttl(123)?;
+

pub fn split<'a>(&'a mut self) -> (ReadHalf<'a>, WriteHalf<'a>)

Splits a TcpStream into a read half and a write half, which can be used +to read and write the stream concurrently.

+

This method is more efficient than into_split, but the halves cannot be +moved into independently spawned tasks.

+

pub fn into_split(self) -> (OwnedReadHalf, OwnedWriteHalf)

Splits a TcpStream into a read half and a write half, which can be used +to read and write the stream concurrently.

+

Unlike split, the owned halves can be moved to separate tasks, however +this comes at the cost of a heap allocation.

+

Note: Dropping the write half will shut down the write half of the TCP +stream. This is equivalent to calling shutdown() on the TcpStream.

+

Trait Implementations§

§

impl AsFd for TcpStream

§

fn as_fd(&self) -> BorrowedFd<'_>

Borrows the file descriptor. Read more
§

impl AsRawFd for TcpStream

§

fn as_raw_fd(&self) -> i32

Extracts the raw file descriptor. Read more
§

impl AsyncRead for TcpStream

§

fn poll_read( + self: Pin<&mut TcpStream>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_> +) -> Poll<Result<(), Error>>

Attempts to read from the AsyncRead into buf. Read more
§

impl AsyncWrite for TcpStream

§

fn poll_write( + self: Pin<&mut TcpStream>, + cx: &mut Context<'_>, + buf: &[u8] +) -> Poll<Result<usize, Error>>

Attempt to write bytes from buf into the object. Read more
§

fn poll_write_vectored( + self: Pin<&mut TcpStream>, + cx: &mut Context<'_>, + bufs: &[IoSlice<'_>] +) -> Poll<Result<usize, Error>>

Like poll_write, except that it writes from a slice of buffers. Read more
§

fn is_write_vectored(&self) -> bool

Determines if this writer has an efficient poll_write_vectored +implementation. Read more
§

fn poll_flush( + self: Pin<&mut TcpStream>, + _: &mut Context<'_> +) -> Poll<Result<(), Error>>

Attempts to flush the object, ensuring that any buffered data reach +their destination. Read more
§

fn poll_shutdown( + self: Pin<&mut TcpStream>, + _: &mut Context<'_> +) -> Poll<Result<(), Error>>

Initiates or attempts to shut down this writer, returning success when +the I/O connection has completely shut down. Read more
§

impl Debug for TcpStream

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl FromStream for TcpStream

§

fn from_mio(sock: MioStream) -> Result<TcpStream, Error>

§

impl TryFrom<TcpStream> for TcpStream

§

fn try_from( + stream: TcpStream +) -> Result<TcpStream, <TcpStream as TryFrom<TcpStream>>::Error>

Consumes stream, returning the tokio I/O object.

+

This is equivalent to +TcpStream::from_std(stream).

+
§

type Error = Error

The type returned in the event of a conversion error.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<R> AsyncReadExt for R
where + R: AsyncRead + ?Sized,

§

fn chain<R>(self, next: R) -> Chain<Self, R>
where + Self: Sized, + R: AsyncRead,

Creates a new AsyncRead instance that chains this stream with +next. Read more
§

fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>
where + Self: Unpin,

Pulls some bytes from this source into the specified buffer, +returning how many bytes were read. Read more
§

fn read_buf<'a, B>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B>
where + Self: Unpin, + B: BufMut + ?Sized,

Pulls some bytes from this source into the specified buffer, +advancing the buffer’s internal cursor. Read more
§

fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self>
where + Self: Unpin,

Reads the exact number of bytes required to fill buf. Read more
§

fn read_u8(&mut self) -> ReadU8<&mut Self>
where + Self: Unpin,

Reads an unsigned 8 bit integer from the underlying reader. Read more
§

fn read_i8(&mut self) -> ReadI8<&mut Self>
where + Self: Unpin,

Reads a signed 8 bit integer from the underlying reader. Read more
§

fn read_u16(&mut self) -> ReadU16<&mut Self>
where + Self: Unpin,

Reads an unsigned 16-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i16(&mut self) -> ReadI16<&mut Self>
where + Self: Unpin,

Reads a signed 16-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u32(&mut self) -> ReadU32<&mut Self>
where + Self: Unpin,

Reads an unsigned 32-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i32(&mut self) -> ReadI32<&mut Self>
where + Self: Unpin,

Reads a signed 32-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u64(&mut self) -> ReadU64<&mut Self>
where + Self: Unpin,

Reads an unsigned 64-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i64(&mut self) -> ReadI64<&mut Self>
where + Self: Unpin,

Reads an signed 64-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u128(&mut self) -> ReadU128<&mut Self>
where + Self: Unpin,

Reads an unsigned 128-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i128(&mut self) -> ReadI128<&mut Self>
where + Self: Unpin,

Reads an signed 128-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_f32(&mut self) -> ReadF32<&mut Self>
where + Self: Unpin,

Reads an 32-bit floating point type in big-endian order from the +underlying reader. Read more
§

fn read_f64(&mut self) -> ReadF64<&mut Self>
where + Self: Unpin,

Reads an 64-bit floating point type in big-endian order from the +underlying reader. Read more
§

fn read_u16_le(&mut self) -> ReadU16Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 16-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i16_le(&mut self) -> ReadI16Le<&mut Self>
where + Self: Unpin,

Reads a signed 16-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u32_le(&mut self) -> ReadU32Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 32-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i32_le(&mut self) -> ReadI32Le<&mut Self>
where + Self: Unpin,

Reads a signed 32-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u64_le(&mut self) -> ReadU64Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 64-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i64_le(&mut self) -> ReadI64Le<&mut Self>
where + Self: Unpin,

Reads an signed 64-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u128_le(&mut self) -> ReadU128Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 128-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i128_le(&mut self) -> ReadI128Le<&mut Self>
where + Self: Unpin,

Reads an signed 128-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_f32_le(&mut self) -> ReadF32Le<&mut Self>
where + Self: Unpin,

Reads an 32-bit floating point type in little-endian order from the +underlying reader. Read more
§

fn read_f64_le(&mut self) -> ReadF64Le<&mut Self>
where + Self: Unpin,

Reads an 64-bit floating point type in little-endian order from the +underlying reader. Read more
§

fn read_to_end<'a>(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEnd<'a, Self>
where + Self: Unpin,

Reads all bytes until EOF in this source, placing them into buf. Read more
§

fn read_to_string<'a>( + &'a mut self, + dst: &'a mut String +) -> ReadToString<'a, Self>
where + Self: Unpin,

Reads all bytes until EOF in this source, appending them to buf. Read more
§

fn take(self, limit: u64) -> Take<Self>
where + Self: Sized,

Creates an adaptor which reads at most limit bytes from it. Read more
§

impl<W> AsyncWriteExt for W
where + W: AsyncWrite + ?Sized,

§

fn write<'a>(&'a mut self, src: &'a [u8]) -> Write<'a, Self>
where + Self: Unpin,

Writes a buffer into this writer, returning how many bytes were +written. Read more
§

fn write_vectored<'a, 'b>( + &'a mut self, + bufs: &'a [IoSlice<'b>] +) -> WriteVectored<'a, 'b, Self>
where + Self: Unpin,

Like write, except that it writes from a slice of buffers. Read more
§

fn write_buf<'a, B>(&'a mut self, src: &'a mut B) -> WriteBuf<'a, Self, B>
where + Self: Sized + Unpin, + B: Buf,

Writes a buffer into this writer, advancing the buffer’s internal +cursor. Read more
§

fn write_all_buf<'a, B>( + &'a mut self, + src: &'a mut B +) -> WriteAllBuf<'a, Self, B>
where + Self: Sized + Unpin, + B: Buf,

Attempts to write an entire buffer into this writer. Read more
§

fn write_all<'a>(&'a mut self, src: &'a [u8]) -> WriteAll<'a, Self>
where + Self: Unpin,

Attempts to write an entire buffer into this writer. Read more
§

fn write_u8(&mut self, n: u8) -> WriteU8<&mut Self>
where + Self: Unpin,

Writes an unsigned 8-bit integer to the underlying writer. Read more
§

fn write_i8(&mut self, n: i8) -> WriteI8<&mut Self>
where + Self: Unpin,

Writes a signed 8-bit integer to the underlying writer. Read more
§

fn write_u16(&mut self, n: u16) -> WriteU16<&mut Self>
where + Self: Unpin,

Writes an unsigned 16-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i16(&mut self, n: i16) -> WriteI16<&mut Self>
where + Self: Unpin,

Writes a signed 16-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u32(&mut self, n: u32) -> WriteU32<&mut Self>
where + Self: Unpin,

Writes an unsigned 32-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i32(&mut self, n: i32) -> WriteI32<&mut Self>
where + Self: Unpin,

Writes a signed 32-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u64(&mut self, n: u64) -> WriteU64<&mut Self>
where + Self: Unpin,

Writes an unsigned 64-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i64(&mut self, n: i64) -> WriteI64<&mut Self>
where + Self: Unpin,

Writes an signed 64-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u128(&mut self, n: u128) -> WriteU128<&mut Self>
where + Self: Unpin,

Writes an unsigned 128-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i128(&mut self, n: i128) -> WriteI128<&mut Self>
where + Self: Unpin,

Writes an signed 128-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_f32(&mut self, n: f32) -> WriteF32<&mut Self>
where + Self: Unpin,

Writes an 32-bit floating point type in big-endian order to the +underlying writer. Read more
§

fn write_f64(&mut self, n: f64) -> WriteF64<&mut Self>
where + Self: Unpin,

Writes an 64-bit floating point type in big-endian order to the +underlying writer. Read more
§

fn write_u16_le(&mut self, n: u16) -> WriteU16Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 16-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i16_le(&mut self, n: i16) -> WriteI16Le<&mut Self>
where + Self: Unpin,

Writes a signed 16-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u32_le(&mut self, n: u32) -> WriteU32Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 32-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i32_le(&mut self, n: i32) -> WriteI32Le<&mut Self>
where + Self: Unpin,

Writes a signed 32-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u64_le(&mut self, n: u64) -> WriteU64Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 64-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i64_le(&mut self, n: i64) -> WriteI64Le<&mut Self>
where + Self: Unpin,

Writes an signed 64-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u128_le(&mut self, n: u128) -> WriteU128Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 128-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i128_le(&mut self, n: i128) -> WriteI128Le<&mut Self>
where + Self: Unpin,

Writes an signed 128-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_f32_le(&mut self, n: f32) -> WriteF32Le<&mut Self>
where + Self: Unpin,

Writes an 32-bit floating point type in little-endian order to the +underlying writer. Read more
§

fn write_f64_le(&mut self, n: f64) -> WriteF64Le<&mut Self>
where + Self: Unpin,

Writes an 64-bit floating point type in little-endian order to the +underlying writer. Read more
§

fn flush(&mut self) -> Flush<'_, Self>
where + Self: Unpin,

Flushes this output stream, ensuring that all intermediately buffered +contents reach their destination. Read more
§

fn shutdown(&mut self) -> Shutdown<'_, Self>
where + Self: Unpin,

Shuts down the output stream, ensuring that the value can be dropped +cleanly. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/net/struct.UdpSocket.html b/actix_web/rt/net/struct.UdpSocket.html new file mode 100644 index 000000000..dde953854 --- /dev/null +++ b/actix_web/rt/net/struct.UdpSocket.html @@ -0,0 +1,1188 @@ +UdpSocket in actix_web::rt::net - Rust

Struct actix_web::rt::net::UdpSocket

pub struct UdpSocket { /* private fields */ }
Available on crate feature net only.
Expand description

A UDP socket.

+

UDP is “connectionless”, unlike TCP. Meaning, regardless of what address you’ve bound to, a UdpSocket +is free to communicate with many different remotes. In tokio there are basically two main ways to use UdpSocket:

+
    +
  • one to many: bind and use send_to +and recv_from to communicate with many different addresses
  • +
  • one to one: connect and associate with a single address, using send +and recv to communicate only with that remote address
  • +
+

This type does not provide a split method, because this functionality +can be achieved by instead wrapping the socket in an Arc. Note that +you do not need a Mutex to share the UdpSocket — an Arc<UdpSocket> +is enough. This is because all of the methods take &self instead of +&mut self. Once you have wrapped it in an Arc, you can call +.clone() on the Arc<UdpSocket> to get multiple shared handles to the +same socket. An example of such usage can be found further down.

+

§Streams

+

If you need to listen over UDP and produce a Stream, you can look +at UdpFramed.

+

§Example: one to many (bind)

+

Using bind we can create a simple echo server that sends and recv’s with many different clients:

+ +
use tokio::net::UdpSocket;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let sock = UdpSocket::bind("0.0.0.0:8080").await?;
+    let mut buf = [0; 1024];
+    loop {
+        let (len, addr) = sock.recv_from(&mut buf).await?;
+        println!("{:?} bytes received from {:?}", len, addr);
+
+        let len = sock.send_to(&buf[..len], addr).await?;
+        println!("{:?} bytes sent", len);
+    }
+}
+

§Example: one to one (connect)

+

Or using connect we can echo with a single remote address using send and recv:

+ +
use tokio::net::UdpSocket;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let sock = UdpSocket::bind("0.0.0.0:8080").await?;
+
+    let remote_addr = "127.0.0.1:59611";
+    sock.connect(remote_addr).await?;
+    let mut buf = [0; 1024];
+    loop {
+        let len = sock.recv(&mut buf).await?;
+        println!("{:?} bytes received from {:?}", len, remote_addr);
+
+        let len = sock.send(&buf[..len]).await?;
+        println!("{:?} bytes sent", len);
+    }
+}
+

§Example: Splitting with Arc

+

Because send_to and recv_from take &self. It’s perfectly alright +to use an Arc<UdpSocket> and share the references to multiple tasks. +Here is a similar “echo” example that supports concurrent +sending/receiving:

+ +
use tokio::{net::UdpSocket, sync::mpsc};
+use std::{io, net::SocketAddr, sync::Arc};
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let sock = UdpSocket::bind("0.0.0.0:8080".parse::<SocketAddr>().unwrap()).await?;
+    let r = Arc::new(sock);
+    let s = r.clone();
+    let (tx, mut rx) = mpsc::channel::<(Vec<u8>, SocketAddr)>(1_000);
+
+    tokio::spawn(async move {
+        while let Some((bytes, addr)) = rx.recv().await {
+            let len = s.send_to(&bytes, &addr).await.unwrap();
+            println!("{:?} bytes sent", len);
+        }
+    });
+
+    let mut buf = [0; 1024];
+    loop {
+        let (len, addr) = r.recv_from(&mut buf).await?;
+        println!("{:?} bytes received from {:?}", len, addr);
+        tx.send((buf[..len].to_vec(), addr)).await.unwrap();
+    }
+}
+

Implementations§

§

impl UdpSocket

pub async fn bind<A>(addr: A) -> Result<UdpSocket, Error>
where + A: ToSocketAddrs,

This function will create a new UDP socket and attempt to bind it to +the addr provided.

+

Binding with a port number of 0 will request that the OS assigns a port +to this listener. The port allocated can be queried via the local_addr +method.

+
§Example
+
use tokio::net::UdpSocket;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let sock = UdpSocket::bind("0.0.0.0:8080").await?;
+    // use `sock`
+    Ok(())
+}
+

pub fn from_std(socket: UdpSocket) -> Result<UdpSocket, Error>

Creates new UdpSocket from a previously bound std::net::UdpSocket.

+

This function is intended to be used to wrap a UDP socket from the +standard library in the Tokio equivalent.

+

This can be used in conjunction with socket2’s Socket interface to +configure a socket before it’s handed off, such as setting options like +reuse_address or binding to multiple addresses.

+
§Notes
+

The caller is responsible for ensuring that the socket is in +non-blocking mode. Otherwise all I/O operations on the socket +will block the thread, which will cause unexpected behavior. +Non-blocking mode can be set using set_nonblocking.

+
§Panics
+

This function panics if thread-local runtime is not set.

+

The runtime is usually set implicitly when this function is called +from a future driven by a tokio runtime, otherwise runtime can be set +explicitly with Runtime::enter function.

+
§Example
+
use tokio::net::UdpSocket;
+
+let addr = "0.0.0.0:8080".parse::<SocketAddr>().unwrap();
+let std_sock = std::net::UdpSocket::bind(addr)?;
+std_sock.set_nonblocking(true)?;
+let sock = UdpSocket::from_std(std_sock)?;
+// use `sock`
+

pub fn into_std(self) -> Result<UdpSocket, Error>

Turns a tokio::net::UdpSocket into a std::net::UdpSocket.

+

The returned std::net::UdpSocket will have nonblocking mode set as +true. Use set_nonblocking to change the blocking mode if needed.

+
§Examples
+
use std::error::Error;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    let tokio_socket = tokio::net::UdpSocket::bind("127.0.0.1:0").await?;
+    let std_socket = tokio_socket.into_std()?;
+    std_socket.set_nonblocking(false)?;
+    Ok(())
+}
+

pub fn local_addr(&self) -> Result<SocketAddr, Error>

Returns the local address that this socket is bound to.

+
§Example
+
use tokio::net::UdpSocket;
+
+let addr = "0.0.0.0:8080".parse::<SocketAddr>().unwrap();
+let sock = UdpSocket::bind(addr).await?;
+// the address the socket is bound to
+let local_addr = sock.local_addr()?;
+

pub fn peer_addr(&self) -> Result<SocketAddr, Error>

Returns the socket address of the remote peer this socket was connected to.

+
§Example
+
use tokio::net::UdpSocket;
+
+let addr = "0.0.0.0:8080".parse::<SocketAddr>().unwrap();
+let peer = "127.0.0.1:11100".parse::<SocketAddr>().unwrap();
+let sock = UdpSocket::bind(addr).await?;
+sock.connect(peer).await?;
+assert_eq!(peer, sock.peer_addr()?);
+

pub async fn connect<A>(&self, addr: A) -> Result<(), Error>
where + A: ToSocketAddrs,

Connects the UDP socket setting the default destination for send() and +limiting packets that are read via recv from the address specified in +addr.

+
§Example
+
use tokio::net::UdpSocket;
+
+let sock = UdpSocket::bind("0.0.0.0:8080".parse::<SocketAddr>().unwrap()).await?;
+
+let remote_addr = "127.0.0.1:59600".parse::<SocketAddr>().unwrap();
+sock.connect(remote_addr).await?;
+let mut buf = [0u8; 32];
+// recv from remote_addr
+let len = sock.recv(&mut buf).await?;
+// send to remote_addr
+let _len = sock.send(&buf[..len]).await?;
+

pub async fn ready(&self, interest: Interest) -> Result<Ready, Error>

Waits for any of the requested ready states.

+

This function is usually paired with try_recv() or try_send(). It +can be used to concurrently recv / send to the same socket on a single +task without splitting the socket.

+

The function may complete without the socket being ready. This is a +false-positive and attempting an operation will return with +io::ErrorKind::WouldBlock. The function can also return with an empty +Ready set, so you should always check the returned value and possibly +wait again if the requested states are not set.

+
§Cancel safety
+

This method is cancel safe. Once a readiness event occurs, the method +will continue to return immediately until the readiness event is +consumed by an attempt to read or write that fails with WouldBlock or +Poll::Pending.

+
§Examples
+

Concurrently receive from and send to the socket on the same task +without splitting.

+ +
use tokio::io::{self, Interest};
+use tokio::net::UdpSocket;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
+    socket.connect("127.0.0.1:8081").await?;
+
+    loop {
+        let ready = socket.ready(Interest::READABLE | Interest::WRITABLE).await?;
+
+        if ready.is_readable() {
+            // The buffer is **not** included in the async task and will only exist
+            // on the stack.
+            let mut data = [0; 1024];
+            match socket.try_recv(&mut data[..]) {
+                Ok(n) => {
+                    println!("received {:?}", &data[..n]);
+                }
+                // False-positive, continue
+                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
+                Err(e) => {
+                    return Err(e);
+                }
+            }
+        }
+
+        if ready.is_writable() {
+            // Write some data
+            match socket.try_send(b"hello world") {
+                Ok(n) => {
+                    println!("sent {} bytes", n);
+                }
+                // False-positive, continue
+                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
+                Err(e) => {
+                    return Err(e);
+                }
+            }
+        }
+    }
+}
+

pub async fn writable(&self) -> Result<(), Error>

Waits for the socket to become writable.

+

This function is equivalent to ready(Interest::WRITABLE) and is +usually paired with try_send() or try_send_to().

+

The function may complete without the socket being writable. This is a +false-positive and attempting a try_send() will return with +io::ErrorKind::WouldBlock.

+
§Cancel safety
+

This method is cancel safe. Once a readiness event occurs, the method +will continue to return immediately until the readiness event is +consumed by an attempt to write that fails with WouldBlock or +Poll::Pending.

+
§Examples
+
use tokio::net::UdpSocket;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    // Bind socket
+    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
+    socket.connect("127.0.0.1:8081").await?;
+
+    loop {
+        // Wait for the socket to be writable
+        socket.writable().await?;
+
+        // Try to send data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match socket.try_send(b"hello world") {
+            Ok(n) => {
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e);
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn poll_send_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Error>>

Polls for write/send readiness.

+

If the udp stream is not currently ready for sending, this method will +store a clone of the Waker from the provided Context. When the udp +stream becomes ready for sending, Waker::wake will be called on the +waker.

+

Note that on multiple calls to poll_send_ready or poll_send, only +the Waker from the Context passed to the most recent call is +scheduled to receive a wakeup. (However, poll_recv_ready retains a +second, independent waker.)

+

This function is intended for cases where creating and pinning a future +via writable is not feasible. Where possible, using writable is +preferred, as this supports polling from multiple tasks at once.

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if the udp stream is not ready for writing.
  • +
  • Poll::Ready(Ok(())) if the udp stream is ready for writing.
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+

pub async fn send(&self, buf: &[u8]) -> Result<usize, Error>

Sends data on the socket to the remote address that the socket is +connected to.

+

The connect method will connect this socket to a remote address. +This method will fail if the socket is not connected.

+
§Return
+

On success, the number of bytes sent is returned, otherwise, the +encountered error is returned.

+
§Cancel safety
+

This method is cancel safe. If send is used as the event in a +tokio::select! statement and some other branch +completes first, then it is guaranteed that the message was not sent.

+
§Examples
+
use tokio::io;
+use tokio::net::UdpSocket;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    // Bind socket
+    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
+    socket.connect("127.0.0.1:8081").await?;
+
+    // Send a message
+    socket.send(b"hello world").await?;
+
+    Ok(())
+}
+

pub fn poll_send( + &self, + cx: &mut Context<'_>, + buf: &[u8] +) -> Poll<Result<usize, Error>>

Attempts to send data on the socket to the remote address to which it +was previously connected.

+

The connect method will connect this socket to a remote address. +This method will fail if the socket is not connected.

+

Note that on multiple calls to a poll_* method in the send direction, +only the Waker from the Context passed to the most recent call will +be scheduled to receive a wakeup.

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if the socket is not available to write
  • +
  • Poll::Ready(Ok(n)) n is the number of bytes sent
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+

pub fn try_send(&self, buf: &[u8]) -> Result<usize, Error>

Tries to send data on the socket to the remote address to which it is +connected.

+

When the socket buffer is full, Err(io::ErrorKind::WouldBlock) is +returned. This function is usually paired with writable().

+
§Returns
+

If successful, Ok(n) is returned, where n is the number of bytes +sent. If the socket is not ready to send data, +Err(ErrorKind::WouldBlock) is returned.

+
§Examples
+
use tokio::net::UdpSocket;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    // Bind a UDP socket
+    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
+
+    // Connect to a peer
+    socket.connect("127.0.0.1:8081").await?;
+
+    loop {
+        // Wait for the socket to be writable
+        socket.writable().await?;
+
+        // Try to send data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match socket.try_send(b"hello world") {
+            Ok(n) => {
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e);
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub async fn readable(&self) -> Result<(), Error>

Waits for the socket to become readable.

+

This function is equivalent to ready(Interest::READABLE) and is usually +paired with try_recv().

+

The function may complete without the socket being readable. This is a +false-positive and attempting a try_recv() will return with +io::ErrorKind::WouldBlock.

+
§Cancel safety
+

This method is cancel safe. Once a readiness event occurs, the method +will continue to return immediately until the readiness event is +consumed by an attempt to read that fails with WouldBlock or +Poll::Pending.

+
§Examples
+
use tokio::net::UdpSocket;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    // Connect to a peer
+    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
+    socket.connect("127.0.0.1:8081").await?;
+
+    loop {
+        // Wait for the socket to be readable
+        socket.readable().await?;
+
+        // The buffer is **not** included in the async task and will
+        // only exist on the stack.
+        let mut buf = [0; 1024];
+
+        // Try to recv data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match socket.try_recv(&mut buf) {
+            Ok(n) => {
+                println!("GOT {:?}", &buf[..n]);
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e);
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn poll_recv_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Error>>

Polls for read/receive readiness.

+

If the udp stream is not currently ready for receiving, this method will +store a clone of the Waker from the provided Context. When the udp +socket becomes ready for reading, Waker::wake will be called on the +waker.

+

Note that on multiple calls to poll_recv_ready, poll_recv or +poll_peek, only the Waker from the Context passed to the most +recent call is scheduled to receive a wakeup. (However, +poll_send_ready retains a second, independent waker.)

+

This function is intended for cases where creating and pinning a future +via readable is not feasible. Where possible, using readable is +preferred, as this supports polling from multiple tasks at once.

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if the udp stream is not ready for reading.
  • +
  • Poll::Ready(Ok(())) if the udp stream is ready for reading.
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+

pub async fn recv(&self, buf: &mut [u8]) -> Result<usize, Error>

Receives a single datagram message on the socket from the remote address +to which it is connected. On success, returns the number of bytes read.

+

The function must be called with valid byte array buf of sufficient +size to hold the message bytes. If a message is too long to fit in the +supplied buffer, excess bytes may be discarded.

+

The connect method will connect this socket to a remote address. +This method will fail if the socket is not connected.

+
§Cancel safety
+

This method is cancel safe. If recv is used as the event in a +tokio::select! statement and some other branch +completes first, it is guaranteed that no messages were received on this +socket.

+ +
use tokio::net::UdpSocket;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    // Bind socket
+    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
+    socket.connect("127.0.0.1:8081").await?;
+
+    let mut buf = vec![0; 10];
+    let n = socket.recv(&mut buf).await?;
+
+    println!("received {} bytes {:?}", n, &buf[..n]);
+
+    Ok(())
+}
+

pub fn poll_recv( + &self, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_> +) -> Poll<Result<(), Error>>

Attempts to receive a single datagram message on the socket from the remote +address to which it is connected.

+

The connect method will connect this socket to a remote address. This method +resolves to an error if the socket is not connected.

+

Note that on multiple calls to a poll_* method in the recv direction, only the +Waker from the Context passed to the most recent call will be scheduled to +receive a wakeup.

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if the socket is not ready to read
  • +
  • Poll::Ready(Ok(())) reads data ReadBuf if the socket is ready
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+

pub fn try_recv(&self, buf: &mut [u8]) -> Result<usize, Error>

Tries to receive a single datagram message on the socket from the remote +address to which it is connected. On success, returns the number of +bytes read.

+

This method must be called with valid byte array buf of sufficient size +to hold the message bytes. If a message is too long to fit in the +supplied buffer, excess bytes may be discarded.

+

When there is no pending data, Err(io::ErrorKind::WouldBlock) is +returned. This function is usually paired with readable().

+
§Examples
+
use tokio::net::UdpSocket;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    // Connect to a peer
+    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
+    socket.connect("127.0.0.1:8081").await?;
+
+    loop {
+        // Wait for the socket to be readable
+        socket.readable().await?;
+
+        // The buffer is **not** included in the async task and will
+        // only exist on the stack.
+        let mut buf = [0; 1024];
+
+        // Try to recv data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match socket.try_recv(&mut buf) {
+            Ok(n) => {
+                println!("GOT {:?}", &buf[..n]);
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e);
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn try_recv_buf<B>(&self, buf: &mut B) -> Result<usize, Error>
where + B: BufMut,

Available on crate feature io-util only.

Tries to receive data from the stream into the provided buffer, advancing the +buffer’s internal cursor, returning how many bytes were read.

+

This method must be called with valid byte array buf of sufficient size +to hold the message bytes. If a message is too long to fit in the +supplied buffer, excess bytes may be discarded.

+

This method can be used even if buf is uninitialized.

+

When there is no pending data, Err(io::ErrorKind::WouldBlock) is +returned. This function is usually paired with readable().

+
§Examples
+
use tokio::net::UdpSocket;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    // Connect to a peer
+    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
+    socket.connect("127.0.0.1:8081").await?;
+
+    loop {
+        // Wait for the socket to be readable
+        socket.readable().await?;
+
+        let mut buf = Vec::with_capacity(1024);
+
+        // Try to recv data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match socket.try_recv_buf(&mut buf) {
+            Ok(n) => {
+                println!("GOT {:?}", &buf[..n]);
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e);
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub async fn recv_buf<B>(&self, buf: &mut B) -> Result<usize, Error>
where + B: BufMut,

Available on crate feature io-util only.

Receives a single datagram message on the socket from the remote address +to which it is connected, advancing the buffer’s internal cursor, +returning how many bytes were read.

+

This method must be called with valid byte array buf of sufficient size +to hold the message bytes. If a message is too long to fit in the +supplied buffer, excess bytes may be discarded.

+

This method can be used even if buf is uninitialized.

+
§Examples
+
use tokio::net::UdpSocket;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    // Connect to a peer
+    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
+    socket.connect("127.0.0.1:8081").await?;
+
+    let mut buf = Vec::with_capacity(512);
+    let len = socket.recv_buf(&mut buf).await?;
+
+    println!("received {} bytes {:?}", len, &buf[..len]);
+
+    Ok(())
+}
+

pub fn try_recv_buf_from<B>( + &self, + buf: &mut B +) -> Result<(usize, SocketAddr), Error>
where + B: BufMut,

Available on crate feature io-util only.

Tries to receive a single datagram message on the socket. On success, +returns the number of bytes read and the origin.

+

This method must be called with valid byte array buf of sufficient size +to hold the message bytes. If a message is too long to fit in the +supplied buffer, excess bytes may be discarded.

+

This method can be used even if buf is uninitialized.

+

When there is no pending data, Err(io::ErrorKind::WouldBlock) is +returned. This function is usually paired with readable().

+
§Notes
+

Note that the socket address cannot be implicitly trusted, because it is relatively +trivial to send a UDP datagram with a spoofed origin in a packet injection attack. +Because UDP is stateless and does not validate the origin of a packet, +the attacker does not need to be able to intercept traffic in order to interfere. +It is important to be aware of this when designing your application-level protocol.

+
§Examples
+
use tokio::net::UdpSocket;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    // Connect to a peer
+    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
+
+    loop {
+        // Wait for the socket to be readable
+        socket.readable().await?;
+
+        let mut buf = Vec::with_capacity(1024);
+
+        // Try to recv data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match socket.try_recv_buf_from(&mut buf) {
+            Ok((n, _addr)) => {
+                println!("GOT {:?}", &buf[..n]);
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e);
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub async fn recv_buf_from<B>( + &self, + buf: &mut B +) -> Result<(usize, SocketAddr), Error>
where + B: BufMut,

Available on crate feature io-util only.

Receives a single datagram message on the socket, advancing the +buffer’s internal cursor, returning how many bytes were read and the origin.

+

This method must be called with valid byte array buf of sufficient size +to hold the message bytes. If a message is too long to fit in the +supplied buffer, excess bytes may be discarded.

+

This method can be used even if buf is uninitialized.

+
§Notes
+

Note that the socket address cannot be implicitly trusted, because it is relatively +trivial to send a UDP datagram with a spoofed origin in a packet injection attack. +Because UDP is stateless and does not validate the origin of a packet, +the attacker does not need to be able to intercept traffic in order to interfere. +It is important to be aware of this when designing your application-level protocol.

+
§Examples
+
use tokio::net::UdpSocket;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    // Connect to a peer
+    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
+    socket.connect("127.0.0.1:8081").await?;
+
+    let mut buf = Vec::with_capacity(512);
+    let (len, addr) = socket.recv_buf_from(&mut buf).await?;
+
+    println!("received {:?} bytes from {:?}", len, addr);
+
+    Ok(())
+}
+

pub async fn send_to<A>(&self, buf: &[u8], target: A) -> Result<usize, Error>
where + A: ToSocketAddrs,

Sends data on the socket to the given address. On success, returns the +number of bytes written.

+

Address type can be any implementor of ToSocketAddrs trait. See its +documentation for concrete examples.

+

It is possible for addr to yield multiple addresses, but send_to +will only send data to the first address yielded by addr.

+

This will return an error when the IP version of the local socket does +not match that returned from ToSocketAddrs.

+
§Cancel safety
+

This method is cancel safe. If send_to is used as the event in a +tokio::select! statement and some other branch +completes first, then it is guaranteed that the message was not sent.

+
§Example
+
use tokio::net::UdpSocket;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
+    let len = socket.send_to(b"hello world", "127.0.0.1:8081").await?;
+
+    println!("Sent {} bytes", len);
+
+    Ok(())
+}
+

pub fn poll_send_to( + &self, + cx: &mut Context<'_>, + buf: &[u8], + target: SocketAddr +) -> Poll<Result<usize, Error>>

Attempts to send data on the socket to a given address.

+

Note that on multiple calls to a poll_* method in the send direction, only the +Waker from the Context passed to the most recent call will be scheduled to +receive a wakeup.

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if the socket is not ready to write
  • +
  • Poll::Ready(Ok(n)) n is the number of bytes sent.
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+

pub fn try_send_to( + &self, + buf: &[u8], + target: SocketAddr +) -> Result<usize, Error>

Tries to send data on the socket to the given address, but if the send is +blocked this will return right away.

+

This function is usually paired with writable().

+
§Returns
+

If successful, returns the number of bytes sent

+

Users should ensure that when the remote cannot receive, the +ErrorKind::WouldBlock is properly handled. An error can also occur +if the IP version of the socket does not match that of target.

+
§Example
+
use tokio::net::UdpSocket;
+use std::error::Error;
+use std::io;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
+
+    let dst = "127.0.0.1:8081".parse()?;
+
+    loop {
+        socket.writable().await?;
+
+        match socket.try_send_to(&b"hello world"[..], dst) {
+            Ok(sent) => {
+                println!("sent {} bytes", sent);
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                // Writable false positive.
+                continue;
+            }
+            Err(e) => return Err(e.into()),
+        }
+    }
+
+    Ok(())
+}
+

pub async fn recv_from( + &self, + buf: &mut [u8] +) -> Result<(usize, SocketAddr), Error>

Receives a single datagram message on the socket. On success, returns +the number of bytes read and the origin.

+

The function must be called with valid byte array buf of sufficient +size to hold the message bytes. If a message is too long to fit in the +supplied buffer, excess bytes may be discarded.

+
§Cancel safety
+

This method is cancel safe. If recv_from is used as the event in a +tokio::select! statement and some other branch +completes first, it is guaranteed that no messages were received on this +socket.

+
§Example
+
use tokio::net::UdpSocket;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
+
+    let mut buf = vec![0u8; 32];
+    let (len, addr) = socket.recv_from(&mut buf).await?;
+
+    println!("received {:?} bytes from {:?}", len, addr);
+
+    Ok(())
+}
+
§Notes
+

Note that the socket address cannot be implicitly trusted, because it is relatively +trivial to send a UDP datagram with a spoofed origin in a packet injection attack. +Because UDP is stateless and does not validate the origin of a packet, +the attacker does not need to be able to intercept traffic in order to interfere. +It is important to be aware of this when designing your application-level protocol.

+

pub fn poll_recv_from( + &self, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_> +) -> Poll<Result<SocketAddr, Error>>

Attempts to receive a single datagram on the socket.

+

Note that on multiple calls to a poll_* method in the recv direction, only the +Waker from the Context passed to the most recent call will be scheduled to +receive a wakeup.

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if the socket is not ready to read
  • +
  • Poll::Ready(Ok(addr)) reads data from addr into ReadBuf if the socket is ready
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+
§Notes
+

Note that the socket address cannot be implicitly trusted, because it is relatively +trivial to send a UDP datagram with a spoofed origin in a packet injection attack. +Because UDP is stateless and does not validate the origin of a packet, +the attacker does not need to be able to intercept traffic in order to interfere. +It is important to be aware of this when designing your application-level protocol.

+

pub fn try_recv_from( + &self, + buf: &mut [u8] +) -> Result<(usize, SocketAddr), Error>

Tries to receive a single datagram message on the socket. On success, +returns the number of bytes read and the origin.

+

This method must be called with valid byte array buf of sufficient size +to hold the message bytes. If a message is too long to fit in the +supplied buffer, excess bytes may be discarded.

+

When there is no pending data, Err(io::ErrorKind::WouldBlock) is +returned. This function is usually paired with readable().

+
§Notes
+

Note that the socket address cannot be implicitly trusted, because it is relatively +trivial to send a UDP datagram with a spoofed origin in a packet injection attack. +Because UDP is stateless and does not validate the origin of a packet, +the attacker does not need to be able to intercept traffic in order to interfere. +It is important to be aware of this when designing your application-level protocol.

+
§Examples
+
use tokio::net::UdpSocket;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    // Connect to a peer
+    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
+
+    loop {
+        // Wait for the socket to be readable
+        socket.readable().await?;
+
+        // The buffer is **not** included in the async task and will
+        // only exist on the stack.
+        let mut buf = [0; 1024];
+
+        // Try to recv data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match socket.try_recv_from(&mut buf) {
+            Ok((n, _addr)) => {
+                println!("GOT {:?}", &buf[..n]);
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e);
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn try_io<R>( + &self, + interest: Interest, + f: impl FnOnce() -> Result<R, Error> +) -> Result<R, Error>

Tries to read or write from the socket using a user-provided IO operation.

+

If the socket is ready, the provided closure is called. The closure +should attempt to perform IO operation on the socket by manually +calling the appropriate syscall. If the operation fails because the +socket is not actually ready, then the closure should return a +WouldBlock error and the readiness flag is cleared. The return value +of the closure is then returned by try_io.

+

If the socket is not ready, then the closure is not called +and a WouldBlock error is returned.

+

The closure should only return a WouldBlock error if it has performed +an IO operation on the socket that failed due to the socket not being +ready. Returning a WouldBlock error in any other situation will +incorrectly clear the readiness flag, which can cause the socket to +behave incorrectly.

+

The closure should not perform the IO operation using any of the methods +defined on the Tokio UdpSocket type, as this will mess with the +readiness flag and can cause the socket to behave incorrectly.

+

This method is not intended to be used with combined interests. +The closure should perform only one type of IO operation, so it should not +require more than one ready state. This method may panic or sleep forever +if it is called with a combined interest.

+

Usually, readable(), writable() or ready() is used with this function.

+

pub async fn async_io<R>( + &self, + interest: Interest, + f: impl FnMut() -> Result<R, Error> +) -> Result<R, Error>

Reads or writes from the socket using a user-provided IO operation.

+

The readiness of the socket is awaited and when the socket is ready, +the provided closure is called. The closure should attempt to perform +IO operation on the socket by manually calling the appropriate syscall. +If the operation fails because the socket is not actually ready, +then the closure should return a WouldBlock error. In such case the +readiness flag is cleared and the socket readiness is awaited again. +This loop is repeated until the closure returns an Ok or an error +other than WouldBlock.

+

The closure should only return a WouldBlock error if it has performed +an IO operation on the socket that failed due to the socket not being +ready. Returning a WouldBlock error in any other situation will +incorrectly clear the readiness flag, which can cause the socket to +behave incorrectly.

+

The closure should not perform the IO operation using any of the methods +defined on the Tokio UdpSocket type, as this will mess with the +readiness flag and can cause the socket to behave incorrectly.

+

This method is not intended to be used with combined interests. +The closure should perform only one type of IO operation, so it should not +require more than one ready state. This method may panic or sleep forever +if it is called with a combined interest.

+

pub async fn peek_from( + &self, + buf: &mut [u8] +) -> Result<(usize, SocketAddr), Error>

Receives data from the socket, without removing it from the input queue. +On success, returns the number of bytes read and the address from whence +the data came.

+
§Notes
+

On Windows, if the data is larger than the buffer specified, the buffer +is filled with the first part of the data, and peek_from returns the error +WSAEMSGSIZE(10040). The excess data is lost. +Make sure to always use a sufficiently large buffer to hold the +maximum UDP packet size, which can be up to 65536 bytes in size.

+

MacOS will return an error if you pass a zero-sized buffer.

+

If you’re merely interested in learning the sender of the data at the head of the queue, +try peek_sender.

+

Note that the socket address cannot be implicitly trusted, because it is relatively +trivial to send a UDP datagram with a spoofed origin in a packet injection attack. +Because UDP is stateless and does not validate the origin of a packet, +the attacker does not need to be able to intercept traffic in order to interfere. +It is important to be aware of this when designing your application-level protocol.

+
§Examples
+
use tokio::net::UdpSocket;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
+
+    let mut buf = vec![0u8; 32];
+    let (len, addr) = socket.peek_from(&mut buf).await?;
+
+    println!("peeked {:?} bytes from {:?}", len, addr);
+
+    Ok(())
+}
+

pub fn poll_peek_from( + &self, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_> +) -> Poll<Result<SocketAddr, Error>>

Receives data from the socket, without removing it from the input queue. +On success, returns the sending address of the datagram.

+
§Notes
+

Note that on multiple calls to a poll_* method in the recv direction, only the +Waker from the Context passed to the most recent call will be scheduled to +receive a wakeup

+

On Windows, if the data is larger than the buffer specified, the buffer +is filled with the first part of the data, and peek returns the error +WSAEMSGSIZE(10040). The excess data is lost. +Make sure to always use a sufficiently large buffer to hold the +maximum UDP packet size, which can be up to 65536 bytes in size.

+

MacOS will return an error if you pass a zero-sized buffer.

+

If you’re merely interested in learning the sender of the data at the head of the queue, +try poll_peek_sender.

+

Note that the socket address cannot be implicitly trusted, because it is relatively +trivial to send a UDP datagram with a spoofed origin in a packet injection attack. +Because UDP is stateless and does not validate the origin of a packet, +the attacker does not need to be able to intercept traffic in order to interfere. +It is important to be aware of this when designing your application-level protocol.

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if the socket is not ready to read
  • +
  • Poll::Ready(Ok(addr)) reads data from addr into ReadBuf if the socket is ready
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+

pub fn try_peek_from( + &self, + buf: &mut [u8] +) -> Result<(usize, SocketAddr), Error>

Tries to receive data on the socket without removing it from the input queue. +On success, returns the number of bytes read and the sending address of the +datagram.

+

When there is no pending data, Err(io::ErrorKind::WouldBlock) is +returned. This function is usually paired with readable().

+
§Notes
+

On Windows, if the data is larger than the buffer specified, the buffer +is filled with the first part of the data, and peek returns the error +WSAEMSGSIZE(10040). The excess data is lost. +Make sure to always use a sufficiently large buffer to hold the +maximum UDP packet size, which can be up to 65536 bytes in size.

+

MacOS will return an error if you pass a zero-sized buffer.

+

If you’re merely interested in learning the sender of the data at the head of the queue, +try try_peek_sender.

+

Note that the socket address cannot be implicitly trusted, because it is relatively +trivial to send a UDP datagram with a spoofed origin in a packet injection attack. +Because UDP is stateless and does not validate the origin of a packet, +the attacker does not need to be able to intercept traffic in order to interfere. +It is important to be aware of this when designing your application-level protocol.

+

pub async fn peek_sender(&self) -> Result<SocketAddr, Error>

Retrieve the sender of the data at the head of the input queue, waiting if empty.

+

This is equivalent to calling peek_from with a zero-sized buffer, +but suppresses the WSAEMSGSIZE error on Windows and the “invalid argument” error on macOS.

+

Note that the socket address cannot be implicitly trusted, because it is relatively +trivial to send a UDP datagram with a spoofed origin in a packet injection attack. +Because UDP is stateless and does not validate the origin of a packet, +the attacker does not need to be able to intercept traffic in order to interfere. +It is important to be aware of this when designing your application-level protocol.

+

pub fn poll_peek_sender( + &self, + cx: &mut Context<'_> +) -> Poll<Result<SocketAddr, Error>>

Retrieve the sender of the data at the head of the input queue, +scheduling a wakeup if empty.

+

This is equivalent to calling poll_peek_from with a zero-sized buffer, +but suppresses the WSAEMSGSIZE error on Windows and the “invalid argument” error on macOS.

+
§Notes
+

Note that on multiple calls to a poll_* method in the recv direction, only the +Waker from the Context passed to the most recent call will be scheduled to +receive a wakeup.

+

Note that the socket address cannot be implicitly trusted, because it is relatively +trivial to send a UDP datagram with a spoofed origin in a packet injection attack. +Because UDP is stateless and does not validate the origin of a packet, +the attacker does not need to be able to intercept traffic in order to interfere. +It is important to be aware of this when designing your application-level protocol.

+

pub fn try_peek_sender(&self) -> Result<SocketAddr, Error>

Try to retrieve the sender of the data at the head of the input queue.

+

When there is no pending data, Err(io::ErrorKind::WouldBlock) is +returned. This function is usually paired with readable().

+

Note that the socket address cannot be implicitly trusted, because it is relatively +trivial to send a UDP datagram with a spoofed origin in a packet injection attack. +Because UDP is stateless and does not validate the origin of a packet, +the attacker does not need to be able to intercept traffic in order to interfere. +It is important to be aware of this when designing your application-level protocol.

+

pub fn broadcast(&self) -> Result<bool, Error>

Gets the value of the SO_BROADCAST option for this socket.

+

For more information about this option, see set_broadcast.

+

pub fn set_broadcast(&self, on: bool) -> Result<(), Error>

Sets the value of the SO_BROADCAST option for this socket.

+

When enabled, this socket is allowed to send packets to a broadcast +address.

+

pub fn multicast_loop_v4(&self) -> Result<bool, Error>

Gets the value of the IP_MULTICAST_LOOP option for this socket.

+

For more information about this option, see set_multicast_loop_v4.

+

pub fn set_multicast_loop_v4(&self, on: bool) -> Result<(), Error>

Sets the value of the IP_MULTICAST_LOOP option for this socket.

+

If enabled, multicast packets will be looped back to the local socket.

+
§Note
+

This may not have any affect on IPv6 sockets.

+

pub fn multicast_ttl_v4(&self) -> Result<u32, Error>

Gets the value of the IP_MULTICAST_TTL option for this socket.

+

For more information about this option, see set_multicast_ttl_v4.

+

pub fn set_multicast_ttl_v4(&self, ttl: u32) -> Result<(), Error>

Sets the value of the IP_MULTICAST_TTL option for this socket.

+

Indicates the time-to-live value of outgoing multicast packets for +this socket. The default value is 1 which means that multicast packets +don’t leave the local network unless explicitly requested.

+
§Note
+

This may not have any affect on IPv6 sockets.

+

pub fn multicast_loop_v6(&self) -> Result<bool, Error>

Gets the value of the IPV6_MULTICAST_LOOP option for this socket.

+

For more information about this option, see set_multicast_loop_v6.

+

pub fn set_multicast_loop_v6(&self, on: bool) -> Result<(), Error>

Sets the value of the IPV6_MULTICAST_LOOP option for this socket.

+

Controls whether this socket sees the multicast packets it sends itself.

+
§Note
+

This may not have any affect on IPv4 sockets.

+

pub fn ttl(&self) -> Result<u32, Error>

Gets the value of the IP_TTL option for this socket.

+

For more information about this option, see set_ttl.

+
§Examples
+
use tokio::net::UdpSocket;
+
+let sock = UdpSocket::bind("127.0.0.1:8080").await?;
+
+println!("{:?}", sock.ttl()?);
+

pub fn set_ttl(&self, ttl: u32) -> Result<(), Error>

Sets the value for the IP_TTL option on this socket.

+

This value sets the time-to-live field that is used in every packet sent +from this socket.

+
§Examples
+
use tokio::net::UdpSocket;
+
+let sock = UdpSocket::bind("127.0.0.1:8080").await?;
+sock.set_ttl(60)?;
+
+

pub fn tos(&self) -> Result<u32, Error>

Available on neither Fuchsia nor Redox nor Solaris nor illumos.

Gets the value of the IP_TOS option for this socket.

+

For more information about this option, see set_tos.

+

NOTE: On Windows, IP_TOS is only supported on Windows 8+ or +Windows Server 2012+.

+

pub fn set_tos(&self, tos: u32) -> Result<(), Error>

Available on neither Fuchsia nor Redox nor Solaris nor illumos.

Sets the value for the IP_TOS option on this socket.

+

This value sets the type-of-service field that is used in every packet +sent from this socket.

+

NOTE: On Windows, IP_TOS is only supported on Windows 8+ or +Windows Server 2012+.

+

pub fn device(&self) -> Result<Option<Vec<u8>>, Error>

Available on Android or Fuchsia or Linux only.

Gets the value for the SO_BINDTODEVICE option on this socket

+

This value gets the socket-bound device’s interface name.

+

pub fn bind_device(&self, interface: Option<&[u8]>) -> Result<(), Error>

Available on Android or Fuchsia or Linux only.

Sets the value for the SO_BINDTODEVICE option on this socket

+

If a socket is bound to an interface, only packets received from that +particular interface are processed by the socket. Note that this only +works for some socket types, particularly AF_INET sockets.

+

If interface is None or an empty string it removes the binding.

+

pub fn join_multicast_v4( + &self, + multiaddr: Ipv4Addr, + interface: Ipv4Addr +) -> Result<(), Error>

Executes an operation of the IP_ADD_MEMBERSHIP type.

+

This function specifies a new multicast group for this socket to join. +The address must be a valid multicast address, and interface is the +address of the local interface with which the system should join the +multicast group. If it’s equal to INADDR_ANY then an appropriate +interface is chosen by the system.

+

pub fn join_multicast_v6( + &self, + multiaddr: &Ipv6Addr, + interface: u32 +) -> Result<(), Error>

Executes an operation of the IPV6_ADD_MEMBERSHIP type.

+

This function specifies a new multicast group for this socket to join. +The address must be a valid multicast address, and interface is the +index of the interface to join/leave (or 0 to indicate any interface).

+

pub fn leave_multicast_v4( + &self, + multiaddr: Ipv4Addr, + interface: Ipv4Addr +) -> Result<(), Error>

Executes an operation of the IP_DROP_MEMBERSHIP type.

+

For more information about this option, see join_multicast_v4.

+

pub fn leave_multicast_v6( + &self, + multiaddr: &Ipv6Addr, + interface: u32 +) -> Result<(), Error>

Executes an operation of the IPV6_DROP_MEMBERSHIP type.

+

For more information about this option, see join_multicast_v6.

+

pub fn take_error(&self) -> Result<Option<Error>, Error>

Returns the value of the SO_ERROR option.

+
§Examples
+
use tokio::net::UdpSocket;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    // Create a socket
+    let socket = UdpSocket::bind("0.0.0.0:8080").await?;
+
+    if let Ok(Some(err)) = socket.take_error() {
+        println!("Got error: {:?}", err);
+    }
+
+    Ok(())
+}
+

Trait Implementations§

§

impl AsFd for UdpSocket

§

fn as_fd(&self) -> BorrowedFd<'_>

Borrows the file descriptor. Read more
§

impl AsRawFd for UdpSocket

§

fn as_raw_fd(&self) -> i32

Extracts the raw file descriptor. Read more
§

impl Debug for UdpSocket

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl TryFrom<UdpSocket> for UdpSocket

§

fn try_from( + stream: UdpSocket +) -> Result<UdpSocket, <UdpSocket as TryFrom<UdpSocket>>::Error>

Consumes stream, returning the tokio I/O object.

+

This is equivalent to +UdpSocket::from_std(stream).

+
§

type Error = Error

The type returned in the event of a conversion error.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/net/struct.UnixDatagram.html b/actix_web/rt/net/struct.UnixDatagram.html new file mode 100644 index 000000000..8f7ff6a2f --- /dev/null +++ b/actix_web/rt/net/struct.UnixDatagram.html @@ -0,0 +1,1009 @@ +UnixDatagram in actix_web::rt::net - Rust

Struct actix_web::rt::net::UnixDatagram

pub struct UnixDatagram { /* private fields */ }
Available on Unix and crate feature net only.
Expand description

An I/O object representing a Unix datagram socket.

+

A socket can be either named (associated with a filesystem path) or +unnamed.

+

This type does not provide a split method, because this functionality +can be achieved by wrapping the socket in an Arc. Note that you do +not need a Mutex to share the UnixDatagram — an Arc<UnixDatagram> +is enough. This is because all of the methods take &self instead of +&mut self.

+

Note: named sockets are persisted even after the object is dropped +and the program has exited, and cannot be reconnected. It is advised +that you either check for and unlink the existing socket if it exists, +or use a temporary file that is guaranteed to not already exist.

+

§Examples

+

Using named sockets, associated with a filesystem path:

+ +
use tokio::net::UnixDatagram;
+use tempfile::tempdir;
+
+// We use a temporary directory so that the socket
+// files left by the bound sockets will get cleaned up.
+let tmp = tempdir()?;
+
+// Bind each socket to a filesystem path
+let tx_path = tmp.path().join("tx");
+let tx = UnixDatagram::bind(&tx_path)?;
+let rx_path = tmp.path().join("rx");
+let rx = UnixDatagram::bind(&rx_path)?;
+
+let bytes = b"hello world";
+tx.send_to(bytes, &rx_path).await?;
+
+let mut buf = vec![0u8; 24];
+let (size, addr) = rx.recv_from(&mut buf).await?;
+
+let dgram = &buf[..size];
+assert_eq!(dgram, bytes);
+assert_eq!(addr.as_pathname().unwrap(), &tx_path);
+
+

Using unnamed sockets, created as a pair

+ +
use tokio::net::UnixDatagram;
+
+// Create the pair of sockets
+let (sock1, sock2) = UnixDatagram::pair()?;
+
+// Since the sockets are paired, the paired send/recv
+// functions can be used
+let bytes = b"hello world";
+sock1.send(bytes).await?;
+
+let mut buff = vec![0u8; 24];
+let size = sock2.recv(&mut buff).await?;
+
+let dgram = &buff[..size];
+assert_eq!(dgram, bytes);
+
+

Implementations§

§

impl UnixDatagram

pub async fn ready(&self, interest: Interest) -> Result<Ready, Error>

Waits for any of the requested ready states.

+

This function is usually paired with try_recv() or try_send(). It +can be used to concurrently recv / send to the same socket on a single +task without splitting the socket.

+

The function may complete without the socket being ready. This is a +false-positive and attempting an operation will return with +io::ErrorKind::WouldBlock. The function can also return with an empty +Ready set, so you should always check the returned value and possibly +wait again if the requested states are not set.

+
§Cancel safety
+

This method is cancel safe. Once a readiness event occurs, the method +will continue to return immediately until the readiness event is +consumed by an attempt to read or write that fails with WouldBlock or +Poll::Pending.

+
§Examples
+

Concurrently receive from and send to the socket on the same task +without splitting.

+ +
use tokio::io::Interest;
+use tokio::net::UnixDatagram;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let dir = tempfile::tempdir().unwrap();
+    let client_path = dir.path().join("client.sock");
+    let server_path = dir.path().join("server.sock");
+    let socket = UnixDatagram::bind(&client_path)?;
+    socket.connect(&server_path)?;
+
+    loop {
+        let ready = socket.ready(Interest::READABLE | Interest::WRITABLE).await?;
+
+        if ready.is_readable() {
+            let mut data = [0; 1024];
+            match socket.try_recv(&mut data[..]) {
+                Ok(n) => {
+                    println!("received {:?}", &data[..n]);
+                }
+                // False-positive, continue
+                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
+                Err(e) => {
+                    return Err(e);
+                }
+            }
+        }
+
+        if ready.is_writable() {
+            // Write some data
+            match socket.try_send(b"hello world") {
+                Ok(n) => {
+                    println!("sent {} bytes", n);
+                }
+                // False-positive, continue
+                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
+                Err(e) => {
+                    return Err(e);
+                }
+            }
+        }
+    }
+}
+

pub async fn writable(&self) -> Result<(), Error>

Waits for the socket to become writable.

+

This function is equivalent to ready(Interest::WRITABLE) and is +usually paired with try_send() or try_send_to().

+

The function may complete without the socket being writable. This is a +false-positive and attempting a try_send() will return with +io::ErrorKind::WouldBlock.

+
§Cancel safety
+

This method is cancel safe. Once a readiness event occurs, the method +will continue to return immediately until the readiness event is +consumed by an attempt to write that fails with WouldBlock or +Poll::Pending.

+
§Examples
+
use tokio::net::UnixDatagram;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let dir = tempfile::tempdir().unwrap();
+    let client_path = dir.path().join("client.sock");
+    let server_path = dir.path().join("server.sock");
+    let socket = UnixDatagram::bind(&client_path)?;
+    socket.connect(&server_path)?;
+
+    loop {
+        // Wait for the socket to be writable
+        socket.writable().await?;
+
+        // Try to send data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match socket.try_send(b"hello world") {
+            Ok(n) => {
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e);
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn poll_send_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Error>>

Polls for write/send readiness.

+

If the socket is not currently ready for sending, this method will +store a clone of the Waker from the provided Context. When the socket +becomes ready for sending, Waker::wake will be called on the +waker.

+

Note that on multiple calls to poll_send_ready or poll_send, only +the Waker from the Context passed to the most recent call is +scheduled to receive a wakeup. (However, poll_recv_ready retains a +second, independent waker.)

+

This function is intended for cases where creating and pinning a future +via writable is not feasible. Where possible, using writable is +preferred, as this supports polling from multiple tasks at once.

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if the socket is not ready for writing.
  • +
  • Poll::Ready(Ok(())) if the socket is ready for writing.
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+

pub async fn readable(&self) -> Result<(), Error>

Waits for the socket to become readable.

+

This function is equivalent to ready(Interest::READABLE) and is usually +paired with try_recv().

+

The function may complete without the socket being readable. This is a +false-positive and attempting a try_recv() will return with +io::ErrorKind::WouldBlock.

+
§Cancel safety
+

This method is cancel safe. Once a readiness event occurs, the method +will continue to return immediately until the readiness event is +consumed by an attempt to read that fails with WouldBlock or +Poll::Pending.

+
§Examples
+
use tokio::net::UnixDatagram;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    // Connect to a peer
+    let dir = tempfile::tempdir().unwrap();
+    let client_path = dir.path().join("client.sock");
+    let server_path = dir.path().join("server.sock");
+    let socket = UnixDatagram::bind(&client_path)?;
+    socket.connect(&server_path)?;
+
+    loop {
+        // Wait for the socket to be readable
+        socket.readable().await?;
+
+        // The buffer is **not** included in the async task and will
+        // only exist on the stack.
+        let mut buf = [0; 1024];
+
+        // Try to recv data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match socket.try_recv(&mut buf) {
+            Ok(n) => {
+                println!("GOT {:?}", &buf[..n]);
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e);
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn poll_recv_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Error>>

Polls for read/receive readiness.

+

If the socket is not currently ready for receiving, this method will +store a clone of the Waker from the provided Context. When the +socket becomes ready for reading, Waker::wake will be called on the +waker.

+

Note that on multiple calls to poll_recv_ready, poll_recv or +poll_peek, only the Waker from the Context passed to the most +recent call is scheduled to receive a wakeup. (However, +poll_send_ready retains a second, independent waker.)

+

This function is intended for cases where creating and pinning a future +via readable is not feasible. Where possible, using readable is +preferred, as this supports polling from multiple tasks at once.

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if the socket is not ready for reading.
  • +
  • Poll::Ready(Ok(())) if the socket is ready for reading.
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+

pub fn bind<P>(path: P) -> Result<UnixDatagram, Error>
where + P: AsRef<Path>,

Creates a new UnixDatagram bound to the specified path.

+
§Examples
+
use tokio::net::UnixDatagram;
+use tempfile::tempdir;
+
+// We use a temporary directory so that the socket
+// files left by the bound sockets will get cleaned up.
+let tmp = tempdir()?;
+
+// Bind the socket to a filesystem path
+let socket_path = tmp.path().join("socket");
+let socket = UnixDatagram::bind(&socket_path)?;
+
+

pub fn pair() -> Result<(UnixDatagram, UnixDatagram), Error>

Creates an unnamed pair of connected sockets.

+

This function will create a pair of interconnected Unix sockets for +communicating back and forth between one another.

+
§Examples
+
use tokio::net::UnixDatagram;
+
+// Create the pair of sockets
+let (sock1, sock2) = UnixDatagram::pair()?;
+
+// Since the sockets are paired, the paired send/recv
+// functions can be used
+let bytes = b"hail eris";
+sock1.send(bytes).await?;
+
+let mut buff = vec![0u8; 24];
+let size = sock2.recv(&mut buff).await?;
+
+let dgram = &buff[..size];
+assert_eq!(dgram, bytes);
+
+

pub fn from_std(datagram: UnixDatagram) -> Result<UnixDatagram, Error>

Creates new UnixDatagram from a std::os::unix::net::UnixDatagram.

+

This function is intended to be used to wrap a UnixDatagram from the +standard library in the Tokio equivalent.

+
§Notes
+

The caller is responsible for ensuring that the socket is in +non-blocking mode. Otherwise all I/O operations on the socket +will block the thread, which will cause unexpected behavior. +Non-blocking mode can be set using set_nonblocking.

+
§Panics
+

This function panics if it is not called from within a runtime with +IO enabled.

+

The runtime is usually set implicitly when this function is called +from a future driven by a Tokio runtime, otherwise runtime can be set +explicitly with Runtime::enter function.

+
§Examples
+
use tokio::net::UnixDatagram;
+use std::os::unix::net::UnixDatagram as StdUDS;
+use tempfile::tempdir;
+
+// We use a temporary directory so that the socket
+// files left by the bound sockets will get cleaned up.
+let tmp = tempdir()?;
+
+// Bind the socket to a filesystem path
+let socket_path = tmp.path().join("socket");
+let std_socket = StdUDS::bind(&socket_path)?;
+std_socket.set_nonblocking(true)?;
+let tokio_socket = UnixDatagram::from_std(std_socket)?;
+
+

pub fn into_std(self) -> Result<UnixDatagram, Error>

Turns a tokio::net::UnixDatagram into a std::os::unix::net::UnixDatagram.

+

The returned std::os::unix::net::UnixDatagram will have nonblocking +mode set as true. Use set_nonblocking to change the blocking mode +if needed.

+
§Examples
+
let tokio_socket = tokio::net::UnixDatagram::bind("/path/to/the/socket")?;
+let std_socket = tokio_socket.into_std()?;
+std_socket.set_nonblocking(false)?;
+

pub fn unbound() -> Result<UnixDatagram, Error>

Creates a new UnixDatagram which is not bound to any address.

+
§Examples
+
use tokio::net::UnixDatagram;
+use tempfile::tempdir;
+
+// Create an unbound socket
+let tx = UnixDatagram::unbound()?;
+
+// Create another, bound socket
+let tmp = tempdir()?;
+let rx_path = tmp.path().join("rx");
+let rx = UnixDatagram::bind(&rx_path)?;
+
+// Send to the bound socket
+let bytes = b"hello world";
+tx.send_to(bytes, &rx_path).await?;
+
+let mut buf = vec![0u8; 24];
+let (size, addr) = rx.recv_from(&mut buf).await?;
+
+let dgram = &buf[..size];
+assert_eq!(dgram, bytes);
+
+

pub fn connect<P>(&self, path: P) -> Result<(), Error>
where + P: AsRef<Path>,

Connects the socket to the specified address.

+

The send method may be used to send data to the specified address. +recv and recv_from will only receive data from that address.

+
§Examples
+
use tokio::net::UnixDatagram;
+use tempfile::tempdir;
+
+// Create an unbound socket
+let tx = UnixDatagram::unbound()?;
+
+// Create another, bound socket
+let tmp = tempdir()?;
+let rx_path = tmp.path().join("rx");
+let rx = UnixDatagram::bind(&rx_path)?;
+
+// Connect to the bound socket
+tx.connect(&rx_path)?;
+
+// Send to the bound socket
+let bytes = b"hello world";
+tx.send(bytes).await?;
+
+let mut buf = vec![0u8; 24];
+let (size, addr) = rx.recv_from(&mut buf).await?;
+
+let dgram = &buf[..size];
+assert_eq!(dgram, bytes);
+
+

pub async fn send(&self, buf: &[u8]) -> Result<usize, Error>

Sends data on the socket to the socket’s peer.

+
§Cancel safety
+

This method is cancel safe. If send is used as the event in a +tokio::select! statement and some other branch +completes first, then it is guaranteed that the message was not sent.

+
§Examples
+
use tokio::net::UnixDatagram;
+
+// Create the pair of sockets
+let (sock1, sock2) = UnixDatagram::pair()?;
+
+// Since the sockets are paired, the paired send/recv
+// functions can be used
+let bytes = b"hello world";
+sock1.send(bytes).await?;
+
+let mut buff = vec![0u8; 24];
+let size = sock2.recv(&mut buff).await?;
+
+let dgram = &buff[..size];
+assert_eq!(dgram, bytes);
+
+

pub fn try_send(&self, buf: &[u8]) -> Result<usize, Error>

Tries to send a datagram to the peer without waiting.

+
§Examples
+
use tokio::net::UnixDatagram;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let dir = tempfile::tempdir().unwrap();
+    let client_path = dir.path().join("client.sock");
+    let server_path = dir.path().join("server.sock");
+    let socket = UnixDatagram::bind(&client_path)?;
+    socket.connect(&server_path)?;
+
+    loop {
+        // Wait for the socket to be writable
+        socket.writable().await?;
+
+        // Try to send data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match socket.try_send(b"hello world") {
+            Ok(n) => {
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e);
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn try_send_to<P>(&self, buf: &[u8], target: P) -> Result<usize, Error>
where + P: AsRef<Path>,

Tries to send a datagram to the peer without waiting.

+
§Examples
+
use tokio::net::UnixDatagram;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let dir = tempfile::tempdir().unwrap();
+    let client_path = dir.path().join("client.sock");
+    let server_path = dir.path().join("server.sock");
+    let socket = UnixDatagram::bind(&client_path)?;
+
+    loop {
+        // Wait for the socket to be writable
+        socket.writable().await?;
+
+        // Try to send data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match socket.try_send_to(b"hello world", &server_path) {
+            Ok(n) => {
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e);
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub async fn recv(&self, buf: &mut [u8]) -> Result<usize, Error>

Receives data from the socket.

+
§Cancel safety
+

This method is cancel safe. If recv is used as the event in a +tokio::select! statement and some other branch +completes first, it is guaranteed that no messages were received on this +socket.

+
§Examples
+
use tokio::net::UnixDatagram;
+
+// Create the pair of sockets
+let (sock1, sock2) = UnixDatagram::pair()?;
+
+// Since the sockets are paired, the paired send/recv
+// functions can be used
+let bytes = b"hello world";
+sock1.send(bytes).await?;
+
+let mut buff = vec![0u8; 24];
+let size = sock2.recv(&mut buff).await?;
+
+let dgram = &buff[..size];
+assert_eq!(dgram, bytes);
+
+

pub fn try_recv(&self, buf: &mut [u8]) -> Result<usize, Error>

Tries to receive a datagram from the peer without waiting.

+
§Examples
+
use tokio::net::UnixDatagram;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    // Connect to a peer
+    let dir = tempfile::tempdir().unwrap();
+    let client_path = dir.path().join("client.sock");
+    let server_path = dir.path().join("server.sock");
+    let socket = UnixDatagram::bind(&client_path)?;
+    socket.connect(&server_path)?;
+
+    loop {
+        // Wait for the socket to be readable
+        socket.readable().await?;
+
+        // The buffer is **not** included in the async task and will
+        // only exist on the stack.
+        let mut buf = [0; 1024];
+
+        // Try to recv data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match socket.try_recv(&mut buf) {
+            Ok(n) => {
+                println!("GOT {:?}", &buf[..n]);
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e);
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn try_recv_buf_from<B>( + &self, + buf: &mut B +) -> Result<(usize, SocketAddr), Error>
where + B: BufMut,

Available on crate feature io-util only.

Tries to receive data from the socket without waiting.

+

This method can be used even if buf is uninitialized.

+
§Examples
+
use tokio::net::UnixDatagram;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    // Connect to a peer
+    let dir = tempfile::tempdir().unwrap();
+    let client_path = dir.path().join("client.sock");
+    let server_path = dir.path().join("server.sock");
+    let socket = UnixDatagram::bind(&client_path)?;
+
+    loop {
+        // Wait for the socket to be readable
+        socket.readable().await?;
+
+        let mut buf = Vec::with_capacity(1024);
+
+        // Try to recv data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match socket.try_recv_buf_from(&mut buf) {
+            Ok((n, _addr)) => {
+                println!("GOT {:?}", &buf[..n]);
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e);
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub async fn recv_buf_from<B>( + &self, + buf: &mut B +) -> Result<(usize, SocketAddr), Error>
where + B: BufMut,

Available on crate feature io-util only.

Receives from the socket, advances the +buffer’s internal cursor and returns how many bytes were read and the origin.

+

This method can be used even if buf is uninitialized.

+
§Examples
+
use tokio::net::UnixDatagram;
+use tempfile::tempdir;
+
+// We use a temporary directory so that the socket
+// files left by the bound sockets will get cleaned up.
+let tmp = tempdir()?;
+
+// Bind each socket to a filesystem path
+let tx_path = tmp.path().join("tx");
+let tx = UnixDatagram::bind(&tx_path)?;
+let rx_path = tmp.path().join("rx");
+let rx = UnixDatagram::bind(&rx_path)?;
+
+let bytes = b"hello world";
+tx.send_to(bytes, &rx_path).await?;
+
+let mut buf = Vec::with_capacity(24);
+let (size, addr) = rx.recv_buf_from(&mut buf).await?;
+
+let dgram = &buf[..size];
+assert_eq!(dgram, bytes);
+assert_eq!(addr.as_pathname().unwrap(), &tx_path);
+
+

pub fn try_recv_buf<B>(&self, buf: &mut B) -> Result<usize, Error>
where + B: BufMut,

Available on crate feature io-util only.

Tries to read data from the stream into the provided buffer, advancing the +buffer’s internal cursor, returning how many bytes were read.

+

This method can be used even if buf is uninitialized.

+
§Examples
+
use tokio::net::UnixDatagram;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    // Connect to a peer
+    let dir = tempfile::tempdir().unwrap();
+    let client_path = dir.path().join("client.sock");
+    let server_path = dir.path().join("server.sock");
+    let socket = UnixDatagram::bind(&client_path)?;
+    socket.connect(&server_path)?;
+
+    loop {
+        // Wait for the socket to be readable
+        socket.readable().await?;
+
+        let mut buf = Vec::with_capacity(1024);
+
+        // Try to recv data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match socket.try_recv_buf(&mut buf) {
+            Ok(n) => {
+                println!("GOT {:?}", &buf[..n]);
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e);
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub async fn recv_buf<B>(&self, buf: &mut B) -> Result<usize, Error>
where + B: BufMut,

Available on crate feature io-util only.

Receives data from the socket from the address to which it is connected, +advancing the buffer’s internal cursor, returning how many bytes were read.

+

This method can be used even if buf is uninitialized.

+
§Examples
+
use tokio::net::UnixDatagram;
+
+// Create the pair of sockets
+let (sock1, sock2) = UnixDatagram::pair()?;
+
+// Since the sockets are paired, the paired send/recv
+// functions can be used
+let bytes = b"hello world";
+sock1.send(bytes).await?;
+
+let mut buff = Vec::with_capacity(24);
+let size = sock2.recv_buf(&mut buff).await?;
+
+let dgram = &buff[..size];
+assert_eq!(dgram, bytes);
+
+

pub async fn send_to<P>(&self, buf: &[u8], target: P) -> Result<usize, Error>
where + P: AsRef<Path>,

Sends data on the socket to the specified address.

+
§Cancel safety
+

This method is cancel safe. If send_to is used as the event in a +tokio::select! statement and some other branch +completes first, then it is guaranteed that the message was not sent.

+
§Examples
+
use tokio::net::UnixDatagram;
+use tempfile::tempdir;
+
+// We use a temporary directory so that the socket
+// files left by the bound sockets will get cleaned up.
+let tmp = tempdir()?;
+
+// Bind each socket to a filesystem path
+let tx_path = tmp.path().join("tx");
+let tx = UnixDatagram::bind(&tx_path)?;
+let rx_path = tmp.path().join("rx");
+let rx = UnixDatagram::bind(&rx_path)?;
+
+let bytes = b"hello world";
+tx.send_to(bytes, &rx_path).await?;
+
+let mut buf = vec![0u8; 24];
+let (size, addr) = rx.recv_from(&mut buf).await?;
+
+let dgram = &buf[..size];
+assert_eq!(dgram, bytes);
+assert_eq!(addr.as_pathname().unwrap(), &tx_path);
+
+

pub async fn recv_from( + &self, + buf: &mut [u8] +) -> Result<(usize, SocketAddr), Error>

Receives data from the socket.

+
§Cancel safety
+

This method is cancel safe. If recv_from is used as the event in a +tokio::select! statement and some other branch +completes first, it is guaranteed that no messages were received on this +socket.

+
§Examples
+
use tokio::net::UnixDatagram;
+use tempfile::tempdir;
+
+// We use a temporary directory so that the socket
+// files left by the bound sockets will get cleaned up.
+let tmp = tempdir()?;
+
+// Bind each socket to a filesystem path
+let tx_path = tmp.path().join("tx");
+let tx = UnixDatagram::bind(&tx_path)?;
+let rx_path = tmp.path().join("rx");
+let rx = UnixDatagram::bind(&rx_path)?;
+
+let bytes = b"hello world";
+tx.send_to(bytes, &rx_path).await?;
+
+let mut buf = vec![0u8; 24];
+let (size, addr) = rx.recv_from(&mut buf).await?;
+
+let dgram = &buf[..size];
+assert_eq!(dgram, bytes);
+assert_eq!(addr.as_pathname().unwrap(), &tx_path);
+
+

pub fn poll_recv_from( + &self, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_> +) -> Poll<Result<SocketAddr, Error>>

Attempts to receive a single datagram on the specified address.

+

Note that on multiple calls to a poll_* method in the recv direction, only the +Waker from the Context passed to the most recent call will be scheduled to +receive a wakeup.

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if the socket is not ready to read
  • +
  • Poll::Ready(Ok(addr)) reads data from addr into ReadBuf if the socket is ready
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+

pub fn poll_send_to<P>( + &self, + cx: &mut Context<'_>, + buf: &[u8], + target: P +) -> Poll<Result<usize, Error>>
where + P: AsRef<Path>,

Attempts to send data to the specified address.

+

Note that on multiple calls to a poll_* method in the send direction, only the +Waker from the Context passed to the most recent call will be scheduled to +receive a wakeup.

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if the socket is not ready to write
  • +
  • Poll::Ready(Ok(n)) n is the number of bytes sent.
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+

pub fn poll_send( + &self, + cx: &mut Context<'_>, + buf: &[u8] +) -> Poll<Result<usize, Error>>

Attempts to send data on the socket to the remote address to which it +was previously connected.

+

The connect method will connect this socket to a remote address. +This method will fail if the socket is not connected.

+

Note that on multiple calls to a poll_* method in the send direction, +only the Waker from the Context passed to the most recent call will +be scheduled to receive a wakeup.

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if the socket is not available to write
  • +
  • Poll::Ready(Ok(n)) n is the number of bytes sent
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+

pub fn poll_recv( + &self, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_> +) -> Poll<Result<(), Error>>

Attempts to receive a single datagram message on the socket from the remote +address to which it is connected.

+

The connect method will connect this socket to a remote address. This method +resolves to an error if the socket is not connected.

+

Note that on multiple calls to a poll_* method in the recv direction, only the +Waker from the Context passed to the most recent call will be scheduled to +receive a wakeup.

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if the socket is not ready to read
  • +
  • Poll::Ready(Ok(())) reads data ReadBuf if the socket is ready
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+

pub fn try_recv_from( + &self, + buf: &mut [u8] +) -> Result<(usize, SocketAddr), Error>

Tries to receive data from the socket without waiting.

+
§Examples
+
use tokio::net::UnixDatagram;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    // Connect to a peer
+    let dir = tempfile::tempdir().unwrap();
+    let client_path = dir.path().join("client.sock");
+    let server_path = dir.path().join("server.sock");
+    let socket = UnixDatagram::bind(&client_path)?;
+
+    loop {
+        // Wait for the socket to be readable
+        socket.readable().await?;
+
+        // The buffer is **not** included in the async task and will
+        // only exist on the stack.
+        let mut buf = [0; 1024];
+
+        // Try to recv data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match socket.try_recv_from(&mut buf) {
+            Ok((n, _addr)) => {
+                println!("GOT {:?}", &buf[..n]);
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e);
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn try_io<R>( + &self, + interest: Interest, + f: impl FnOnce() -> Result<R, Error> +) -> Result<R, Error>

Tries to read or write from the socket using a user-provided IO operation.

+

If the socket is ready, the provided closure is called. The closure +should attempt to perform IO operation on the socket by manually +calling the appropriate syscall. If the operation fails because the +socket is not actually ready, then the closure should return a +WouldBlock error and the readiness flag is cleared. The return value +of the closure is then returned by try_io.

+

If the socket is not ready, then the closure is not called +and a WouldBlock error is returned.

+

The closure should only return a WouldBlock error if it has performed +an IO operation on the socket that failed due to the socket not being +ready. Returning a WouldBlock error in any other situation will +incorrectly clear the readiness flag, which can cause the socket to +behave incorrectly.

+

The closure should not perform the IO operation using any of the methods +defined on the Tokio UnixDatagram type, as this will mess with the +readiness flag and can cause the socket to behave incorrectly.

+

This method is not intended to be used with combined interests. +The closure should perform only one type of IO operation, so it should not +require more than one ready state. This method may panic or sleep forever +if it is called with a combined interest.

+

Usually, readable(), writable() or ready() is used with this function.

+

pub async fn async_io<R>( + &self, + interest: Interest, + f: impl FnMut() -> Result<R, Error> +) -> Result<R, Error>

Reads or writes from the socket using a user-provided IO operation.

+

The readiness of the socket is awaited and when the socket is ready, +the provided closure is called. The closure should attempt to perform +IO operation on the socket by manually calling the appropriate syscall. +If the operation fails because the socket is not actually ready, +then the closure should return a WouldBlock error. In such case the +readiness flag is cleared and the socket readiness is awaited again. +This loop is repeated until the closure returns an Ok or an error +other than WouldBlock.

+

The closure should only return a WouldBlock error if it has performed +an IO operation on the socket that failed due to the socket not being +ready. Returning a WouldBlock error in any other situation will +incorrectly clear the readiness flag, which can cause the socket to +behave incorrectly.

+

The closure should not perform the IO operation using any of the methods +defined on the Tokio UnixDatagram type, as this will mess with the +readiness flag and can cause the socket to behave incorrectly.

+

This method is not intended to be used with combined interests. +The closure should perform only one type of IO operation, so it should not +require more than one ready state. This method may panic or sleep forever +if it is called with a combined interest.

+

pub fn local_addr(&self) -> Result<SocketAddr, Error>

Returns the local address that this socket is bound to.

+
§Examples
+

For a socket bound to a local path

+ +
use tokio::net::UnixDatagram;
+use tempfile::tempdir;
+
+// We use a temporary directory so that the socket
+// files left by the bound sockets will get cleaned up.
+let tmp = tempdir()?;
+
+// Bind socket to a filesystem path
+let socket_path = tmp.path().join("socket");
+let socket = UnixDatagram::bind(&socket_path)?;
+
+assert_eq!(socket.local_addr()?.as_pathname().unwrap(), &socket_path);
+
+

For an unbound socket

+ +
use tokio::net::UnixDatagram;
+
+// Create an unbound socket
+let socket = UnixDatagram::unbound()?;
+
+assert!(socket.local_addr()?.is_unnamed());
+
+

pub fn peer_addr(&self) -> Result<SocketAddr, Error>

Returns the address of this socket’s peer.

+

The connect method will connect the socket to a peer.

+
§Examples
+

For a peer with a local path

+ +
use tokio::net::UnixDatagram;
+use tempfile::tempdir;
+
+// Create an unbound socket
+let tx = UnixDatagram::unbound()?;
+
+// Create another, bound socket
+let tmp = tempdir()?;
+let rx_path = tmp.path().join("rx");
+let rx = UnixDatagram::bind(&rx_path)?;
+
+// Connect to the bound socket
+tx.connect(&rx_path)?;
+
+assert_eq!(tx.peer_addr()?.as_pathname().unwrap(), &rx_path);
+
+

For an unbound peer

+ +
use tokio::net::UnixDatagram;
+
+// Create the pair of sockets
+let (sock1, sock2) = UnixDatagram::pair()?;
+
+assert!(sock1.peer_addr()?.is_unnamed());
+
+

pub fn take_error(&self) -> Result<Option<Error>, Error>

Returns the value of the SO_ERROR option.

+
§Examples
+
use tokio::net::UnixDatagram;
+
+// Create an unbound socket
+let socket = UnixDatagram::unbound()?;
+
+if let Ok(Some(err)) = socket.take_error() {
+    println!("Got error: {:?}", err);
+}
+
+

pub fn shutdown(&self, how: Shutdown) -> Result<(), Error>

Shuts down the read, write, or both halves of this connection.

+

This function will cause all pending and future I/O calls on the +specified portions to immediately return with an appropriate value +(see the documentation of Shutdown).

+
§Examples
+
use tokio::net::UnixDatagram;
+use std::net::Shutdown;
+
+// Create an unbound socket
+let (socket, other) = UnixDatagram::pair()?;
+
+socket.shutdown(Shutdown::Both)?;
+
+// NOTE: the following commented out code does NOT work as expected.
+// Due to an underlying issue, the recv call will block indefinitely.
+// See: https://github.com/tokio-rs/tokio/issues/1679
+//let mut buff = vec![0u8; 24];
+//let size = socket.recv(&mut buff).await?;
+//assert_eq!(size, 0);
+
+let send_result = socket.send(b"hello world").await;
+assert!(send_result.is_err());
+
+

Trait Implementations§

§

impl AsFd for UnixDatagram

§

fn as_fd(&self) -> BorrowedFd<'_>

Borrows the file descriptor. Read more
§

impl AsRawFd for UnixDatagram

§

fn as_raw_fd(&self) -> i32

Extracts the raw file descriptor. Read more
§

impl Debug for UnixDatagram

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl TryFrom<UnixDatagram> for UnixDatagram

§

fn try_from( + stream: UnixDatagram +) -> Result<UnixDatagram, <UnixDatagram as TryFrom<UnixDatagram>>::Error>

Consumes stream, returning the Tokio I/O object.

+

This is equivalent to +UnixDatagram::from_std(stream).

+
§

type Error = Error

The type returned in the event of a conversion error.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/net/struct.UnixListener.html b/actix_web/rt/net/struct.UnixListener.html new file mode 100644 index 000000000..f3b6bb049 --- /dev/null +++ b/actix_web/rt/net/struct.UnixListener.html @@ -0,0 +1,96 @@ +UnixListener in actix_web::rt::net - Rust

Struct actix_web::rt::net::UnixListener

pub struct UnixListener { /* private fields */ }
Available on Unix and crate feature net only.
Expand description

A Unix socket which can accept connections from other Unix sockets.

+

You can accept a new connection by using the accept method.

+

A UnixListener can be turned into a Stream with UnixListenerStream.

+

§Errors

+

Note that accepting a connection can lead to various errors and not all +of them are necessarily fatal ‒ for example having too many open file +descriptors or the other side closing the connection while it waits in +an accept queue. These would terminate the stream if not handled in any +way.

+

§Examples

+
use tokio::net::UnixListener;
+
+#[tokio::main]
+async fn main() {
+    let listener = UnixListener::bind("/path/to/the/socket").unwrap();
+    loop {
+        match listener.accept().await {
+            Ok((stream, _addr)) => {
+                println!("new client!");
+            }
+            Err(e) => { /* connection failed */ }
+        }
+    }
+}
+

Implementations§

§

impl UnixListener

pub fn bind<P>(path: P) -> Result<UnixListener, Error>
where + P: AsRef<Path>,

Creates a new UnixListener bound to the specified path.

+
§Panics
+

This function panics if it is not called from within a runtime with +IO enabled.

+

The runtime is usually set implicitly when this function is called +from a future driven by a tokio runtime, otherwise runtime can be set +explicitly with Runtime::enter function.

+

pub fn from_std(listener: UnixListener) -> Result<UnixListener, Error>

Creates new UnixListener from a std::os::unix::net::UnixListener.

+

This function is intended to be used to wrap a UnixListener from the +standard library in the Tokio equivalent.

+
§Notes
+

The caller is responsible for ensuring that the listener is in +non-blocking mode. Otherwise all I/O operations on the listener +will block the thread, which will cause unexpected behavior. +Non-blocking mode can be set using set_nonblocking.

+
§Examples
+
use tokio::net::UnixListener;
+use std::os::unix::net::UnixListener as StdUnixListener;
+
+let std_listener = StdUnixListener::bind("/path/to/the/socket")?;
+std_listener.set_nonblocking(true)?;
+let listener = UnixListener::from_std(std_listener)?;
+
§Panics
+

This function panics if it is not called from within a runtime with +IO enabled.

+

The runtime is usually set implicitly when this function is called +from a future driven by a tokio runtime, otherwise runtime can be set +explicitly with Runtime::enter function.

+

pub fn into_std(self) -> Result<UnixListener, Error>

Turns a tokio::net::UnixListener into a std::os::unix::net::UnixListener.

+

The returned std::os::unix::net::UnixListener will have nonblocking mode +set as true. Use set_nonblocking to change the blocking mode if needed.

+
§Examples
+
let tokio_listener = tokio::net::UnixListener::bind("/path/to/the/socket")?;
+let std_listener = tokio_listener.into_std()?;
+std_listener.set_nonblocking(false)?;
+

pub fn local_addr(&self) -> Result<SocketAddr, Error>

Returns the local socket address of this listener.

+

pub fn take_error(&self) -> Result<Option<Error>, Error>

Returns the value of the SO_ERROR option.

+

pub async fn accept(&self) -> Result<(UnixStream, SocketAddr), Error>

Accepts a new incoming connection to this listener.

+
§Cancel safety
+

This method is cancel safe. If the method is used as the event in a +tokio::select! statement and some other branch +completes first, then it is guaranteed that no new connections were +accepted by this method.

+

pub fn poll_accept( + &self, + cx: &mut Context<'_> +) -> Poll<Result<(UnixStream, SocketAddr), Error>>

Polls to accept a new incoming connection to this listener.

+

If there is no connection to accept, Poll::Pending is returned and the +current task will be notified by a waker. Note that on multiple calls +to poll_accept, only the Waker from the Context passed to the most +recent call is scheduled to receive a wakeup.

+

Trait Implementations§

§

impl AsFd for UnixListener

§

fn as_fd(&self) -> BorrowedFd<'_>

Borrows the file descriptor. Read more
§

impl AsRawFd for UnixListener

§

fn as_raw_fd(&self) -> i32

Extracts the raw file descriptor. Read more
§

impl Debug for UnixListener

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl TryFrom<UnixListener> for UnixListener

§

fn try_from(stream: UnixListener) -> Result<UnixListener, Error>

Consumes stream, returning the tokio I/O object.

+

This is equivalent to +UnixListener::from_std(stream).

+
§

type Error = Error

The type returned in the event of a conversion error.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/net/struct.UnixStream.html b/actix_web/rt/net/struct.UnixStream.html new file mode 100644 index 000000000..20fe20998 --- /dev/null +++ b/actix_web/rt/net/struct.UnixStream.html @@ -0,0 +1,750 @@ +UnixStream in actix_web::rt::net - Rust

Struct actix_web::rt::net::UnixStream

pub struct UnixStream { /* private fields */ }
Available on Unix and crate feature net only.
Expand description

A structure representing a connected Unix socket.

+

This socket can be connected directly with UnixStream::connect or accepted +from a listener with UnixListener::accept. Additionally, a pair of +anonymous Unix sockets can be created with UnixStream::pair.

+

To shut down the stream in the write direction, you can call the +shutdown() method. This will cause the other peer to receive a read of +length 0, indicating that no more data will be sent. This only closes +the stream in one direction.

+

Implementations§

§

impl UnixStream

pub async fn connect<P>(path: P) -> Result<UnixStream, Error>
where + P: AsRef<Path>,

Connects to the socket named by path.

+

This function will create a new Unix socket and connect to the path +specified, associating the returned stream with the default event loop’s +handle.

+

pub async fn ready(&self, interest: Interest) -> Result<Ready, Error>

Waits for any of the requested ready states.

+

This function is usually paired with try_read() or try_write(). It +can be used to concurrently read / write to the same socket on a single +task without splitting the socket.

+

The function may complete without the socket being ready. This is a +false-positive and attempting an operation will return with +io::ErrorKind::WouldBlock. The function can also return with an empty +Ready set, so you should always check the returned value and possibly +wait again if the requested states are not set.

+
§Cancel safety
+

This method is cancel safe. Once a readiness event occurs, the method +will continue to return immediately until the readiness event is +consumed by an attempt to read or write that fails with WouldBlock or +Poll::Pending.

+
§Examples
+

Concurrently read and write to the stream on the same task without +splitting.

+ +
use tokio::io::Interest;
+use tokio::net::UnixStream;
+use std::error::Error;
+use std::io;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    let dir = tempfile::tempdir().unwrap();
+    let bind_path = dir.path().join("bind_path");
+    let stream = UnixStream::connect(bind_path).await?;
+
+    loop {
+        let ready = stream.ready(Interest::READABLE | Interest::WRITABLE).await?;
+
+        if ready.is_readable() {
+            let mut data = vec![0; 1024];
+            // Try to read data, this may still fail with `WouldBlock`
+            // if the readiness event is a false positive.
+            match stream.try_read(&mut data) {
+                Ok(n) => {
+                    println!("read {} bytes", n);        
+                }
+                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                    continue;
+                }
+                Err(e) => {
+                    return Err(e.into());
+                }
+            }
+
+        }
+
+        if ready.is_writable() {
+            // Try to write data, this may still fail with `WouldBlock`
+            // if the readiness event is a false positive.
+            match stream.try_write(b"hello world") {
+                Ok(n) => {
+                    println!("write {} bytes", n);
+                }
+                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                    continue;
+                }
+                Err(e) => {
+                    return Err(e.into());
+                }
+            }
+        }
+    }
+}
+

pub async fn readable(&self) -> Result<(), Error>

Waits for the socket to become readable.

+

This function is equivalent to ready(Interest::READABLE) and is usually +paired with try_read().

+
§Cancel safety
+

This method is cancel safe. Once a readiness event occurs, the method +will continue to return immediately until the readiness event is +consumed by an attempt to read that fails with WouldBlock or +Poll::Pending.

+
§Examples
+
use tokio::net::UnixStream;
+use std::error::Error;
+use std::io;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    // Connect to a peer
+    let dir = tempfile::tempdir().unwrap();
+    let bind_path = dir.path().join("bind_path");
+    let stream = UnixStream::connect(bind_path).await?;
+
+    let mut msg = vec![0; 1024];
+
+    loop {
+        // Wait for the socket to be readable
+        stream.readable().await?;
+
+        // Try to read data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match stream.try_read(&mut msg) {
+            Ok(n) => {
+                msg.truncate(n);
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e.into());
+            }
+        }
+    }
+
+    println!("GOT = {:?}", msg);
+    Ok(())
+}
+

pub fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Error>>

Polls for read readiness.

+

If the unix stream is not currently ready for reading, this method will +store a clone of the Waker from the provided Context. When the unix +stream becomes ready for reading, Waker::wake will be called on the +waker.

+

Note that on multiple calls to poll_read_ready or poll_read, only +the Waker from the Context passed to the most recent call is +scheduled to receive a wakeup. (However, poll_write_ready retains a +second, independent waker.)

+

This function is intended for cases where creating and pinning a future +via readable is not feasible. Where possible, using readable is +preferred, as this supports polling from multiple tasks at once.

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if the unix stream is not ready for reading.
  • +
  • Poll::Ready(Ok(())) if the unix stream is ready for reading.
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+

pub fn try_read(&self, buf: &mut [u8]) -> Result<usize, Error>

Try to read data from the stream into the provided buffer, returning how +many bytes were read.

+

Receives any pending data from the socket but does not wait for new data +to arrive. On success, returns the number of bytes read. Because +try_read() is non-blocking, the buffer does not have to be stored by +the async task and can exist entirely on the stack.

+

Usually, readable() or ready() is used with this function.

+
§Return
+

If data is successfully read, Ok(n) is returned, where n is the +number of bytes read. If n is 0, then it can indicate one of two scenarios:

+
    +
  1. The stream’s read half is closed and will no longer yield data.
  2. +
  3. The specified buffer was 0 bytes in length.
  4. +
+

If the stream is not ready to read data, +Err(io::ErrorKind::WouldBlock) is returned.

+
§Examples
+
use tokio::net::UnixStream;
+use std::error::Error;
+use std::io;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    // Connect to a peer
+    let dir = tempfile::tempdir().unwrap();
+    let bind_path = dir.path().join("bind_path");
+    let stream = UnixStream::connect(bind_path).await?;
+
+    loop {
+        // Wait for the socket to be readable
+        stream.readable().await?;
+
+        // Creating the buffer **after** the `await` prevents it from
+        // being stored in the async task.
+        let mut buf = [0; 4096];
+
+        // Try to read data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match stream.try_read(&mut buf) {
+            Ok(0) => break,
+            Ok(n) => {
+                println!("read {} bytes", n);
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e.into());
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn try_read_vectored( + &self, + bufs: &mut [IoSliceMut<'_>] +) -> Result<usize, Error>

Tries to read data from the stream into the provided buffers, returning +how many bytes were read.

+

Data is copied to fill each buffer in order, with the final buffer +written to possibly being only partially filled. This method behaves +equivalently to a single call to try_read() with concatenated +buffers.

+

Receives any pending data from the socket but does not wait for new data +to arrive. On success, returns the number of bytes read. Because +try_read_vectored() is non-blocking, the buffer does not have to be +stored by the async task and can exist entirely on the stack.

+

Usually, readable() or ready() is used with this function.

+
§Return
+

If data is successfully read, Ok(n) is returned, where n is the +number of bytes read. Ok(0) indicates the stream’s read half is closed +and will no longer yield data. If the stream is not ready to read data +Err(io::ErrorKind::WouldBlock) is returned.

+
§Examples
+
use tokio::net::UnixStream;
+use std::error::Error;
+use std::io::{self, IoSliceMut};
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    // Connect to a peer
+    let dir = tempfile::tempdir().unwrap();
+    let bind_path = dir.path().join("bind_path");
+    let stream = UnixStream::connect(bind_path).await?;
+
+    loop {
+        // Wait for the socket to be readable
+        stream.readable().await?;
+
+        // Creating the buffer **after** the `await` prevents it from
+        // being stored in the async task.
+        let mut buf_a = [0; 512];
+        let mut buf_b = [0; 1024];
+        let mut bufs = [
+            IoSliceMut::new(&mut buf_a),
+            IoSliceMut::new(&mut buf_b),
+        ];
+
+        // Try to read data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match stream.try_read_vectored(&mut bufs) {
+            Ok(0) => break,
+            Ok(n) => {
+                println!("read {} bytes", n);
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e.into());
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn try_read_buf<B>(&self, buf: &mut B) -> Result<usize, Error>
where + B: BufMut,

Available on crate feature io-util only.

Tries to read data from the stream into the provided buffer, advancing the +buffer’s internal cursor, returning how many bytes were read.

+

Receives any pending data from the socket but does not wait for new data +to arrive. On success, returns the number of bytes read. Because +try_read_buf() is non-blocking, the buffer does not have to be stored by +the async task and can exist entirely on the stack.

+

Usually, readable() or ready() is used with this function.

+
§Return
+

If data is successfully read, Ok(n) is returned, where n is the +number of bytes read. Ok(0) indicates the stream’s read half is closed +and will no longer yield data. If the stream is not ready to read data +Err(io::ErrorKind::WouldBlock) is returned.

+
§Examples
+
use tokio::net::UnixStream;
+use std::error::Error;
+use std::io;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    // Connect to a peer
+    let dir = tempfile::tempdir().unwrap();
+    let bind_path = dir.path().join("bind_path");
+    let stream = UnixStream::connect(bind_path).await?;
+
+    loop {
+        // Wait for the socket to be readable
+        stream.readable().await?;
+
+        let mut buf = Vec::with_capacity(4096);
+
+        // Try to read data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match stream.try_read_buf(&mut buf) {
+            Ok(0) => break,
+            Ok(n) => {
+                println!("read {} bytes", n);
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e.into());
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub async fn writable(&self) -> Result<(), Error>

Waits for the socket to become writable.

+

This function is equivalent to ready(Interest::WRITABLE) and is usually +paired with try_write().

+
§Cancel safety
+

This method is cancel safe. Once a readiness event occurs, the method +will continue to return immediately until the readiness event is +consumed by an attempt to write that fails with WouldBlock or +Poll::Pending.

+
§Examples
+
use tokio::net::UnixStream;
+use std::error::Error;
+use std::io;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    // Connect to a peer
+    let dir = tempfile::tempdir().unwrap();
+    let bind_path = dir.path().join("bind_path");
+    let stream = UnixStream::connect(bind_path).await?;
+
+    loop {
+        // Wait for the socket to be writable
+        stream.writable().await?;
+
+        // Try to write data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match stream.try_write(b"hello world") {
+            Ok(n) => {
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e.into());
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Error>>

Polls for write readiness.

+

If the unix stream is not currently ready for writing, this method will +store a clone of the Waker from the provided Context. When the unix +stream becomes ready for writing, Waker::wake will be called on the +waker.

+

Note that on multiple calls to poll_write_ready or poll_write, only +the Waker from the Context passed to the most recent call is +scheduled to receive a wakeup. (However, poll_read_ready retains a +second, independent waker.)

+

This function is intended for cases where creating and pinning a future +via writable is not feasible. Where possible, using writable is +preferred, as this supports polling from multiple tasks at once.

+
§Return value
+

The function returns:

+
    +
  • Poll::Pending if the unix stream is not ready for writing.
  • +
  • Poll::Ready(Ok(())) if the unix stream is ready for writing.
  • +
  • Poll::Ready(Err(e)) if an error is encountered.
  • +
+
§Errors
+

This function may encounter any standard I/O error except WouldBlock.

+

pub fn try_write(&self, buf: &[u8]) -> Result<usize, Error>

Tries to write a buffer to the stream, returning how many bytes were +written.

+

The function will attempt to write the entire contents of buf, but +only part of the buffer may be written.

+

This function is usually paired with writable().

+
§Return
+

If data is successfully written, Ok(n) is returned, where n is the +number of bytes written. If the stream is not ready to write data, +Err(io::ErrorKind::WouldBlock) is returned.

+
§Examples
+
use tokio::net::UnixStream;
+use std::error::Error;
+use std::io;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    // Connect to a peer
+    let dir = tempfile::tempdir().unwrap();
+    let bind_path = dir.path().join("bind_path");
+    let stream = UnixStream::connect(bind_path).await?;
+
+    loop {
+        // Wait for the socket to be writable
+        stream.writable().await?;
+
+        // Try to write data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match stream.try_write(b"hello world") {
+            Ok(n) => {
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e.into());
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn try_write_vectored(&self, buf: &[IoSlice<'_>]) -> Result<usize, Error>

Tries to write several buffers to the stream, returning how many bytes +were written.

+

Data is written from each buffer in order, with the final buffer read +from possible being only partially consumed. This method behaves +equivalently to a single call to try_write() with concatenated +buffers.

+

This function is usually paired with writable().

+
§Return
+

If data is successfully written, Ok(n) is returned, where n is the +number of bytes written. If the stream is not ready to write data, +Err(io::ErrorKind::WouldBlock) is returned.

+
§Examples
+
use tokio::net::UnixStream;
+use std::error::Error;
+use std::io;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    // Connect to a peer
+    let dir = tempfile::tempdir().unwrap();
+    let bind_path = dir.path().join("bind_path");
+    let stream = UnixStream::connect(bind_path).await?;
+
+    let bufs = [io::IoSlice::new(b"hello "), io::IoSlice::new(b"world")];
+
+    loop {
+        // Wait for the socket to be writable
+        stream.writable().await?;
+
+        // Try to write data, this may still fail with `WouldBlock`
+        // if the readiness event is a false positive.
+        match stream.try_write_vectored(&bufs) {
+            Ok(n) => {
+                break;
+            }
+            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
+                continue;
+            }
+            Err(e) => {
+                return Err(e.into());
+            }
+        }
+    }
+
+    Ok(())
+}
+

pub fn try_io<R>( + &self, + interest: Interest, + f: impl FnOnce() -> Result<R, Error> +) -> Result<R, Error>

Tries to read or write from the socket using a user-provided IO operation.

+

If the socket is ready, the provided closure is called. The closure +should attempt to perform IO operation on the socket by manually +calling the appropriate syscall. If the operation fails because the +socket is not actually ready, then the closure should return a +WouldBlock error and the readiness flag is cleared. The return value +of the closure is then returned by try_io.

+

If the socket is not ready, then the closure is not called +and a WouldBlock error is returned.

+

The closure should only return a WouldBlock error if it has performed +an IO operation on the socket that failed due to the socket not being +ready. Returning a WouldBlock error in any other situation will +incorrectly clear the readiness flag, which can cause the socket to +behave incorrectly.

+

The closure should not perform the IO operation using any of the methods +defined on the Tokio UnixStream type, as this will mess with the +readiness flag and can cause the socket to behave incorrectly.

+

This method is not intended to be used with combined interests. +The closure should perform only one type of IO operation, so it should not +require more than one ready state. This method may panic or sleep forever +if it is called with a combined interest.

+

Usually, readable(), writable() or ready() is used with this function.

+

pub async fn async_io<R>( + &self, + interest: Interest, + f: impl FnMut() -> Result<R, Error> +) -> Result<R, Error>

Reads or writes from the socket using a user-provided IO operation.

+

The readiness of the socket is awaited and when the socket is ready, +the provided closure is called. The closure should attempt to perform +IO operation on the socket by manually calling the appropriate syscall. +If the operation fails because the socket is not actually ready, +then the closure should return a WouldBlock error. In such case the +readiness flag is cleared and the socket readiness is awaited again. +This loop is repeated until the closure returns an Ok or an error +other than WouldBlock.

+

The closure should only return a WouldBlock error if it has performed +an IO operation on the socket that failed due to the socket not being +ready. Returning a WouldBlock error in any other situation will +incorrectly clear the readiness flag, which can cause the socket to +behave incorrectly.

+

The closure should not perform the IO operation using any of the methods +defined on the Tokio UnixStream type, as this will mess with the +readiness flag and can cause the socket to behave incorrectly.

+

This method is not intended to be used with combined interests. +The closure should perform only one type of IO operation, so it should not +require more than one ready state. This method may panic or sleep forever +if it is called with a combined interest.

+

pub fn from_std(stream: UnixStream) -> Result<UnixStream, Error>

Creates new UnixStream from a std::os::unix::net::UnixStream.

+

This function is intended to be used to wrap a UnixStream from the +standard library in the Tokio equivalent.

+
§Notes
+

The caller is responsible for ensuring that the stream is in +non-blocking mode. Otherwise all I/O operations on the stream +will block the thread, which will cause unexpected behavior. +Non-blocking mode can be set using set_nonblocking.

+
§Examples
+
use tokio::net::UnixStream;
+use std::os::unix::net::UnixStream as StdUnixStream;
+
+let std_stream = StdUnixStream::connect("/path/to/the/socket")?;
+std_stream.set_nonblocking(true)?;
+let stream = UnixStream::from_std(std_stream)?;
+
§Panics
+

This function panics if it is not called from within a runtime with +IO enabled.

+

The runtime is usually set implicitly when this function is called +from a future driven by a tokio runtime, otherwise runtime can be set +explicitly with Runtime::enter function.

+

pub fn into_std(self) -> Result<UnixStream, Error>

Turns a tokio::net::UnixStream into a std::os::unix::net::UnixStream.

+

The returned std::os::unix::net::UnixStream will have nonblocking +mode set as true. Use set_nonblocking to change the blocking +mode if needed.

+
§Examples
+
use std::error::Error;
+use std::io::Read;
+use tokio::net::UnixListener;
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn Error>> {
+    let dir = tempfile::tempdir().unwrap();
+    let bind_path = dir.path().join("bind_path");
+
+    let mut data = [0u8; 12];
+    let listener = UnixListener::bind(&bind_path)?;
+    let (tokio_unix_stream, _) = listener.accept().await?;
+    let mut std_unix_stream = tokio_unix_stream.into_std()?;
+    std_unix_stream.set_nonblocking(false)?;
+    std_unix_stream.read_exact(&mut data)?;
+    Ok(())
+}
+

pub fn pair() -> Result<(UnixStream, UnixStream), Error>

Creates an unnamed pair of connected sockets.

+

This function will create a pair of interconnected Unix sockets for +communicating back and forth between one another. Each socket will +be associated with the default event loop’s handle.

+

pub fn local_addr(&self) -> Result<SocketAddr, Error>

Returns the socket address of the local half of this connection.

+
§Examples
+
use tokio::net::UnixStream;
+
+let dir = tempfile::tempdir().unwrap();
+let bind_path = dir.path().join("bind_path");
+let stream = UnixStream::connect(bind_path).await?;
+
+println!("{:?}", stream.local_addr()?);
+

pub fn peer_addr(&self) -> Result<SocketAddr, Error>

Returns the socket address of the remote half of this connection.

+
§Examples
+
use tokio::net::UnixStream;
+
+let dir = tempfile::tempdir().unwrap();
+let bind_path = dir.path().join("bind_path");
+let stream = UnixStream::connect(bind_path).await?;
+
+println!("{:?}", stream.peer_addr()?);
+

pub fn peer_cred(&self) -> Result<UCred, Error>

Returns effective credentials of the process which called connect or pair.

+

pub fn take_error(&self) -> Result<Option<Error>, Error>

Returns the value of the SO_ERROR option.

+

pub fn split<'a>(&'a mut self) -> (ReadHalf<'a>, WriteHalf<'a>)

Splits a UnixStream into a read half and a write half, which can be used +to read and write the stream concurrently.

+

This method is more efficient than into_split, but the halves cannot be +moved into independently spawned tasks.

+

pub fn into_split(self) -> (OwnedReadHalf, OwnedWriteHalf)

Splits a UnixStream into a read half and a write half, which can be used +to read and write the stream concurrently.

+

Unlike split, the owned halves can be moved to separate tasks, however +this comes at the cost of a heap allocation.

+

Note: Dropping the write half will shut down the write half of the +stream. This is equivalent to calling shutdown() on the UnixStream.

+

Trait Implementations§

§

impl AsFd for UnixStream

§

fn as_fd(&self) -> BorrowedFd<'_>

Borrows the file descriptor. Read more
§

impl AsRawFd for UnixStream

§

fn as_raw_fd(&self) -> i32

Extracts the raw file descriptor. Read more
§

impl AsyncRead for UnixStream

§

fn poll_read( + self: Pin<&mut UnixStream>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_> +) -> Poll<Result<(), Error>>

Attempts to read from the AsyncRead into buf. Read more
§

impl AsyncWrite for UnixStream

§

fn poll_write( + self: Pin<&mut UnixStream>, + cx: &mut Context<'_>, + buf: &[u8] +) -> Poll<Result<usize, Error>>

Attempt to write bytes from buf into the object. Read more
§

fn poll_write_vectored( + self: Pin<&mut UnixStream>, + cx: &mut Context<'_>, + bufs: &[IoSlice<'_>] +) -> Poll<Result<usize, Error>>

Like poll_write, except that it writes from a slice of buffers. Read more
§

fn is_write_vectored(&self) -> bool

Determines if this writer has an efficient poll_write_vectored +implementation. Read more
§

fn poll_flush( + self: Pin<&mut UnixStream>, + _: &mut Context<'_> +) -> Poll<Result<(), Error>>

Attempts to flush the object, ensuring that any buffered data reach +their destination. Read more
§

fn poll_shutdown( + self: Pin<&mut UnixStream>, + _: &mut Context<'_> +) -> Poll<Result<(), Error>>

Initiates or attempts to shut down this writer, returning success when +the I/O connection has completely shut down. Read more
§

impl Debug for UnixStream

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl FromStream for UnixStream

§

fn from_mio(sock: MioStream) -> Result<UnixStream, Error>

§

impl TryFrom<UnixStream> for UnixStream

§

fn try_from(stream: UnixStream) -> Result<UnixStream, Error>

Consumes stream, returning the tokio I/O object.

+

This is equivalent to +UnixStream::from_std(stream).

+
§

type Error = Error

The type returned in the event of a conversion error.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<R> AsyncReadExt for R
where + R: AsyncRead + ?Sized,

§

fn chain<R>(self, next: R) -> Chain<Self, R>
where + Self: Sized, + R: AsyncRead,

Creates a new AsyncRead instance that chains this stream with +next. Read more
§

fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>
where + Self: Unpin,

Pulls some bytes from this source into the specified buffer, +returning how many bytes were read. Read more
§

fn read_buf<'a, B>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B>
where + Self: Unpin, + B: BufMut + ?Sized,

Pulls some bytes from this source into the specified buffer, +advancing the buffer’s internal cursor. Read more
§

fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self>
where + Self: Unpin,

Reads the exact number of bytes required to fill buf. Read more
§

fn read_u8(&mut self) -> ReadU8<&mut Self>
where + Self: Unpin,

Reads an unsigned 8 bit integer from the underlying reader. Read more
§

fn read_i8(&mut self) -> ReadI8<&mut Self>
where + Self: Unpin,

Reads a signed 8 bit integer from the underlying reader. Read more
§

fn read_u16(&mut self) -> ReadU16<&mut Self>
where + Self: Unpin,

Reads an unsigned 16-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i16(&mut self) -> ReadI16<&mut Self>
where + Self: Unpin,

Reads a signed 16-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u32(&mut self) -> ReadU32<&mut Self>
where + Self: Unpin,

Reads an unsigned 32-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i32(&mut self) -> ReadI32<&mut Self>
where + Self: Unpin,

Reads a signed 32-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u64(&mut self) -> ReadU64<&mut Self>
where + Self: Unpin,

Reads an unsigned 64-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i64(&mut self) -> ReadI64<&mut Self>
where + Self: Unpin,

Reads an signed 64-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u128(&mut self) -> ReadU128<&mut Self>
where + Self: Unpin,

Reads an unsigned 128-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i128(&mut self) -> ReadI128<&mut Self>
where + Self: Unpin,

Reads an signed 128-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_f32(&mut self) -> ReadF32<&mut Self>
where + Self: Unpin,

Reads an 32-bit floating point type in big-endian order from the +underlying reader. Read more
§

fn read_f64(&mut self) -> ReadF64<&mut Self>
where + Self: Unpin,

Reads an 64-bit floating point type in big-endian order from the +underlying reader. Read more
§

fn read_u16_le(&mut self) -> ReadU16Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 16-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i16_le(&mut self) -> ReadI16Le<&mut Self>
where + Self: Unpin,

Reads a signed 16-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u32_le(&mut self) -> ReadU32Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 32-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i32_le(&mut self) -> ReadI32Le<&mut Self>
where + Self: Unpin,

Reads a signed 32-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u64_le(&mut self) -> ReadU64Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 64-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i64_le(&mut self) -> ReadI64Le<&mut Self>
where + Self: Unpin,

Reads an signed 64-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u128_le(&mut self) -> ReadU128Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 128-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i128_le(&mut self) -> ReadI128Le<&mut Self>
where + Self: Unpin,

Reads an signed 128-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_f32_le(&mut self) -> ReadF32Le<&mut Self>
where + Self: Unpin,

Reads an 32-bit floating point type in little-endian order from the +underlying reader. Read more
§

fn read_f64_le(&mut self) -> ReadF64Le<&mut Self>
where + Self: Unpin,

Reads an 64-bit floating point type in little-endian order from the +underlying reader. Read more
§

fn read_to_end<'a>(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEnd<'a, Self>
where + Self: Unpin,

Reads all bytes until EOF in this source, placing them into buf. Read more
§

fn read_to_string<'a>( + &'a mut self, + dst: &'a mut String +) -> ReadToString<'a, Self>
where + Self: Unpin,

Reads all bytes until EOF in this source, appending them to buf. Read more
§

fn take(self, limit: u64) -> Take<Self>
where + Self: Sized,

Creates an adaptor which reads at most limit bytes from it. Read more
§

impl<W> AsyncWriteExt for W
where + W: AsyncWrite + ?Sized,

§

fn write<'a>(&'a mut self, src: &'a [u8]) -> Write<'a, Self>
where + Self: Unpin,

Writes a buffer into this writer, returning how many bytes were +written. Read more
§

fn write_vectored<'a, 'b>( + &'a mut self, + bufs: &'a [IoSlice<'b>] +) -> WriteVectored<'a, 'b, Self>
where + Self: Unpin,

Like write, except that it writes from a slice of buffers. Read more
§

fn write_buf<'a, B>(&'a mut self, src: &'a mut B) -> WriteBuf<'a, Self, B>
where + Self: Sized + Unpin, + B: Buf,

Writes a buffer into this writer, advancing the buffer’s internal +cursor. Read more
§

fn write_all_buf<'a, B>( + &'a mut self, + src: &'a mut B +) -> WriteAllBuf<'a, Self, B>
where + Self: Sized + Unpin, + B: Buf,

Attempts to write an entire buffer into this writer. Read more
§

fn write_all<'a>(&'a mut self, src: &'a [u8]) -> WriteAll<'a, Self>
where + Self: Unpin,

Attempts to write an entire buffer into this writer. Read more
§

fn write_u8(&mut self, n: u8) -> WriteU8<&mut Self>
where + Self: Unpin,

Writes an unsigned 8-bit integer to the underlying writer. Read more
§

fn write_i8(&mut self, n: i8) -> WriteI8<&mut Self>
where + Self: Unpin,

Writes a signed 8-bit integer to the underlying writer. Read more
§

fn write_u16(&mut self, n: u16) -> WriteU16<&mut Self>
where + Self: Unpin,

Writes an unsigned 16-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i16(&mut self, n: i16) -> WriteI16<&mut Self>
where + Self: Unpin,

Writes a signed 16-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u32(&mut self, n: u32) -> WriteU32<&mut Self>
where + Self: Unpin,

Writes an unsigned 32-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i32(&mut self, n: i32) -> WriteI32<&mut Self>
where + Self: Unpin,

Writes a signed 32-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u64(&mut self, n: u64) -> WriteU64<&mut Self>
where + Self: Unpin,

Writes an unsigned 64-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i64(&mut self, n: i64) -> WriteI64<&mut Self>
where + Self: Unpin,

Writes an signed 64-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u128(&mut self, n: u128) -> WriteU128<&mut Self>
where + Self: Unpin,

Writes an unsigned 128-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i128(&mut self, n: i128) -> WriteI128<&mut Self>
where + Self: Unpin,

Writes an signed 128-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_f32(&mut self, n: f32) -> WriteF32<&mut Self>
where + Self: Unpin,

Writes an 32-bit floating point type in big-endian order to the +underlying writer. Read more
§

fn write_f64(&mut self, n: f64) -> WriteF64<&mut Self>
where + Self: Unpin,

Writes an 64-bit floating point type in big-endian order to the +underlying writer. Read more
§

fn write_u16_le(&mut self, n: u16) -> WriteU16Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 16-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i16_le(&mut self, n: i16) -> WriteI16Le<&mut Self>
where + Self: Unpin,

Writes a signed 16-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u32_le(&mut self, n: u32) -> WriteU32Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 32-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i32_le(&mut self, n: i32) -> WriteI32Le<&mut Self>
where + Self: Unpin,

Writes a signed 32-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u64_le(&mut self, n: u64) -> WriteU64Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 64-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i64_le(&mut self, n: i64) -> WriteI64Le<&mut Self>
where + Self: Unpin,

Writes an signed 64-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u128_le(&mut self, n: u128) -> WriteU128Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 128-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i128_le(&mut self, n: i128) -> WriteI128Le<&mut Self>
where + Self: Unpin,

Writes an signed 128-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_f32_le(&mut self, n: f32) -> WriteF32Le<&mut Self>
where + Self: Unpin,

Writes an 32-bit floating point type in little-endian order to the +underlying writer. Read more
§

fn write_f64_le(&mut self, n: f64) -> WriteF64Le<&mut Self>
where + Self: Unpin,

Writes an 64-bit floating point type in little-endian order to the +underlying writer. Read more
§

fn flush(&mut self) -> Flush<'_, Self>
where + Self: Unpin,

Flushes this output stream, ensuring that all intermediately buffered +contents reach their destination. Read more
§

fn shutdown(&mut self) -> Shutdown<'_, Self>
where + Self: Unpin,

Shuts down the output stream, ensuring that the value can be dropped +cleanly. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/sidebar-items.js b/actix_web/rt/sidebar-items.js new file mode 100644 index 000000000..37f93ad52 --- /dev/null +++ b/actix_web/rt/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["spawn"],"macro":["pin"],"mod":["net","signal","task","time"],"struct":["Runtime","System","SystemRunner"]}; \ No newline at end of file diff --git a/actix_web/rt/signal/fn.ctrl_c.html b/actix_web/rt/signal/fn.ctrl_c.html new file mode 100644 index 000000000..8c9f2c3f2 --- /dev/null +++ b/actix_web/rt/signal/fn.ctrl_c.html @@ -0,0 +1,39 @@ +ctrl_c in actix_web::rt::signal - Rust

Function actix_web::rt::signal::ctrl_c

pub async fn ctrl_c() -> Result<(), Error>
Expand description

Completes when a “ctrl-c” notification is sent to the process.

+

While signals are handled very differently between Unix and Windows, both +platforms support receiving a signal on “ctrl-c”. This function provides a +portable API for receiving this notification.

+

Once the returned future is polled, a listener is registered. The future +will complete on the first received ctrl-c after the initial call to +either Future::poll or .await.

+

§Caveats

+

On Unix platforms, the first time that a Signal instance is registered for a +particular signal kind, an OS signal-handler is installed which replaces the +default platform behavior when that signal is received, for the duration of +the entire process.

+

For example, Unix systems will terminate a process by default when it +receives a signal generated by "CTRL+C" on the terminal. But, when a +ctrl_c stream is created to listen for this signal, the time it arrives, +it will be translated to a stream event, and the process will continue to +execute. Even if this Signal instance is dropped, subsequent SIGINT +deliveries will end up captured by Tokio, and the default platform behavior +will NOT be reset.

+

Thus, applications should take care to ensure the expected signal behavior +occurs as expected after listening for specific signals.

+

§Examples

+
use tokio::signal;
+
+#[tokio::main]
+async fn main() {
+    println!("waiting for ctrl-c");
+
+    signal::ctrl_c().await.expect("failed to listen for event");
+
+    println!("received ctrl-c event");
+}
+

Listen in the background:

+ +
tokio::spawn(async move {
+    tokio::signal::ctrl_c().await.unwrap();
+    // Your handler here
+});
+
\ No newline at end of file diff --git a/actix_web/rt/signal/index.html b/actix_web/rt/signal/index.html new file mode 100644 index 000000000..c95ef0407 --- /dev/null +++ b/actix_web/rt/signal/index.html @@ -0,0 +1,2 @@ +actix_web::rt::signal - Rust

Module actix_web::rt::signal

Expand description

Asynchronous signal handling (Tokio re-exports).

+

Modules§

  • unixUnix
    Unix specific signals (Tokio re-exports).

Functions§

  • Completes when a “ctrl-c” notification is sent to the process.
\ No newline at end of file diff --git a/actix_web/rt/signal/sidebar-items.js b/actix_web/rt/signal/sidebar-items.js new file mode 100644 index 000000000..ad5573caf --- /dev/null +++ b/actix_web/rt/signal/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["ctrl_c"],"mod":["unix"]}; \ No newline at end of file diff --git a/actix_web/rt/signal/unix/fn.signal.html b/actix_web/rt/signal/unix/fn.signal.html new file mode 100644 index 000000000..774f75b55 --- /dev/null +++ b/actix_web/rt/signal/unix/fn.signal.html @@ -0,0 +1,25 @@ +signal in actix_web::rt::signal::unix - Rust

Function actix_web::rt::signal::unix::signal

pub fn signal(kind: SignalKind) -> Result<Signal, Error>
Available on Unix only.
Expand description

Creates a new listener which will receive notifications when the current +process receives the specified signal kind.

+

This function will create a new stream which binds to the default reactor. +The Signal stream is an infinite stream which will receive +notifications whenever a signal is received. More documentation can be +found on Signal itself, but to reiterate:

+
    +
  • Signals may be coalesced beyond what the kernel already does.
  • +
  • Once a signal handler is registered with the process the underlying +libc signal handler is never unregistered.
  • +
+

A Signal stream can be created for a particular signal number +multiple times. When a signal is received then all the associated +channels will receive the signal notification.

+

§Errors

+
    +
  • If the lower-level C functions fail for some reason.
  • +
  • If the previous initialization of this specific signal failed.
  • +
  • If the signal is one of +signal_hook::FORBIDDEN
  • +
+

§Panics

+

This function panics if there is no current reactor set, or if the rt +feature flag is not enabled.

+
\ No newline at end of file diff --git a/actix_web/rt/signal/unix/index.html b/actix_web/rt/signal/unix/index.html new file mode 100644 index 000000000..04450a2c6 --- /dev/null +++ b/actix_web/rt/signal/unix/index.html @@ -0,0 +1,3 @@ +actix_web::rt::signal::unix - Rust

Module actix_web::rt::signal::unix

Available on Unix only.
Expand description

Unix specific signals (Tokio re-exports).

+

Structs§

  • An listener for receiving a particular type of OS signal.
  • Represents the specific kind of signal to listen for.

Functions§

  • Creates a new listener which will receive notifications when the current +process receives the specified signal kind.
\ No newline at end of file diff --git a/actix_web/rt/signal/unix/sidebar-items.js b/actix_web/rt/signal/unix/sidebar-items.js new file mode 100644 index 000000000..344a2272d --- /dev/null +++ b/actix_web/rt/signal/unix/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["signal"],"struct":["Signal","SignalKind"]}; \ No newline at end of file diff --git a/actix_web/rt/signal/unix/struct.Signal.html b/actix_web/rt/signal/unix/struct.Signal.html new file mode 100644 index 000000000..5cc8a9e84 --- /dev/null +++ b/actix_web/rt/signal/unix/struct.Signal.html @@ -0,0 +1,125 @@ +Signal in actix_web::rt::signal::unix - Rust

Struct actix_web::rt::signal::unix::Signal

pub struct Signal { /* private fields */ }
Available on Unix only.
Expand description

An listener for receiving a particular type of OS signal.

+

The listener can be turned into a Stream using SignalStream.

+

In general signal handling on Unix is a pretty tricky topic, and this +structure is no exception! There are some important limitations to keep in +mind when using Signal streams:

+
    +
  • +

    Signals handling in Unix already necessitates coalescing signals +together sometimes. This Signal stream is also no exception here in +that it will also coalesce signals. That is, even if the signal handler +for this process runs multiple times, the Signal stream may only return +one signal notification. Specifically, before poll is called, all +signal notifications are coalesced into one item returned from poll. +Once poll has been called, however, a further signal is guaranteed to +be yielded as an item.

    +

    Put another way, any element pulled off the returned listener corresponds to +at least one signal, but possibly more.

    +
  • +
  • +

    Signal handling in general is relatively inefficient. Although some +improvements are possible in this crate, it’s recommended to not plan on +having millions of signal channels open.

    +
  • +
+

If you’ve got any questions about this feel free to open an issue on the +repo! New approaches to alleviate some of these limitations are always +appreciated!

+

§Caveats

+

The first time that a Signal instance is registered for a particular +signal kind, an OS signal-handler is installed which replaces the default +platform behavior when that signal is received, for the duration of the +entire process.

+

For example, Unix systems will terminate a process by default when it +receives SIGINT. But, when a Signal instance is created to listen for +this signal, the next SIGINT that arrives will be translated to a stream +event, and the process will continue to execute. Even if this Signal +instance is dropped, subsequent SIGINT deliveries will end up captured by +Tokio, and the default platform behavior will NOT be reset.

+

Thus, applications should take care to ensure the expected signal behavior +occurs as expected after listening for specific signals.

+

§Examples

+

Wait for SIGHUP

+ +
use tokio::signal::unix::{signal, SignalKind};
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn std::error::Error>> {
+    // An infinite stream of hangup signals.
+    let mut sig = signal(SignalKind::hangup())?;
+
+    // Print whenever a HUP signal is received
+    loop {
+        sig.recv().await;
+        println!("got signal HUP");
+    }
+}
+

Implementations§

§

impl Signal

pub async fn recv(&mut self) -> Option<()>

Receives the next signal notification event.

+

None is returned if no more events can be received by this stream.

+
§Cancel safety
+

This method is cancel safe. If you use it as the event in a +tokio::select! statement and some other branch +completes first, then it is guaranteed that no signal is lost.

+
§Examples
+

Wait for SIGHUP

+ +
use tokio::signal::unix::{signal, SignalKind};
+
+#[tokio::main]
+async fn main() -> Result<(), Box<dyn std::error::Error>> {
+    // An infinite stream of hangup signals.
+    let mut stream = signal(SignalKind::hangup())?;
+
+    // Print whenever a HUP signal is received
+    loop {
+        stream.recv().await;
+        println!("got signal HUP");
+    }
+}
+

pub fn poll_recv(&mut self, cx: &mut Context<'_>) -> Poll<Option<()>>

Polls to receive the next signal notification event, outside of an +async context.

+

This method returns:

+
    +
  • Poll::Pending if no signals are available but the channel is not +closed.
  • +
  • Poll::Ready(Some(())) if a signal is available.
  • +
  • Poll::Ready(None) if the channel has been closed and all signals +sent before it was closed have been received.
  • +
+
§Examples
+

Polling from a manually implemented future

+ +
use std::pin::Pin;
+use std::future::Future;
+use std::task::{Context, Poll};
+use tokio::signal::unix::Signal;
+
+struct MyFuture {
+    signal: Signal,
+}
+
+impl Future for MyFuture {
+    type Output = Option<()>;
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        println!("polling MyFuture");
+        self.signal.poll_recv(cx)
+    }
+}
+

Trait Implementations§

§

impl Debug for Signal

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for Signal

§

impl !RefUnwindSafe for Signal

§

impl Send for Signal

§

impl Sync for Signal

§

impl Unpin for Signal

§

impl !UnwindSafe for Signal

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/signal/unix/struct.SignalKind.html b/actix_web/rt/signal/unix/struct.SignalKind.html new file mode 100644 index 000000000..b6b8a124c --- /dev/null +++ b/actix_web/rt/signal/unix/struct.SignalKind.html @@ -0,0 +1,73 @@ +SignalKind in actix_web::rt::signal::unix - Rust

Struct actix_web::rt::signal::unix::SignalKind

pub struct SignalKind(/* private fields */);
Available on Unix only.
Expand description

Represents the specific kind of signal to listen for.

+

Implementations§

§

impl SignalKind

pub const fn from_raw(signum: i32) -> SignalKind

Allows for listening to any valid OS signal.

+

For example, this can be used for listening for platform-specific +signals.

+ +
// let signum = libc::OS_SPECIFIC_SIGNAL;
+let kind = SignalKind::from_raw(signum);
+

pub const fn as_raw_value(&self) -> i32

Get the signal’s numeric value.

+ +
let kind = SignalKind::interrupt();
+assert_eq!(kind.as_raw_value(), libc::SIGINT);
+

pub const fn alarm() -> SignalKind

Represents the SIGALRM signal.

+

On Unix systems this signal is sent when a real-time timer has expired. +By default, the process is terminated by this signal.

+

pub const fn child() -> SignalKind

Represents the SIGCHLD signal.

+

On Unix systems this signal is sent when the status of a child process +has changed. By default, this signal is ignored.

+

pub const fn hangup() -> SignalKind

Represents the SIGHUP signal.

+

On Unix systems this signal is sent when the terminal is disconnected. +By default, the process is terminated by this signal.

+

pub const fn interrupt() -> SignalKind

Represents the SIGINT signal.

+

On Unix systems this signal is sent to interrupt a program. +By default, the process is terminated by this signal.

+

pub const fn io() -> SignalKind

Represents the SIGIO signal.

+

On Unix systems this signal is sent when I/O operations are possible +on some file descriptor. By default, this signal is ignored.

+

pub const fn pipe() -> SignalKind

Represents the SIGPIPE signal.

+

On Unix systems this signal is sent when the process attempts to write +to a pipe which has no reader. By default, the process is terminated by +this signal.

+

pub const fn quit() -> SignalKind

Represents the SIGQUIT signal.

+

On Unix systems this signal is sent to issue a shutdown of the +process, after which the OS will dump the process core. +By default, the process is terminated by this signal.

+

pub const fn terminate() -> SignalKind

Represents the SIGTERM signal.

+

On Unix systems this signal is sent to issue a shutdown of the +process. By default, the process is terminated by this signal.

+

pub const fn user_defined1() -> SignalKind

Represents the SIGUSR1 signal.

+

On Unix systems this is a user defined signal. +By default, the process is terminated by this signal.

+

pub const fn user_defined2() -> SignalKind

Represents the SIGUSR2 signal.

+

On Unix systems this is a user defined signal. +By default, the process is terminated by this signal.

+

pub const fn window_change() -> SignalKind

Represents the SIGWINCH signal.

+

On Unix systems this signal is sent when the terminal window is resized. +By default, this signal is ignored.

+

Trait Implementations§

§

impl Clone for SignalKind

§

fn clone(&self) -> SignalKind

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for SignalKind

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl From<i32> for SignalKind

§

fn from(signum: i32) -> SignalKind

Converts to this type from the input type.
§

impl Hash for SignalKind

§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl PartialEq for SignalKind

§

fn eq(&self, other: &SignalKind) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for SignalKind

§

impl Eq for SignalKind

§

impl StructuralPartialEq for SignalKind

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/struct.Runtime.html b/actix_web/rt/struct.Runtime.html new file mode 100644 index 000000000..bebe78db9 --- /dev/null +++ b/actix_web/rt/struct.Runtime.html @@ -0,0 +1,91 @@ +Runtime in actix_web::rt - Rust

Struct actix_web::rt::Runtime

pub struct Runtime { /* private fields */ }
Expand description

A Tokio-based runtime proxy.

+

All spawned futures will be executed on the current thread. Therefore, there is no Send bound +on submitted futures.

+

Implementations§

§

impl Runtime

pub fn new() -> Result<Runtime, Error>

Returns a new runtime initialized with default configuration values.

+

pub fn spawn<F>(&self, future: F) -> JoinHandle<<F as Future>::Output>
where + F: Future + 'static,

Offload a future onto the single-threaded runtime.

+

The returned join handle can be used to await the future’s result.

+

See [crate root][crate] documentation for more details.

+
§Examples
+
let rt = actix_rt::Runtime::new().unwrap();
+
+// Spawn a future onto the runtime
+let handle = rt.spawn(async {
+    println!("running on the runtime");
+    42
+});
+
+assert_eq!(rt.block_on(handle).unwrap(), 42);
+
§Panics
+

This function panics if the spawn fails. Failure occurs if the executor is currently at +capacity and is unable to spawn a new future.

+

pub fn tokio_runtime(&self) -> &Runtime

Retrieves a reference to the underlying Tokio runtime associated with this instance.

+

The Tokio runtime is responsible for executing asynchronous tasks and managing +the event loop for an asynchronous Rust program. This method allows accessing +the runtime to interact with its features directly.

+

In a typical use case, you might need to share the same runtime between different +modules of your project. For example, a module might require a tokio::runtime::Handle +to spawn tasks on the same runtime, or the runtime itself to configure more complex +behaviours.

+
§Example
+
use actix_rt::Runtime;
+
+mod module_a {
+    pub fn do_something(handle: tokio::runtime::Handle) {
+        handle.spawn(async {
+            // Some asynchronous task here
+        });
+    }
+}
+
+mod module_b {
+    pub fn do_something_else(rt: &tokio::runtime::Runtime) {
+        rt.spawn(async {
+            // Another asynchronous task here
+        });
+    }
+}
+
+let actix_runtime = actix_rt::Runtime::new().unwrap();
+let tokio_runtime = actix_runtime.tokio_runtime();
+
+let handle = tokio_runtime.handle().clone();
+
+module_a::do_something(handle);
+module_b::do_something_else(tokio_runtime);
+
§Returns
+

An immutable reference to the tokio::runtime::Runtime instance associated with this +Runtime instance.

+
§Note
+

While this method provides an immutable reference to the Tokio runtime, which is safe to share across threads, +be aware that spawning blocking tasks on the Tokio runtime could potentially impact the execution +of the Actix runtime. This is because Tokio is responsible for driving the Actix system, +and blocking tasks could delay or deadlock other tasks in run loop.

+

pub fn block_on<F>(&self, f: F) -> <F as Future>::Output
where + F: Future,

Runs the provided future, blocking the current thread until the future completes.

+

This function can be used to synchronously block the current thread until the provided +future has resolved either successfully or with an error. The result of the future is +then returned from this function call.

+

Note that this function will also execute any spawned futures on the current thread, but +will not block until these other spawned futures have completed. Once the function returns, +any uncompleted futures remain pending in the Runtime instance. These futures will not run +until block_on or run is called again.

+

The caller is responsible for ensuring that other spawned futures complete execution by +calling block_on or run.

+

Trait Implementations§

§

impl Debug for Runtime

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl From<Runtime> for Runtime

§

fn from(rt: Runtime) -> Runtime

Converts to this type from the input type.

Auto Trait Implementations§

§

impl !Freeze for Runtime

§

impl !RefUnwindSafe for Runtime

§

impl !Send for Runtime

§

impl !Sync for Runtime

§

impl Unpin for Runtime

§

impl !UnwindSafe for Runtime

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/struct.System.html b/actix_web/rt/struct.System.html new file mode 100644 index 000000000..d5156ce25 --- /dev/null +++ b/actix_web/rt/struct.System.html @@ -0,0 +1,34 @@ +System in actix_web::rt - Rust

Struct actix_web::rt::System

pub struct System { /* private fields */ }
Expand description

A manager for a per-thread distributed async runtime.

+

Implementations§

§

impl System

pub fn new() -> SystemRunner

Available on crate feature io-uring only.

Create a new system.

+
§Panics
+

Panics if underlying Tokio runtime can not be created.

+
§

impl System

pub fn current() -> System

Get current running system.

+
§Panics
+

Panics if no system is registered on the current thread.

+

pub fn try_current() -> Option<System>

Try to get current running system.

+

Returns None if no System has been started.

+

Unlike current, this never panics.

+

pub fn arbiter(&self) -> &ArbiterHandle

Get handle to a the System’s initial [Arbiter].

+

pub fn is_registered() -> bool

Check if there is a System registered on the current thread.

+

pub fn id(&self) -> usize

Numeric system identifier.

+

Useful when using multiple Systems.

+

pub fn stop(&self)

Stop the system (with code 0).

+

pub fn stop_with_code(&self, code: i32)

Stop the system with a given exit code.

+

Trait Implementations§

§

impl Clone for System

§

fn clone(&self) -> System

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for System

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl Freeze for System

§

impl !RefUnwindSafe for System

§

impl Send for System

§

impl Sync for System

§

impl Unpin for System

§

impl !UnwindSafe for System

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/struct.SystemRunner.html b/actix_web/rt/struct.SystemRunner.html new file mode 100644 index 000000000..ec236c192 --- /dev/null +++ b/actix_web/rt/struct.SystemRunner.html @@ -0,0 +1,22 @@ +SystemRunner in actix_web::rt - Rust

Struct actix_web::rt::SystemRunner

pub struct SystemRunner;
Expand description

Runner that keeps a System’s event loop alive until stop message is received.

+

Implementations§

§

impl SystemRunner

pub fn run(self) -> Result<(), Error>

Available on crate feature io-uring only.

Starts event loop and will return once System is stopped.

+

pub fn run_with_code(self) -> Result<i32, Error>

Available on crate feature io-uring only.

Runs the event loop until stopped, returning the exit code.

+

pub fn block_on<F>(&self, fut: F) -> <F as Future>::Output
where + F: Future,

Available on crate feature io-uring only.

Runs the provided future, blocking the current thread until the future completes.

+

Trait Implementations§

§

impl Debug for SystemRunner

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/task/fn.spawn_blocking.html b/actix_web/rt/task/fn.spawn_blocking.html new file mode 100644 index 000000000..eacc0e095 --- /dev/null +++ b/actix_web/rt/task/fn.spawn_blocking.html @@ -0,0 +1,89 @@ +spawn_blocking in actix_web::rt::task - Rust

Function actix_web::rt::task::spawn_blocking

pub fn spawn_blocking<F, R>(f: F) -> JoinHandle<R> 
where + F: FnOnce() -> R + Send + 'static, + R: Send + 'static,
Available on crate feature rt only.
Expand description

Runs the provided closure on a thread where blocking is acceptable.

+

In general, issuing a blocking call or performing a lot of compute in a +future without yielding is problematic, as it may prevent the executor from +driving other futures forward. This function runs the provided closure on a +thread dedicated to blocking operations. See the CPU-bound tasks and +blocking code section for more information.

+

Tokio will spawn more blocking threads when they are requested through this +function until the upper limit configured on the Builder is reached. +After reaching the upper limit, the tasks are put in a queue. +The thread limit is very large by default, because spawn_blocking is often +used for various kinds of IO operations that cannot be performed +asynchronously. When you run CPU-bound code using spawn_blocking, you +should keep this large upper limit in mind. When running many CPU-bound +computations, a semaphore or some other synchronization primitive should be +used to limit the number of computation executed in parallel. Specialized +CPU-bound executors, such as rayon, may also be a good fit.

+

This function is intended for non-async operations that eventually finish on +their own. If you want to spawn an ordinary thread, you should use +thread::spawn instead.

+

Closures spawned using spawn_blocking cannot be cancelled abruptly; there +is no standard low level API to cause a thread to stop running. However, +a useful pattern is to pass some form of “cancellation token” into +the thread. This could be an AtomicBool that the task checks periodically. +Another approach is to have the thread primarily read or write from a channel, +and to exit when the channel closes; assuming the other side of the channel is dropped +when cancellation occurs, this will cause the blocking task thread to exit +soon after as well.

+

When you shut down the executor, it will wait indefinitely for all blocking operations to +finish. You can use shutdown_timeout to stop waiting for them after a +certain timeout. Be aware that this will still not cancel the tasks — they +are simply allowed to keep running after the method returns. It is possible +for a blocking task to be cancelled if it has not yet started running, but this +is not guaranteed.

+

Note that if you are using the single threaded runtime, this function will +still spawn additional threads for blocking operations. The current-thread +scheduler’s single thread is only used for asynchronous code.

+ +

In simple cases, it is sufficient to have the closure accept input +parameters at creation time and return a single value (or struct/tuple, etc.).

+

For more complex situations in which it is desirable to stream data to or from +the synchronous context, the mpsc channel has blocking_send and +blocking_recv methods for use in non-async code such as the thread created +by spawn_blocking.

+

Another option is SyncIoBridge for cases where the synchronous context +is operating on byte streams. For example, you might use an asynchronous +HTTP client such as hyper to fetch data, but perform complex parsing +of the payload body using a library written for synchronous I/O.

+

Finally, see also Bridging with sync code for discussions +around the opposite case of using Tokio as part of a larger synchronous +codebase.

+

§Examples

+

Pass an input value and receive result of computation:

+ +
use tokio::task;
+
+// Initial input
+let mut v = "Hello, ".to_string();
+let res = task::spawn_blocking(move || {
+    // Stand-in for compute-heavy work or using synchronous APIs
+    v.push_str("world");
+    // Pass ownership of the value back to the asynchronous context
+    v
+}).await?;
+
+// `res` is the value returned from the thread
+assert_eq!(res.as_str(), "Hello, world");
+

Use a channel:

+ +
use tokio::task;
+use tokio::sync::mpsc;
+
+let (tx, mut rx) = mpsc::channel(2);
+let start = 5;
+let worker = task::spawn_blocking(move || {
+    for x in 0..10 {
+        // Stand in for complex computation
+        tx.blocking_send(start + x).unwrap();
+    }
+});
+
+let mut acc = 0;
+while let Some(v) = rx.recv().await {
+    acc += v;
+}
+assert_eq!(acc, 95);
+worker.await.unwrap();
+
\ No newline at end of file diff --git a/actix_web/rt/task/fn.yield_now.html b/actix_web/rt/task/fn.yield_now.html new file mode 100644 index 000000000..8253b4d7c --- /dev/null +++ b/actix_web/rt/task/fn.yield_now.html @@ -0,0 +1,24 @@ +yield_now in actix_web::rt::task - Rust

Function actix_web::rt::task::yield_now

pub async fn yield_now()
Expand description

Yields execution back to the Tokio runtime.

+

A task yields by awaiting on yield_now(), and may resume when that future +completes (with no output.) The current task will be re-added as a pending +task at the back of the pending queue. Any other pending tasks will be +scheduled. No other waking is required for the task to continue.

+

See also the usage example in the task module.

+

§Non-guarantees

+

This function may not yield all the way up to the executor if there are any +special combinators above it in the call stack. For example, if a +tokio::select! has another branch complete during the same poll as the +yield_now(), then the yield is not propagated all the way up to the +runtime.

+

It is generally not guaranteed that the runtime behaves like you expect it +to when deciding which task to schedule next after a call to yield_now(). +In particular, the runtime may choose to poll the task that just ran +yield_now() again immediately without polling any other tasks first. For +example, the runtime will not drive the IO driver between every poll of a +task, and this could result in the runtime polling the current task again +immediately even if there is another task that could make progress if that +other task is waiting for a notification from the IO driver.

+

In general, changes to the order in which the runtime polls tasks is not +considered a breaking change, and your program should be correct no matter +which order the runtime polls your tasks in.

+
\ No newline at end of file diff --git a/actix_web/rt/task/index.html b/actix_web/rt/task/index.html new file mode 100644 index 000000000..7a4165c76 --- /dev/null +++ b/actix_web/rt/task/index.html @@ -0,0 +1,2 @@ +actix_web::rt::task - Rust

Module actix_web::rt::task

Expand description

Task management (Tokio re-exports).

+

Structs§

  • Task failed to execute to completion.
  • An owned permission to join on a task (await its termination).

Functions§

  • Runs the provided closure on a thread where blocking is acceptable.
  • Yields execution back to the Tokio runtime.
\ No newline at end of file diff --git a/actix_web/rt/task/sidebar-items.js b/actix_web/rt/task/sidebar-items.js new file mode 100644 index 000000000..e5d1fa75a --- /dev/null +++ b/actix_web/rt/task/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["spawn_blocking","yield_now"],"struct":["JoinError","JoinHandle"]}; \ No newline at end of file diff --git a/actix_web/rt/task/struct.JoinError.html b/actix_web/rt/task/struct.JoinError.html new file mode 100644 index 000000000..2518c86b7 --- /dev/null +++ b/actix_web/rt/task/struct.JoinError.html @@ -0,0 +1,69 @@ +JoinError in actix_web::rt::task - Rust

Struct actix_web::rt::task::JoinError

pub struct JoinError { /* private fields */ }
Available on crate feature rt only.
Expand description

Task failed to execute to completion.

+

Implementations§

§

impl JoinError

pub fn is_cancelled(&self) -> bool

Returns true if the error was caused by the task being cancelled.

+

See the module level docs for more information on cancellation.

+

pub fn is_panic(&self) -> bool

Returns true if the error was caused by the task panicking.

+
§Examples
+
use std::panic;
+
+#[tokio::main]
+async fn main() {
+    let err = tokio::spawn(async {
+        panic!("boom");
+    }).await.unwrap_err();
+
+    assert!(err.is_panic());
+}
+

pub fn into_panic(self) -> Box<dyn Any + Send>

Consumes the join error, returning the object with which the task panicked.

+
§Panics
+

into_panic() panics if the Error does not represent the underlying +task terminating with a panic. Use is_panic to check the error reason +or try_into_panic for a variant that does not panic.

+
§Examples
+
use std::panic;
+
+#[tokio::main]
+async fn main() {
+    let err = tokio::spawn(async {
+        panic!("boom");
+    }).await.unwrap_err();
+
+    if err.is_panic() {
+        // Resume the panic on the main task
+        panic::resume_unwind(err.into_panic());
+    }
+}
+

pub fn try_into_panic(self) -> Result<Box<dyn Any + Send>, JoinError>

Consumes the join error, returning the object with which the task +panicked if the task terminated due to a panic. Otherwise, self is +returned.

+
§Examples
+
use std::panic;
+
+#[tokio::main]
+async fn main() {
+    let err = tokio::spawn(async {
+        panic!("boom");
+    }).await.unwrap_err();
+
+    if let Ok(reason) = err.try_into_panic() {
+        // Resume the panic on the main task
+        panic::resume_unwind(reason);
+    }
+}
+

Trait Implementations§

§

impl Debug for JoinError

§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for JoinError

§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for JoinError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/task/struct.JoinHandle.html b/actix_web/rt/task/struct.JoinHandle.html new file mode 100644 index 000000000..e2a5efd2b --- /dev/null +++ b/actix_web/rt/task/struct.JoinHandle.html @@ -0,0 +1,295 @@ +JoinHandle in actix_web::rt::task - Rust

Struct actix_web::rt::task::JoinHandle

pub struct JoinHandle<T> { /* private fields */ }
Available on crate feature rt only.
Expand description

An owned permission to join on a task (await its termination).

+

This can be thought of as the equivalent of std::thread::JoinHandle +for a Tokio task rather than a thread. Note that the background task +associated with this JoinHandle started running immediately when you +called spawn, even if you have not yet awaited the JoinHandle.

+

A JoinHandle detaches the associated task when it is dropped, which +means that there is no longer any handle to the task, and no way to join +on it.

+

This struct is created by the task::spawn and task::spawn_blocking +functions.

+

§Cancel safety

+

The &mut JoinHandle<T> type is cancel safe. If it is used as the event +in a tokio::select! statement and some other branch completes first, +then it is guaranteed that the output of the task is not lost.

+

If a JoinHandle is dropped, then the task continues running in the +background and its return value is lost.

+

§Examples

+

Creation from task::spawn:

+ +
use tokio::task;
+
+let join_handle: task::JoinHandle<_> = task::spawn(async {
+    // some work here
+});
+

Creation from task::spawn_blocking:

+ +
use tokio::task;
+
+let join_handle: task::JoinHandle<_> = task::spawn_blocking(|| {
+    // some blocking work here
+});
+

The generic parameter T in JoinHandle<T> is the return type of the spawned task. +If the return value is an i32, the join handle has type JoinHandle<i32>:

+ +
use tokio::task;
+
+let join_handle: task::JoinHandle<i32> = task::spawn(async {
+    5 + 3
+});
+
+

If the task does not have a return value, the join handle has type JoinHandle<()>:

+ +
use tokio::task;
+
+let join_handle: task::JoinHandle<()> = task::spawn(async {
+    println!("I return nothing.");
+});
+

Note that handle.await doesn’t give you the return type directly. It is wrapped in a +Result because panics in the spawned task are caught by Tokio. The ? operator has +to be double chained to extract the returned value:

+ +
use tokio::task;
+use std::io;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let join_handle: task::JoinHandle<Result<i32, io::Error>> = tokio::spawn(async {
+        Ok(5 + 3)
+    });
+
+    let result = join_handle.await??;
+    assert_eq!(result, 8);
+    Ok(())
+}
+

If the task panics, the error is a JoinError that contains the panic:

+ +
use tokio::task;
+use std::io;
+use std::panic;
+
+#[tokio::main]
+async fn main() -> io::Result<()> {
+    let join_handle: task::JoinHandle<Result<i32, io::Error>> = tokio::spawn(async {
+        panic!("boom");
+    });
+
+    let err = join_handle.await.unwrap_err();
+    assert!(err.is_panic());
+    Ok(())
+}
+
+

Child being detached and outliving its parent:

+ +
use tokio::task;
+use tokio::time;
+use std::time::Duration;
+
+let original_task = task::spawn(async {
+    let _detached_task = task::spawn(async {
+        // Here we sleep to make sure that the first task returns before.
+        time::sleep(Duration::from_millis(10)).await;
+        // This will be called, even though the JoinHandle is dropped.
+        println!("♫ Still alive ♫");
+    });
+});
+
+original_task.await.expect("The task being joined has panicked");
+println!("Original task is joined.");
+
+// We make sure that the new task has time to run, before the main
+// task returns.
+
+time::sleep(Duration::from_millis(1000)).await;
+

Implementations§

§

impl<T> JoinHandle<T>

pub fn abort(&self)

Abort the task associated with the handle.

+

Awaiting a cancelled task might complete as usual if the task was +already completed at the time it was cancelled, but most likely it +will fail with a cancelled JoinError.

+

See also the module level docs for more information on cancellation.

+ +
use tokio::time;
+
+let mut handles = Vec::new();
+
+handles.push(tokio::spawn(async {
+   time::sleep(time::Duration::from_secs(10)).await;
+   true
+}));
+
+handles.push(tokio::spawn(async {
+   time::sleep(time::Duration::from_secs(10)).await;
+   false
+}));
+
+for handle in &handles {
+    handle.abort();
+}
+
+for handle in handles {
+    assert!(handle.await.unwrap_err().is_cancelled());
+}
+

pub fn is_finished(&self) -> bool

Checks if the task associated with this JoinHandle has finished.

+

Please note that this method can return false even if abort has been +called on the task. This is because the cancellation process may take +some time, and this method does not return true until it has +completed.

+ +
use tokio::time;
+
+let handle1 = tokio::spawn(async {
+    // do some stuff here
+});
+let handle2 = tokio::spawn(async {
+    // do some other stuff here
+    time::sleep(time::Duration::from_secs(10)).await;
+});
+// Wait for the task to finish
+handle2.abort();
+time::sleep(time::Duration::from_secs(1)).await;
+assert!(handle1.is_finished());
+assert!(handle2.is_finished());
+

pub fn abort_handle(&self) -> AbortHandle

Returns a new AbortHandle that can be used to remotely abort this task.

+

Awaiting a task cancelled by the AbortHandle might complete as usual if the task was +already completed at the time it was cancelled, but most likely it +will fail with a cancelled JoinError.

+ +
use tokio::{time, task};
+
+let mut handles = Vec::new();
+
+handles.push(tokio::spawn(async {
+   time::sleep(time::Duration::from_secs(10)).await;
+   true
+}));
+
+handles.push(tokio::spawn(async {
+   time::sleep(time::Duration::from_secs(10)).await;
+   false
+}));
+
+let abort_handles: Vec<task::AbortHandle> = handles.iter().map(|h| h.abort_handle()).collect();
+
+for handle in abort_handles {
+    handle.abort();
+}
+
+for handle in handles {
+    assert!(handle.await.unwrap_err().is_cancelled());
+}
+

Trait Implementations§

§

impl<T> Debug for JoinHandle<T>
where + T: Debug,

§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<T> Drop for JoinHandle<T>

§

fn drop(&mut self)

Executes the destructor for this type. Read more
§

impl<T> Future for JoinHandle<T>

§

type Output = Result<T, JoinError>

The type of value produced on completion.
§

fn poll( + self: Pin<&mut JoinHandle<T>>, + cx: &mut Context<'_> +) -> Poll<<JoinHandle<T> as Future>::Output>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
§

impl<T> RefUnwindSafe for JoinHandle<T>

§

impl<T> Send for JoinHandle<T>
where + T: Send,

§

impl<T> Sync for JoinHandle<T>
where + T: Send,

§

impl<T> Unpin for JoinHandle<T>

§

impl<T> UnwindSafe for JoinHandle<T>

Auto Trait Implementations§

§

impl<T> Freeze for JoinHandle<T>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> FutureExt for T
where + T: Future + ?Sized,

§

fn map<U, F>(self, f: F) -> Map<Self, F>
where + F: FnOnce(Self::Output) -> U, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn map_into<U>(self) -> MapInto<Self, U>
where + Self::Output: Into<U>, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnOnce(Self::Output) -> Fut, + Fut: Future, + Self: Sized,

Chain on a computation for when a future finished, passing the result of +the future to the provided closure f. Read more
§

fn left_future<B>(self) -> Either<Self, B>
where + B: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the left-hand variant +of that Either. Read more
§

fn right_future<A>(self) -> Either<A, Self>
where + A: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the right-hand variant +of that Either. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Convert this future into a single element stream. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Output: Future, + Self: Sized,

Flatten the execution of this future when the output of this +future is itself another future. Read more
§

fn flatten_stream(self) -> FlattenStream<Self>
where + Self::Output: Stream, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a future such that poll will never again be called once it has +completed. This method can be used to turn any Future into a +FusedFuture. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnOnce(&Self::Output), + Self: Sized,

Do something with the output of a future before passing it on. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the future. Read more
§

fn shared(self) -> Shared<Self>
where + Self: Sized, + Self::Output: Clone,

Available on crate feature std only.
Create a cloneable handle to this future where all handles will resolve +to the same result. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn unit_error(self) -> UnitError<Self>
where + Self: Sized,

§

fn never_error(self) -> NeverError<Self>
where + Self: Sized,

§

fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where + Self: Unpin,

A convenience for calling Future::poll on Unpin future types.
§

fn now_or_never(self) -> Option<Self::Output>
where + Self: Sized,

Evaluates and consumes the future, returning the resulting output if +the future is ready after the first call to Future::poll. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<F> IntoFuture for F
where + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

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
§

fn try_poll( + self: Pin<&mut F>, + cx: &mut Context<'_> +) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
§

impl<Fut> TryFutureExt for Fut
where + Fut: TryFuture + ?Sized,

§

fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>
where + Self::Ok: Sink<Item, Error = Self::Error>, + Self: Sized,

Available on crate feature sink only.
Flattens the execution of this future when the successful result of this +future is a [Sink]. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + F: FnOnce(Self::Ok) -> T, + Self: Sized,

Maps this future’s success value to a different value. Read more
§

fn map_ok_or_else<T, E, F>(self, e: E, f: F) -> MapOkOrElse<Self, F, E>
where + F: FnOnce(Self::Ok) -> T, + E: FnOnce(Self::Error) -> T, + Self: Sized,

Maps this future’s success value to a different value, and permits for error handling resulting in the same type. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + F: FnOnce(Self::Error) -> E, + Self: Sized,

Maps this future’s error value to a different value. Read more
§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Maps this future’s Error to a new error type +using the Into trait. Read more
§

fn ok_into<U>(self) -> OkInto<Self, U>
where + Self: Sized, + Self::Ok: Into<U>,

Maps this future’s Ok to a new type +using the Into trait.
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnOnce(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Executes another future after this one resolves successfully. The +success value is passed to a closure to create this subsequent future. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnOnce(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Executes another future if this one resolves to an error. The +error value is passed to a closure to create this subsequent future. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnOnce(&Self::Ok), + Self: Sized,

Do something with the success value of a future before passing it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnOnce(&Self::Error), + Self: Sized,

Do something with the error value of a future before passing it on. Read more
§

fn try_flatten(self) -> TryFlatten<Self, Self::Ok>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is another future. Read more
§

fn try_flatten_stream(self) -> TryFlattenStream<Self>
where + Self::Ok: TryStream<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F>
where + Self: Sized, + F: FnOnce(Self::Error) -> Self::Ok,

Unwraps this future’s output, producing a future with this future’s +Ok type as its +Output type. Read more
§

fn into_future(self) -> IntoFuture<Self>
where + Self: Sized,

Wraps a [TryFuture] into a type that implements +Future. Read more
§

fn try_poll_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Result<Self::Ok, Self::Error>>
where + Self: Unpin,

A convenience method for calling [TryFuture::try_poll] on Unpin +future types.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/time/fn.interval.html b/actix_web/rt/time/fn.interval.html new file mode 100644 index 000000000..30ababa8c --- /dev/null +++ b/actix_web/rt/time/fn.interval.html @@ -0,0 +1,48 @@ +interval in actix_web::rt::time - Rust

Function actix_web::rt::time::interval

pub fn interval(period: Duration) -> Interval
Expand description

Creates new Interval that yields with interval of period. The first +tick completes immediately. The default [MissedTickBehavior] is +Burst, but this can be configured +by calling set_missed_tick_behavior.

+

An interval will tick indefinitely. At any time, the Interval value can +be dropped. This cancels the interval.

+

This function is equivalent to +interval_at(Instant::now(), period).

+

§Panics

+

This function panics if period is zero.

+

§Examples

+
use tokio::time::{self, Duration};
+
+#[tokio::main]
+async fn main() {
+    let mut interval = time::interval(Duration::from_millis(10));
+
+    interval.tick().await; // ticks immediately
+    interval.tick().await; // ticks after 10ms
+    interval.tick().await; // ticks after 10ms
+
+    // approximately 20ms have elapsed.
+}
+

A simple example using interval to execute a task every two seconds.

+

The difference between interval and sleep is that an Interval +measures the time since the last tick, which means that .tick().await +may wait for a shorter time than the duration specified for the interval +if some time has passed between calls to .tick().await.

+

If the tick in the example below was replaced with sleep, the task +would only be executed once every three seconds, and not every two +seconds.

+ +
use tokio::time;
+
+async fn task_that_takes_a_second() {
+    println!("hello");
+    time::sleep(time::Duration::from_secs(1)).await
+}
+
+#[tokio::main]
+async fn main() {
+    let mut interval = time::interval(time::Duration::from_secs(2));
+    for _i in 0..5 {
+        interval.tick().await;
+        task_that_takes_a_second().await;
+    }
+}
+
\ No newline at end of file diff --git a/actix_web/rt/time/fn.interval_at.html b/actix_web/rt/time/fn.interval_at.html new file mode 100644 index 000000000..0a2e54193 --- /dev/null +++ b/actix_web/rt/time/fn.interval_at.html @@ -0,0 +1,23 @@ +interval_at in actix_web::rt::time - Rust

Function actix_web::rt::time::interval_at

pub fn interval_at(start: Instant, period: Duration) -> Interval
Expand description

Creates new Interval that yields with interval of period with the +first tick completing at start. The default [MissedTickBehavior] is +Burst, but this can be configured +by calling set_missed_tick_behavior.

+

An interval will tick indefinitely. At any time, the Interval value can +be dropped. This cancels the interval.

+

§Panics

+

This function panics if period is zero.

+

§Examples

+
use tokio::time::{interval_at, Duration, Instant};
+
+#[tokio::main]
+async fn main() {
+    let start = Instant::now() + Duration::from_millis(50);
+    let mut interval = interval_at(start, Duration::from_millis(10));
+
+    interval.tick().await; // ticks after 50ms
+    interval.tick().await; // ticks after 10ms
+    interval.tick().await; // ticks after 10ms
+
+    // approximately 70ms have elapsed.
+}
+
\ No newline at end of file diff --git a/actix_web/rt/time/fn.sleep.html b/actix_web/rt/time/fn.sleep.html new file mode 100644 index 000000000..a814054b3 --- /dev/null +++ b/actix_web/rt/time/fn.sleep.html @@ -0,0 +1,36 @@ +sleep in actix_web::rt::time - Rust

Function actix_web::rt::time::sleep

pub fn sleep(duration: Duration) -> Sleep 
Expand description

Waits until duration has elapsed.

+

Equivalent to sleep_until(Instant::now() + duration). An asynchronous +analog to std::thread::sleep.

+

No work is performed while awaiting on the sleep future to complete. Sleep +operates at millisecond granularity and should not be used for tasks that +require high-resolution timers. The implementation is platform specific, +and some platforms (specifically Windows) will provide timers with a +larger resolution than 1 ms.

+

To run something regularly on a schedule, see interval.

+

The maximum duration for a sleep is 68719476734 milliseconds (approximately 2.2 years).

+

§Cancellation

+

Canceling a sleep instance is done by dropping the returned future. No additional +cleanup work is required.

+

§Examples

+

Wait 100ms and print “100 ms have elapsed”.

+ +
use tokio::time::{sleep, Duration};
+
+#[tokio::main]
+async fn main() {
+    sleep(Duration::from_millis(100)).await;
+    println!("100 ms have elapsed");
+}
+

See the documentation for the Sleep type for more examples.

+

§Panics

+

This function panics if there is no current timer set.

+

It can be triggered when Builder::enable_time or +Builder::enable_all are not included in the builder.

+

It can also panic whenever a timer is created outside of a +Tokio runtime. That is why rt.block_on(sleep(...)) will panic, +since the function is executed outside of the runtime. +Whereas rt.block_on(async {sleep(...).await}) doesn’t panic. +And this is because wrapping the function on an async makes it lazy, +and so gets executed inside the runtime successfully without +panicking.

+
\ No newline at end of file diff --git a/actix_web/rt/time/fn.sleep_until.html b/actix_web/rt/time/fn.sleep_until.html new file mode 100644 index 000000000..d5b259009 --- /dev/null +++ b/actix_web/rt/time/fn.sleep_until.html @@ -0,0 +1,31 @@ +sleep_until in actix_web::rt::time - Rust

Function actix_web::rt::time::sleep_until

pub fn sleep_until(deadline: Instant) -> Sleep 
Expand description

Waits until deadline is reached.

+

No work is performed while awaiting on the sleep future to complete. Sleep +operates at millisecond granularity and should not be used for tasks that +require high-resolution timers.

+

To run something regularly on a schedule, see interval.

+

§Cancellation

+

Canceling a sleep instance is done by dropping the returned future. No additional +cleanup work is required.

+

§Examples

+

Wait 100ms and print “100 ms have elapsed”.

+ +
use tokio::time::{sleep_until, Instant, Duration};
+
+#[tokio::main]
+async fn main() {
+    sleep_until(Instant::now() + Duration::from_millis(100)).await;
+    println!("100 ms have elapsed");
+}
+

See the documentation for the Sleep type for more examples.

+

§Panics

+

This function panics if there is no current timer set.

+

It can be triggered when Builder::enable_time or +Builder::enable_all are not included in the builder.

+

It can also panic whenever a timer is created outside of a +Tokio runtime. That is why rt.block_on(sleep(...)) will panic, +since the function is executed outside of the runtime. +Whereas rt.block_on(async {sleep(...).await}) doesn’t panic. +And this is because wrapping the function on an async makes it lazy, +and so gets executed inside the runtime successfully without +panicking.

+
\ No newline at end of file diff --git a/actix_web/rt/time/fn.timeout.html b/actix_web/rt/time/fn.timeout.html new file mode 100644 index 000000000..e34865f18 --- /dev/null +++ b/actix_web/rt/time/fn.timeout.html @@ -0,0 +1,44 @@ +timeout in actix_web::rt::time - Rust

Function actix_web::rt::time::timeout

pub fn timeout<F>(duration: Duration, future: F) -> Timeout<F> 
where + F: Future,
Expand description

Requires a Future to complete before the specified duration has elapsed.

+

If the future completes before the duration has elapsed, then the completed +value is returned. Otherwise, an error is returned and the future is +canceled.

+

Note that the timeout is checked before polling the future, so if the future +does not yield during execution then it is possible for the future to complete +and exceed the timeout without returning an error.

+

This function returns a future whose return type is Result<T,Elapsed>, where T is the +return type of the provided future.

+

If the provided future completes immediately, then the future returned from +this function is guaranteed to complete immediately with an Ok variant +no matter the provided duration.

+

§Cancellation

+

Cancelling a timeout is done by dropping the future. No additional cleanup +or other work is required.

+

The original future may be obtained by calling Timeout::into_inner. This +consumes the Timeout.

+

§Examples

+

Create a new Timeout set to expire in 10 milliseconds.

+ +
use tokio::time::timeout;
+use tokio::sync::oneshot;
+
+use std::time::Duration;
+
+let (tx, rx) = oneshot::channel();
+
+// Wrap the future with a `Timeout` set to expire in 10 milliseconds.
+if let Err(_) = timeout(Duration::from_millis(10), rx).await {
+    println!("did not receive value within 10 ms");
+}
+

§Panics

+

This function panics if there is no current timer set.

+

It can be triggered when Builder::enable_time or +Builder::enable_all are not included in the builder.

+

It can also panic whenever a timer is created outside of a +Tokio runtime. That is why rt.block_on(sleep(...)) will panic, +since the function is executed outside of the runtime. +Whereas rt.block_on(async {sleep(...).await}) doesn’t panic. +And this is because wrapping the function on an async makes it lazy, +and so gets executed inside the runtime successfully without +panicking.

+
\ No newline at end of file diff --git a/actix_web/rt/time/index.html b/actix_web/rt/time/index.html new file mode 100644 index 000000000..d8ae04b59 --- /dev/null +++ b/actix_web/rt/time/index.html @@ -0,0 +1,9 @@ +actix_web::rt::time - Rust

Module actix_web::rt::time

Expand description

Utilities for tracking time (Tokio re-exports).

+

Structs§

Functions§

  • Creates new Interval that yields with interval of period. The first +tick completes immediately. The default [MissedTickBehavior] is +Burst, but this can be configured +by calling set_missed_tick_behavior.
  • Creates new Interval that yields with interval of period with the +first tick completing at start. The default [MissedTickBehavior] is +Burst, but this can be configured +by calling set_missed_tick_behavior.
  • Waits until duration has elapsed.
  • Waits until deadline is reached.
  • Requires a Future to complete before the specified duration has elapsed.
\ No newline at end of file diff --git a/actix_web/rt/time/sidebar-items.js b/actix_web/rt/time/sidebar-items.js new file mode 100644 index 000000000..414553ba9 --- /dev/null +++ b/actix_web/rt/time/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["interval","interval_at","sleep","sleep_until","timeout"],"struct":["Instant","Interval","Sleep","Timeout"]}; \ No newline at end of file diff --git a/actix_web/rt/time/struct.Instant.html b/actix_web/rt/time/struct.Instant.html new file mode 100644 index 000000000..4b678e8c8 --- /dev/null +++ b/actix_web/rt/time/struct.Instant.html @@ -0,0 +1,107 @@ +Instant in actix_web::rt::time - Rust

Struct actix_web::rt::time::Instant

pub struct Instant { /* private fields */ }
Expand description

A measurement of a monotonically nondecreasing clock. +Opaque and useful only with Duration.

+

Instants are always guaranteed to be no less than any previously measured +instant when created, and are often useful for tasks such as measuring +benchmarks or timing how long an operation takes.

+

Note, however, that instants are not guaranteed to be steady. In other +words, each tick of the underlying clock may not be the same length (e.g. +some seconds may be longer than others). An instant may jump forwards or +experience time dilation (slow down or speed up), but it will never go +backwards.

+

Instants are opaque types that can only be compared to one another. There is +no method to get “the number of seconds” from an instant. Instead, it only +allows measuring the duration between two instants (or comparing two +instants).

+

The size of an Instant struct may vary depending on the target operating +system.

+

§Note

+

This type wraps the inner std variant and is used to align the Tokio +clock for uses of now(). This can be useful for testing where you can +take advantage of time::pause() and time::advance().

+

Implementations§

§

impl Instant

pub fn now() -> Instant

Returns an instant corresponding to “now”.

+
§Examples
+
use tokio::time::Instant;
+
+let now = Instant::now();
+

pub fn from_std(std: Instant) -> Instant

Create a tokio::time::Instant from a std::time::Instant.

+

pub fn into_std(self) -> Instant

Convert the value into a std::time::Instant.

+

pub fn duration_since(&self, earlier: Instant) -> Duration

Returns the amount of time elapsed from another instant to this one, or +zero duration if that instant is later than this one.

+

pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration>

Returns the amount of time elapsed from another instant to this one, or +None if that instant is later than this one.

+
§Examples
+
use tokio::time::{Duration, Instant, sleep};
+
+#[tokio::main]
+async fn main() {
+    let now = Instant::now();
+    sleep(Duration::new(1, 0)).await;
+    let new_now = Instant::now();
+    println!("{:?}", new_now.checked_duration_since(now));
+    println!("{:?}", now.checked_duration_since(new_now)); // None
+}
+

pub fn saturating_duration_since(&self, earlier: Instant) -> Duration

Returns the amount of time elapsed from another instant to this one, or +zero duration if that instant is later than this one.

+
§Examples
+
use tokio::time::{Duration, Instant, sleep};
+
+#[tokio::main]
+async fn main() {
+    let now = Instant::now();
+    sleep(Duration::new(1, 0)).await;
+    let new_now = Instant::now();
+    println!("{:?}", new_now.saturating_duration_since(now));
+    println!("{:?}", now.saturating_duration_since(new_now)); // 0ns
+}
+

pub fn elapsed(&self) -> Duration

Returns the amount of time elapsed since this instant was created, +or zero duration if that this instant is in the future.

+
§Examples
+
use tokio::time::{Duration, Instant, sleep};
+
+#[tokio::main]
+async fn main() {
+    let instant = Instant::now();
+    let three_secs = Duration::from_secs(3);
+    sleep(three_secs).await;
+    assert!(instant.elapsed() >= three_secs);
+}
+

pub fn checked_add(&self, duration: Duration) -> Option<Instant>

Returns Some(t) where t is the time self + duration if t can be +represented as Instant (which means it’s inside the bounds of the +underlying data structure), None otherwise.

+

pub fn checked_sub(&self, duration: Duration) -> Option<Instant>

Returns Some(t) where t is the time self - duration if t can be +represented as Instant (which means it’s inside the bounds of the +underlying data structure), None otherwise.

+

Trait Implementations§

§

impl Add<Duration> for Instant

§

type Output = Instant

The resulting type after applying the + operator.
§

fn add(self, other: Duration) -> Instant

Performs the + operation. Read more
§

impl AddAssign<Duration> for Instant

§

fn add_assign(&mut self, rhs: Duration)

Performs the += operation. Read more
§

impl Clone for Instant

§

fn clone(&self) -> Instant

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Instant

§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl From<Instant> for Instant

§

fn from(time: Instant) -> Instant

Converts to this type from the input type.
§

impl Hash for Instant

§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl Ord for Instant

§

fn cmp(&self, other: &Instant) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
§

impl PartialEq for Instant

§

fn eq(&self, other: &Instant) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialOrd for Instant

§

fn partial_cmp(&self, other: &Instant) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl Sub<Duration> for Instant

§

type Output = Instant

The resulting type after applying the - operator.
§

fn sub(self, rhs: Duration) -> Instant

Performs the - operation. Read more
§

impl Sub for Instant

§

type Output = Duration

The resulting type after applying the - operator.
§

fn sub(self, rhs: Instant) -> Duration

Performs the - operation. Read more
§

impl SubAssign<Duration> for Instant

§

fn sub_assign(&mut self, rhs: Duration)

Performs the -= operation. Read more
§

impl Copy for Instant

§

impl Eq for Instant

§

impl StructuralPartialEq for Instant

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/time/struct.Interval.html b/actix_web/rt/time/struct.Interval.html new file mode 100644 index 000000000..d377cf485 --- /dev/null +++ b/actix_web/rt/time/struct.Interval.html @@ -0,0 +1,150 @@ +Interval in actix_web::rt::time - Rust

Struct actix_web::rt::time::Interval

pub struct Interval { /* private fields */ }
Expand description

Interval returned by interval and interval_at.

+

This type allows you to wait on a sequence of instants with a certain +duration between each instant. Unlike calling sleep in a loop, this lets +you count the time spent between the calls to sleep as well.

+

An Interval can be turned into a Stream with IntervalStream.

+

Implementations§

§

impl Interval

pub async fn tick(&mut self) -> Instant

Completes when the next instant in the interval has been reached.

+
§Cancel safety
+

This method is cancellation safe. If tick is used as the branch in a tokio::select! and +another branch completes first, then no tick has been consumed.

+
§Examples
+
use tokio::time;
+
+use std::time::Duration;
+
+#[tokio::main]
+async fn main() {
+    let mut interval = time::interval(Duration::from_millis(10));
+
+    interval.tick().await;
+    // approximately 0ms have elapsed. The first tick completes immediately.
+    interval.tick().await;
+    interval.tick().await;
+
+    // approximately 20ms have elapsed.
+}
+

pub fn poll_tick(&mut self, cx: &mut Context<'_>) -> Poll<Instant>

Polls for the next instant in the interval to be reached.

+

This method can return the following values:

+
    +
  • Poll::Pending if the next instant has not yet been reached.
  • +
  • Poll::Ready(instant) if the next instant has been reached.
  • +
+

When this method returns Poll::Pending, the current task is scheduled +to receive a wakeup when the instant has elapsed. Note that on multiple +calls to poll_tick, only the Waker from the +Context passed to the most recent call is scheduled to receive a +wakeup.

+

pub fn reset(&mut self)

Resets the interval to complete one period after the current time.

+

This method ignores [MissedTickBehavior] strategy.

+

This is equivalent to calling reset_at(Instant::now() + period).

+
§Examples
+
use tokio::time;
+
+use std::time::Duration;
+
+#[tokio::main]
+async fn main() {
+    let mut interval = time::interval(Duration::from_millis(100));
+
+    interval.tick().await;
+
+    time::sleep(Duration::from_millis(50)).await;
+    interval.reset();
+
+    interval.tick().await;
+    interval.tick().await;
+
+    // approximately 250ms have elapsed.
+}
+

pub fn reset_immediately(&mut self)

Resets the interval immediately.

+

This method ignores [MissedTickBehavior] strategy.

+

This is equivalent to calling reset_at(Instant::now()).

+
§Examples
+
use tokio::time;
+
+use std::time::Duration;
+
+#[tokio::main]
+async fn main() {
+    let mut interval = time::interval(Duration::from_millis(100));
+
+    interval.tick().await;
+
+    time::sleep(Duration::from_millis(50)).await;
+    interval.reset_immediately();
+
+    interval.tick().await;
+    interval.tick().await;
+
+    // approximately 150ms have elapsed.
+}
+

pub fn reset_after(&mut self, after: Duration)

Resets the interval after the specified std::time::Duration.

+

This method ignores [MissedTickBehavior] strategy.

+

This is equivalent to calling reset_at(Instant::now() + after).

+
§Examples
+
use tokio::time;
+
+use std::time::Duration;
+
+#[tokio::main]
+async fn main() {
+    let mut interval = time::interval(Duration::from_millis(100));
+    interval.tick().await;
+
+    time::sleep(Duration::from_millis(50)).await;
+
+    let after = Duration::from_millis(20);
+    interval.reset_after(after);
+
+    interval.tick().await;
+    interval.tick().await;
+
+    // approximately 170ms have elapsed.
+}
+

pub fn reset_at(&mut self, deadline: Instant)

Resets the interval to a crate::time::Instant deadline.

+

Sets the next tick to expire at the given instant. If the instant is in +the past, then the [MissedTickBehavior] strategy will be used to +catch up. If the instant is in the future, then the next tick will +complete at the given instant, even if that means that it will sleep for +longer than the duration of this Interval. If the Interval had +any missed ticks before calling this method, then those are discarded.

+
§Examples
+
use tokio::time::{self, Instant};
+
+use std::time::Duration;
+
+#[tokio::main]
+async fn main() {
+    let mut interval = time::interval(Duration::from_millis(100));
+    interval.tick().await;
+
+    time::sleep(Duration::from_millis(50)).await;
+
+    let deadline = Instant::now() + Duration::from_millis(30);
+    interval.reset_at(deadline);
+
+    interval.tick().await;
+    interval.tick().await;
+
+    // approximately 180ms have elapsed.
+}
+

pub fn missed_tick_behavior(&self) -> MissedTickBehavior

Returns the [MissedTickBehavior] strategy currently being used.

+

pub fn set_missed_tick_behavior(&mut self, behavior: MissedTickBehavior)

Sets the [MissedTickBehavior] strategy that should be used.

+

pub fn period(&self) -> Duration

Returns the period of the interval.

+

Trait Implementations§

§

impl Debug for Interval

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/time/struct.Sleep.html b/actix_web/rt/time/struct.Sleep.html new file mode 100644 index 000000000..89055e709 --- /dev/null +++ b/actix_web/rt/time/struct.Sleep.html @@ -0,0 +1,158 @@ +Sleep in actix_web::rt::time - Rust

Struct actix_web::rt::time::Sleep

pub struct Sleep { /* private fields */ }
Expand description

Future returned by sleep and sleep_until.

+

This type does not implement the Unpin trait, which means that if you +use it with select! or by calling poll, you have to pin it first. +If you use it with .await, this does not apply.

+

§Examples

+

Wait 100ms and print “100 ms have elapsed”.

+ +
use tokio::time::{sleep, Duration};
+
+#[tokio::main]
+async fn main() {
+    sleep(Duration::from_millis(100)).await;
+    println!("100 ms have elapsed");
+}
+

Use with select!. Pinning the Sleep with tokio::pin! is +necessary when the same Sleep is selected on multiple times.

+ +
use tokio::time::{self, Duration, Instant};
+
+#[tokio::main]
+async fn main() {
+    let sleep = time::sleep(Duration::from_millis(10));
+    tokio::pin!(sleep);
+
+    loop {
+        tokio::select! {
+            () = &mut sleep => {
+                println!("timer elapsed");
+                sleep.as_mut().reset(Instant::now() + Duration::from_millis(50));
+            },
+        }
+    }
+}
+

Use in a struct with boxing. By pinning the Sleep with a Box, the +HasSleep struct implements Unpin, even though Sleep does not.

+ +
use std::future::Future;
+use std::pin::Pin;
+use std::task::{Context, Poll};
+use tokio::time::Sleep;
+
+struct HasSleep {
+    sleep: Pin<Box<Sleep>>,
+}
+
+impl Future for HasSleep {
+    type Output = ();
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
+        self.sleep.as_mut().poll(cx)
+    }
+}
+

Use in a struct with pin projection. This method avoids the Box, but +the HasSleep struct will not be Unpin as a consequence.

+ +
use std::future::Future;
+use std::pin::Pin;
+use std::task::{Context, Poll};
+use tokio::time::Sleep;
+use pin_project_lite::pin_project;
+
+pin_project! {
+    struct HasSleep {
+        #[pin]
+        sleep: Sleep,
+    }
+}
+
+impl Future for HasSleep {
+    type Output = ();
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
+        self.project().sleep.poll(cx)
+    }
+}
+

Implementations§

§

impl Sleep

pub fn deadline(&self) -> Instant

Returns the instant at which the future will complete.

+

pub fn is_elapsed(&self) -> bool

Returns true if Sleep has elapsed.

+

A Sleep instance is elapsed when the requested duration has elapsed.

+

pub fn reset(self: Pin<&mut Sleep>, deadline: Instant)

Resets the Sleep instance to a new deadline.

+

Calling this function allows changing the instant at which the Sleep +future completes without having to create new associated state.

+

This function can be called both before and after the future has +completed.

+

To call this method, you will usually combine the call with +Pin::as_mut, which lets you call the method without consuming the +Sleep itself.

+
§Example
+
use tokio::time::{Duration, Instant};
+
+let sleep = tokio::time::sleep(Duration::from_millis(10));
+tokio::pin!(sleep);
+
+sleep.as_mut().reset(Instant::now() + Duration::from_millis(20));
+

See also the top-level examples.

+

Trait Implementations§

§

impl Debug for Sleep

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Future for Sleep

§

type Output = ()

The type of value produced on completion.
§

fn poll( + self: Pin<&mut Sleep>, + cx: &mut Context<'_> +) -> Poll<<Sleep as Future>::Output>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more

Auto Trait Implementations§

§

impl !Freeze for Sleep

§

impl !RefUnwindSafe for Sleep

§

impl Send for Sleep

§

impl Sync for Sleep

§

impl !UnwindSafe for Sleep

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> FutureExt for T
where + T: Future + ?Sized,

§

fn map<U, F>(self, f: F) -> Map<Self, F>
where + F: FnOnce(Self::Output) -> U, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn map_into<U>(self) -> MapInto<Self, U>
where + Self::Output: Into<U>, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnOnce(Self::Output) -> Fut, + Fut: Future, + Self: Sized,

Chain on a computation for when a future finished, passing the result of +the future to the provided closure f. Read more
§

fn left_future<B>(self) -> Either<Self, B>
where + B: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the left-hand variant +of that Either. Read more
§

fn right_future<A>(self) -> Either<A, Self>
where + A: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the right-hand variant +of that Either. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Convert this future into a single element stream. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Output: Future, + Self: Sized,

Flatten the execution of this future when the output of this +future is itself another future. Read more
§

fn flatten_stream(self) -> FlattenStream<Self>
where + Self::Output: Stream, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a future such that poll will never again be called once it has +completed. This method can be used to turn any Future into a +FusedFuture. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnOnce(&Self::Output), + Self: Sized,

Do something with the output of a future before passing it on. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the future. Read more
§

fn shared(self) -> Shared<Self>
where + Self: Sized, + Self::Output: Clone,

Available on crate feature std only.
Create a cloneable handle to this future where all handles will resolve +to the same result. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn unit_error(self) -> UnitError<Self>
where + Self: Sized,

§

fn never_error(self) -> NeverError<Self>
where + Self: Sized,

§

fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where + Self: Unpin,

A convenience for calling Future::poll on Unpin future types.
§

fn now_or_never(self) -> Option<Self::Output>
where + Self: Sized,

Evaluates and consumes the future, returning the resulting output if +the future is ready after the first call to Future::poll. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<F> IntoFuture for F
where + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/rt/time/struct.Timeout.html b/actix_web/rt/time/struct.Timeout.html new file mode 100644 index 000000000..efc1dcf82 --- /dev/null +++ b/actix_web/rt/time/struct.Timeout.html @@ -0,0 +1,123 @@ +Timeout in actix_web::rt::time - Rust

Struct actix_web::rt::time::Timeout

pub struct Timeout<T> { /* private fields */ }
Expand description

Future returned by timeout and timeout_at.

+

Implementations§

§

impl<T> Timeout<T>

pub fn get_ref(&self) -> &T

Gets a reference to the underlying value in this timeout.

+

pub fn get_mut(&mut self) -> &mut T

Gets a mutable reference to the underlying value in this timeout.

+

pub fn into_inner(self) -> T

Consumes this timeout, returning the underlying value.

+

Trait Implementations§

§

impl<T> Debug for Timeout<T>
where + T: Debug,

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<T> Future for Timeout<T>
where + T: Future,

§

type Output = Result<<T as Future>::Output, Elapsed>

The type of value produced on completion.
§

fn poll( + self: Pin<&mut Timeout<T>>, + cx: &mut Context<'_> +) -> Poll<<Timeout<T> as Future>::Output>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
§

impl<'__pin, T> Unpin for Timeout<T>
where + __Origin<'__pin, T>: Unpin,

Auto Trait Implementations§

§

impl<T> !Freeze for Timeout<T>

§

impl<T> !RefUnwindSafe for Timeout<T>

§

impl<T> Send for Timeout<T>
where + T: Send,

§

impl<T> Sync for Timeout<T>
where + T: Sync,

§

impl<T> !UnwindSafe for Timeout<T>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> FutureExt for T
where + T: Future + ?Sized,

§

fn map<U, F>(self, f: F) -> Map<Self, F>
where + F: FnOnce(Self::Output) -> U, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn map_into<U>(self) -> MapInto<Self, U>
where + Self::Output: Into<U>, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnOnce(Self::Output) -> Fut, + Fut: Future, + Self: Sized,

Chain on a computation for when a future finished, passing the result of +the future to the provided closure f. Read more
§

fn left_future<B>(self) -> Either<Self, B>
where + B: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the left-hand variant +of that Either. Read more
§

fn right_future<A>(self) -> Either<A, Self>
where + A: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the right-hand variant +of that Either. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Convert this future into a single element stream. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Output: Future, + Self: Sized,

Flatten the execution of this future when the output of this +future is itself another future. Read more
§

fn flatten_stream(self) -> FlattenStream<Self>
where + Self::Output: Stream, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a future such that poll will never again be called once it has +completed. This method can be used to turn any Future into a +FusedFuture. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnOnce(&Self::Output), + Self: Sized,

Do something with the output of a future before passing it on. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the future. Read more
§

fn shared(self) -> Shared<Self>
where + Self: Sized, + Self::Output: Clone,

Available on crate feature std only.
Create a cloneable handle to this future where all handles will resolve +to the same result. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn unit_error(self) -> UnitError<Self>
where + Self: Sized,

§

fn never_error(self) -> NeverError<Self>
where + Self: Sized,

§

fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where + Self: Unpin,

A convenience for calling Future::poll on Unpin future types.
§

fn now_or_never(self) -> Option<Self::Output>
where + Self: Sized,

Evaluates and consumes the future, returning the resulting output if +the future is ready after the first call to Future::poll. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<F> IntoFuture for F
where + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

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
§

fn try_poll( + self: Pin<&mut F>, + cx: &mut Context<'_> +) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
§

impl<Fut> TryFutureExt for Fut
where + Fut: TryFuture + ?Sized,

§

fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>
where + Self::Ok: Sink<Item, Error = Self::Error>, + Self: Sized,

Available on crate feature sink only.
Flattens the execution of this future when the successful result of this +future is a [Sink]. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + F: FnOnce(Self::Ok) -> T, + Self: Sized,

Maps this future’s success value to a different value. Read more
§

fn map_ok_or_else<T, E, F>(self, e: E, f: F) -> MapOkOrElse<Self, F, E>
where + F: FnOnce(Self::Ok) -> T, + E: FnOnce(Self::Error) -> T, + Self: Sized,

Maps this future’s success value to a different value, and permits for error handling resulting in the same type. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + F: FnOnce(Self::Error) -> E, + Self: Sized,

Maps this future’s error value to a different value. Read more
§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Maps this future’s Error to a new error type +using the Into trait. Read more
§

fn ok_into<U>(self) -> OkInto<Self, U>
where + Self: Sized, + Self::Ok: Into<U>,

Maps this future’s Ok to a new type +using the Into trait.
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnOnce(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Executes another future after this one resolves successfully. The +success value is passed to a closure to create this subsequent future. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnOnce(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Executes another future if this one resolves to an error. The +error value is passed to a closure to create this subsequent future. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnOnce(&Self::Ok), + Self: Sized,

Do something with the success value of a future before passing it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnOnce(&Self::Error), + Self: Sized,

Do something with the error value of a future before passing it on. Read more
§

fn try_flatten(self) -> TryFlatten<Self, Self::Ok>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is another future. Read more
§

fn try_flatten_stream(self) -> TryFlattenStream<Self>
where + Self::Ok: TryStream<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F>
where + Self: Sized, + F: FnOnce(Self::Error) -> Self::Ok,

Unwraps this future’s output, producing a future with this future’s +Ok type as its +Output type. Read more
§

fn into_future(self) -> IntoFuture<Self>
where + Self: Sized,

Wraps a [TryFuture] into a type that implements +Future. Read more
§

fn try_poll_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Result<Self::Ok, Self::Error>>
where + Self: Unpin,

A convenience method for calling [TryFuture::try_poll] on Unpin +future types.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/scope/struct.Scope.html b/actix_web/scope/struct.Scope.html new file mode 100644 index 000000000..2234af949 --- /dev/null +++ b/actix_web/scope/struct.Scope.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/struct.Scope.html...

+ + + \ No newline at end of file diff --git a/actix_web/server/struct.HttpServer.html b/actix_web/server/struct.HttpServer.html new file mode 100644 index 000000000..0cc997fa4 --- /dev/null +++ b/actix_web/server/struct.HttpServer.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/struct.HttpServer.html...

+ + + \ No newline at end of file diff --git a/actix_web/service/struct.ServiceRequest.html b/actix_web/service/struct.ServiceRequest.html new file mode 100644 index 000000000..02fd03a62 --- /dev/null +++ b/actix_web/service/struct.ServiceRequest.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/dev/struct.ServiceRequest.html...

+ + + \ No newline at end of file diff --git a/actix_web/service/struct.ServiceResponse.html b/actix_web/service/struct.ServiceResponse.html new file mode 100644 index 000000000..2b1a6442c --- /dev/null +++ b/actix_web/service/struct.ServiceResponse.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/dev/struct.ServiceResponse.html...

+ + + \ No newline at end of file diff --git a/actix_web/service/struct.WebService.html b/actix_web/service/struct.WebService.html new file mode 100644 index 000000000..3bb00d06d --- /dev/null +++ b/actix_web/service/struct.WebService.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/dev/struct.WebService.html...

+ + + \ No newline at end of file diff --git a/actix_web/service/trait.HttpServiceFactory.html b/actix_web/service/trait.HttpServiceFactory.html new file mode 100644 index 000000000..b47a9fd59 --- /dev/null +++ b/actix_web/service/trait.HttpServiceFactory.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web/dev/trait.HttpServiceFactory.html...

+ + + \ No newline at end of file diff --git a/actix_web/sidebar-items.js b/actix_web/sidebar-items.js new file mode 100644 index 000000000..d899527f2 --- /dev/null +++ b/actix_web/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"attr":["connect","delete","get","head","main","options","patch","post","put","route","routes","test","trace"],"enum":["Either"],"macro":["services"],"mod":["body","cookie","dev","error","guard","http","middleware","rt","test","web"],"struct":["App","CustomizeResponder","HttpRequest","HttpResponse","HttpResponseBuilder","HttpServer","Resource","Route","Scope"],"trait":["FromRequest","Handler","HttpMessage","Responder"],"type":["Result"]}; \ No newline at end of file diff --git a/actix_web/struct.App.html b/actix_web/struct.App.html new file mode 100644 index 000000000..aa5fe0a10 --- /dev/null +++ b/actix_web/struct.App.html @@ -0,0 +1,216 @@ +App in actix_web - Rust

Struct actix_web::App

source ·
pub struct App<T> { /* private fields */ }
Expand description

The top-level builder for an Actix Web application.

+

Implementations§

source§

impl App<AppEntry>

source

pub fn new() -> Self

Create application builder. Application can be configured with a builder-like pattern.

+
source§

impl<T> App<T>
where + T: ServiceFactory<ServiceRequest, Config = (), Error = Error, InitError = ()>,

source

pub fn app_data<U: 'static>(self, ext: U) -> Self

Set application (root level) data.

+

Application data stored with App::app_data() method is available through the +HttpRequest::app_data method at runtime.

+
§Data<T>
+

Any Data<T> type added here can utilize its extractor implementation in handlers. +Types not wrapped in Data<T> cannot use this extractor. See its docs for more +about its usage and patterns.

+ +
use std::cell::Cell;
+use actix_web::{web, App, HttpRequest, HttpResponse, Responder};
+
+struct MyData {
+    count: std::cell::Cell<usize>,
+}
+
+async fn handler(req: HttpRequest, counter: web::Data<MyData>) -> impl Responder {
+    // note this cannot use the Data<T> extractor because it was not added with it
+    let incr = *req.app_data::<usize>().unwrap();
+    assert_eq!(incr, 3);
+
+    // update counter using other value from app data
+    counter.count.set(counter.count.get() + incr);
+
+    HttpResponse::Ok().body(counter.count.get().to_string())
+}
+
+let app = App::new().service(
+    web::resource("/")
+        .app_data(3usize)
+        .app_data(web::Data::new(MyData { count: Default::default() }))
+        .route(web::get().to(handler))
+);
+
§Shared Mutable State
+

HttpServer::new accepts an application factory rather than an +application instance; the factory closure is called on each worker thread independently. +Therefore, if you want to share a data object between different workers, a shareable object +needs to be created first, outside the HttpServer::new closure and cloned into it. +Data<T> is an example of such a sharable object.

+ +
let counter = web::Data::new(AppStateWithCounter {
+    counter: Mutex::new(0),
+});
+
+HttpServer::new(move || {
+    // move counter object into the closure and clone for each worker
+
+    App::new()
+        .app_data(counter.clone())
+        .route("/", web::get().to(handler))
+})
+
source

pub fn data<U: 'static>(self, data: U) -> Self

👎Deprecated since 4.0.0: Use .app_data(Data::new(val)) instead.

Add application (root) data after wrapping in Data<T>.

+

Deprecated in favor of app_data.

+
source

pub fn data_factory<F, Out, D, E>(self, data: F) -> Self
where + F: Fn() -> Out + 'static, + Out: Future<Output = Result<D, E>> + 'static, + D: 'static, + E: Debug,

Add application data factory that resolves asynchronously.

+

Data items are constructed during application initialization, before the server starts +accepting requests.

+

The returned data value D is wrapped as Data<D>.

+
source

pub fn configure<F>(self, f: F) -> Self
where + F: FnOnce(&mut ServiceConfig),

Run external configuration as part of the application building +process

+

This function is useful for moving parts of configuration to a +different module or even library. For example, +some of the resource’s configuration could be moved to different module.

+ +
use actix_web::{web, App, HttpResponse};
+
+// this function could be located in different module
+fn config(cfg: &mut web::ServiceConfig) {
+    cfg.service(web::resource("/test")
+        .route(web::get().to(|| HttpResponse::Ok()))
+        .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
+    );
+}
+
+App::new()
+    .configure(config)  // <- register resources
+    .route("/index.html", web::get().to(|| HttpResponse::Ok()));
+
source

pub fn route(self, path: &str, route: Route) -> Self

Configure route for a specific path.

+

This is a simplified version of the App::service() method. +This method can be used multiple times with same path, in that case +multiple resources with one route would be registered for same resource path.

+ +
use actix_web::{web, App, HttpResponse};
+
+async fn index(data: web::Path<(String, String)>) -> &'static str {
+    "Welcome!"
+}
+
+let app = App::new()
+    .route("/test1", web::get().to(index))
+    .route("/test2", web::post().to(|| HttpResponse::MethodNotAllowed()));
+
source

pub fn service<F>(self, factory: F) -> Self
where + F: HttpServiceFactory + 'static,

Register HTTP service.

+

Http service is any type that implements HttpServiceFactory trait.

+

Actix Web provides several services implementations:

+
    +
  • Resource is an entry in resource table which corresponds to requested URL.
  • +
  • Scope is a set of resources with common root path.
  • +
  • “StaticFiles” is a service for static files support
  • +
+
source

pub fn default_service<F, U>(self, svc: F) -> Self
where + F: IntoServiceFactory<U, ServiceRequest>, + U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error> + 'static, + U::InitError: Debug,

Default service that is invoked when no matching resource could be found.

+

You can use a Route as default service.

+

If a default service is not registered, an empty 404 Not Found response will be sent to +the client instead.

+
§Examples
+
use actix_web::{web, App, HttpResponse};
+
+async fn index() -> &'static str {
+    "Welcome!"
+}
+
+let app = App::new()
+    .service(web::resource("/index.html").route(web::get().to(index)))
+    .default_service(web::to(|| HttpResponse::NotFound()));
+
source

pub fn external_resource<N, U>(self, name: N, url: U) -> Self
where + N: AsRef<str>, + U: AsRef<str>,

Register an external resource.

+

External resources are useful for URL generation purposes only +and are never considered for matching at request time. Calls to +HttpRequest::url_for() will work as expected.

+ +
use actix_web::{web, App, HttpRequest, HttpResponse, Result};
+
+async fn index(req: HttpRequest) -> Result<HttpResponse> {
+    let url = req.url_for("youtube", &["asdlkjqme"])?;
+    assert_eq!(url.as_str(), "https://youtube.com/watch/asdlkjqme");
+    Ok(HttpResponse::Ok().into())
+}
+
+let app = App::new()
+    .service(web::resource("/index.html").route(
+        web::get().to(index)))
+    .external_resource("youtube", "https://youtube.com/watch/{video_id}");
+
source

pub fn wrap<M, B>( + self, + mw: M +) -> App<impl ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B>, Error = Error, InitError = ()>>
where + M: Transform<T::Service, ServiceRequest, Response = ServiceResponse<B>, Error = Error, InitError = ()> + 'static, + B: MessageBody,

Registers an app-wide middleware.

+

Registers middleware, in the form of a middleware component (type), that runs during +inbound and/or outbound processing in the request life-cycle (request -> response), +modifying request/response as necessary, across all requests managed by the App.

+

Use middleware when you need to read or modify every request or response in some way.

+

Middleware can be applied similarly to individual Scopes and Resources. +See Scope::wrap and Resource::wrap.

+

For more info on middleware take a look at the middleware module.

+
§Examples
+
use actix_web::{middleware, web, App};
+
+async fn index() -> &'static str {
+    "Welcome!"
+}
+
+let app = App::new()
+    .wrap(middleware::Logger::default())
+    .route("/index.html", web::get().to(index));
+
source

pub fn wrap_fn<F, R, B>( + self, + mw: F +) -> App<impl ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B>, Error = Error, InitError = ()>>
where + F: Fn(ServiceRequest, &T::Service) -> R + Clone + 'static, + R: Future<Output = Result<ServiceResponse<B>, Error>>, + B: MessageBody,

Registers an app-wide function middleware.

+

mw is a closure that runs during inbound and/or outbound processing in the request +life-cycle (request -> response), modifying request/response as necessary, across all +requests handled by the App.

+

Use middleware when you need to read or modify every request or response in some way.

+

Middleware can also be applied to individual Scopes and Resources.

+

See App::wrap for details on how middlewares compose with each other.

+
§Examples
+
use actix_web::{dev::Service as _, middleware, web, App};
+use actix_web::http::header::{CONTENT_TYPE, HeaderValue};
+
+async fn index() -> &'static str {
+    "Welcome!"
+}
+
+let app = App::new()
+    .wrap_fn(|req, srv| {
+        let fut = srv.call(req);
+        async {
+            let mut res = fut.await?;
+            res.headers_mut()
+                .insert(CONTENT_TYPE, HeaderValue::from_static("text/plain"));
+            Ok(res)
+        }
+    })
+    .route("/index.html", web::get().to(index));
+

Auto Trait Implementations§

§

impl<T> Freeze for App<T>
where + T: Freeze,

§

impl<T> !RefUnwindSafe for App<T>

§

impl<T> !Send for App<T>

§

impl<T> !Sync for App<T>

§

impl<T> Unpin for App<T>
where + T: Unpin,

§

impl<T> !UnwindSafe for App<T>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/struct.CustomizeResponder.html b/actix_web/struct.CustomizeResponder.html new file mode 100644 index 000000000..4378ebb6a --- /dev/null +++ b/actix_web/struct.CustomizeResponder.html @@ -0,0 +1,66 @@ +CustomizeResponder in actix_web - Rust

Struct actix_web::CustomizeResponder

source ·
pub struct CustomizeResponder<R> { /* private fields */ }
Expand description

Allows overriding status code and headers for a Responder.

+

Created by calling the customize method on a Responder type.

+

Implementations§

source§

impl<R: Responder> CustomizeResponder<R>

source

pub fn with_status(self, status: StatusCode) -> Self

Override a status code for the Responder’s response.

+
§Examples
+
use actix_web::{Responder, http::StatusCode, test::TestRequest};
+
+let responder = "Welcome!".customize().with_status(StatusCode::ACCEPTED);
+
+let request = TestRequest::default().to_http_request();
+let response = responder.respond_to(&request);
+assert_eq!(response.status(), StatusCode::ACCEPTED);
+
source

pub fn insert_header(self, header: impl TryIntoHeaderPair) -> Self

Insert (override) header in the final response.

+

Overrides other headers with the same name. +See HeaderMap::insert.

+

Headers added with this method will be inserted before those added +with append_header. As such, header(s) can be overridden with more +than one new header by first calling insert_header followed by append_header.

+
§Examples
+
use actix_web::{Responder, test::TestRequest};
+
+let responder = "Hello world!"
+    .customize()
+    .insert_header(("x-version", "1.2.3"));
+
+let request = TestRequest::default().to_http_request();
+let response = responder.respond_to(&request);
+assert_eq!(response.headers().get("x-version").unwrap(), "1.2.3");
+
source

pub fn append_header(self, header: impl TryIntoHeaderPair) -> Self

Append header to the final response.

+

Unlike insert_header, this will not override existing headers. +See HeaderMap::append.

+

Headers added here are appended after additions/overrides from insert_header.

+
§Examples
+
use actix_web::{Responder, test::TestRequest};
+
+let responder = "Hello world!"
+    .customize()
+    .append_header(("x-version", "1.2.3"));
+
+let request = TestRequest::default().to_http_request();
+let response = responder.respond_to(&request);
+assert_eq!(response.headers().get("x-version").unwrap(), "1.2.3");
+

Trait Implementations§

source§

impl<T> Responder for CustomizeResponder<T>
where + T: Responder,

§

type Body = EitherBody<<T as Responder>::Body>

source§

fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body>

Convert self to HttpResponse.
source§

fn customize(self) -> CustomizeResponder<Self>
where + Self: Sized,

Wraps responder to allow alteration of its response. Read more

Auto Trait Implementations§

§

impl<R> Freeze for CustomizeResponder<R>
where + R: Freeze,

§

impl<R> RefUnwindSafe for CustomizeResponder<R>
where + R: RefUnwindSafe,

§

impl<R> Send for CustomizeResponder<R>
where + R: Send,

§

impl<R> Sync for CustomizeResponder<R>
where + R: Sync,

§

impl<R> Unpin for CustomizeResponder<R>
where + R: Unpin,

§

impl<R> UnwindSafe for CustomizeResponder<R>
where + R: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/struct.HttpRequest.html b/actix_web/struct.HttpRequest.html new file mode 100644 index 000000000..985ff39d3 --- /dev/null +++ b/actix_web/struct.HttpRequest.html @@ -0,0 +1,115 @@ +HttpRequest in actix_web - Rust

Struct actix_web::HttpRequest

source ·
pub struct HttpRequest { /* private fields */ }
Expand description

An incoming request.

+

Implementations§

source§

impl HttpRequest

source

pub fn head(&self) -> &RequestHead

This method returns reference to the request head

+
source

pub fn uri(&self) -> &Uri

Request’s uri.

+
source

pub fn method(&self) -> &Method

Read the Request method.

+
source

pub fn version(&self) -> Version

Read the Request Version.

+
source

pub fn headers(&self) -> &HeaderMap

Returns request’s headers.

+
source

pub fn path(&self) -> &str

The target path of this request.

+
source

pub fn query_string(&self) -> &str

The query string in the URL.

+

Example: id=10

+
source

pub fn match_info(&self) -> &Path<Url>

Returns a reference to the URL parameters container.

+

A URL parameter is specified in the form {identifier}, where the identifier can be used +later in a request handler to access the matched value for that parameter.

+
§Percent Encoding and URL Parameters
+

Because each URL parameter is able to capture multiple path segments, none of +["%2F", "%25", "%2B"] found in the request URI are decoded into ["/", "%", "+"] in order +to preserve path integrity. If a URL parameter is expected to contain these characters, then +it is on the user to decode them or use the web::Path extractor which +will decode these special sequences.

+
source

pub fn match_pattern(&self) -> Option<String>

The resource definition pattern that matched the path. Useful for logging and metrics.

+

For example, when a resource with pattern /user/{id}/profile is defined and a call is made +to /user/123/profile this function would return Some("/user/{id}/profile").

+

Returns a None when no resource is fully matched, including default services.

+
source

pub fn match_name(&self) -> Option<&str>

The resource name that matched the path. Useful for logging and metrics.

+

Returns a None when no resource is fully matched, including default services.

+
source

pub fn conn_data<T: 'static>(&self) -> Option<&T>

Returns a reference a piece of connection data set in an on-connect callback.

+ +
let opt_t = req.conn_data::<PeerCertificate>();
+
source

pub fn url_for<U, I>( + &self, + name: &str, + elements: U +) -> Result<Url, UrlGenerationError>
where + U: IntoIterator<Item = I>, + I: AsRef<str>,

Generates URL for a named resource.

+

This substitutes in sequence all URL parameters that appear in the resource itself and in +parent scopes, if any.

+

It is worth noting that the characters ['/', '%'] are not escaped and therefore a single +URL parameter may expand into multiple path segments and elements can be percent-encoded +beforehand without worrying about double encoding. Any other character that is not valid in +a URL path context is escaped using percent-encoding.

+
§Examples
+
fn index(req: HttpRequest) -> HttpResponse {
+    let url = req.url_for("foo", &["1", "2", "3"]); // <- generate URL for "foo" resource
+    HttpResponse::Ok().into()
+}
+
+let app = App::new()
+    .service(web::resource("/test/{one}/{two}/{three}")
+         .name("foo")  // <- set resource name so it can be used in `url_for`
+         .route(web::get().to(|| HttpResponse::Ok()))
+    );
+
source

pub fn url_for_static(&self, name: &str) -> Result<Url, UrlGenerationError>

Generate URL for named resource

+

This method is similar to HttpRequest::url_for() but it can be used +for urls that do not contain variable parts.

+
source

pub fn resource_map(&self) -> &ResourceMap

Get a reference to a ResourceMap of current application.

+
source

pub fn peer_addr(&self) -> Option<SocketAddr>

Returns peer socket address.

+

Peer address is the directly connected peer’s socket address. If a proxy is used in front of +the Actix Web server, then it would be address of this proxy.

+

For expanded client connection information, use connection_info instead.

+

Will only return None when called in unit tests unless TestRequest::peer_addr is used.

+
source

pub fn connection_info(&self) -> Ref<'_, ConnectionInfo>

Returns connection info for the current request.

+

The return type, ConnectionInfo, can also be used as an extractor.

+
§Panics
+

Panics if request’s extensions container is already borrowed.

+
source

pub fn app_config(&self) -> &AppConfig

Returns a reference to the application’s connection configuration.

+
source

pub fn app_data<T: 'static>(&self) -> Option<&T>

Retrieves a piece of application state.

+

Extracts any object stored with App::app_data() (or the +counterpart methods on Scope and +Resource) during application configuration.

+

Since the Actix Web router layers application data, the returned object will reference the +“closest” instance of the type. For example, if an App stores a u32, a nested Scope +also stores a u32, and the delegated request handler falls within that Scope, then +calling .app_data::<u32>() on an HttpRequest within that handler will return the +Scope’s instance. However, using the same router set up and a request that does not get +captured by the Scope, .app_data::<u32>() would return the App’s instance.

+

If the state was stored using the Data wrapper, then it must also be retrieved using +this same type.

+

See also the Data extractor.

+
§Examples
+
let opt_t: Option<&Data<T>> = req.app_data::<Data<T>>();
+
source

pub fn cookies(&self) -> Result<Ref<'_, Vec<Cookie<'static>>>, CookieParseError>

Available on crate feature cookies only.

Load request cookies.

+
source

pub fn cookie(&self, name: &str) -> Option<Cookie<'static>>

Available on crate feature cookies only.

Return request cookie.

+

Trait Implementations§

source§

impl Clone for HttpRequest

source§

fn clone(&self) -> HttpRequest

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for HttpRequest

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Drop for HttpRequest

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl FromRequest for HttpRequest

It is possible to get HttpRequest as an extractor handler parameter

+

§Examples

+
use actix_web::{web, App, HttpRequest};
+use serde::Deserialize;
+
+/// extract `Thing` from request
+async fn index(req: HttpRequest) -> String {
+   format!("Got thing: {:?}", req)
+}
+
+let app = App::new().service(
+    web::resource("/users/{first}").route(
+        web::get().to(index))
+);
+
§

type Error = Error

The associated error which can be returned.
§

type Future = Ready<Result<HttpRequest, Error>>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more
source§

impl HttpMessage for HttpRequest

§

type Stream = ()

Type of message payload stream
source§

fn headers(&self) -> &HeaderMap

Read the message headers.
source§

fn extensions(&self) -> Ref<'_, Extensions>

Returns a reference to the request-local data/extensions container.
source§

fn extensions_mut(&self) -> RefMut<'_, Extensions>

Returns a mutable reference to the request-local data/extensions container.
source§

fn take_payload(&mut self) -> Payload<Self::Stream>

Message payload stream
source§

fn content_type(&self) -> &str

Read the request content type. If request did not contain a Content-Type header, an empty +string is returned.
source§

fn encoding(&self) -> Result<&'static Encoding, ContentTypeError>

Get content type encoding. Read more
source§

fn mime_type(&self) -> Result<Option<Mime>, ContentTypeError>

Convert the request content type to a known mime type.
source§

fn chunked(&self) -> Result<bool, ParseError>

Check if request has chunked transfer encoding.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/struct.HttpResponse.html b/actix_web/struct.HttpResponse.html new file mode 100644 index 000000000..8745bce0a --- /dev/null +++ b/actix_web/struct.HttpResponse.html @@ -0,0 +1,81 @@ +HttpResponse in actix_web - Rust

Struct actix_web::HttpResponse

source ·
pub struct HttpResponse<B = BoxBody> { /* private fields */ }
Expand description

An outgoing response.

+

Implementations§

source§

impl HttpResponse

source

pub fn Continue() -> HttpResponseBuilder

source

pub fn SwitchingProtocols() -> HttpResponseBuilder

source

pub fn Processing() -> HttpResponseBuilder

source

pub fn Ok() -> HttpResponseBuilder

source

pub fn Created() -> HttpResponseBuilder

source

pub fn Accepted() -> HttpResponseBuilder

source

pub fn NonAuthoritativeInformation() -> HttpResponseBuilder

source

pub fn NoContent() -> HttpResponseBuilder

source

pub fn ResetContent() -> HttpResponseBuilder

source

pub fn PartialContent() -> HttpResponseBuilder

source

pub fn MultiStatus() -> HttpResponseBuilder

source

pub fn AlreadyReported() -> HttpResponseBuilder

source

pub fn ImUsed() -> HttpResponseBuilder

source

pub fn MultipleChoices() -> HttpResponseBuilder

source

pub fn MovedPermanently() -> HttpResponseBuilder

source

pub fn Found() -> HttpResponseBuilder

source

pub fn SeeOther() -> HttpResponseBuilder

source

pub fn NotModified() -> HttpResponseBuilder

source

pub fn UseProxy() -> HttpResponseBuilder

source

pub fn TemporaryRedirect() -> HttpResponseBuilder

source

pub fn PermanentRedirect() -> HttpResponseBuilder

source

pub fn BadRequest() -> HttpResponseBuilder

source

pub fn Unauthorized() -> HttpResponseBuilder

source

pub fn PaymentRequired() -> HttpResponseBuilder

source

pub fn Forbidden() -> HttpResponseBuilder

source

pub fn NotFound() -> HttpResponseBuilder

source

pub fn MethodNotAllowed() -> HttpResponseBuilder

source

pub fn NotAcceptable() -> HttpResponseBuilder

source

pub fn ProxyAuthenticationRequired() -> HttpResponseBuilder

source

pub fn RequestTimeout() -> HttpResponseBuilder

source

pub fn Conflict() -> HttpResponseBuilder

source

pub fn Gone() -> HttpResponseBuilder

source

pub fn LengthRequired() -> HttpResponseBuilder

source

pub fn PreconditionFailed() -> HttpResponseBuilder

source

pub fn PayloadTooLarge() -> HttpResponseBuilder

source

pub fn UriTooLong() -> HttpResponseBuilder

source

pub fn UnsupportedMediaType() -> HttpResponseBuilder

source

pub fn RangeNotSatisfiable() -> HttpResponseBuilder

source

pub fn ExpectationFailed() -> HttpResponseBuilder

source

pub fn ImATeapot() -> HttpResponseBuilder

source

pub fn MisdirectedRequest() -> HttpResponseBuilder

source

pub fn UnprocessableEntity() -> HttpResponseBuilder

source

pub fn Locked() -> HttpResponseBuilder

source

pub fn FailedDependency() -> HttpResponseBuilder

source

pub fn UpgradeRequired() -> HttpResponseBuilder

source

pub fn PreconditionRequired() -> HttpResponseBuilder

source

pub fn TooManyRequests() -> HttpResponseBuilder

source

pub fn RequestHeaderFieldsTooLarge() -> HttpResponseBuilder

source

pub fn UnavailableForLegalReasons() -> HttpResponseBuilder

source

pub fn InternalServerError() -> HttpResponseBuilder

source

pub fn NotImplemented() -> HttpResponseBuilder

source

pub fn BadGateway() -> HttpResponseBuilder

source

pub fn ServiceUnavailable() -> HttpResponseBuilder

source

pub fn GatewayTimeout() -> HttpResponseBuilder

source

pub fn VersionNotSupported() -> HttpResponseBuilder

source

pub fn VariantAlsoNegotiates() -> HttpResponseBuilder

source

pub fn InsufficientStorage() -> HttpResponseBuilder

source

pub fn LoopDetected() -> HttpResponseBuilder

source

pub fn NotExtended() -> HttpResponseBuilder

source

pub fn NetworkAuthenticationRequired() -> HttpResponseBuilder

source§

impl HttpResponse<BoxBody>

source

pub fn new(status: StatusCode) -> Self

Constructs a response.

+
source

pub fn build(status: StatusCode) -> HttpResponseBuilder

Constructs a response builder with specific HTTP status.

+
source

pub fn from_error(error: impl Into<Error>) -> Self

Create an error response.

+
source§

impl<B> HttpResponse<B>

source

pub fn with_body(status: StatusCode, body: B) -> Self

Constructs a response with body

+
source

pub fn head(&self) -> &ResponseHead

Returns a reference to response head.

+
source

pub fn head_mut(&mut self) -> &mut ResponseHead

Returns a mutable reference to response head.

+
source

pub fn error(&self) -> Option<&Error>

The source error for this response

+
source

pub fn status(&self) -> StatusCode

Get the response status code

+
source

pub fn status_mut(&mut self) -> &mut StatusCode

Set the StatusCode for this response

+
source

pub fn headers(&self) -> &HeaderMap

Get the headers from the response

+
source

pub fn headers_mut(&mut self) -> &mut HeaderMap

Get a mutable reference to the headers

+
source

pub fn cookies(&self) -> CookieIter<'_>

Available on crate feature cookies only.

Get an iterator for the cookies set by this response.

+
Available on crate feature cookies only.

Add a cookie to this response.

+
§Errors
+

Returns an error if the cookie results in a malformed Set-Cookie header.

+
Available on crate feature cookies only.

Add a “removal” cookie to the response that matches attributes of given cookie.

+

This will cause browsers/clients to remove stored cookies with this name.

+

The Set-Cookie header added to the response will have:

+
    +
  • name matching given cookie;
  • +
  • domain matching given cookie;
  • +
  • path matching given cookie;
  • +
  • an empty value;
  • +
  • a max-age of 0;
  • +
  • an expiration date far in the past.
  • +
+

If the cookie you’re trying to remove has an explicit path or domain set, those attributes +will need to be included in the cookie passed in here.

+
§Errors
+

Returns an error if the given name results in a malformed Set-Cookie header.

+
Available on crate feature cookies only.

Remove all cookies with the given name from this response.

+

Returns the number of cookies removed.

+

This method can not cause a browser/client to delete any of its stored cookies. Its only +purpose is to delete cookies that were added to this response using add_cookie +and add_removal_cookie. Use add_removal_cookie to send a “removal” cookie.

+
source

pub fn upgrade(&self) -> bool

Connection upgrade status

+
source

pub fn keep_alive(&self) -> bool

Keep-alive status for this connection

+
source

pub fn extensions(&self) -> Ref<'_, Extensions>

Returns reference to the response-local data/extensions container.

+
source

pub fn extensions_mut(&mut self) -> RefMut<'_, Extensions>

Returns reference to the response-local data/extensions container.

+
source

pub fn body(&self) -> &B

Returns a reference to this response’s body.

+
source

pub fn set_body<B2>(self, body: B2) -> HttpResponse<B2>

Sets new body.

+
source

pub fn into_parts(self) -> (HttpResponse<()>, B)

Returns split head and body.

+
§Implementation Notes
+

Due to internal performance optimizations, the first element of the returned tuple is an +HttpResponse as well but only contains the head of the response this was called on.

+
source

pub fn drop_body(self) -> HttpResponse<()>

Drops body and returns new response.

+
source

pub fn map_body<F, B2>(self, f: F) -> HttpResponse<B2>
where + F: FnOnce(&mut ResponseHead, B) -> B2,

Map the current body type to another using a closure, returning a new response.

+

Closure receives the response head and the current body type.

+
source

pub fn map_into_left_body<R>(self) -> HttpResponse<EitherBody<B, R>>

Map the current body type B to EitherBody::Left(B).

+

Useful for middleware which can generate their own responses.

+
source

pub fn map_into_right_body<L>(self) -> HttpResponse<EitherBody<L, B>>

Map the current body type B to EitherBody::Right(B).

+

Useful for middleware which can generate their own responses.

+
source

pub fn map_into_boxed_body(self) -> HttpResponse<BoxBody>
where + B: MessageBody + 'static,

Map the current body to a type-erased BoxBody.

+
source

pub fn into_body(self) -> B

Returns the response body, dropping all other parts.

+

Trait Implementations§

source§

impl<B> Debug for HttpResponse<B>
where + B: MessageBody,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl From<Error> for HttpResponse

source§

fn from(err: Error) -> Self

Converts to this type from the input type.
source§

impl<B> From<HttpResponse<B>> for Response<B>

source§

fn from(res: HttpResponse<B>) -> Self

Converts to this type from the input type.
source§

impl From<HttpResponseBuilder> for HttpResponse

source§

fn from(builder: HttpResponseBuilder) -> Self

Converts to this type from the input type.
source§

impl<B> From<Response<B>> for HttpResponse<B>

source§

fn from(res: Response<B>) -> Self

Converts to this type from the input type.
source§

impl<B> From<ServiceResponse<B>> for HttpResponse<B>

source§

fn from(res: ServiceResponse<B>) -> HttpResponse<B>

Converts to this type from the input type.
source§

impl<B> Responder for HttpResponse<B>
where + B: MessageBody + 'static,

§

type Body = B

source§

fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body>

Convert self to HttpResponse.
source§

fn customize(self) -> CustomizeResponder<Self>
where + Self: Sized,

Wraps responder to allow alteration of its response. Read more

Auto Trait Implementations§

§

impl<B = BoxBody> !Freeze for HttpResponse<B>

§

impl<B = BoxBody> !RefUnwindSafe for HttpResponse<B>

§

impl<B = BoxBody> !Send for HttpResponse<B>

§

impl<B = BoxBody> !Sync for HttpResponse<B>

§

impl<B> Unpin for HttpResponse<B>
where + B: Unpin,

§

impl<B = BoxBody> !UnwindSafe for HttpResponse<B>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/struct.HttpResponseBuilder.html b/actix_web/struct.HttpResponseBuilder.html new file mode 100644 index 000000000..382112988 --- /dev/null +++ b/actix_web/struct.HttpResponseBuilder.html @@ -0,0 +1,191 @@ +HttpResponseBuilder in actix_web - Rust

Struct actix_web::HttpResponseBuilder

source ·
pub struct HttpResponseBuilder { /* private fields */ }
Expand description

An HTTP response builder.

+

This type can be used to construct an instance of Response through a builder-like pattern.

+

Implementations§

source§

impl HttpResponseBuilder

source

pub fn new(status: StatusCode) -> Self

Create response builder

+
source

pub fn status(&mut self, status: StatusCode) -> &mut Self

Set HTTP status code of this response.

+
source

pub fn insert_header(&mut self, header: impl TryIntoHeaderPair) -> &mut Self

Insert a header, replacing any that were set with an equivalent field name.

+ +
use actix_web::{HttpResponse, http::header};
+
+HttpResponse::Ok()
+    .insert_header(header::ContentType(mime::APPLICATION_JSON))
+    .insert_header(("X-TEST", "value"))
+    .finish();
+
source

pub fn append_header(&mut self, header: impl TryIntoHeaderPair) -> &mut Self

Append a header, keeping any that were set with an equivalent field name.

+ +
use actix_web::{HttpResponse, http::header};
+
+HttpResponse::Ok()
+    .append_header(header::ContentType(mime::APPLICATION_JSON))
+    .append_header(("X-TEST", "value1"))
+    .append_header(("X-TEST", "value2"))
+    .finish();
+
source

pub fn reason(&mut self, reason: &'static str) -> &mut Self

Set the custom reason for the response.

+
source

pub fn keep_alive(&mut self) -> &mut Self

Set connection type to KeepAlive

+
source

pub fn upgrade<V>(&mut self, value: V) -> &mut Self
where + V: TryIntoHeaderValue,

Set connection type to Upgrade

+
source

pub fn force_close(&mut self) -> &mut Self

Force close connection, even if it is marked as keep-alive

+
source

pub fn no_chunking(&mut self, len: u64) -> &mut Self

Disable chunked transfer encoding for HTTP/1.1 streaming responses.

+
source

pub fn content_type<V>(&mut self, value: V) -> &mut Self
where + V: TryIntoHeaderValue,

Set response content type.

+
source

pub fn cookie(&mut self, cookie: Cookie<'_>) -> &mut Self

Available on crate feature cookies only.

Add a cookie to the response.

+

To send a “removal” cookie, call .make_removal() on the +given cookie. See HttpResponse::add_removal_cookie() to learn more.

+
§Examples
+

Send a new cookie:

+ +
use actix_web::{HttpResponse, cookie::Cookie};
+
+let res = HttpResponse::Ok()
+    .cookie(
+        Cookie::build("name", "value")
+            .domain("www.rust-lang.org")
+            .path("/")
+            .secure(true)
+            .http_only(true)
+            .finish(),
+    )
+    .finish();
+

Send a removal cookie:

+ +
use actix_web::{HttpResponse, cookie::Cookie};
+
+// the name, domain and path match the cookie created in the previous example
+let mut cookie = Cookie::build("name", "value-does-not-matter")
+    .domain("www.rust-lang.org")
+    .path("/")
+    .finish();
+cookie.make_removal();
+
+let res = HttpResponse::Ok()
+    .cookie(cookie)
+    .finish();
+
source

pub fn extensions(&self) -> Ref<'_, Extensions>

Returns a reference to the response-local data/extensions container.

+
source

pub fn extensions_mut(&mut self) -> RefMut<'_, Extensions>

Returns a mutable reference to the response-local data/extensions container.

+
source

pub fn body<B>(&mut self, body: B) -> HttpResponse<BoxBody>
where + B: MessageBody + 'static,

Set a body and build the HttpResponse.

+

Unlike message_body, errors are converted into error +responses immediately.

+

HttpResponseBuilder can not be used after this call.

+
source

pub fn message_body<B>(&mut self, body: B) -> Result<HttpResponse<B>, Error>

Set a body and build the HttpResponse.

+

HttpResponseBuilder can not be used after this call.

+
source

pub fn streaming<S, E>(&mut self, stream: S) -> HttpResponse
where + S: Stream<Item = Result<Bytes, E>> + 'static, + E: Into<Box<dyn Error>> + 'static,

Set a streaming body and build the HttpResponse.

+

HttpResponseBuilder can not be used after this call.

+
source

pub fn json(&mut self, value: impl Serialize) -> HttpResponse

Set a JSON body and build the HttpResponse.

+

HttpResponseBuilder can not be used after this call.

+
source

pub fn finish(&mut self) -> HttpResponse

Set an empty body and build the HttpResponse.

+

HttpResponseBuilder can not be used after this call.

+
source

pub fn take(&mut self) -> Self

This method construct new HttpResponseBuilder

+

Trait Implementations§

source§

impl From<HttpResponseBuilder> for HttpResponse

source§

fn from(builder: HttpResponseBuilder) -> Self

Converts to this type from the input type.
source§

impl From<HttpResponseBuilder> for Response<BoxBody>

source§

fn from(builder: HttpResponseBuilder) -> Self

Converts to this type from the input type.
source§

impl Future for HttpResponseBuilder

§

type Output = Result<HttpResponse, Error>

The type of value produced on completion.
source§

fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
source§

impl Responder for HttpResponseBuilder

§

type Body = BoxBody

source§

fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body>

Convert self to HttpResponse.
source§

fn customize(self) -> CustomizeResponder<Self>
where + Self: Sized,

Wraps responder to allow alteration of its response. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> FutureExt for T
where + T: Future + ?Sized,

§

fn map<U, F>(self, f: F) -> Map<Self, F>
where + F: FnOnce(Self::Output) -> U, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn map_into<U>(self) -> MapInto<Self, U>
where + Self::Output: Into<U>, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnOnce(Self::Output) -> Fut, + Fut: Future, + Self: Sized,

Chain on a computation for when a future finished, passing the result of +the future to the provided closure f. Read more
§

fn left_future<B>(self) -> Either<Self, B>
where + B: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the left-hand variant +of that Either. Read more
§

fn right_future<A>(self) -> Either<A, Self>
where + A: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the right-hand variant +of that Either. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Convert this future into a single element stream. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Output: Future, + Self: Sized,

Flatten the execution of this future when the output of this +future is itself another future. Read more
§

fn flatten_stream(self) -> FlattenStream<Self>
where + Self::Output: Stream, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a future such that poll will never again be called once it has +completed. This method can be used to turn any Future into a +FusedFuture. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnOnce(&Self::Output), + Self: Sized,

Do something with the output of a future before passing it on. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the future. Read more
§

fn shared(self) -> Shared<Self>
where + Self: Sized, + Self::Output: Clone,

Available on crate feature std only.
Create a cloneable handle to this future where all handles will resolve +to the same result. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn unit_error(self) -> UnitError<Self>
where + Self: Sized,

§

fn never_error(self) -> NeverError<Self>
where + Self: Sized,

§

fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where + Self: Unpin,

A convenience for calling Future::poll on Unpin future types.
§

fn now_or_never(self) -> Option<Self::Output>
where + Self: Sized,

Evaluates and consumes the future, returning the resulting output if +the future is ready after the first call to Future::poll. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<F> IntoFuture for F
where + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

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
§

fn try_poll( + self: Pin<&mut F>, + cx: &mut Context<'_> +) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
§

impl<Fut> TryFutureExt for Fut
where + Fut: TryFuture + ?Sized,

§

fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>
where + Self::Ok: Sink<Item, Error = Self::Error>, + Self: Sized,

Available on crate feature sink only.
Flattens the execution of this future when the successful result of this +future is a [Sink]. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + F: FnOnce(Self::Ok) -> T, + Self: Sized,

Maps this future’s success value to a different value. Read more
§

fn map_ok_or_else<T, E, F>(self, e: E, f: F) -> MapOkOrElse<Self, F, E>
where + F: FnOnce(Self::Ok) -> T, + E: FnOnce(Self::Error) -> T, + Self: Sized,

Maps this future’s success value to a different value, and permits for error handling resulting in the same type. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + F: FnOnce(Self::Error) -> E, + Self: Sized,

Maps this future’s error value to a different value. Read more
§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Maps this future’s Error to a new error type +using the Into trait. Read more
§

fn ok_into<U>(self) -> OkInto<Self, U>
where + Self: Sized, + Self::Ok: Into<U>,

Maps this future’s Ok to a new type +using the Into trait.
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnOnce(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Executes another future after this one resolves successfully. The +success value is passed to a closure to create this subsequent future. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnOnce(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Executes another future if this one resolves to an error. The +error value is passed to a closure to create this subsequent future. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnOnce(&Self::Ok), + Self: Sized,

Do something with the success value of a future before passing it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnOnce(&Self::Error), + Self: Sized,

Do something with the error value of a future before passing it on. Read more
§

fn try_flatten(self) -> TryFlatten<Self, Self::Ok>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is another future. Read more
§

fn try_flatten_stream(self) -> TryFlattenStream<Self>
where + Self::Ok: TryStream<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F>
where + Self: Sized, + F: FnOnce(Self::Error) -> Self::Ok,

Unwraps this future’s output, producing a future with this future’s +Ok type as its +Output type. Read more
§

fn into_future(self) -> IntoFuture<Self>
where + Self: Sized,

Wraps a [TryFuture] into a type that implements +Future. Read more
§

fn try_poll_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Result<Self::Ok, Self::Error>>
where + Self: Unpin,

A convenience method for calling [TryFuture::try_poll] on Unpin +future types.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/struct.HttpServer.html b/actix_web/struct.HttpServer.html new file mode 100644 index 000000000..9e405d604 --- /dev/null +++ b/actix_web/struct.HttpServer.html @@ -0,0 +1,289 @@ +HttpServer in actix_web - Rust

Struct actix_web::HttpServer

source ·
pub struct HttpServer<F, I, S, B>
where + F: Fn() -> I + Send + Clone + 'static, + I: IntoServiceFactory<S, Request>, + S: ServiceFactory<Request, Config = AppConfig>, + S::Error: Into<Error>, + S::InitError: Debug, + S::Response: Into<Response<B>>, + B: MessageBody,
{ /* private fields */ }
Expand description

An HTTP Server.

+

Create new HTTP server with application factory.

+

§Automatic HTTP Version Selection

+

There are two ways to select the HTTP version of an incoming connection:

+
    +
  • One is to rely on the ALPN information that is provided when using a TLS (HTTPS); both +versions are supported automatically when using either of the .bind_rustls() or +.bind_openssl() methods.
  • +
  • The other is to read the first few bytes of the TCP stream. This is the only viable approach +for supporting H2C, which allows the HTTP/2 protocol to work over plaintext connections. Use +the .bind_auto_h2c() method to enable this behavior.
  • +
+

§Examples

+
use actix_web::{web, App, HttpResponse, HttpServer};
+
+#[actix_web::main]
+async fn main() -> std::io::Result<()> {
+    HttpServer::new(|| {
+        App::new()
+            .service(web::resource("/").to(|| async { "hello world" }))
+    })
+    .bind(("127.0.0.1", 8080))?
+    .run()
+    .await
+}
+

Implementations§

source§

impl<F, I, S, B> HttpServer<F, I, S, B>
where + F: Fn() -> I + Send + Clone + 'static, + I: IntoServiceFactory<S, Request>, + S: ServiceFactory<Request, Config = AppConfig> + 'static, + S::Error: Into<Error> + 'static, + S::InitError: Debug, + S::Response: Into<Response<B>> + 'static, + <S::Service as Service<Request>>::Future: 'static, + S::Service: 'static, + B: MessageBody + 'static,

source

pub fn new(factory: F) -> Self

Create new HTTP server with application factory

+
§Worker Count
+

The factory will be instantiated multiple times in most configurations. See +bind() docs for more on how worker count and bind address resolution +causes multiple server factory instantiations.

+
source

pub fn workers(self, num: usize) -> Self

Sets number of workers to start (per bind address).

+

The default worker count is the determined by std::thread::available_parallelism(). See +its documentation to determine what behavior you should expect when server is run.

+

Note that the server factory passed to new will be instantiated at least +once per worker. See bind() docs for more on how worker count and bind +address resolution causes multiple server factory instantiations.

+

num must be greater than 0.

+
§Panics
+

Panics if num is 0.

+
source

pub fn keep_alive<T: Into<KeepAlive>>(self, val: T) -> Self

Sets server keep-alive preference.

+

By default keep-alive is set to 5 seconds.

+
source

pub fn backlog(self, backlog: u32) -> Self

Sets the maximum number of pending connections.

+

This refers to the number of clients that can be waiting to be served. Exceeding this number +results in the client getting an error when attempting to connect. It should only affect +servers under significant load.

+

Generally set in the 64–2048 range. Default value is 2048.

+

This method will have no effect if called after a bind().

+
source

pub fn max_connections(self, num: usize) -> Self

Sets the per-worker maximum number of concurrent connections.

+

All socket listeners will stop accepting connections when this limit is reached for +each worker.

+

By default max connections is set to a 25k.

+
source

pub fn max_connection_rate(self, num: usize) -> Self

Sets the per-worker maximum concurrent TLS connection limit.

+

All listeners will stop accepting connections when this limit is reached. It can be used to +limit the global TLS CPU usage.

+

By default max connections is set to a 256.

+
source

pub fn worker_max_blocking_threads(self, num: usize) -> Self

Sets max number of threads for each worker’s blocking task thread pool.

+

One thread pool is set up per worker; not shared across workers.

+

By default set to 512 divided by the number of workers.

+
source

pub fn client_request_timeout(self, dur: Duration) -> Self

Sets server client timeout for first request.

+

Defines a timeout for reading client request head. If a client does not transmit the entire +set headers within this time, the request is terminated with a 408 (Request Timeout) error.

+

To disable timeout set value to 0.

+

By default client timeout is set to 5000 milliseconds.

+
source

pub fn client_disconnect_timeout(self, dur: Duration) -> Self

Sets server connection shutdown timeout.

+

Defines a timeout for connection shutdown. If a shutdown procedure does not complete within +this time, the request is dropped.

+

To disable timeout set value to 0.

+

By default client timeout is set to 5000 milliseconds.

+
source

pub fn tls_handshake_timeout(self, dur: Duration) -> Self

Available on crate features openssl or rustls-0_20 or rustls-0_21 or rustls-0_22 or rustls-0_23 only.

Sets TLS handshake timeout.

+

Defines a timeout for TLS handshake. If the TLS handshake does not complete within this +time, the connection is closed.

+

By default, the handshake timeout is 3 seconds.

+
source

pub fn on_connect<CB>(self, f: CB) -> HttpServer<F, I, S, B>
where + CB: Fn(&dyn Any, &mut Extensions) + Send + Sync + 'static,

Sets function that will be called once before each connection is handled.

+

It will receive a &std::any::Any, which contains underlying connection type and an +Extensions container so that connection data can be accessed in middleware and handlers.

+
§Connection Types
+
    +
  • actix_tls::accept::openssl::TlsStream<actix_web::rt::net::TcpStream> when using OpenSSL.
  • +
  • actix_tls::accept::rustls_0_20::TlsStream<actix_web::rt::net::TcpStream> when using +Rustls v0.20.
  • +
  • actix_tls::accept::rustls_0_21::TlsStream<actix_web::rt::net::TcpStream> when using +Rustls v0.21.
  • +
  • actix_tls::accept::rustls_0_22::TlsStream<actix_web::rt::net::TcpStream> when using +Rustls v0.22.
  • +
  • actix_tls::accept::rustls_0_23::TlsStream<actix_web::rt::net::TcpStream> when using +Rustls v0.23.
  • +
  • actix_web::rt::net::TcpStream when no encryption is used.
  • +
+

See the on_connect example for additional details.

+
source

pub fn server_hostname<T: AsRef<str>>(self, val: T) -> Self

Sets server host name.

+

Host name is used by application router as a hostname for url generation. Check +ConnectionInfo docs for more info.

+

By default, hostname is set to “localhost”.

+
source

pub fn system_exit(self) -> Self

Flags the System to exit after server shutdown.

+

Does nothing when running under #[tokio::main] runtime.

+
source

pub fn disable_signals(self) -> Self

Disables signal handling.

+
source

pub fn shutdown_timeout(self, sec: u64) -> Self

Sets timeout for graceful worker shutdown of workers.

+

After receiving a stop signal, workers have this much time to finish serving requests. +Workers still alive after the timeout are force dropped.

+

By default shutdown timeout sets to 30 seconds.

+
source

pub fn addrs(&self) -> Vec<SocketAddr>

Returns addresses of bound sockets.

+
source

pub fn addrs_with_scheme(&self) -> Vec<(SocketAddr, &str)>

Returns addresses of bound sockets and the scheme for it.

+

This is useful when the server is bound from different sources with some sockets listening +on HTTP and some listening on HTTPS and the user should be presented with an enumeration of +which socket requires which protocol.

+
source

pub fn bind<A: ToSocketAddrs>(self, addrs: A) -> Result<Self>

Resolves socket address(es) and binds server to created listener(s).

+
§Hostname Resolution
+

When addrs includes a hostname, it is possible for this method to bind to both the IPv4 +and IPv6 addresses that result from a DNS lookup. You can test this by passing +localhost:8080 and noting that the server binds to 127.0.0.1:8080 and [::1]:8080. To +bind additional addresses, call this method multiple times.

+

Note that, if a DNS lookup is required, resolving hostnames is a blocking operation.

+
§Worker Count
+

The factory will be instantiated multiple times in most scenarios. The number of +instantiations is number of workers × number of sockets resolved by +addrs.

+

For example, if you’ve manually set workers to 2, and use 127.0.0.1 +as the bind addrs, then factory will be instantiated twice. However, using localhost +as the bind addrs can often resolve to both 127.0.0.1 (IPv4) and ::1 (IPv6), causing +the factory to be instantiated 4 times (2 workers × 2 bind addresses).

+

Using a bind address of 0.0.0.0, which signals to use all interfaces, may also multiple +the number of instantiations in a similar way.

+
§Typical Usage
+

In general, use 127.0.0.1:<port> when testing locally and 0.0.0.0:<port> when deploying +(with or without a reverse proxy or load balancer) so that the server is accessible.

+
§Errors
+

Returns an io::Error if:

+
    +
  • addrs cannot be resolved into one or more socket addresses;
  • +
  • all the resolved socket addresses are already bound.
  • +
+
§Example
+
HttpServer::new(|| App::new())
+    .bind(("127.0.0.1", 8080))?
+    .bind("[::1]:9000")?
+
source

pub fn bind_auto_h2c<A: ToSocketAddrs>(self, addrs: A) -> Result<Self>

Available on crate feature http2 only.

Resolves socket address(es) and binds server to created listener(s) for plaintext HTTP/1.x +or HTTP/2 connections.

+

See bind() for more details on addrs argument.

+
source

pub fn bind_rustls<A: ToSocketAddrs>( + self, + addrs: A, + config: ServerConfig +) -> Result<Self>

Available on crate feature rustls-0_20 only.

Resolves socket address(es) and binds server to created listener(s) for TLS connections +using Rustls v0.20.

+

See bind() for more details on addrs argument.

+

ALPN protocols “h2” and “http/1.1” are added to any configured ones.

+
source

pub fn bind_rustls_021<A: ToSocketAddrs>( + self, + addrs: A, + config: ServerConfig +) -> Result<Self>

Available on crate feature rustls-0_21 only.

Resolves socket address(es) and binds server to created listener(s) for TLS connections +using Rustls v0.21.

+

See bind() for more details on addrs argument.

+

ALPN protocols “h2” and “http/1.1” are added to any configured ones.

+
source

pub fn bind_rustls_0_22<A: ToSocketAddrs>( + self, + addrs: A, + config: ServerConfig +) -> Result<Self>

Available on crate feature rustls-0_22 only.

Resolves socket address(es) and binds server to created listener(s) for TLS connections +using Rustls v0.22.

+

See bind() for more details on addrs argument.

+

ALPN protocols “h2” and “http/1.1” are added to any configured ones.

+
source

pub fn bind_rustls_0_23<A: ToSocketAddrs>( + self, + addrs: A, + config: ServerConfig +) -> Result<Self>

Available on crate feature rustls-0_23 only.

Resolves socket address(es) and binds server to created listener(s) for TLS connections +using Rustls v0.23.

+

See bind() for more details on addrs argument.

+

ALPN protocols “h2” and “http/1.1” are added to any configured ones.

+
source

pub fn bind_openssl<A>( + self, + addrs: A, + builder: SslAcceptorBuilder +) -> Result<Self>
where + A: ToSocketAddrs,

Available on crate feature openssl only.

Resolves socket address(es) and binds server to created listener(s) for TLS connections +using OpenSSL.

+

See bind() for more details on addrs argument.

+

ALPN protocols “h2” and “http/1.1” are added to any configured ones.

+
source

pub fn listen(self, lst: TcpListener) -> Result<Self>

Binds to existing listener for accepting incoming connection requests.

+

No changes are made to lst’s configuration. Ensure it is configured properly before +passing ownership to listen().

+
source

pub fn listen_auto_h2c(self, lst: TcpListener) -> Result<Self>

Available on crate feature http2 only.

Binds to existing listener for accepting incoming plaintext HTTP/1.x or HTTP/2 connections.

+
source

pub fn listen_rustls( + self, + lst: TcpListener, + config: ServerConfig +) -> Result<Self>

Available on crate feature rustls-0_20 only.

Binds to existing listener for accepting incoming TLS connection requests using Rustls +v0.20.

+

See listen() for more details on the lst argument.

+

ALPN protocols “h2” and “http/1.1” are added to any configured ones.

+
source

pub fn listen_rustls_0_21( + self, + lst: TcpListener, + config: ServerConfig +) -> Result<Self>

Available on crate feature rustls-0_21 only.

Binds to existing listener for accepting incoming TLS connection requests using Rustls +v0.21.

+

See listen() for more details on the lst argument.

+

ALPN protocols “h2” and “http/1.1” are added to any configured ones.

+
source

pub fn listen_rustls_0_22( + self, + lst: TcpListener, + config: ServerConfig +) -> Result<Self>

Available on crate feature rustls-0_22 only.

Binds to existing listener for accepting incoming TLS connection requests using Rustls +v0.22.

+

See listen() for more details on the lst argument.

+

ALPN protocols “h2” and “http/1.1” are added to any configured ones.

+
source

pub fn listen_rustls_0_23( + self, + lst: TcpListener, + config: ServerConfig +) -> Result<Self>

Available on crate feature rustls-0_23 only.

Binds to existing listener for accepting incoming TLS connection requests using Rustls +v0.23.

+

See listen() for more details on the lst argument.

+

ALPN protocols “h2” and “http/1.1” are added to any configured ones.

+
source

pub fn listen_openssl( + self, + lst: TcpListener, + builder: SslAcceptorBuilder +) -> Result<Self>

Available on crate feature openssl only.

Binds to existing listener for accepting incoming TLS connection requests using OpenSSL.

+

See listen() for more details on the lst argument.

+

ALPN protocols “h2” and “http/1.1” are added to any configured ones.

+
source

pub fn bind_uds<A>(self, uds_path: A) -> Result<Self>
where + A: AsRef<Path>,

Available on Unix only.

Opens Unix Domain Socket (UDS) from uds path and binds server to created listener.

+
source

pub fn listen_uds(self, lst: UnixListener) -> Result<Self>

Available on Unix only.

Binds to existing Unix Domain Socket (UDS) listener.

+
source§

impl<F, I, S, B> HttpServer<F, I, S, B>
where + F: Fn() -> I + Send + Clone + 'static, + I: IntoServiceFactory<S, Request>, + S: ServiceFactory<Request, Config = AppConfig>, + S::Error: Into<Error>, + S::InitError: Debug, + S::Response: Into<Response<B>>, + S::Service: 'static, + B: MessageBody,

source

pub fn run(self) -> Server

Start listening for incoming connections.

+
§Workers
+

This method starts a number of HTTP workers in separate threads. The number of workers in a +set is defined by workers() or, by default, the number of the machine’s +physical cores. One worker set is created for each socket address to be bound. For example, +if workers is set to 4, and there are 2 addresses to bind, then 8 worker threads will be +spawned.

+
§Panics
+

This methods panics if no socket addresses were successfully bound or if no Tokio runtime +is set up.

+

Auto Trait Implementations§

§

impl<F, I, S, B> Freeze for HttpServer<F, I, S, B>

§

impl<F, I, S, B> !RefUnwindSafe for HttpServer<F, I, S, B>

§

impl<F, I, S, B> Send for HttpServer<F, I, S, B>
where + <S as ServiceFactory<Request>>::Response: Sized, + <S as ServiceFactory<Request>>::Error: Sized, + S: Send, + B: Send,

§

impl<F, I, S, B> !Sync for HttpServer<F, I, S, B>

§

impl<F, I, S, B> Unpin for HttpServer<F, I, S, B>
where + <S as ServiceFactory<Request>>::Response: Sized, + <S as ServiceFactory<Request>>::Error: Sized, + F: Unpin, + S: Unpin, + B: Unpin,

§

impl<F, I, S, B> !UnwindSafe for HttpServer<F, I, S, B>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/struct.Resource.html b/actix_web/struct.Resource.html new file mode 100644 index 000000000..e9367fb31 --- /dev/null +++ b/actix_web/struct.Resource.html @@ -0,0 +1,225 @@ +Resource in actix_web - Rust

Struct actix_web::Resource

source ·
pub struct Resource<T = ResourceEndpoint> { /* private fields */ }
Expand description

A collection of Routes that respond to the same path pattern.

+

Resource in turn has at least one route. Route consists of an handlers objects and list of +guards (objects that implement Guard trait). Resources and routes uses builder-like pattern +for configuration. During request handling, resource object iterate through all routes and check +guards for specific route, if request matches all guards, route considered matched and route +handler get called.

+

§Examples

+
use actix_web::{web, App, HttpResponse};
+
+let app = App::new().service(
+    web::resource("/")
+        .get(|| HttpResponse::Ok())
+        .post(|| async { "Hello World!" })
+);
+

If no matching route is found, an empty 405 response is returned which includes an +appropriate Allow header. This default behavior can be overridden using +default_service().

+

Implementations§

source§

impl Resource

source

pub fn new<T: IntoPatterns>(path: T) -> Resource

Constructs new resource that matches a path pattern.

+
source§

impl<T> Resource<T>
where + T: ServiceFactory<ServiceRequest, Config = (), Error = Error, InitError = ()>,

source

pub fn name(self, name: &str) -> Self

Set resource name.

+

Name is used for url generation.

+
source

pub fn guard<G: Guard + 'static>(self, guard: G) -> Self

Add match guard to a resource.

+ +
use actix_web::{web, guard, App, HttpResponse};
+
+async fn index(data: web::Path<(String, String)>) -> &'static str {
+    "Welcome!"
+}
+
+let app = App::new()
+    .service(
+        web::resource("/app")
+            .guard(guard::Header("content-type", "text/plain"))
+            .route(web::get().to(index))
+    )
+    .service(
+        web::resource("/app")
+            .guard(guard::Header("content-type", "text/json"))
+            .route(web::get().to(|| HttpResponse::MethodNotAllowed()))
+    );
+
source

pub fn route(self, route: Route) -> Self

Register a new route.

+ +
use actix_web::{web, guard, App, HttpResponse};
+
+let app = App::new().service(
+    web::resource("/").route(
+        web::route()
+            .guard(guard::Any(guard::Get()).or(guard::Put()))
+            .guard(guard::Header("Content-Type", "text/plain"))
+            .to(|| HttpResponse::Ok()))
+);
+

Multiple routes could be added to a resource. Resource object uses +match guards for route selection.

+ +
use actix_web::{web, guard, App};
+
+let app = App::new().service(
+    web::resource("/container/")
+         .route(web::get().to(get_handler))
+         .route(web::post().to(post_handler))
+         .route(web::delete().to(delete_handler))
+);
+
+
source

pub fn app_data<U: 'static>(self, data: U) -> Self

Add resource data.

+

Data of different types from parent contexts will still be accessible. Any Data<T> types +set here can be extracted in handlers using the Data<T> extractor.

+
§Examples
+
use std::cell::Cell;
+use actix_web::{web, App, HttpRequest, HttpResponse, Responder};
+
+struct MyData {
+    count: std::cell::Cell<usize>,
+}
+
+async fn handler(req: HttpRequest, counter: web::Data<MyData>) -> impl Responder {
+    // note this cannot use the Data<T> extractor because it was not added with it
+    let incr = *req.app_data::<usize>().unwrap();
+    assert_eq!(incr, 3);
+
+    // update counter using other value from app data
+    counter.count.set(counter.count.get() + incr);
+
+    HttpResponse::Ok().body(counter.count.get().to_string())
+}
+
+let app = App::new().service(
+    web::resource("/")
+        .app_data(3usize)
+        .app_data(web::Data::new(MyData { count: Default::default() }))
+        .route(web::get().to(handler))
+);
+
source

pub fn data<U: 'static>(self, data: U) -> Self

👎Deprecated since 4.0.0: Use .app_data(Data::new(val)) instead.

Add resource data after wrapping in Data<T>.

+

Deprecated in favor of app_data.

+
source

pub fn to<F, Args>(self, handler: F) -> Self
where + F: Handler<Args>, + Args: FromRequest + 'static, + F::Output: Responder + 'static,

Register a new route and add handler. This route matches all requests.

+ +
use actix_web::{App, HttpRequest, HttpResponse, web};
+
+async fn index(req: HttpRequest) -> HttpResponse {
+    todo!()
+}
+
+App::new().service(web::resource("/").to(index));
+

This is shortcut for:

+ +
App::new().service(web::resource("/").route(web::route().to(index)));
+
source

pub fn wrap<M, B>( + self, + mw: M +) -> Resource<impl ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B>, Error = Error, InitError = ()>>
where + M: Transform<T::Service, ServiceRequest, Response = ServiceResponse<B>, Error = Error, InitError = ()> + 'static, + B: MessageBody,

Registers a resource middleware.

+

mw is a middleware component (type), that can modify the request and response across all +routes managed by this Resource.

+

See App::wrap for more details.

+
source

pub fn wrap_fn<F, R, B>( + self, + mw: F +) -> Resource<impl ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B>, Error = Error, InitError = ()>>
where + F: Fn(ServiceRequest, &T::Service) -> R + Clone + 'static, + R: Future<Output = Result<ServiceResponse<B>, Error>>, + B: MessageBody,

Registers a resource function middleware.

+

mw is a closure that runs during inbound and/or outbound processing in the request +life-cycle (request -> response), modifying request/response as necessary, across all +requests handled by the Resource.

+

See App::wrap_fn for examples and more details.

+
source

pub fn default_service<F, U>(self, f: F) -> Self
where + F: IntoServiceFactory<U, ServiceRequest>, + U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error> + 'static, + U::InitError: Debug,

Sets the default service to be used if no matching route is found.

+

Unlike Scopes, a Resource does not inherit its parent’s default service. You can +use a Route as default service.

+

If a custom default service is not registered, an empty 405 Method Not Allowed response +with an appropriate Allow header will be sent instead.

+
§Examples
+
use actix_web::{App, HttpResponse, web};
+
+let resource = web::resource("/test")
+    .route(web::get().to(HttpResponse::Ok))
+    .default_service(web::to(|| {
+        HttpResponse::BadRequest()
+    }));
+
+App::new().service(resource);
+
source§

impl<T> Resource<T>
where + T: ServiceFactory<ServiceRequest, Config = (), Error = Error, InitError = ()>,

Concise routes for well-known HTTP methods.

+
source

pub fn get<F, Args>(self, handler: F) -> Self
where + F: Handler<Args>, + Args: FromRequest + 'static, + F::Output: Responder + 'static,

Adds a GET route.

+

Use route if you need to add additional guards.

+
§Examples
+
web::resource("/")
+    .get(|| async { "Hello World!" })
+
source

pub fn post<F, Args>(self, handler: F) -> Self
where + F: Handler<Args>, + Args: FromRequest + 'static, + F::Output: Responder + 'static,

Adds a POST route.

+

Use route if you need to add additional guards.

+
§Examples
+
web::resource("/")
+    .post(|| async { "Hello World!" })
+
source

pub fn put<F, Args>(self, handler: F) -> Self
where + F: Handler<Args>, + Args: FromRequest + 'static, + F::Output: Responder + 'static,

Adds a PUT route.

+

Use route if you need to add additional guards.

+
§Examples
+
web::resource("/")
+    .put(|| async { "Hello World!" })
+
source

pub fn patch<F, Args>(self, handler: F) -> Self
where + F: Handler<Args>, + Args: FromRequest + 'static, + F::Output: Responder + 'static,

Adds a PATCH route.

+

Use route if you need to add additional guards.

+
§Examples
+
web::resource("/")
+    .patch(|| async { "Hello World!" })
+
source

pub fn delete<F, Args>(self, handler: F) -> Self
where + F: Handler<Args>, + Args: FromRequest + 'static, + F::Output: Responder + 'static,

Adds a DELETE route.

+

Use route if you need to add additional guards.

+
§Examples
+
web::resource("/")
+    .delete(|| async { "Hello World!" })
+
source

pub fn head<F, Args>(self, handler: F) -> Self
where + F: Handler<Args>, + Args: FromRequest + 'static, + F::Output: Responder + 'static,

Adds a HEAD route.

+

Use route if you need to add additional guards.

+
§Examples
+
web::resource("/")
+    .head(|| async { "Hello World!" })
+
source

pub fn trace<F, Args>(self, handler: F) -> Self
where + F: Handler<Args>, + Args: FromRequest + 'static, + F::Output: Responder + 'static,

Adds a TRACE route.

+

Use route if you need to add additional guards.

+
§Examples
+
web::resource("/")
+    .trace(|| async { "Hello World!" })
+

Trait Implementations§

source§

impl<T, B> HttpServiceFactory for Resource<T>
where + T: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B>, Error = Error, InitError = ()> + 'static, + B: MessageBody + 'static,

source§

fn register(self, config: &mut AppService)

Auto Trait Implementations§

§

impl<T> Freeze for Resource<T>
where + T: Freeze,

§

impl<T = ResourceEndpoint> !RefUnwindSafe for Resource<T>

§

impl<T = ResourceEndpoint> !Send for Resource<T>

§

impl<T = ResourceEndpoint> !Sync for Resource<T>

§

impl<T> Unpin for Resource<T>
where + T: Unpin,

§

impl<T = ResourceEndpoint> !UnwindSafe for Resource<T>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/struct.Route.html b/actix_web/struct.Route.html new file mode 100644 index 000000000..03c5341e5 --- /dev/null +++ b/actix_web/struct.Route.html @@ -0,0 +1,128 @@ +Route in actix_web - Rust

Struct actix_web::Route

source ·
pub struct Route { /* private fields */ }
Expand description

A request handler with guards.

+

Route uses a builder-like pattern for configuration. If handler is not set, a 404 Not Found +handler is used.

+

Implementations§

source§

impl Route

source

pub fn new() -> Route

Create new route which matches any request.

+
source

pub fn wrap<M, B>(self, mw: M) -> Route
where + M: Transform<BoxService<ServiceRequest, ServiceResponse, Error>, ServiceRequest, Response = ServiceResponse<B>, Error = Error, InitError = ()> + 'static, + B: MessageBody + 'static,

Registers a route middleware.

+

mw is a middleware component (type), that can modify the requests and responses handled by +this Route.

+

See App::wrap for more details.

+
source§

impl Route

source

pub fn method(self, method: Method) -> Self

Add method guard to the route.

+
§Examples
+
App::new().service(web::resource("/path").route(
+    web::get()
+        .method(http::Method::CONNECT)
+        .guard(guard::Header("content-type", "text/plain"))
+        .to(|req: HttpRequest| HttpResponse::Ok()))
+);
+
source

pub fn guard<F: Guard + 'static>(self, f: F) -> Self

Add guard to the route.

+
§Examples
+
App::new().service(web::resource("/path").route(
+    web::route()
+        .guard(guard::Get())
+        .guard(guard::Header("content-type", "text/plain"))
+        .to(|req: HttpRequest| HttpResponse::Ok()))
+);
+
source

pub fn to<F, Args>(self, handler: F) -> Self
where + F: Handler<Args>, + Args: FromRequest + 'static, + F::Output: Responder + 'static,

Set handler function, use request extractors for parameters.

+
§Examples
+
use actix_web::{web, http, App};
+use serde::Deserialize;
+
+#[derive(Deserialize)]
+struct Info {
+    username: String,
+}
+
+/// extract path info using serde
+async fn index(info: web::Path<Info>) -> String {
+    format!("Welcome {}!", info.username)
+}
+
+let app = App::new().service(
+    web::resource("/{username}/index.html") // <- define path parameters
+        .route(web::get().to(index))        // <- register handler
+);
+

It is possible to use multiple extractors for one handler function.

+ +
use actix_web::{web, App};
+
+#[derive(Deserialize)]
+struct Info {
+    username: String,
+}
+
+/// extract path info using serde
+async fn index(
+    path: web::Path<Info>,
+    query: web::Query<HashMap<String, String>>,
+    body: web::Json<Info>
+) -> String {
+    format!("Welcome {}!", path.username)
+}
+
+let app = App::new().service(
+    web::resource("/{username}/index.html") // <- define path parameters
+        .route(web::get().to(index))
+);
+
source

pub fn service<S, E>(self, service_factory: S) -> Self
where + S: ServiceFactory<ServiceRequest, Response = ServiceResponse, Error = E, InitError = (), Config = ()> + 'static, + E: Into<Error> + 'static,

Set raw service to be constructed and called as the request handler.

+
§Examples
+
struct HelloWorld;
+
+impl Service<ServiceRequest> for HelloWorld {
+    type Response = ServiceResponse;
+    type Error = Infallible;
+    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
+
+    dev::always_ready!();
+
+    fn call(&self, req: ServiceRequest) -> Self::Future {
+        let (req, _) = req.into_parts();
+
+        let res = HttpResponse::Ok()
+            .insert_header(header::ContentType::plaintext())
+            .body("Hello world!");
+
+        Box::pin(async move { Ok(ServiceResponse::new(req, res)) })
+    }
+}
+
+App::new().route(
+    "/",
+    web::get().service(fn_factory(|| async { Ok(HelloWorld) })),
+);
+

Trait Implementations§

source§

impl ServiceFactory<ServiceRequest> for Route

§

type Response = ServiceResponse

Responses given by the created services.
§

type Error = Error

Errors produced by the created services.
§

type Config = ()

Service factory configuration.
§

type Service = RouteService

The kind of Service created by this factory.
§

type InitError = ()

Errors potentially raised while building a service.
§

type Future = Pin<Box<dyn Future<Output = Result<<Route as ServiceFactory<ServiceRequest>>::Service, <Route as ServiceFactory<ServiceRequest>>::InitError>>>>

The future of the Service instance.g
source§

fn new_service(&self, _: ()) -> Self::Future

Create and return a new service asynchronously.

Auto Trait Implementations§

§

impl Freeze for Route

§

impl !RefUnwindSafe for Route

§

impl !Send for Route

§

impl !Sync for Route

§

impl Unpin for Route

§

impl !UnwindSafe for Route

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
§

impl<SF, Req> IntoServiceFactory<SF, Req> for SF
where + SF: ServiceFactory<Req>,

§

fn into_factory(self) -> SF

Convert Self to a ServiceFactory
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<SF, Req> ServiceFactoryExt<Req> for SF
where + SF: ServiceFactory<Req>,

§

fn map<F, R>(self, f: F) -> MapServiceFactory<Self, F, Req, R>
where + Self: Sized, + F: FnMut(Self::Response) -> R + Clone,

Map this service’s output to a different type, returning a new service +of the resulting type.
§

fn map_err<F, E>(self, f: F) -> MapErrServiceFactory<Self, Req, F, E>
where + Self: Sized, + F: Fn(Self::Error) -> E + Clone,

Map this service’s error to a different error, returning a new service.
§

fn map_init_err<F, E>(self, f: F) -> MapInitErr<Self, F, Req, E>
where + Self: Sized, + F: Fn(Self::InitError) -> E + Clone,

Map this factory’s init error to a different error, returning a new service.
§

fn and_then<I, SF1>(self, factory: I) -> AndThenServiceFactory<Self, SF1, Req>
where + Self: Sized, + Self::Config: Clone, + I: IntoServiceFactory<SF1, Self::Response>, + SF1: ServiceFactory<Self::Response, Config = Self::Config, Error = Self::Error, InitError = Self::InitError>,

Call another service after call to this one has resolved successfully.
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/struct.Scope.html b/actix_web/struct.Scope.html new file mode 100644 index 000000000..77303e50b --- /dev/null +++ b/actix_web/struct.Scope.html @@ -0,0 +1,179 @@ +Scope in actix_web - Rust

Struct actix_web::Scope

source ·
pub struct Scope<T = ScopeEndpoint> { /* private fields */ }
Expand description

A collection of Routes, Resources, or other services that share a common path prefix.

+

The Scope’s path can contain dynamic segments. The dynamic segments can be extracted from +requests using the Path extractor or +with HttpRequest::match_info().

+

§Avoid Trailing Slashes

+

Avoid using trailing slashes in the scope prefix (e.g., web::scope("/scope/")). It will almost +certainly not have the expected behavior. See the documentation on resource definitions +to understand why this is the case and how to correctly construct scope/prefix definitions.

+

§Examples

+
use actix_web::{web, App, HttpResponse};
+
+let app = App::new().service(
+    web::scope("/{project_id}")
+        .service(web::resource("/path1").to(|| async { "OK" }))
+        .service(web::resource("/path2").route(web::get().to(|| HttpResponse::Ok())))
+        .service(web::resource("/path3").route(web::head().to(HttpResponse::MethodNotAllowed)))
+);
+

In the above example three routes get registered:

+
    +
  • /{project_id}/path1 - responds to all HTTP methods
  • +
  • /{project_id}/path2 - responds to GET requests
  • +
  • /{project_id}/path3 - responds to HEAD requests
  • +
+

Implementations§

source§

impl Scope

source

pub fn new(path: &str) -> Scope

Create a new scope

+
source§

impl<T> Scope<T>
where + T: ServiceFactory<ServiceRequest, Config = (), Error = Error, InitError = ()>,

source

pub fn guard<G: Guard + 'static>(self, guard: G) -> Self

Add match guard to a scope.

+ +
use actix_web::{web, guard, App, HttpRequest, HttpResponse};
+
+async fn index(data: web::Path<(String, String)>) -> &'static str {
+    "Welcome!"
+}
+
+let app = App::new().service(
+    web::scope("/app")
+        .guard(guard::Header("content-type", "text/plain"))
+        .route("/test1", web::get().to(index))
+        .route("/test2", web::post().to(|r: HttpRequest| {
+            HttpResponse::MethodNotAllowed()
+        }))
+);
+
source

pub fn app_data<U: 'static>(self, data: U) -> Self

Add scope data.

+

Data of different types from parent contexts will still be accessible. Any Data<T> types +set here can be extracted in handlers using the Data<T> extractor.

+
§Examples
+
use std::cell::Cell;
+use actix_web::{web, App, HttpRequest, HttpResponse, Responder};
+
+struct MyData {
+    count: std::cell::Cell<usize>,
+}
+
+async fn handler(req: HttpRequest, counter: web::Data<MyData>) -> impl Responder {
+    // note this cannot use the Data<T> extractor because it was not added with it
+    let incr = *req.app_data::<usize>().unwrap();
+    assert_eq!(incr, 3);
+
+    // update counter using other value from app data
+    counter.count.set(counter.count.get() + incr);
+
+    HttpResponse::Ok().body(counter.count.get().to_string())
+}
+
+let app = App::new().service(
+    web::scope("/app")
+        .app_data(3usize)
+        .app_data(web::Data::new(MyData { count: Default::default() }))
+        .route("/", web::get().to(handler))
+);
+
source

pub fn data<U: 'static>(self, data: U) -> Self

👎Deprecated since 4.0.0: Use .app_data(Data::new(val)) instead.

Add scope data after wrapping in Data<T>.

+

Deprecated in favor of app_data.

+
source

pub fn configure<F>(self, cfg_fn: F) -> Self
where + F: FnOnce(&mut ServiceConfig),

Run external configuration as part of the scope building process.

+

This function is useful for moving parts of configuration to a different module or library. +For example, some of the resource’s configuration could be moved to different module.

+ +
use actix_web::{web, middleware, App, HttpResponse};
+
+// this function could be located in different module
+fn config(cfg: &mut web::ServiceConfig) {
+    cfg.service(web::resource("/test")
+        .route(web::get().to(|| HttpResponse::Ok()))
+        .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
+    );
+}
+
+let app = App::new()
+    .wrap(middleware::Logger::default())
+    .service(
+        web::scope("/api")
+            .configure(config)
+    )
+    .route("/index.html", web::get().to(|| HttpResponse::Ok()));
+
source

pub fn service<F>(self, factory: F) -> Self
where + F: HttpServiceFactory + 'static,

Register HTTP service.

+

This is similar to App's service registration.

+

Actix Web provides several services implementations:

+
    +
  • Resource is an entry in resource table which corresponds to requested URL.
  • +
  • Scope is a set of resources with common root path.
  • +
  • “StaticFiles” is a service for static files support
  • +
+ +
use actix_web::{web, App, HttpRequest};
+
+struct AppState;
+
+async fn index(req: HttpRequest) -> &'static str {
+    "Welcome!"
+}
+
+let app = App::new().service(
+    web::scope("/app").service(
+        web::scope("/v1")
+            .service(web::resource("/test1").to(index)))
+);
+
source

pub fn route(self, path: &str, route: Route) -> Self

Configure route for a specific path.

+

This is a simplified version of the Scope::service() method. +This method can be called multiple times, in that case +multiple resources with one route would be registered for same resource path.

+ +
use actix_web::{web, App, HttpResponse};
+
+async fn index(data: web::Path<(String, String)>) -> &'static str {
+    "Welcome!"
+}
+
+let app = App::new().service(
+    web::scope("/app")
+        .route("/test1", web::get().to(index))
+        .route("/test2", web::post().to(|| HttpResponse::MethodNotAllowed()))
+);
+
source

pub fn default_service<F, U>(self, f: F) -> Self
where + F: IntoServiceFactory<U, ServiceRequest>, + U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error> + 'static, + U::InitError: Debug,

Default service to be used if no matching resource could be found.

+

If a default service is not registered, it will fall back to the default service of +the parent App (see App::default_service).

+
source

pub fn wrap<M, B>( + self, + mw: M +) -> Scope<impl ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B>, Error = Error, InitError = ()>>
where + M: Transform<T::Service, ServiceRequest, Response = ServiceResponse<B>, Error = Error, InitError = ()> + 'static, + B: MessageBody,

Registers a scope-wide middleware.

+

mw is a middleware component (type), that can modify the request and response across all +sub-resources managed by this Scope.

+

See App::wrap for more details.

+
source

pub fn wrap_fn<F, R, B>( + self, + mw: F +) -> Scope<impl ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B>, Error = Error, InitError = ()>>
where + F: Fn(ServiceRequest, &T::Service) -> R + Clone + 'static, + R: Future<Output = Result<ServiceResponse<B>, Error>>, + B: MessageBody,

Registers a scope-wide function middleware.

+

mw is a closure that runs during inbound and/or outbound processing in the request +life-cycle (request -> response), modifying request/response as necessary, across all +requests handled by the Scope.

+

See App::wrap_fn for examples and more details.

+

Trait Implementations§

source§

impl<T, B> HttpServiceFactory for Scope<T>
where + T: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse<B>, Error = Error, InitError = ()> + 'static, + B: MessageBody + 'static,

source§

fn register(self, config: &mut AppService)

Auto Trait Implementations§

§

impl<T> Freeze for Scope<T>
where + T: Freeze,

§

impl<T = ScopeEndpoint> !RefUnwindSafe for Scope<T>

§

impl<T = ScopeEndpoint> !Send for Scope<T>

§

impl<T = ScopeEndpoint> !Sync for Scope<T>

§

impl<T> Unpin for Scope<T>
where + T: Unpin,

§

impl<T = ScopeEndpoint> !UnwindSafe for Scope<T>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/test/fn.call_and_read_body.html b/actix_web/test/fn.call_and_read_body.html new file mode 100644 index 000000000..311256bfb --- /dev/null +++ b/actix_web/test/fn.call_and_read_body.html @@ -0,0 +1,32 @@ +call_and_read_body in actix_web::test - Rust

Function actix_web::test::call_and_read_body

source ·
pub async fn call_and_read_body<S, B>(app: &S, req: Request) -> Bytes
where + S: Service<Request, Response = ServiceResponse<B>, Error = Error>, + B: MessageBody,
Expand description

Helper function that returns a response body of a TestRequest

+

§Examples

+
use actix_web::{test, web, App, HttpResponse, http::header};
+use bytes::Bytes;
+
+#[actix_web::test]
+async fn test_index() {
+    let app = test::init_service(
+        App::new().service(
+            web::resource("/index.html")
+                .route(web::post().to(|| async {
+                    HttpResponse::Ok().body("welcome!")
+                })))
+    ).await;
+
+    let req = test::TestRequest::post()
+        .uri("/index.html")
+        .header(header::CONTENT_TYPE, "application/json")
+        .to_request();
+
+    let result = test::call_and_read_body(&app, req).await;
+    assert_eq!(result, Bytes::from_static(b"welcome!"));
+}
+

§Panics

+

Panics if:

+
    +
  • service call returns error;
  • +
  • body yields an error while it is being read.
  • +
+
\ No newline at end of file diff --git a/actix_web/test/fn.call_and_read_body_json.html b/actix_web/test/fn.call_and_read_body_json.html new file mode 100644 index 000000000..bd79c8423 --- /dev/null +++ b/actix_web/test/fn.call_and_read_body_json.html @@ -0,0 +1,43 @@ +call_and_read_body_json in actix_web::test - Rust

Function actix_web::test::call_and_read_body_json

source ·
pub async fn call_and_read_body_json<S, B, T>(app: &S, req: Request) -> T
where + S: Service<Request, Response = ServiceResponse<B>, Error = Error>, + B: MessageBody, + T: DeserializeOwned,
Expand description

Helper function that returns a deserialized response body of a TestRequest

+

§Examples

+
use actix_web::{App, test, web, HttpResponse, http::header};
+use serde::{Serialize, Deserialize};
+
+#[derive(Serialize, Deserialize)]
+pub struct Person {
+    id: String,
+    name: String
+}
+
+#[actix_web::test]
+async fn test_add_person() {
+    let app = test::init_service(
+        App::new().service(
+            web::resource("/people")
+                .route(web::post().to(|person: web::Json<Person>| async {
+                    HttpResponse::Ok()
+                        .json(person)})
+                    ))
+    ).await;
+
+    let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes();
+
+    let req = test::TestRequest::post()
+        .uri("/people")
+        .header(header::CONTENT_TYPE, "application/json")
+        .set_payload(payload)
+        .to_request();
+
+    let result: Person = test::call_and_read_body_json(&mut app, req).await;
+}
+

§Panics

+

Panics if:

+
    +
  • service call returns an error body yields an error while it is being read;
  • +
  • body yields an error while it is being read;
  • +
  • received body is not a valid JSON representation of T.
  • +
+
\ No newline at end of file diff --git a/actix_web/test/fn.call_service.html b/actix_web/test/fn.call_service.html new file mode 100644 index 000000000..b93282843 --- /dev/null +++ b/actix_web/test/fn.call_service.html @@ -0,0 +1,25 @@ +call_service in actix_web::test - Rust

Function actix_web::test::call_service

source ·
pub async fn call_service<S, R, B, E>(app: &S, req: R) -> S::Response
where + S: Service<R, Response = ServiceResponse<B>, Error = E>, + E: Debug,
Expand description

Calls service and waits for response future completion.

+

§Examples

+
use actix_web::{test, web, App, HttpResponse, http::StatusCode};
+
+#[actix_web::test]
+async fn test_response() {
+    let app = test::init_service(
+        App::new()
+            .service(web::resource("/test").to(|| async {
+                HttpResponse::Ok()
+            }))
+    ).await;
+
+    // Create request object
+    let req = test::TestRequest::with_uri("/test").to_request();
+
+    // Call application
+    let res = test::call_service(&app, req).await;
+    assert_eq!(res.status(), StatusCode::OK);
+}
+

§Panics

+

Panics if service call returns error. To handle errors use app.call(req).

+
\ No newline at end of file diff --git a/actix_web/test/fn.init_service.html b/actix_web/test/fn.init_service.html new file mode 100644 index 000000000..032d81c23 --- /dev/null +++ b/actix_web/test/fn.init_service.html @@ -0,0 +1,27 @@ +init_service in actix_web::test - Rust

Function actix_web::test::init_service

source ·
pub async fn init_service<R, S, B, E>(
+    app: R
+) -> impl Service<Request, Response = ServiceResponse<B>, Error = E>
where + R: IntoServiceFactory<S, Request>, + S: ServiceFactory<Request, Config = AppConfig, Response = ServiceResponse<B>, Error = E>, + S::InitError: Debug,
Expand description

Initialize service from application builder instance.

+

§Examples

+
use actix_service::Service;
+use actix_web::{test, web, App, HttpResponse, http::StatusCode};
+
+#[actix_web::test]
+async fn test_init_service() {
+    let app = test::init_service(
+        App::new()
+            .service(web::resource("/test").to(|| async { "OK" }))
+    ).await;
+
+    // Create request object
+    let req = test::TestRequest::with_uri("/test").to_request();
+
+    // Execute application
+    let res = app.call(req).await.unwrap();
+    assert_eq!(res.status(), StatusCode::OK);
+}
+

§Panics

+

Panics if service initialization returns an error.

+
\ No newline at end of file diff --git a/actix_web/test/fn.ok_service.html b/actix_web/test/fn.ok_service.html new file mode 100644 index 000000000..45137a745 --- /dev/null +++ b/actix_web/test/fn.ok_service.html @@ -0,0 +1,3 @@ +ok_service in actix_web::test - Rust

Function actix_web::test::ok_service

source ·
pub fn ok_service(
+) -> impl Service<ServiceRequest, Response = ServiceResponse<BoxBody>, Error = Error>
Expand description

Creates service that always responds with 200 OK and no body.

+
\ No newline at end of file diff --git a/actix_web/test/fn.read_body.html b/actix_web/test/fn.read_body.html new file mode 100644 index 000000000..36c73e778 --- /dev/null +++ b/actix_web/test/fn.read_body.html @@ -0,0 +1,28 @@ +read_body in actix_web::test - Rust

Function actix_web::test::read_body

source ·
pub async fn read_body<B>(res: ServiceResponse<B>) -> Bytes
where + B: MessageBody,
Expand description

Helper function that returns a response body of a ServiceResponse.

+

§Examples

+
use actix_web::{test, web, App, HttpResponse, http::header};
+use bytes::Bytes;
+
+#[actix_web::test]
+async fn test_index() {
+    let app = test::init_service(
+        App::new().service(
+            web::resource("/index.html")
+                .route(web::post().to(|| async {
+                    HttpResponse::Ok().body("welcome!")
+                })))
+    ).await;
+
+    let req = test::TestRequest::post()
+        .uri("/index.html")
+        .header(header::CONTENT_TYPE, "application/json")
+        .to_request();
+
+    let res = test::call_service(&app, req).await;
+    let result = test::read_body(res).await;
+    assert_eq!(result, Bytes::from_static(b"welcome!"));
+}
+

§Panics

+

Panics if body yields an error while it is being read.

+
\ No newline at end of file diff --git a/actix_web/test/fn.read_body_json.html b/actix_web/test/fn.read_body_json.html new file mode 100644 index 000000000..48b81239c --- /dev/null +++ b/actix_web/test/fn.read_body_json.html @@ -0,0 +1,44 @@ +read_body_json in actix_web::test - Rust

Function actix_web::test::read_body_json

source ·
pub async fn read_body_json<T, B>(res: ServiceResponse<B>) -> T
where + B: MessageBody, + T: DeserializeOwned,
Expand description

Helper function that returns a deserialized response body of a ServiceResponse.

+

§Examples

+
use actix_web::{App, test, web, HttpResponse, http::header};
+use serde::{Serialize, Deserialize};
+
+#[derive(Serialize, Deserialize)]
+pub struct Person {
+    id: String,
+    name: String,
+}
+
+#[actix_web::test]
+async fn test_post_person() {
+    let app = test::init_service(
+        App::new().service(
+            web::resource("/people")
+                .route(web::post().to(|person: web::Json<Person>| async {
+                    HttpResponse::Ok()
+                        .json(person)})
+                    ))
+    ).await;
+
+    let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes();
+
+    let res = test::TestRequest::post()
+        .uri("/people")
+        .header(header::CONTENT_TYPE, "application/json")
+        .set_payload(payload)
+        .send_request(&mut app)
+        .await;
+
+    assert!(res.status().is_success());
+
+    let result: Person = test::read_body_json(res).await;
+}
+

§Panics

+

Panics if:

+
    +
  • body yields an error while it is being read;
  • +
  • received body is not a valid JSON representation of T.
  • +
+
\ No newline at end of file diff --git a/actix_web/test/fn.status_service.html b/actix_web/test/fn.status_service.html new file mode 100644 index 000000000..f7de66642 --- /dev/null +++ b/actix_web/test/fn.status_service.html @@ -0,0 +1,4 @@ +status_service in actix_web::test - Rust

Function actix_web::test::status_service

source ·
pub fn status_service(
+    status_code: StatusCode
+) -> impl Service<ServiceRequest, Response = ServiceResponse<BoxBody>, Error = Error>
Expand description

Creates service that always responds with given status code and no body.

+
\ No newline at end of file diff --git a/actix_web/test/fn.try_call_and_read_body_json.html b/actix_web/test/fn.try_call_and_read_body_json.html new file mode 100644 index 000000000..44851f297 --- /dev/null +++ b/actix_web/test/fn.try_call_and_read_body_json.html @@ -0,0 +1,8 @@ +try_call_and_read_body_json in actix_web::test - Rust

Function actix_web::test::try_call_and_read_body_json

source ·
pub async fn try_call_and_read_body_json<S, B, T>(
+    app: &S,
+    req: Request
+) -> Result<T, Box<dyn StdError>>
where + S: Service<Request, Response = ServiceResponse<B>, Error = Error>, + B: MessageBody, + T: DeserializeOwned,
Expand description

Fallible version of call_and_read_body_json that allows testing service call errors.

+
\ No newline at end of file diff --git a/actix_web/test/fn.try_call_service.html b/actix_web/test/fn.try_call_service.html new file mode 100644 index 000000000..27e43a14e --- /dev/null +++ b/actix_web/test/fn.try_call_service.html @@ -0,0 +1,7 @@ +try_call_service in actix_web::test - Rust

Function actix_web::test::try_call_service

source ·
pub async fn try_call_service<S, R, B, E>(
+    app: &S,
+    req: R
+) -> Result<S::Response, E>
where + S: Service<R, Response = ServiceResponse<B>, Error = E>, + E: Debug,
Expand description

Fallible version of call_service that allows testing response completion errors.

+
\ No newline at end of file diff --git a/actix_web/test/fn.try_read_body.html b/actix_web/test/fn.try_read_body.html new file mode 100644 index 000000000..89998128b --- /dev/null +++ b/actix_web/test/fn.try_read_body.html @@ -0,0 +1,5 @@ +try_read_body in actix_web::test - Rust

Function actix_web::test::try_read_body

source ·
pub async fn try_read_body<B>(
+    res: ServiceResponse<B>
+) -> Result<Bytes, <B as MessageBody>::Error>
where + B: MessageBody,
Expand description

Fallible version of read_body that allows testing MessageBody reading errors.

+
\ No newline at end of file diff --git a/actix_web/test/fn.try_read_body_json.html b/actix_web/test/fn.try_read_body_json.html new file mode 100644 index 000000000..445e94f5a --- /dev/null +++ b/actix_web/test/fn.try_read_body_json.html @@ -0,0 +1,6 @@ +try_read_body_json in actix_web::test - Rust

Function actix_web::test::try_read_body_json

source ·
pub async fn try_read_body_json<T, B>(
+    res: ServiceResponse<B>
+) -> Result<T, Box<dyn StdError>>
where + B: MessageBody, + T: DeserializeOwned,
Expand description

Fallible version of read_body_json that allows testing response deserialization errors.

+
\ No newline at end of file diff --git a/actix_web/test/index.html b/actix_web/test/index.html new file mode 100644 index 000000000..a3906cdd4 --- /dev/null +++ b/actix_web/test/index.html @@ -0,0 +1,27 @@ +actix_web::test - Rust

Module actix_web::test

source ·
Expand description

Various helpers for Actix applications to use during testing.

+

§Creating A Test Service

+ +

§Off-The-Shelf Test Services

+ +

§Calling Test Service

+ +

§Reading Response Payloads

+ +

Re-exports§

  • pub use self::test_services::default_service;
    Deprecated
  • pub use self::test_services::simple_service;
    Deprecated
  • pub use self::test_utils::read_response;
    Deprecated
  • pub use self::test_utils::read_response_json;
    Deprecated

Structs§

Functions§

\ No newline at end of file diff --git a/actix_web/test/sidebar-items.js b/actix_web/test/sidebar-items.js new file mode 100644 index 000000000..7bca85d2a --- /dev/null +++ b/actix_web/test/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["call_and_read_body","call_and_read_body_json","call_service","init_service","ok_service","read_body","read_body_json","status_service","try_call_and_read_body_json","try_call_service","try_read_body","try_read_body_json"],"struct":["TestBuffer","TestRequest"]}; \ No newline at end of file diff --git a/actix_web/test/struct.TestBuffer.html b/actix_web/test/struct.TestBuffer.html new file mode 100644 index 000000000..69d2faebe --- /dev/null +++ b/actix_web/test/struct.TestBuffer.html @@ -0,0 +1,179 @@ +TestBuffer in actix_web::test - Rust

Struct actix_web::test::TestBuffer

source ·
pub struct TestBuffer {
+    pub read_buf: Rc<RefCell<BytesMut>>,
+    pub write_buf: Rc<RefCell<BytesMut>>,
+    pub err: Option<Rc<Error>>,
+}
Expand description

Async I/O test buffer.

+

Fields§

§read_buf: Rc<RefCell<BytesMut>>§write_buf: Rc<RefCell<BytesMut>>§err: Option<Rc<Error>>

Implementations§

source§

impl TestBuffer

source

pub fn new<T>(data: T) -> TestBuffer
where + T: Into<BytesMut>,

Create new TestBuffer instance with initial read buffer.

+
source

pub fn empty() -> TestBuffer

Create new empty TestBuffer instance.

+
source

pub fn extend_read_buf<T>(&mut self, data: T)
where + T: AsRef<[u8]>,

Add data to read buffer.

+

Trait Implementations§

source§

impl AsyncRead for TestBuffer

source§

fn poll_read( + self: Pin<&mut TestBuffer>, + _: &mut Context<'_>, + buf: &mut ReadBuf<'_> +) -> Poll<Result<(), Error>>

Attempts to read from the AsyncRead into buf. Read more
source§

impl AsyncWrite for TestBuffer

source§

fn poll_write( + self: Pin<&mut TestBuffer>, + _: &mut Context<'_>, + buf: &[u8] +) -> Poll<Result<usize, Error>>

Attempt to write bytes from buf into the object. Read more
source§

fn poll_flush( + self: Pin<&mut TestBuffer>, + _: &mut Context<'_> +) -> Poll<Result<(), Error>>

Attempts to flush the object, ensuring that any buffered data reach +their destination. Read more
source§

fn poll_shutdown( + self: Pin<&mut TestBuffer>, + _: &mut Context<'_> +) -> Poll<Result<(), Error>>

Initiates or attempts to shut down this writer, returning success when +the I/O connection has completely shut down. Read more
§

fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[IoSlice<'_>] +) -> Poll<Result<usize, Error>>

Like poll_write, except that it writes from a slice of buffers. Read more
§

fn is_write_vectored(&self) -> bool

Determines if this writer has an efficient poll_write_vectored +implementation. Read more
source§

impl Debug for TestBuffer

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Read for TestBuffer

source§

fn read(&mut self, dst: &mut [u8]) -> Result<usize, Error>

Pull some bytes from this source into the specified buffer, returning +how many bytes were read. Read more
1.36.0 · source§

fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize, Error>

Like read, except that it reads into a slice of buffers. Read more
source§

fn is_read_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Reader has an efficient read_vectored +implementation. Read more
1.0.0 · source§

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, Error>

Read all bytes until EOF in this source, placing them into buf. Read more
1.0.0 · source§

fn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>

Read all bytes until EOF in this source, appending them to buf. Read more
1.6.0 · source§

fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>

Read the exact number of bytes required to fill buf. Read more
source§

fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<(), Error>

🔬This is a nightly-only experimental API. (read_buf)
Pull some bytes from this source into the specified buffer. Read more
source§

fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<(), Error>

🔬This is a nightly-only experimental API. (read_buf)
Read the exact number of bytes required to fill cursor. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Creates a “by reference” adaptor for this instance of Read. Read more
1.0.0 · source§

fn bytes(self) -> Bytes<Self>
where + Self: Sized,

Transforms this Read instance to an Iterator over its bytes. Read more
1.0.0 · source§

fn chain<R>(self, next: R) -> Chain<Self, R>
where + R: Read, + Self: Sized,

Creates an adapter which will chain this stream with another. Read more
1.0.0 · source§

fn take(self, limit: u64) -> Take<Self>
where + Self: Sized,

Creates an adapter which will read at most limit bytes from it. Read more
source§

impl Write for TestBuffer

source§

fn write(&mut self, buf: &[u8]) -> Result<usize, Error>

Write a buffer into this writer, returning how many bytes were written. Read more
source§

fn flush(&mut self) -> Result<(), Error>

Flush this output stream, ensuring that all intermediately buffered +contents reach their destination. Read more
1.36.0 · source§

fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize, Error>

Like write, except that it writes from a slice of buffers. Read more
source§

fn is_write_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Writer has an efficient write_vectored +implementation. Read more
1.0.0 · source§

fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>

Attempts to write an entire buffer into this writer. Read more
source§

fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>

🔬This is a nightly-only experimental API. (write_all_vectored)
Attempts to write multiple buffers into this writer. Read more
1.0.0 · source§

fn write_fmt(&mut self, fmt: Arguments<'_>) -> Result<(), Error>

Writes a formatted string into this writer, returning any error +encountered. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Creates a “by reference” adapter for this instance of Write. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<R> AsyncReadExt for R
where + R: AsyncRead + ?Sized,

§

fn chain<R>(self, next: R) -> Chain<Self, R>
where + Self: Sized, + R: AsyncRead,

Creates a new AsyncRead instance that chains this stream with +next. Read more
§

fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>
where + Self: Unpin,

Pulls some bytes from this source into the specified buffer, +returning how many bytes were read. Read more
§

fn read_buf<'a, B>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B>
where + Self: Unpin, + B: BufMut + ?Sized,

Pulls some bytes from this source into the specified buffer, +advancing the buffer’s internal cursor. Read more
§

fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self>
where + Self: Unpin,

Reads the exact number of bytes required to fill buf. Read more
§

fn read_u8(&mut self) -> ReadU8<&mut Self>
where + Self: Unpin,

Reads an unsigned 8 bit integer from the underlying reader. Read more
§

fn read_i8(&mut self) -> ReadI8<&mut Self>
where + Self: Unpin,

Reads a signed 8 bit integer from the underlying reader. Read more
§

fn read_u16(&mut self) -> ReadU16<&mut Self>
where + Self: Unpin,

Reads an unsigned 16-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i16(&mut self) -> ReadI16<&mut Self>
where + Self: Unpin,

Reads a signed 16-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u32(&mut self) -> ReadU32<&mut Self>
where + Self: Unpin,

Reads an unsigned 32-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i32(&mut self) -> ReadI32<&mut Self>
where + Self: Unpin,

Reads a signed 32-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u64(&mut self) -> ReadU64<&mut Self>
where + Self: Unpin,

Reads an unsigned 64-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i64(&mut self) -> ReadI64<&mut Self>
where + Self: Unpin,

Reads an signed 64-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_u128(&mut self) -> ReadU128<&mut Self>
where + Self: Unpin,

Reads an unsigned 128-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_i128(&mut self) -> ReadI128<&mut Self>
where + Self: Unpin,

Reads an signed 128-bit integer in big-endian order from the +underlying reader. Read more
§

fn read_f32(&mut self) -> ReadF32<&mut Self>
where + Self: Unpin,

Reads an 32-bit floating point type in big-endian order from the +underlying reader. Read more
§

fn read_f64(&mut self) -> ReadF64<&mut Self>
where + Self: Unpin,

Reads an 64-bit floating point type in big-endian order from the +underlying reader. Read more
§

fn read_u16_le(&mut self) -> ReadU16Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 16-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i16_le(&mut self) -> ReadI16Le<&mut Self>
where + Self: Unpin,

Reads a signed 16-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u32_le(&mut self) -> ReadU32Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 32-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i32_le(&mut self) -> ReadI32Le<&mut Self>
where + Self: Unpin,

Reads a signed 32-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u64_le(&mut self) -> ReadU64Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 64-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i64_le(&mut self) -> ReadI64Le<&mut Self>
where + Self: Unpin,

Reads an signed 64-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_u128_le(&mut self) -> ReadU128Le<&mut Self>
where + Self: Unpin,

Reads an unsigned 128-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_i128_le(&mut self) -> ReadI128Le<&mut Self>
where + Self: Unpin,

Reads an signed 128-bit integer in little-endian order from the +underlying reader. Read more
§

fn read_f32_le(&mut self) -> ReadF32Le<&mut Self>
where + Self: Unpin,

Reads an 32-bit floating point type in little-endian order from the +underlying reader. Read more
§

fn read_f64_le(&mut self) -> ReadF64Le<&mut Self>
where + Self: Unpin,

Reads an 64-bit floating point type in little-endian order from the +underlying reader. Read more
§

fn read_to_end<'a>(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEnd<'a, Self>
where + Self: Unpin,

Reads all bytes until EOF in this source, placing them into buf. Read more
§

fn read_to_string<'a>( + &'a mut self, + dst: &'a mut String +) -> ReadToString<'a, Self>
where + Self: Unpin,

Reads all bytes until EOF in this source, appending them to buf. Read more
§

fn take(self, limit: u64) -> Take<Self>
where + Self: Sized,

Creates an adaptor which reads at most limit bytes from it. Read more
§

impl<W> AsyncWriteExt for W
where + W: AsyncWrite + ?Sized,

§

fn write<'a>(&'a mut self, src: &'a [u8]) -> Write<'a, Self>
where + Self: Unpin,

Writes a buffer into this writer, returning how many bytes were +written. Read more
§

fn write_vectored<'a, 'b>( + &'a mut self, + bufs: &'a [IoSlice<'b>] +) -> WriteVectored<'a, 'b, Self>
where + Self: Unpin,

Like write, except that it writes from a slice of buffers. Read more
§

fn write_buf<'a, B>(&'a mut self, src: &'a mut B) -> WriteBuf<'a, Self, B>
where + Self: Sized + Unpin, + B: Buf,

Writes a buffer into this writer, advancing the buffer’s internal +cursor. Read more
§

fn write_all_buf<'a, B>( + &'a mut self, + src: &'a mut B +) -> WriteAllBuf<'a, Self, B>
where + Self: Sized + Unpin, + B: Buf,

Attempts to write an entire buffer into this writer. Read more
§

fn write_all<'a>(&'a mut self, src: &'a [u8]) -> WriteAll<'a, Self>
where + Self: Unpin,

Attempts to write an entire buffer into this writer. Read more
§

fn write_u8(&mut self, n: u8) -> WriteU8<&mut Self>
where + Self: Unpin,

Writes an unsigned 8-bit integer to the underlying writer. Read more
§

fn write_i8(&mut self, n: i8) -> WriteI8<&mut Self>
where + Self: Unpin,

Writes a signed 8-bit integer to the underlying writer. Read more
§

fn write_u16(&mut self, n: u16) -> WriteU16<&mut Self>
where + Self: Unpin,

Writes an unsigned 16-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i16(&mut self, n: i16) -> WriteI16<&mut Self>
where + Self: Unpin,

Writes a signed 16-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u32(&mut self, n: u32) -> WriteU32<&mut Self>
where + Self: Unpin,

Writes an unsigned 32-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i32(&mut self, n: i32) -> WriteI32<&mut Self>
where + Self: Unpin,

Writes a signed 32-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u64(&mut self, n: u64) -> WriteU64<&mut Self>
where + Self: Unpin,

Writes an unsigned 64-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i64(&mut self, n: i64) -> WriteI64<&mut Self>
where + Self: Unpin,

Writes an signed 64-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_u128(&mut self, n: u128) -> WriteU128<&mut Self>
where + Self: Unpin,

Writes an unsigned 128-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_i128(&mut self, n: i128) -> WriteI128<&mut Self>
where + Self: Unpin,

Writes an signed 128-bit integer in big-endian order to the +underlying writer. Read more
§

fn write_f32(&mut self, n: f32) -> WriteF32<&mut Self>
where + Self: Unpin,

Writes an 32-bit floating point type in big-endian order to the +underlying writer. Read more
§

fn write_f64(&mut self, n: f64) -> WriteF64<&mut Self>
where + Self: Unpin,

Writes an 64-bit floating point type in big-endian order to the +underlying writer. Read more
§

fn write_u16_le(&mut self, n: u16) -> WriteU16Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 16-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i16_le(&mut self, n: i16) -> WriteI16Le<&mut Self>
where + Self: Unpin,

Writes a signed 16-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u32_le(&mut self, n: u32) -> WriteU32Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 32-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i32_le(&mut self, n: i32) -> WriteI32Le<&mut Self>
where + Self: Unpin,

Writes a signed 32-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u64_le(&mut self, n: u64) -> WriteU64Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 64-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i64_le(&mut self, n: i64) -> WriteI64Le<&mut Self>
where + Self: Unpin,

Writes an signed 64-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_u128_le(&mut self, n: u128) -> WriteU128Le<&mut Self>
where + Self: Unpin,

Writes an unsigned 128-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_i128_le(&mut self, n: i128) -> WriteI128Le<&mut Self>
where + Self: Unpin,

Writes an signed 128-bit integer in little-endian order to the +underlying writer. Read more
§

fn write_f32_le(&mut self, n: f32) -> WriteF32Le<&mut Self>
where + Self: Unpin,

Writes an 32-bit floating point type in little-endian order to the +underlying writer. Read more
§

fn write_f64_le(&mut self, n: f64) -> WriteF64Le<&mut Self>
where + Self: Unpin,

Writes an 64-bit floating point type in little-endian order to the +underlying writer. Read more
§

fn flush(&mut self) -> Flush<'_, Self>
where + Self: Unpin,

Flushes this output stream, ensuring that all intermediately buffered +contents reach their destination. Read more
§

fn shutdown(&mut self) -> Shutdown<'_, Self>
where + Self: Unpin,

Shuts down the output stream, ensuring that the value can be dropped +cleanly. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/test/struct.TestRequest.html b/actix_web/test/struct.TestRequest.html new file mode 100644 index 000000000..eed32bdbb --- /dev/null +++ b/actix_web/test/struct.TestRequest.html @@ -0,0 +1,89 @@ +TestRequest in actix_web::test - Rust

Struct actix_web::test::TestRequest

source ·
pub struct TestRequest { /* private fields */ }
Expand description

Test Request builder.

+

For unit testing, actix provides a request builder type and a simple handler runner. TestRequest implements a builder-like pattern. +You can generate various types of request via TestRequest’s methods:

+ + +
use actix_web::{test, HttpRequest, HttpResponse, HttpMessage};
+use actix_web::http::{header, StatusCode};
+
+async fn handler(req: HttpRequest) -> HttpResponse {
+    if let Some(hdr) = req.headers().get(header::CONTENT_TYPE) {
+        HttpResponse::Ok().into()
+    } else {
+        HttpResponse::BadRequest().into()
+    }
+}
+
+#[actix_web::test]
+async fn test_index() {
+    let req = test::TestRequest::default()
+        .insert_header(header::ContentType::plaintext())
+        .to_http_request();
+
+    let resp = handler(req).await;
+    assert_eq!(resp.status(), StatusCode::OK);
+
+    let req = test::TestRequest::default().to_http_request();
+    let resp = handler(req).await;
+    assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+}
+

Implementations§

source§

impl TestRequest

source

pub fn with_uri(uri: &str) -> TestRequest

Constructs test request and sets request URI.

+
source

pub fn get() -> TestRequest

Constructs test request with GET method.

+
source

pub fn post() -> TestRequest

Constructs test request with POST method.

+
source

pub fn put() -> TestRequest

Constructs test request with PUT method.

+
source

pub fn patch() -> TestRequest

Constructs test request with PATCH method.

+
source

pub fn delete() -> TestRequest

Constructs test request with DELETE method.

+
source

pub fn version(self, ver: Version) -> Self

Sets HTTP version of this request.

+
source

pub fn method(self, meth: Method) -> Self

Sets method of this request.

+
source

pub fn uri(self, path: &str) -> Self

Sets URI of this request.

+
source

pub fn insert_header(self, header: impl TryIntoHeaderPair) -> Self

Inserts a header, replacing any that were set with an equivalent field name.

+
source

pub fn append_header(self, header: impl TryIntoHeaderPair) -> Self

Appends a header, keeping any that were set with an equivalent field name.

+
source

pub fn cookie(self, cookie: Cookie<'_>) -> Self

Available on crate feature cookies only.

Sets cookie for this request.

+
source

pub fn param( + self, + name: impl Into<Cow<'static, str>>, + value: impl Into<Cow<'static, str>> +) -> Self

Sets request path pattern parameter.

+
§Examples
+
use actix_web::test::TestRequest;
+
+let req = TestRequest::default().param("foo", "bar");
+let req = TestRequest::default().param("foo".to_owned(), "bar".to_owned());
+
source

pub fn peer_addr(self, addr: SocketAddr) -> Self

Sets peer address.

+
source

pub fn set_payload(self, data: impl Into<Bytes>) -> Self

Sets request payload.

+
source

pub fn set_form(self, data: impl Serialize) -> Self

Serializes data to a URL encoded form and set it as the request payload.

+

The Content-Type header is set to application/x-www-form-urlencoded.

+
source

pub fn set_json(self, data: impl Serialize) -> Self

Serializes data to JSON and set it as the request payload.

+

The Content-Type header is set to application/json.

+
source

pub fn app_data<T: 'static>(self, data: T) -> Self

Inserts application data.

+

This is equivalent of App::app_data() method for testing purpose.

+
source

pub fn to_request(self) -> Request

Finalizes request creation and returns Request instance.

+
source

pub fn to_srv_request(self) -> ServiceRequest

Finalizes request creation and returns ServiceRequest instance.

+
source

pub fn to_srv_response<B>(self, res: HttpResponse<B>) -> ServiceResponse<B>

Finalizes request creation and returns ServiceResponse instance.

+
source

pub fn to_http_request(self) -> HttpRequest

Finalizes request creation and returns HttpRequest instance.

+
source

pub fn to_http_parts(self) -> (HttpRequest, Payload)

Finalizes request creation and returns HttpRequest and Payload pair.

+
source

pub async fn send_request<S, B, E>(self, app: &S) -> S::Response
where + S: Service<Request, Response = ServiceResponse<B>, Error = E>, + E: Debug,

Finalizes request creation, calls service, and waits for response future completion.

+

Trait Implementations§

source§

impl Default for TestRequest

source§

fn default() -> TestRequest

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/test/test_request/struct.TestRequest.html b/actix_web/test/test_request/struct.TestRequest.html new file mode 100644 index 000000000..49e55b2e6 --- /dev/null +++ b/actix_web/test/test_request/struct.TestRequest.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/test/struct.TestRequest.html...

+ + + \ No newline at end of file diff --git a/actix_web/test/test_services/fn.ok_service.html b/actix_web/test/test_services/fn.ok_service.html new file mode 100644 index 000000000..602758fa6 --- /dev/null +++ b/actix_web/test/test_services/fn.ok_service.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/test/fn.ok_service.html...

+ + + \ No newline at end of file diff --git a/actix_web/test/test_services/fn.status_service.html b/actix_web/test/test_services/fn.status_service.html new file mode 100644 index 000000000..f4f9e4894 --- /dev/null +++ b/actix_web/test/test_services/fn.status_service.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/test/fn.status_service.html...

+ + + \ No newline at end of file diff --git a/actix_web/test/test_utils/fn.call_and_read_body.html b/actix_web/test/test_utils/fn.call_and_read_body.html new file mode 100644 index 000000000..7ea3eb9b8 --- /dev/null +++ b/actix_web/test/test_utils/fn.call_and_read_body.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/test/fn.call_and_read_body.html...

+ + + \ No newline at end of file diff --git a/actix_web/test/test_utils/fn.call_and_read_body_json.html b/actix_web/test/test_utils/fn.call_and_read_body_json.html new file mode 100644 index 000000000..71d5c5f36 --- /dev/null +++ b/actix_web/test/test_utils/fn.call_and_read_body_json.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/test/fn.call_and_read_body_json.html...

+ + + \ No newline at end of file diff --git a/actix_web/test/test_utils/fn.call_service.html b/actix_web/test/test_utils/fn.call_service.html new file mode 100644 index 000000000..7794c8eb5 --- /dev/null +++ b/actix_web/test/test_utils/fn.call_service.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/test/fn.call_service.html...

+ + + \ No newline at end of file diff --git a/actix_web/test/test_utils/fn.init_service.html b/actix_web/test/test_utils/fn.init_service.html new file mode 100644 index 000000000..6b8de0565 --- /dev/null +++ b/actix_web/test/test_utils/fn.init_service.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/test/fn.init_service.html...

+ + + \ No newline at end of file diff --git a/actix_web/test/test_utils/fn.read_body.html b/actix_web/test/test_utils/fn.read_body.html new file mode 100644 index 000000000..8d135246c --- /dev/null +++ b/actix_web/test/test_utils/fn.read_body.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/test/fn.read_body.html...

+ + + \ No newline at end of file diff --git a/actix_web/test/test_utils/fn.read_body_json.html b/actix_web/test/test_utils/fn.read_body_json.html new file mode 100644 index 000000000..4f10574b9 --- /dev/null +++ b/actix_web/test/test_utils/fn.read_body_json.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/test/fn.read_body_json.html...

+ + + \ No newline at end of file diff --git a/actix_web/test/test_utils/fn.try_call_and_read_body_json.html b/actix_web/test/test_utils/fn.try_call_and_read_body_json.html new file mode 100644 index 000000000..599003fe0 --- /dev/null +++ b/actix_web/test/test_utils/fn.try_call_and_read_body_json.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/test/fn.try_call_and_read_body_json.html...

+ + + \ No newline at end of file diff --git a/actix_web/test/test_utils/fn.try_call_service.html b/actix_web/test/test_utils/fn.try_call_service.html new file mode 100644 index 000000000..502f918f8 --- /dev/null +++ b/actix_web/test/test_utils/fn.try_call_service.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/test/fn.try_call_service.html...

+ + + \ No newline at end of file diff --git a/actix_web/test/test_utils/fn.try_read_body.html b/actix_web/test/test_utils/fn.try_read_body.html new file mode 100644 index 000000000..f0056934c --- /dev/null +++ b/actix_web/test/test_utils/fn.try_read_body.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/test/fn.try_read_body.html...

+ + + \ No newline at end of file diff --git a/actix_web/test/test_utils/fn.try_read_body_json.html b/actix_web/test/test_utils/fn.try_read_body_json.html new file mode 100644 index 000000000..bd37ae705 --- /dev/null +++ b/actix_web/test/test_utils/fn.try_read_body_json.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/test/fn.try_read_body_json.html...

+ + + \ No newline at end of file diff --git a/actix_web/trait.FromRequest.html b/actix_web/trait.FromRequest.html new file mode 100644 index 000000000..20df9c668 --- /dev/null +++ b/actix_web/trait.FromRequest.html @@ -0,0 +1,219 @@ +FromRequest in actix_web - Rust

Trait actix_web::FromRequest

source ·
pub trait FromRequest: Sized {
+    type Error: Into<Error>;
+    type Future: Future<Output = Result<Self, Self::Error>>;
+
+    // Required method
+    fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future;
+
+    // Provided method
+    fn extract(req: &HttpRequest) -> Self::Future { ... }
+}
Expand description

A type that implements FromRequest is called an extractor and can extract data from +the request. Some types that implement this trait are: Json, Header, and Path.

+

Check out ServiceRequest::extract if you want to +leverage extractors when implementing middlewares.

+

§Configuration

+

An extractor can be customized by injecting the corresponding configuration with one of:

+ +

Here are some built-in extractors and their corresponding configuration. +Please refer to the respective documentation for details.

+

§Implementing An Extractor

+

To reduce duplicate code in handlers where extracting certain parts of a request has a common +structure, you can implement FromRequest for your own types.

+

Note that the request payload can only be consumed by one extractor.

+

Required Associated Types§

source

type Error: Into<Error>

The associated error which can be returned.

+
source

type Future: Future<Output = Result<Self, Self::Error>>

Future that resolves to a Self.

+

To use an async function or block, the futures must be boxed. The following snippet will be +common when creating async/await extractors (that do not consume the body).

+ +
type Future = Pin<Box<dyn Future<Output = Result<Self, Self::Error>>>>;
+// or
+type Future = futures_util::future::LocalBoxFuture<'static, Result<Self, Self::Error>>;
+
+fn from_request(req: HttpRequest, ...) -> Self::Future {
+    let req = req.clone();
+    Box::pin(async move {
+        ...
+    })
+}
+

Required Methods§

source

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.

+

Provided Methods§

source

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously.

+

This method is short for T::from_request(req, &mut Payload::None).

+

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl FromRequest for ()

§

type Error = Infallible

§

type Future = Ready<Result<(), <() as FromRequest>::Error>>

source§

fn from_request(_: &HttpRequest, _: &mut Payload) -> Self::Future

source§

impl FromRequest for String

Extract text information from a request’s body.

+

Text extractor automatically decode body according to the request’s charset.

+

Use PayloadConfig to configure extraction process.

+

§Examples

+
use actix_web::{post, web, FromRequest};
+
+// extract text data from request
+#[post("/")]
+async fn index(text: String) -> String {
+    format!("Body {}!", text)
+}
+
§

type Error = Error

§

type Future = Either<StringExtractFut, Ready<Result<String, Error>>>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<A: FromRequest + 'static> FromRequest for (A,)

FromRequest implementation for tuple

+
§

type Error = Error

§

type Future = TupleFromRequest1<A>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<A: FromRequest + 'static, B: FromRequest + 'static> FromRequest for (A, B)

FromRequest implementation for tuple

+
§

type Error = Error

§

type Future = TupleFromRequest2<A, B>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<A: FromRequest + 'static, B: FromRequest + 'static, C: FromRequest + 'static> FromRequest for (A, B, C)

FromRequest implementation for tuple

+
§

type Error = Error

§

type Future = TupleFromRequest3<A, B, C>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<A: FromRequest + 'static, B: FromRequest + 'static, C: FromRequest + 'static, D: FromRequest + 'static> FromRequest for (A, B, C, D)

FromRequest implementation for tuple

+
§

type Error = Error

§

type Future = TupleFromRequest4<A, B, C, D>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<A: FromRequest + 'static, B: FromRequest + 'static, C: FromRequest + 'static, D: FromRequest + 'static, E: FromRequest + 'static> FromRequest for (A, B, C, D, E)

FromRequest implementation for tuple

+
§

type Error = Error

§

type Future = TupleFromRequest5<A, B, C, D, E>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<A: FromRequest + 'static, B: FromRequest + 'static, C: FromRequest + 'static, D: FromRequest + 'static, E: FromRequest + 'static, F: FromRequest + 'static> FromRequest for (A, B, C, D, E, F)

FromRequest implementation for tuple

+
§

type Error = Error

§

type Future = TupleFromRequest6<A, B, C, D, E, F>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<A: FromRequest + 'static, B: FromRequest + 'static, C: FromRequest + 'static, D: FromRequest + 'static, E: FromRequest + 'static, F: FromRequest + 'static, G: FromRequest + 'static> FromRequest for (A, B, C, D, E, F, G)

FromRequest implementation for tuple

+
§

type Error = Error

§

type Future = TupleFromRequest7<A, B, C, D, E, F, G>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<A: FromRequest + 'static, B: FromRequest + 'static, C: FromRequest + 'static, D: FromRequest + 'static, E: FromRequest + 'static, F: FromRequest + 'static, G: FromRequest + 'static, H: FromRequest + 'static> FromRequest for (A, B, C, D, E, F, G, H)

FromRequest implementation for tuple

+
§

type Error = Error

§

type Future = TupleFromRequest8<A, B, C, D, E, F, G, H>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<A: FromRequest + 'static, B: FromRequest + 'static, C: FromRequest + 'static, D: FromRequest + 'static, E: FromRequest + 'static, F: FromRequest + 'static, G: FromRequest + 'static, H: FromRequest + 'static, I: FromRequest + 'static> FromRequest for (A, B, C, D, E, F, G, H, I)

FromRequest implementation for tuple

+
§

type Error = Error

§

type Future = TupleFromRequest9<A, B, C, D, E, F, G, H, I>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<A: FromRequest + 'static, B: FromRequest + 'static, C: FromRequest + 'static, D: FromRequest + 'static, E: FromRequest + 'static, F: FromRequest + 'static, G: FromRequest + 'static, H: FromRequest + 'static, I: FromRequest + 'static, J: FromRequest + 'static> FromRequest for (A, B, C, D, E, F, G, H, I, J)

FromRequest implementation for tuple

+
§

type Error = Error

§

type Future = TupleFromRequest10<A, B, C, D, E, F, G, H, I, J>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<A: FromRequest + 'static, B: FromRequest + 'static, C: FromRequest + 'static, D: FromRequest + 'static, E: FromRequest + 'static, F: FromRequest + 'static, G: FromRequest + 'static, H: FromRequest + 'static, I: FromRequest + 'static, J: FromRequest + 'static, K: FromRequest + 'static> FromRequest for (A, B, C, D, E, F, G, H, I, J, K)

FromRequest implementation for tuple

+
§

type Error = Error

§

type Future = TupleFromRequest11<A, B, C, D, E, F, G, H, I, J, K>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<A: FromRequest + 'static, B: FromRequest + 'static, C: FromRequest + 'static, D: FromRequest + 'static, E: FromRequest + 'static, F: FromRequest + 'static, G: FromRequest + 'static, H: FromRequest + 'static, I: FromRequest + 'static, J: FromRequest + 'static, K: FromRequest + 'static, L: FromRequest + 'static> FromRequest for (A, B, C, D, E, F, G, H, I, J, K, L)

FromRequest implementation for tuple

+
§

type Error = Error

§

type Future = TupleFromRequest12<A, B, C, D, E, F, G, H, I, J, K, L>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<A: FromRequest + 'static, B: FromRequest + 'static, C: FromRequest + 'static, D: FromRequest + 'static, E: FromRequest + 'static, F: FromRequest + 'static, G: FromRequest + 'static, H: FromRequest + 'static, I: FromRequest + 'static, J: FromRequest + 'static, K: FromRequest + 'static, L: FromRequest + 'static, M: FromRequest + 'static> FromRequest for (A, B, C, D, E, F, G, H, I, J, K, L, M)

FromRequest implementation for tuple

+
§

type Error = Error

§

type Future = TupleFromRequest13<A, B, C, D, E, F, G, H, I, J, K, L, M>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<A: FromRequest + 'static, B: FromRequest + 'static, C: FromRequest + 'static, D: FromRequest + 'static, E: FromRequest + 'static, F: FromRequest + 'static, G: FromRequest + 'static, H: FromRequest + 'static, I: FromRequest + 'static, J: FromRequest + 'static, K: FromRequest + 'static, L: FromRequest + 'static, M: FromRequest + 'static, N: FromRequest + 'static> FromRequest for (A, B, C, D, E, F, G, H, I, J, K, L, M, N)

FromRequest implementation for tuple

+
§

type Error = Error

§

type Future = TupleFromRequest14<A, B, C, D, E, F, G, H, I, J, K, L, M, N>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<A: FromRequest + 'static, B: FromRequest + 'static, C: FromRequest + 'static, D: FromRequest + 'static, E: FromRequest + 'static, F: FromRequest + 'static, G: FromRequest + 'static, H: FromRequest + 'static, I: FromRequest + 'static, J: FromRequest + 'static, K: FromRequest + 'static, L: FromRequest + 'static, M: FromRequest + 'static, N: FromRequest + 'static, O: FromRequest + 'static> FromRequest for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)

FromRequest implementation for tuple

+
§

type Error = Error

§

type Future = TupleFromRequest15<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<A: FromRequest + 'static, B: FromRequest + 'static, C: FromRequest + 'static, D: FromRequest + 'static, E: FromRequest + 'static, F: FromRequest + 'static, G: FromRequest + 'static, H: FromRequest + 'static, I: FromRequest + 'static, J: FromRequest + 'static, K: FromRequest + 'static, L: FromRequest + 'static, M: FromRequest + 'static, N: FromRequest + 'static, O: FromRequest + 'static, P: FromRequest + 'static> FromRequest for (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P)

FromRequest implementation for tuple

+
§

type Error = Error

§

type Future = TupleFromRequest16<A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<T> FromRequest for Option<T>
where + T: FromRequest,

Optionally extract from the request.

+

If the inner T::from_request returns an error, handler will receive None instead.

+

§Examples

+
use actix_web::{web, dev, App, Error, HttpRequest, FromRequest};
+use actix_web::error::ErrorBadRequest;
+use futures_util::future::{ok, err, Ready};
+use serde::Deserialize;
+use rand;
+
+#[derive(Debug, Deserialize)]
+struct Thing {
+    name: String
+}
+
+impl FromRequest for Thing {
+    type Error = Error;
+    type Future = Ready<Result<Self, Self::Error>>;
+
+    fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
+        if rand::random() {
+            ok(Thing { name: "thingy".into() })
+        } else {
+            err(ErrorBadRequest("no luck"))
+        }
+
+    }
+}
+
+/// extract `Thing` from request
+async fn index(supplied_thing: Option<Thing>) -> String {
+    match supplied_thing {
+        // Puns not intended
+        Some(thing) => format!("Got something: {:?}", thing),
+        None => format!("No thing!")
+    }
+}
+
+let app = App::new().service(
+    web::resource("/users/:first").route(
+        web::post().to(index))
+);
+
§

type Error = Infallible

§

type Future = FromRequestOptFuture<<T as FromRequest>::Future>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

source§

impl<T, E> FromRequest for Result<T, E>
where + T: FromRequest, + T::Error: Into<E>,

Extract from the request, passing error type through to handler.

+

If the inner T::from_request returns an error, allow handler to receive the error rather than +immediately returning an error response.

+

§Examples

+
use actix_web::{web, dev, App, Result, Error, HttpRequest, FromRequest};
+use actix_web::error::ErrorBadRequest;
+use futures_util::future::{ok, err, Ready};
+use serde::Deserialize;
+use rand;
+
+#[derive(Debug, Deserialize)]
+struct Thing {
+    name: String
+}
+
+impl FromRequest for Thing {
+    type Error = Error;
+    type Future = Ready<Result<Thing, Error>>;
+
+    fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
+        if rand::random() {
+            ok(Thing { name: "thingy".into() })
+        } else {
+            err(ErrorBadRequest("no luck"))
+        }
+    }
+}
+
+/// extract `Thing` from request
+async fn index(supplied_thing: Result<Thing>) -> String {
+    match supplied_thing {
+        Ok(thing) => format!("Got thing: {thing:?}"),
+        Err(err) => format!("Error extracting thing: {err}"),
+    }
+}
+
+let app = App::new().service(
+    web::resource("/users/:first").route(web::post().to(index))
+);
+
§

type Error = Infallible

§

type Future = FromRequestResFuture<<T as FromRequest>::Future, E>

source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

Implementors§

source§

impl FromRequest for ConnectionInfo

source§

impl FromRequest for PeerAddr

§

type Error = MissingPeerAddr

§

type Future = Ready<Result<PeerAddr, <PeerAddr as FromRequest>::Error>>

source§

impl FromRequest for Method

Extract the request’s method.

+

§Examples

+
use actix_web::{http::Method, web, App, Responder};
+
+async fn handler(method: Method) -> impl Responder {
+    format!("Request method: {}", method)
+}
+
+let app = App::new().default_service(web::to(handler));
+
source§

impl FromRequest for Uri

Extract the request’s URI.

+

§Examples

+
use actix_web::{http::Uri, web, App, Responder};
+
+async fn handler(uri: Uri) -> impl Responder {
+    format!("Requested path: {}", uri.path())
+}
+
+let app = App::new().default_service(web::to(handler));
+
source§

impl FromRequest for HttpRequest

It is possible to get HttpRequest as an extractor handler parameter

+

§Examples

+
use actix_web::{web, App, HttpRequest};
+use serde::Deserialize;
+
+/// extract `Thing` from request
+async fn index(req: HttpRequest) -> String {
+   format!("Got thing: {:?}", req)
+}
+
+let app = App::new().service(
+    web::resource("/users/{first}").route(
+        web::get().to(index))
+);
+
source§

impl FromRequest for Bytes

Extract binary data from a request’s payload.

+

Collects request payload stream into a Bytes instance.

+

Use PayloadConfig to configure extraction process.

+

§Examples

+
use actix_web::{post, web};
+
+/// extract binary data from request
+#[post("/")]
+async fn index(body: web::Bytes) -> String {
+    format!("Body {:?}!", body)
+}
+
§

type Error = Error

§

type Future = Either<BytesExtractFut, Ready<Result<Bytes, Error>>>

source§

impl FromRequest for Payload

See here for example of usage as an extractor.

+
source§

impl<L, R> FromRequest for Either<L, R>
where + L: FromRequest + 'static, + R: FromRequest + 'static,

See here for example of usage as an extractor.

+
§

type Error = EitherExtractError<<L as FromRequest>::Error, <R as FromRequest>::Error>

§

type Future = EitherExtractFut<L, R>

source§

impl<T> FromRequest for Form<T>
where + T: DeserializeOwned + 'static,

See here for example of usage as an extractor.

+
§

type Error = Error

§

type Future = FormExtractFut<T>

source§

impl<T> FromRequest for Header<T>
where + T: ParseHeader,

§

type Error = ParseError

§

type Future = Ready<Result<Header<T>, <Header<T> as FromRequest>::Error>>

source§

impl<T> FromRequest for Path<T>
where + T: DeserializeOwned,

See here for example of usage as an extractor.

+
§

type Error = Error

§

type Future = Ready<Result<Path<T>, <Path<T> as FromRequest>::Error>>

source§

impl<T: Clone + 'static> FromRequest for ReqData<T>

§

type Error = Error

§

type Future = Ready<Result<ReqData<T>, Error>>

source§

impl<T: DeserializeOwned> FromRequest for Json<T>

See here for example of usage as an extractor.

+
§

type Error = Error

§

type Future = JsonExtractFut<T>

source§

impl<T: DeserializeOwned> FromRequest for Query<T>

See here for example of usage as an extractor.

+
§

type Error = Error

§

type Future = Ready<Result<Query<T>, Error>>

source§

impl<T: ?Sized + 'static> FromRequest for Data<T>

§

type Error = Error

§

type Future = Ready<Result<Data<T>, Error>>

\ No newline at end of file diff --git a/actix_web/trait.Handler.html b/actix_web/trait.Handler.html new file mode 100644 index 000000000..a64e9974f --- /dev/null +++ b/actix_web/trait.Handler.html @@ -0,0 +1,102 @@ +Handler in actix_web - Rust

Trait actix_web::Handler

source ·
pub trait Handler<Args>: Clone + 'static {
+    type Output;
+    type Future: Future<Output = Self::Output>;
+
+    // Required method
+    fn call(&self, args: Args) -> Self::Future;
+}
Expand description

The interface for request handlers.

+

§What Is A Request Handler

+

In short, a handler is just an async function that receives request-based arguments, in any +order, and returns something that can be converted to a response.

+

In particular, a request handler has three requirements:

+
    +
  1. It is an async function (or a function/closure that returns an appropriate future);
  2. +
  3. The function parameters (up to 12) implement FromRequest;
  4. +
  5. The async function (or future) resolves to a type that can be converted into an +HttpResponse (i.e., it implements the Responder trait).
  6. +
+

§Compiler Errors

+

If you get the error the trait Handler<_> is not implemented, then your handler does not +fulfill the first of the above requirements. (It could also mean that you’re attempting to use +a macro-routed handler in a manual routing context like web::get().to(handler), which is not +supported). Breaking the other requirements manifests as errors on implementing FromRequest +and Responder, respectively.

+

§How Do Handlers Receive Variable Numbers Of Arguments

+

Rest assured there is no macro magic here; it’s just traits.

+

The first thing to note is that FromRequest is implemented for tuples (up to 12 in length).

+

Secondly, the Handler trait is implemented for functions (up to an arity of 12) in a way +that aligns their parameter positions with a corresponding tuple of types (becoming the Args +type parameter for this trait).

+

Thanks to Rust’s type system, Actix Web can infer the function parameter types. During the +extraction step, the parameter types are described as a tuple type, from_request is run on +that tuple, and the Handler::call implementation for that particular function arity +destructures the tuple into its component types and calls your handler function with them.

+

In pseudo-code the process looks something like this:

+ +
async fn my_handler(body: String, state: web::Data<MyState>) -> impl Responder {
+    ...
+}
+
+// the function params above described as a tuple, names do not matter, only position
+type InferredMyHandlerArgs = (String, web::Data<MyState>);
+
+// create tuple of arguments to be passed to handler
+let args = InferredMyHandlerArgs::from_request(&request, &payload).await;
+
+// call handler with argument tuple
+let response = Handler::call(&my_handler, args).await;
+
+// which is effectively...
+
+let (body, state) = args;
+let response = my_handler(body, state).await;
+

This is the source code for the 2-parameter implementation of Handler to help illustrate the +bounds of the handler call after argument extraction:

+ +
impl<Func, Arg1, Arg2, Fut> Handler<(Arg1, Arg2)> for Func
+where
+    Func: Fn(Arg1, Arg2) -> Fut + Clone + 'static,
+    Fut: Future,
+{
+    type Output = Fut::Output;
+    type Future = Fut;
+
+    fn call(&self, (arg1, arg2): (Arg1, Arg2)) -> Self::Future {
+        (self)(arg1, arg2)
+    }
+}
+

Required Associated Types§

source

type Output

source

type Future: Future<Output = Self::Output>

Required Methods§

source

fn call(&self, args: Args) -> Self::Future

Object Safety§

This trait is not object safe.

Implementors§

source§

impl<Func, Fut> Handler<()> for Func
where + Func: Fn() -> Fut + Clone + 'static, + Fut: Future,

§

type Output = <Fut as Future>::Output

§

type Future = Fut

source§

impl<Func, Fut, A> Handler<(A,)> for Func
where + Func: Fn(A) -> Fut + Clone + 'static, + Fut: Future,

§

type Output = <Fut as Future>::Output

§

type Future = Fut

source§

impl<Func, Fut, A, B> Handler<(A, B)> for Func
where + Func: Fn(A, B) -> Fut + Clone + 'static, + Fut: Future,

§

type Output = <Fut as Future>::Output

§

type Future = Fut

source§

impl<Func, Fut, A, B, C> Handler<(A, B, C)> for Func
where + Func: Fn(A, B, C) -> Fut + Clone + 'static, + Fut: Future,

§

type Output = <Fut as Future>::Output

§

type Future = Fut

source§

impl<Func, Fut, A, B, C, D> Handler<(A, B, C, D)> for Func
where + Func: Fn(A, B, C, D) -> Fut + Clone + 'static, + Fut: Future,

§

type Output = <Fut as Future>::Output

§

type Future = Fut

source§

impl<Func, Fut, A, B, C, D, E> Handler<(A, B, C, D, E)> for Func
where + Func: Fn(A, B, C, D, E) -> Fut + Clone + 'static, + Fut: Future,

§

type Output = <Fut as Future>::Output

§

type Future = Fut

source§

impl<Func, Fut, A, B, C, D, E, F> Handler<(A, B, C, D, E, F)> for Func
where + Func: Fn(A, B, C, D, E, F) -> Fut + Clone + 'static, + Fut: Future,

§

type Output = <Fut as Future>::Output

§

type Future = Fut

source§

impl<Func, Fut, A, B, C, D, E, F, G> Handler<(A, B, C, D, E, F, G)> for Func
where + Func: Fn(A, B, C, D, E, F, G) -> Fut + Clone + 'static, + Fut: Future,

§

type Output = <Fut as Future>::Output

§

type Future = Fut

source§

impl<Func, Fut, A, B, C, D, E, F, G, H> Handler<(A, B, C, D, E, F, G, H)> for Func
where + Func: Fn(A, B, C, D, E, F, G, H) -> Fut + Clone + 'static, + Fut: Future,

§

type Output = <Fut as Future>::Output

§

type Future = Fut

source§

impl<Func, Fut, A, B, C, D, E, F, G, H, I> Handler<(A, B, C, D, E, F, G, H, I)> for Func
where + Func: Fn(A, B, C, D, E, F, G, H, I) -> Fut + Clone + 'static, + Fut: Future,

§

type Output = <Fut as Future>::Output

§

type Future = Fut

source§

impl<Func, Fut, A, B, C, D, E, F, G, H, I, J> Handler<(A, B, C, D, E, F, G, H, I, J)> for Func
where + Func: Fn(A, B, C, D, E, F, G, H, I, J) -> Fut + Clone + 'static, + Fut: Future,

§

type Output = <Fut as Future>::Output

§

type Future = Fut

source§

impl<Func, Fut, A, B, C, D, E, F, G, H, I, J, K> Handler<(A, B, C, D, E, F, G, H, I, J, K)> for Func
where + Func: Fn(A, B, C, D, E, F, G, H, I, J, K) -> Fut + Clone + 'static, + Fut: Future,

§

type Output = <Fut as Future>::Output

§

type Future = Fut

source§

impl<Func, Fut, A, B, C, D, E, F, G, H, I, J, K, L> Handler<(A, B, C, D, E, F, G, H, I, J, K, L)> for Func
where + Func: Fn(A, B, C, D, E, F, G, H, I, J, K, L) -> Fut + Clone + 'static, + Fut: Future,

§

type Output = <Fut as Future>::Output

§

type Future = Fut

source§

impl<Func, Fut, A, B, C, D, E, F, G, H, I, J, K, L, M> Handler<(A, B, C, D, E, F, G, H, I, J, K, L, M)> for Func
where + Func: Fn(A, B, C, D, E, F, G, H, I, J, K, L, M) -> Fut + Clone + 'static, + Fut: Future,

§

type Output = <Fut as Future>::Output

§

type Future = Fut

source§

impl<Func, Fut, A, B, C, D, E, F, G, H, I, J, K, L, M, N> Handler<(A, B, C, D, E, F, G, H, I, J, K, L, M, N)> for Func
where + Func: Fn(A, B, C, D, E, F, G, H, I, J, K, L, M, N) -> Fut + Clone + 'static, + Fut: Future,

§

type Output = <Fut as Future>::Output

§

type Future = Fut

source§

impl<Func, Fut, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O> Handler<(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O)> for Func
where + Func: Fn(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O) -> Fut + Clone + 'static, + Fut: Future,

§

type Output = <Fut as Future>::Output

§

type Future = Fut

source§

impl<Func, Fut, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P> Handler<(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P)> for Func
where + Func: Fn(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) -> Fut + Clone + 'static, + Fut: Future,

§

type Output = <Fut as Future>::Output

§

type Future = Fut

\ No newline at end of file diff --git a/actix_web/trait.HttpMessage.html b/actix_web/trait.HttpMessage.html new file mode 100644 index 000000000..25d90236a --- /dev/null +++ b/actix_web/trait.HttpMessage.html @@ -0,0 +1,31 @@ +HttpMessage in actix_web - Rust

Trait actix_web::HttpMessage

source ·
pub trait HttpMessage: Sized {
+    type Stream;
+
+    // Required methods
+    fn headers(&self) -> &HeaderMap;
+    fn take_payload(&mut self) -> Payload<Self::Stream>;
+    fn extensions(&self) -> Ref<'_, Extensions>;
+    fn extensions_mut(&self) -> RefMut<'_, Extensions>;
+
+    // Provided methods
+    fn content_type(&self) -> &str { ... }
+    fn encoding(&self) -> Result<&'static Encoding, ContentTypeError> { ... }
+    fn mime_type(&self) -> Result<Option<Mime>, ContentTypeError> { ... }
+    fn chunked(&self) -> Result<bool, ParseError> { ... }
+}
Expand description

Trait that implements general purpose operations on HTTP messages.

+

Required Associated Types§

source

type Stream

Type of message payload stream

+

Required Methods§

source

fn headers(&self) -> &HeaderMap

Read the message headers.

+
source

fn take_payload(&mut self) -> Payload<Self::Stream>

Message payload stream

+
source

fn extensions(&self) -> Ref<'_, Extensions>

Returns a reference to the request-local data/extensions container.

+
source

fn extensions_mut(&self) -> RefMut<'_, Extensions>

Returns a mutable reference to the request-local data/extensions container.

+

Provided Methods§

source

fn content_type(&self) -> &str

Read the request content type. If request did not contain a Content-Type header, an empty +string is returned.

+
source

fn encoding(&self) -> Result<&'static Encoding, ContentTypeError>

Get content type encoding.

+

UTF-8 is used by default, If request charset is not set.

+
source

fn mime_type(&self) -> Result<Option<Mime>, ContentTypeError>

Convert the request content type to a known mime type.

+
source

fn chunked(&self) -> Result<bool, ParseError>

Check if request has chunked transfer encoding.

+

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<'a, T> HttpMessage for &'a mut T
where + T: HttpMessage,

source§

fn take_payload(&mut self) -> Payload<<&'a mut T as HttpMessage>::Stream>

Message payload stream

+
source§

fn extensions(&self) -> Ref<'_, Extensions>

Request’s extensions container

+
source§

fn extensions_mut(&self) -> RefMut<'_, Extensions>

Mutable reference to a the request’s extensions container

+
§

type Stream = <T as HttpMessage>::Stream

source§

fn headers(&self) -> &HeaderMap

Implementors§

\ No newline at end of file diff --git a/actix_web/trait.Responder.html b/actix_web/trait.Responder.html new file mode 100644 index 000000000..ba92b2415 --- /dev/null +++ b/actix_web/trait.Responder.html @@ -0,0 +1,62 @@ +Responder in actix_web - Rust

Trait actix_web::Responder

source ·
pub trait Responder {
+    type Body: MessageBody + 'static;
+
+    // Required method
+    fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body>;
+
+    // Provided method
+    fn customize(self) -> CustomizeResponder<Self>
+       where Self: Sized { ... }
+}
Expand description

Trait implemented by types that can be converted to an HTTP response.

+

Any types that implement this trait can be used in the return type of a handler. Since handlers +will only have one return type, it is idiomatic to use opaque return types -> impl Responder.

+

§Implementations

+

It is often not required to implement Responder for your own types due to a broad base of +built-in implementations:

+ +

§Customizing Responder Output

+

Calling .customize() on any responder type will wrap it in a +CustomizeResponder capable of overriding various parts of the response such as the status +code and header map.

+

Required Associated Types§

source

type Body: MessageBody + 'static

Required Methods§

source

fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body>

Convert self to HttpResponse.

+

Provided Methods§

source

fn customize(self) -> CustomizeResponder<Self>
where + Self: Sized,

Wraps responder to allow alteration of its response.

+

See CustomizeResponder docs for more details on its capabilities.

+
§Examples
+
use actix_web::{Responder, http::StatusCode, test::TestRequest};
+
+let responder = "Hello world!"
+    .customize()
+    .with_status(StatusCode::BAD_REQUEST)
+    .insert_header(("x-hello", "world"));
+
+let request = TestRequest::default().to_http_request();
+let response = responder.respond_to(&request);
+assert_eq!(response.status(), StatusCode::BAD_REQUEST);
+assert_eq!(response.headers().get("x-hello").unwrap(), "world");
+

Implementations on Foreign Types§

source§

impl Responder for &'static str

§

type Body = &'static str

source§

fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body>

source§

impl Responder for &'static [u8]

§

type Body = &'static [u8]

source§

fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body>

source§

impl Responder for &String

source§

impl Responder for Cow<'_, str>

source§

impl Responder for ResponseBuilder

source§

impl Responder for String

source§

impl Responder for Vec<u8>

source§

impl Responder for ByteString

§

type Body = ByteString

source§

fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body>

source§

impl<R, E> Responder for Result<R, E>
where + R: Responder, + E: Into<Error>,

source§

impl<R: Responder> Responder for (R, StatusCode)

§

type Body = <R as Responder>::Body

source§

fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body>

source§

impl<R: Responder> Responder for Option<R>

Implementors§

source§

impl Responder for Response<BoxBody>

source§

impl Responder for HttpResponseBuilder

source§

impl Responder for Bytes

§

type Body = Bytes

source§

impl Responder for BytesMut

source§

impl Responder for Redirect

§

type Body = ()

source§

impl<B> Responder for HttpResponse<B>
where + B: MessageBody + 'static,

§

type Body = B

source§

impl<L, R> Responder for Either<L, R>
where + L: Responder, + R: Responder,

See here for example of usage as a handler return type.

+
§

type Body = EitherBody<<L as Responder>::Body, <R as Responder>::Body>

source§

impl<T> Responder for InternalError<T>
where + T: Debug + Display + 'static,

source§

impl<T> Responder for CustomizeResponder<T>
where + T: Responder,

source§

impl<T: Serialize> Responder for Form<T>

See here for example of usage as a handler return type.

+
source§

impl<T: Serialize> Responder for Json<T>

Creates response with OK status code, correct content type header, and serialized JSON payload.

+

If serialization failed

+
\ No newline at end of file diff --git a/actix_web/type.Result.html b/actix_web/type.Result.html new file mode 100644 index 000000000..767a54a6c --- /dev/null +++ b/actix_web/type.Result.html @@ -0,0 +1,8 @@ +Result in actix_web - Rust

Type Alias actix_web::Result

source ·
pub type Result<T, E = Error> = Result<T, E>;
Expand description

A convenience Result for Actix Web operations.

+

This type alias is generally used to avoid writing out actix_http::Error directly.

+

Aliased Type§

enum Result<T, E = Error> {
+    Ok(T),
+    Err(E),
+}

Variants§

§1.0.0

Ok(T)

Contains the success value

+
§1.0.0

Err(E)

Contains the error value

+
\ No newline at end of file diff --git a/actix_web/types/either/enum.Either.html b/actix_web/types/either/enum.Either.html new file mode 100644 index 000000000..6ec417b56 --- /dev/null +++ b/actix_web/types/either/enum.Either.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/web/enum.Either.html...

+ + + \ No newline at end of file diff --git a/actix_web/types/form/struct.Form.html b/actix_web/types/form/struct.Form.html new file mode 100644 index 000000000..c101c44bc --- /dev/null +++ b/actix_web/types/form/struct.Form.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/web/struct.Form.html...

+ + + \ No newline at end of file diff --git a/actix_web/types/form/struct.FormConfig.html b/actix_web/types/form/struct.FormConfig.html new file mode 100644 index 000000000..6f4bd88dd --- /dev/null +++ b/actix_web/types/form/struct.FormConfig.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/web/struct.FormConfig.html...

+ + + \ No newline at end of file diff --git a/actix_web/types/form/struct.UrlEncoded.html b/actix_web/types/form/struct.UrlEncoded.html new file mode 100644 index 000000000..d8b72eb01 --- /dev/null +++ b/actix_web/types/form/struct.UrlEncoded.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/dev/struct.UrlEncoded.html...

+ + + \ No newline at end of file diff --git a/actix_web/types/header/struct.Header.html b/actix_web/types/header/struct.Header.html new file mode 100644 index 000000000..24881c790 --- /dev/null +++ b/actix_web/types/header/struct.Header.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/web/struct.Header.html...

+ + + \ No newline at end of file diff --git a/actix_web/types/json/enum.JsonBody.html b/actix_web/types/json/enum.JsonBody.html new file mode 100644 index 000000000..bcbf2f547 --- /dev/null +++ b/actix_web/types/json/enum.JsonBody.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/dev/enum.JsonBody.html...

+ + + \ No newline at end of file diff --git a/actix_web/types/json/struct.Json.html b/actix_web/types/json/struct.Json.html new file mode 100644 index 000000000..7f900f6e6 --- /dev/null +++ b/actix_web/types/json/struct.Json.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/web/struct.Json.html...

+ + + \ No newline at end of file diff --git a/actix_web/types/json/struct.JsonConfig.html b/actix_web/types/json/struct.JsonConfig.html new file mode 100644 index 000000000..c4b04e31f --- /dev/null +++ b/actix_web/types/json/struct.JsonConfig.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/web/struct.JsonConfig.html...

+ + + \ No newline at end of file diff --git a/actix_web/types/path/struct.Path.html b/actix_web/types/path/struct.Path.html new file mode 100644 index 000000000..6e68579d6 --- /dev/null +++ b/actix_web/types/path/struct.Path.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/web/struct.Path.html...

+ + + \ No newline at end of file diff --git a/actix_web/types/path/struct.PathConfig.html b/actix_web/types/path/struct.PathConfig.html new file mode 100644 index 000000000..22c9c51da --- /dev/null +++ b/actix_web/types/path/struct.PathConfig.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/web/struct.PathConfig.html...

+ + + \ No newline at end of file diff --git a/actix_web/types/payload/struct.Payload.html b/actix_web/types/payload/struct.Payload.html new file mode 100644 index 000000000..dc1af92ac --- /dev/null +++ b/actix_web/types/payload/struct.Payload.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/web/struct.Payload.html...

+ + + \ No newline at end of file diff --git a/actix_web/types/payload/struct.PayloadConfig.html b/actix_web/types/payload/struct.PayloadConfig.html new file mode 100644 index 000000000..edca7a10d --- /dev/null +++ b/actix_web/types/payload/struct.PayloadConfig.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/web/struct.PayloadConfig.html...

+ + + \ No newline at end of file diff --git a/actix_web/types/query/struct.Query.html b/actix_web/types/query/struct.Query.html new file mode 100644 index 000000000..c756d180d --- /dev/null +++ b/actix_web/types/query/struct.Query.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/web/struct.Query.html...

+ + + \ No newline at end of file diff --git a/actix_web/types/query/struct.QueryConfig.html b/actix_web/types/query/struct.QueryConfig.html new file mode 100644 index 000000000..da0b7c97a --- /dev/null +++ b/actix_web/types/query/struct.QueryConfig.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/web/struct.QueryConfig.html...

+ + + \ No newline at end of file diff --git a/actix_web/types/readlines/struct.Readlines.html b/actix_web/types/readlines/struct.Readlines.html new file mode 100644 index 000000000..5dff0d2a5 --- /dev/null +++ b/actix_web/types/readlines/struct.Readlines.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../actix_web/dev/struct.Readlines.html...

+ + + \ No newline at end of file diff --git a/actix_web/web/enum.Either.html b/actix_web/web/enum.Either.html new file mode 100644 index 000000000..858d74c44 --- /dev/null +++ b/actix_web/web/enum.Either.html @@ -0,0 +1,94 @@ +Either in actix_web::web - Rust

Enum actix_web::web::Either

source ·
pub enum Either<L, R> {
+    Left(L),
+    Right(R),
+}
Expand description

Combines two extractor or responder types into a single type.

+

§Extractor

+

Provides a mechanism for trying two extractors, a primary and a fallback. Useful for +“polymorphic payloads” where, for example, a form might be JSON or URL encoded.

+

It is important to note that this extractor, by necessity, buffers the entire request payload +as part of its implementation. Though, it does respect any PayloadConfig maximum size limits.

+ +
use actix_web::{post, web, Either};
+use serde::Deserialize;
+
+#[derive(Deserialize)]
+struct Info {
+    name: String,
+}
+
+// handler that accepts form as JSON or form-urlencoded.
+#[post("/")]
+async fn index(form: Either<web::Json<Info>, web::Form<Info>>) -> String {
+    let name: String = match form {
+        Either::Left(json) => json.name.to_owned(),
+        Either::Right(form) => form.name.to_owned(),
+    };
+
+    format!("Welcome {}!", name)
+}
+

§Responder

+

It may be desirable to use a concrete type for a response with multiple branches. As long as +both types implement Responder, so will the Either type, enabling it to be used as a +handler’s return type.

+

All properties of a response are determined by the Responder branch returned.

+ +
use actix_web::{get, Either, Error, HttpResponse};
+
+#[get("/")]
+async fn index() -> Either<&'static str, Result<HttpResponse, Error>> {
+    if 1 == 2 {
+        // respond with Left variant
+        Either::Left("Bad data")
+    } else {
+        // respond with Right variant
+        Either::Right(
+            Ok(HttpResponse::Ok()
+                .content_type(mime::TEXT_HTML)
+                .body("<p>Hello!</p>"))
+        )
+    }
+}
+

Variants§

§

Left(L)

A value of type L.

+
§

Right(R)

A value of type R.

+

Implementations§

source§

impl<T> Either<Form<T>, Json<T>>

source

pub fn into_inner(self) -> T

source§

impl<T> Either<Json<T>, Form<T>>

source

pub fn into_inner(self) -> T

Trait Implementations§

source§

impl<L: Debug, R: Debug> Debug for Either<L, R>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<L, R> FromRequest for Either<L, R>
where + L: FromRequest + 'static, + R: FromRequest + 'static,

See here for example of usage as an extractor.

+
§

type Error = EitherExtractError<<L as FromRequest>::Error, <R as FromRequest>::Error>

The associated error which can be returned.
§

type Future = EitherExtractFut<L, R>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more
source§

impl<L: PartialEq, R: PartialEq> PartialEq for Either<L, R>

source§

fn eq(&self, other: &Either<L, R>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<L, R> Responder for Either<L, R>
where + L: Responder, + R: Responder,

See here for example of usage as a handler return type.

+
§

type Body = EitherBody<<L as Responder>::Body, <R as Responder>::Body>

source§

fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body>

Convert self to HttpResponse.
source§

fn customize(self) -> CustomizeResponder<Self>
where + Self: Sized,

Wraps responder to allow alteration of its response. Read more
source§

impl<L: Eq, R: Eq> Eq for Either<L, R>

source§

impl<L, R> StructuralPartialEq for Either<L, R>

Auto Trait Implementations§

§

impl<L, R> Freeze for Either<L, R>
where + L: Freeze, + R: Freeze,

§

impl<L, R> RefUnwindSafe for Either<L, R>
where + L: RefUnwindSafe, + R: RefUnwindSafe,

§

impl<L, R> Send for Either<L, R>
where + L: Send, + R: Send,

§

impl<L, R> Sync for Either<L, R>
where + L: Sync, + R: Sync,

§

impl<L, R> Unpin for Either<L, R>
where + L: Unpin, + R: Unpin,

§

impl<L, R> UnwindSafe for Either<L, R>
where + L: UnwindSafe, + R: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/web/enum.JsonBody.html b/actix_web/web/enum.JsonBody.html new file mode 100644 index 000000000..9921adda2 --- /dev/null +++ b/actix_web/web/enum.JsonBody.html @@ -0,0 +1,137 @@ +JsonBody in actix_web::web - Rust

Enum actix_web::web::JsonBody

source ·
pub enum JsonBody<T> {
+    Error(Option<JsonPayloadError>),
+    Body {
+        limit: usize,
+        length: Option<usize>,
+        payload: Decompress<Payload>,
+        buf: BytesMut,
+        _res: PhantomData<T>,
+    },
+}
Expand description

Future that resolves to some T when parsed from a JSON payload.

+

Can deserialize any type T that implements Deserialize.

+

Returns error if:

+
    +
  • Content-Type is not application/json when ctype_required (passed to new) +is true.
  • +
  • Content-Length is greater than limit.
  • +
  • The payload, when consumed, is not valid JSON.
  • +
+

Variants§

§

Error(Option<JsonPayloadError>)

§

Body

Fields

§limit: usize
§length: Option<usize>

Length as reported by Content-Length header, if present.

+
§payload: Decompress<Payload>
Available on crate feature __compress only.
§_res: PhantomData<T>

Implementations§

source§

impl<T: DeserializeOwned> JsonBody<T>

source

pub fn new( + req: &HttpRequest, + payload: &mut Payload, + ctype_fn: Option<&(dyn Fn(Mime) -> bool + Send + Sync)>, + ctype_required: bool +) -> Self

Create a new future to decode a JSON request payload.

+
source

pub fn limit(self, limit: usize) -> Self

Set maximum accepted payload size. The default limit is 2MB.

+

Trait Implementations§

source§

impl<T: DeserializeOwned> Future for JsonBody<T>

§

type Output = Result<T, JsonPayloadError>

The type of value produced on completion.
source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
source§

impl<T> Unpin for JsonBody<T>

Auto Trait Implementations§

§

impl<T> !Freeze for JsonBody<T>

§

impl<T> !RefUnwindSafe for JsonBody<T>

§

impl<T> !Send for JsonBody<T>

§

impl<T> !Sync for JsonBody<T>

§

impl<T> !UnwindSafe for JsonBody<T>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> FutureExt for T
where + T: Future + ?Sized,

§

fn map<U, F>(self, f: F) -> Map<Self, F>
where + F: FnOnce(Self::Output) -> U, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn map_into<U>(self) -> MapInto<Self, U>
where + Self::Output: Into<U>, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnOnce(Self::Output) -> Fut, + Fut: Future, + Self: Sized,

Chain on a computation for when a future finished, passing the result of +the future to the provided closure f. Read more
§

fn left_future<B>(self) -> Either<Self, B>
where + B: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the left-hand variant +of that Either. Read more
§

fn right_future<A>(self) -> Either<A, Self>
where + A: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the right-hand variant +of that Either. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Convert this future into a single element stream. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Output: Future, + Self: Sized,

Flatten the execution of this future when the output of this +future is itself another future. Read more
§

fn flatten_stream(self) -> FlattenStream<Self>
where + Self::Output: Stream, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a future such that poll will never again be called once it has +completed. This method can be used to turn any Future into a +FusedFuture. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnOnce(&Self::Output), + Self: Sized,

Do something with the output of a future before passing it on. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the future. Read more
§

fn shared(self) -> Shared<Self>
where + Self: Sized, + Self::Output: Clone,

Available on crate feature std only.
Create a cloneable handle to this future where all handles will resolve +to the same result. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn unit_error(self) -> UnitError<Self>
where + Self: Sized,

§

fn never_error(self) -> NeverError<Self>
where + Self: Sized,

§

fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where + Self: Unpin,

A convenience for calling Future::poll on Unpin future types.
§

fn now_or_never(self) -> Option<Self::Output>
where + Self: Sized,

Evaluates and consumes the future, returning the resulting output if +the future is ready after the first call to Future::poll. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<F> IntoFuture for F
where + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

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
§

fn try_poll( + self: Pin<&mut F>, + cx: &mut Context<'_> +) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
§

impl<Fut> TryFutureExt for Fut
where + Fut: TryFuture + ?Sized,

§

fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>
where + Self::Ok: Sink<Item, Error = Self::Error>, + Self: Sized,

Available on crate feature sink only.
Flattens the execution of this future when the successful result of this +future is a [Sink]. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + F: FnOnce(Self::Ok) -> T, + Self: Sized,

Maps this future’s success value to a different value. Read more
§

fn map_ok_or_else<T, E, F>(self, e: E, f: F) -> MapOkOrElse<Self, F, E>
where + F: FnOnce(Self::Ok) -> T, + E: FnOnce(Self::Error) -> T, + Self: Sized,

Maps this future’s success value to a different value, and permits for error handling resulting in the same type. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + F: FnOnce(Self::Error) -> E, + Self: Sized,

Maps this future’s error value to a different value. Read more
§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Maps this future’s Error to a new error type +using the Into trait. Read more
§

fn ok_into<U>(self) -> OkInto<Self, U>
where + Self: Sized, + Self::Ok: Into<U>,

Maps this future’s Ok to a new type +using the Into trait.
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnOnce(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Executes another future after this one resolves successfully. The +success value is passed to a closure to create this subsequent future. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnOnce(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Executes another future if this one resolves to an error. The +error value is passed to a closure to create this subsequent future. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnOnce(&Self::Ok), + Self: Sized,

Do something with the success value of a future before passing it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnOnce(&Self::Error), + Self: Sized,

Do something with the error value of a future before passing it on. Read more
§

fn try_flatten(self) -> TryFlatten<Self, Self::Ok>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is another future. Read more
§

fn try_flatten_stream(self) -> TryFlattenStream<Self>
where + Self::Ok: TryStream<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F>
where + Self: Sized, + F: FnOnce(Self::Error) -> Self::Ok,

Unwraps this future’s output, producing a future with this future’s +Ok type as its +Output type. Read more
§

fn into_future(self) -> IntoFuture<Self>
where + Self: Sized,

Wraps a [TryFuture] into a type that implements +Future. Read more
§

fn try_poll_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Result<Self::Ok, Self::Error>>
where + Self: Unpin,

A convenience method for calling [TryFuture::try_poll] on Unpin +future types.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/web/fn.block.html b/actix_web/web/fn.block.html new file mode 100644 index 000000000..093604151 --- /dev/null +++ b/actix_web/web/fn.block.html @@ -0,0 +1,5 @@ +block in actix_web::web - Rust

Function actix_web::web::block

source ·
pub fn block<F, R>(f: F) -> impl Future<Output = Result<R, BlockingError>>
where + F: FnOnce() -> R + Send + 'static, + R: Send + 'static,
Expand description

Executes blocking function on a thread pool, returns future that resolves to result of the +function execution.

+
\ No newline at end of file diff --git a/actix_web/web/fn.delete.html b/actix_web/web/fn.delete.html new file mode 100644 index 000000000..2515a59aa --- /dev/null +++ b/actix_web/web/fn.delete.html @@ -0,0 +1,12 @@ +delete in actix_web::web - Rust

Function actix_web::web::delete

source ·
pub fn delete() -> Route
Expand description

Creates a new route with DELETE method guard.

+

§Examples

+

In this example, one DELETE /{project_id} route is set up:

+ +
use actix_web::{web, App, HttpResponse};
+
+let app = App::new().service(
+    web::resource("/{project_id}")
+         .route(web::delete().to(|| HttpResponse::Ok()))
+
+);
+
\ No newline at end of file diff --git a/actix_web/web/fn.get.html b/actix_web/web/fn.get.html new file mode 100644 index 000000000..371d2b74d --- /dev/null +++ b/actix_web/web/fn.get.html @@ -0,0 +1,12 @@ +get in actix_web::web - Rust

Function actix_web::web::get

source ·
pub fn get() -> Route
Expand description

Creates a new route with GET method guard.

+

§Examples

+

In this example, one GET /{project_id} route is set up:

+ +
use actix_web::{web, App, HttpResponse};
+
+let app = App::new().service(
+    web::resource("/{project_id}")
+         .route(web::get().to(|| HttpResponse::Ok()))
+
+);
+
\ No newline at end of file diff --git a/actix_web/web/fn.head.html b/actix_web/web/fn.head.html new file mode 100644 index 000000000..3f8867cb2 --- /dev/null +++ b/actix_web/web/fn.head.html @@ -0,0 +1,12 @@ +head in actix_web::web - Rust

Function actix_web::web::head

source ·
pub fn head() -> Route
Expand description

Creates a new route with HEAD method guard.

+

§Examples

+

In this example, one HEAD /{project_id} route is set up:

+ +
use actix_web::{web, App, HttpResponse};
+
+let app = App::new().service(
+    web::resource("/{project_id}")
+         .route(web::head().to(|| HttpResponse::Ok()))
+
+);
+
\ No newline at end of file diff --git a/actix_web/web/fn.method.html b/actix_web/web/fn.method.html new file mode 100644 index 000000000..2af9c4737 --- /dev/null +++ b/actix_web/web/fn.method.html @@ -0,0 +1,11 @@ +method in actix_web::web - Rust

Function actix_web::web::method

source ·
pub fn method(method: Method) -> Route
Expand description

Creates a new route with specified method guard.

+

§Examples

+

In this example, one GET /{project_id} route is set up:

+ +
use actix_web::{web, http, App, HttpResponse};
+
+let app = App::new().service(
+    web::resource("/{project_id}")
+        .route(web::method(http::Method::GET).to(|| HttpResponse::Ok()))
+);
+
\ No newline at end of file diff --git a/actix_web/web/fn.patch.html b/actix_web/web/fn.patch.html new file mode 100644 index 000000000..27021b3ad --- /dev/null +++ b/actix_web/web/fn.patch.html @@ -0,0 +1,12 @@ +patch in actix_web::web - Rust

Function actix_web::web::patch

source ·
pub fn patch() -> Route
Expand description

Creates a new route with PATCH method guard.

+

§Examples

+

In this example, one PATCH /{project_id} route is set up:

+ +
use actix_web::{web, App, HttpResponse};
+
+let app = App::new().service(
+    web::resource("/{project_id}")
+         .route(web::patch().to(|| HttpResponse::Ok()))
+
+);
+
\ No newline at end of file diff --git a/actix_web/web/fn.post.html b/actix_web/web/fn.post.html new file mode 100644 index 000000000..208033d56 --- /dev/null +++ b/actix_web/web/fn.post.html @@ -0,0 +1,12 @@ +post in actix_web::web - Rust

Function actix_web::web::post

source ·
pub fn post() -> Route
Expand description

Creates a new route with POST method guard.

+

§Examples

+

In this example, one POST /{project_id} route is set up:

+ +
use actix_web::{web, App, HttpResponse};
+
+let app = App::new().service(
+    web::resource("/{project_id}")
+         .route(web::post().to(|| HttpResponse::Ok()))
+
+);
+
\ No newline at end of file diff --git a/actix_web/web/fn.put.html b/actix_web/web/fn.put.html new file mode 100644 index 000000000..7d3984943 --- /dev/null +++ b/actix_web/web/fn.put.html @@ -0,0 +1,12 @@ +put in actix_web::web - Rust

Function actix_web::web::put

source ·
pub fn put() -> Route
Expand description

Creates a new route with PUT method guard.

+

§Examples

+

In this example, one PUT /{project_id} route is set up:

+ +
use actix_web::{web, App, HttpResponse};
+
+let app = App::new().service(
+    web::resource("/{project_id}")
+         .route(web::put().to(|| HttpResponse::Ok()))
+
+);
+
\ No newline at end of file diff --git a/actix_web/web/fn.redirect.html b/actix_web/web/fn.redirect.html new file mode 100644 index 000000000..43228ac57 --- /dev/null +++ b/actix_web/web/fn.redirect.html @@ -0,0 +1,12 @@ +redirect in actix_web::web - Rust

Function actix_web::web::redirect

source ·
pub fn redirect(
+    from: impl Into<Cow<'static, str>>,
+    to: impl Into<Cow<'static, str>>
+) -> Redirect
Expand description

Create a relative or absolute redirect.

+

See Redirect docs for usage details.

+

§Examples

+
use actix_web::{web, App};
+
+let app = App::new()
+    // the client will resolve this redirect to /api/to-path
+    .service(web::redirect("/api/from-path", "to-path"));
+
\ No newline at end of file diff --git a/actix_web/web/fn.resource.html b/actix_web/web/fn.resource.html new file mode 100644 index 000000000..ca1ff9f71 --- /dev/null +++ b/actix_web/web/fn.resource.html @@ -0,0 +1,19 @@ +resource in actix_web::web - Rust

Function actix_web::web::resource

source ·
pub fn resource<T: IntoPatterns>(path: T) -> Resource
Expand description

Creates a new resource for a specific path.

+

Resources may have dynamic path segments. For example, a resource with the path /a/{name}/c +would match all incoming requests with paths such as /a/b/c, /a/1/c, or /a/etc/c.

+

A dynamic segment is specified in the form {identifier}, where the identifier can be used +later in a request handler to access the matched value for that segment. This is done by looking +up the identifier in the Path object returned by [HttpRequest.match_info()] method.

+

By default, each segment matches the regular expression [^{}/]+.

+

You can also specify a custom regex in the form {identifier:regex}:

+

For instance, to route GET-requests on any route matching /users/{userid}/{friend} and store +userid and friend in the exposed Path object:

+

§Examples

+
use actix_web::{web, App, HttpResponse};
+
+let app = App::new().service(
+    web::resource("/users/{userid}/{friend}")
+        .route(web::get().to(|| HttpResponse::Ok()))
+        .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
+);
+
\ No newline at end of file diff --git a/actix_web/web/fn.route.html b/actix_web/web/fn.route.html new file mode 100644 index 000000000..34c1a323f --- /dev/null +++ b/actix_web/web/fn.route.html @@ -0,0 +1,2 @@ +route in actix_web::web - Rust

Function actix_web::web::route

source ·
pub fn route() -> Route
Expand description

Creates a new un-configured route.

+
\ No newline at end of file diff --git a/actix_web/web/fn.scope.html b/actix_web/web/fn.scope.html new file mode 100644 index 000000000..2c3c8f51c --- /dev/null +++ b/actix_web/web/fn.scope.html @@ -0,0 +1,24 @@ +scope in actix_web::web - Rust

Function actix_web::web::scope

source ·
pub fn scope(path: &str) -> Scope
Expand description

Creates scope for common path prefix.

+

Scopes collect multiple paths under a common path prefix. The scope’s path can contain dynamic +path segments.

+

§Avoid Trailing Slashes

+

Avoid using trailing slashes in the scope prefix (e.g., web::scope("/scope/")). It will almost +certainly not have the expected behavior. See the documentation on resource definitions +to understand why this is the case and how to correctly construct scope/prefix definitions.

+

§Examples

+

In this example, three routes are set up (and will handle any method):

+
    +
  • /{project_id}/path1
  • +
  • /{project_id}/path2
  • +
  • /{project_id}/path3
  • +
+

§Examples

+
use actix_web::{web, App, HttpResponse};
+
+let app = App::new().service(
+    web::scope("/{project_id}")
+        .service(web::resource("/path1").to(|| HttpResponse::Ok()))
+        .service(web::resource("/path2").to(|| HttpResponse::Ok()))
+        .service(web::resource("/path3").to(|| HttpResponse::MethodNotAllowed()))
+);
+
\ No newline at end of file diff --git a/actix_web/web/fn.service.html b/actix_web/web/fn.service.html new file mode 100644 index 000000000..b042d52f6 --- /dev/null +++ b/actix_web/web/fn.service.html @@ -0,0 +1,14 @@ +service in actix_web::web - Rust

Function actix_web::web::service

source ·
pub fn service<T: IntoPatterns>(path: T) -> WebService
Expand description

Creates a raw service for a specific path.

+ +
use actix_web::{dev, web, guard, App, Error, HttpResponse};
+
+async fn my_service(req: dev::ServiceRequest) -> Result<dev::ServiceResponse, Error> {
+    Ok(req.into_response(HttpResponse::Ok().finish()))
+}
+
+let app = App::new().service(
+    web::service("/users/*")
+        .guard(guard::Header("content-type", "text/plain"))
+        .finish(my_service)
+);
+
\ No newline at end of file diff --git a/actix_web/web/fn.to.html b/actix_web/web/fn.to.html new file mode 100644 index 000000000..84b234d31 --- /dev/null +++ b/actix_web/web/fn.to.html @@ -0,0 +1,16 @@ +to in actix_web::web - Rust

Function actix_web::web::to

source ·
pub fn to<F, Args>(handler: F) -> Route
where + F: Handler<Args>, + Args: FromRequest + 'static, + F::Output: Responder + 'static,
Expand description

Creates a new any-method route with handler.

+ +
use actix_web::{web, App, HttpResponse, Responder};
+
+async fn index() -> impl Responder {
+   HttpResponse::Ok()
+}
+
+App::new().service(
+    web::resource("/").route(
+        web::to(index))
+);
+
\ No newline at end of file diff --git a/actix_web/web/fn.trace.html b/actix_web/web/fn.trace.html new file mode 100644 index 000000000..86adfc63f --- /dev/null +++ b/actix_web/web/fn.trace.html @@ -0,0 +1,12 @@ +trace in actix_web::web - Rust

Function actix_web::web::trace

source ·
pub fn trace() -> Route
Expand description

Creates a new route with TRACE method guard.

+

§Examples

+

In this example, one TRACE /{project_id} route is set up:

+ +
use actix_web::{web, App, HttpResponse};
+
+let app = App::new().service(
+    web::resource("/{project_id}")
+         .route(web::trace().to(|| HttpResponse::Ok()))
+
+);
+
\ No newline at end of file diff --git a/actix_web/web/index.html b/actix_web/web/index.html new file mode 100644 index 000000000..9edf9a330 --- /dev/null +++ b/actix_web/web/index.html @@ -0,0 +1,22 @@ +actix_web::web - Rust

Module actix_web::web

source ·
Expand description

Essentials helper functions and types for application registration.

+

§Request Extractors

+
    +
  • Data: Application data item
  • +
  • ReqData: Request-local data item
  • +
  • Path: URL path parameters / dynamic segments
  • +
  • Query: URL query parameters
  • +
  • Header: Typed header
  • +
  • Json: JSON payload
  • +
  • Form: URL-encoded payload
  • +
  • Bytes: Raw payload
  • +
+

§Responders

+
    +
  • Json: JSON response
  • +
  • Form: URL-encoded response
  • +
  • Bytes: Raw bytes response
  • +
  • Redirect: Convenient redirect responses
  • +
+

Structs§

  • A cheaply cloneable and sliceable chunk of contiguous memory.
  • A unique reference to a contiguous slice of memory.
  • Application data wrapper and extractor.
  • URL encoded payload extractor and responder.
  • Form extractor configuration.
  • Extract typed headers from the request.
  • JSON extractor and responder.
  • Json extractor configuration.
  • Extract typed data from request path segments.
  • Path extractor configuration
  • Extract a request’s raw payload stream.
  • Configuration for request payloads.
  • Extract typed information from the request’s query.
  • Query extractor configuration.
  • Stream that reads request line by line.
  • An HTTP service for redirecting one path to another path or URL.
  • Request-local data extractor.
  • Enables parts of app configuration to be declared separately from the app itself. Helpful for +modularizing large applications.
  • Future that resolves to some T when parsed from a URL encoded payload.

Enums§

  • Combines two extractor or responder types into a single type.
  • Future that resolves to some T when parsed from a JSON payload.

Traits§

  • Read bytes from a buffer.
  • A trait for values that provide sequential write access to bytes.

Functions§

  • Executes blocking function on a thread pool, returns future that resolves to result of the +function execution.
  • Creates a new route with DELETE method guard.
  • Creates a new route with GET method guard.
  • Creates a new route with HEAD method guard.
  • Creates a new route with specified method guard.
  • Creates a new route with PATCH method guard.
  • Creates a new route with POST method guard.
  • Creates a new route with PUT method guard.
  • Create a relative or absolute redirect.
  • Creates a new resource for a specific path.
  • Creates a new un-configured route.
  • Creates scope for common path prefix.
  • Creates a raw service for a specific path.
  • Creates a new any-method route with handler.
  • Creates a new route with TRACE method guard.
\ No newline at end of file diff --git a/actix_web/web/sidebar-items.js b/actix_web/web/sidebar-items.js new file mode 100644 index 000000000..da2cbbcac --- /dev/null +++ b/actix_web/web/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Either","JsonBody"],"fn":["block","delete","get","head","method","patch","post","put","redirect","resource","route","scope","service","to","trace"],"struct":["Bytes","BytesMut","Data","Form","FormConfig","Header","Json","JsonConfig","Path","PathConfig","Payload","PayloadConfig","Query","QueryConfig","Readlines","Redirect","ReqData","ServiceConfig","UrlEncoded"],"trait":["Buf","BufMut"]}; \ No newline at end of file diff --git a/actix_web/web/struct.Bytes.html b/actix_web/web/struct.Bytes.html new file mode 100644 index 000000000..2a4e93744 --- /dev/null +++ b/actix_web/web/struct.Bytes.html @@ -0,0 +1,1398 @@ +Bytes in actix_web::web - Rust

Struct actix_web::web::Bytes

pub struct Bytes { /* private fields */ }
Expand description

A cheaply cloneable and sliceable chunk of contiguous memory.

+

Bytes is an efficient container for storing and operating on contiguous +slices of memory. It is intended for use primarily in networking code, but +could have applications elsewhere as well.

+

Bytes values facilitate zero-copy network programming by allowing multiple +Bytes objects to point to the same underlying memory.

+

Bytes does not have a single implementation. It is an interface, whose +exact behavior is implemented through dynamic dispatch in several underlying +implementations of Bytes.

+

All Bytes implementations must fulfill the following requirements:

+
    +
  • They are cheaply cloneable and thereby shareable between an unlimited amount +of components, for example by modifying a reference count.
  • +
  • Instances can be sliced to refer to a subset of the original buffer.
  • +
+ +
use bytes::Bytes;
+
+let mut mem = Bytes::from("Hello world");
+let a = mem.slice(0..5);
+
+assert_eq!(a, "Hello");
+
+let b = mem.split_to(6);
+
+assert_eq!(mem, "world");
+assert_eq!(b, "Hello ");
+

§Memory layout

+

The Bytes struct itself is fairly small, limited to 4 usize fields used +to track information about which segment of the underlying memory the +Bytes handle has access to.

+

Bytes keeps both a pointer to the shared state containing the full memory +slice and a pointer to the start of the region visible by the handle. +Bytes also tracks the length of its view into the memory.

+

§Sharing

+

Bytes contains a vtable, which allows implementations of Bytes to define +how sharing/cloning is implemented in detail. +When Bytes::clone() is called, Bytes will call the vtable function for +cloning the backing storage in order to share it behind multiple Bytes +instances.

+

For Bytes implementations which refer to constant memory (e.g. created +via Bytes::from_static()) the cloning implementation will be a no-op.

+

For Bytes implementations which point to a reference counted shared storage +(e.g. an Arc<[u8]>), sharing will be implemented by increasing the +reference count.

+

Due to this mechanism, multiple Bytes instances may point to the same +shared memory region. +Each Bytes instance can point to different sections within that +memory region, and Bytes instances may or may not have overlapping views +into the memory.

+

The following diagram visualizes a scenario where 2 Bytes instances make +use of an Arc-based backing storage, and provide access to different views:

+

+   Arc ptrs                   ┌─────────┐
+   ________________________ / │ Bytes 2 │
+  /                           └─────────┘
+ /          ┌───────────┐     |         |
+|_________/ │  Bytes 1  │     |         |
+|           └───────────┘     |         |
+|           |           | ___/ data     | tail
+|      data |      tail |/              |
+v           v           v               v
+┌─────┬─────┬───────────┬───────────────┬─────┐
+│ Arc │     │           │               │     │
+└─────┴─────┴───────────┴───────────────┴─────┘
+

Implementations§

§

impl Bytes

pub const fn new() -> Bytes

Available on non-loom only.

Creates a new empty Bytes.

+

This will not allocate and the returned Bytes handle will be empty.

+
§Examples
+
use bytes::Bytes;
+
+let b = Bytes::new();
+assert_eq!(&b[..], b"");
+

pub const fn from_static(bytes: &'static [u8]) -> Bytes

Available on non-loom only.

Creates a new Bytes from a static slice.

+

The returned Bytes will point directly to the static slice. There is +no allocating or copying.

+
§Examples
+
use bytes::Bytes;
+
+let b = Bytes::from_static(b"hello");
+assert_eq!(&b[..], b"hello");
+

pub const fn len(&self) -> usize

Returns the number of bytes contained in this Bytes.

+
§Examples
+
use bytes::Bytes;
+
+let b = Bytes::from(&b"hello"[..]);
+assert_eq!(b.len(), 5);
+

pub const fn is_empty(&self) -> bool

Returns true if the Bytes has a length of 0.

+
§Examples
+
use bytes::Bytes;
+
+let b = Bytes::new();
+assert!(b.is_empty());
+

pub fn is_unique(&self) -> bool

Returns true if this is the only reference to the data.

+

Always returns false if the data is backed by a static slice.

+

The result of this method may be invalidated immediately if another +thread clones this value while this is being called. Ensure you have +unique access to this value (&mut Bytes) first if you need to be +certain the result is valid (i.e. for safety reasons)

+
§Examples
+
use bytes::Bytes;
+
+let a = Bytes::from(vec![1, 2, 3]);
+assert!(a.is_unique());
+let b = a.clone();
+assert!(!a.is_unique());
+

pub fn copy_from_slice(data: &[u8]) -> Bytes

Creates Bytes instance from slice, by copying it.

+

pub fn slice(&self, range: impl RangeBounds<usize>) -> Bytes

Returns a slice of self for the provided range.

+

This will increment the reference count for the underlying memory and +return a new Bytes handle set to the slice.

+

This operation is O(1).

+
§Examples
+
use bytes::Bytes;
+
+let a = Bytes::from(&b"hello world"[..]);
+let b = a.slice(2..5);
+
+assert_eq!(&b[..], b"llo");
+
§Panics
+

Requires that begin <= end and end <= self.len(), otherwise slicing +will panic.

+

pub fn slice_ref(&self, subset: &[u8]) -> Bytes

Returns a slice of self that is equivalent to the given subset.

+

When processing a Bytes buffer with other tools, one often gets a +&[u8] which is in fact a slice of the Bytes, i.e. a subset of it. +This function turns that &[u8] into another Bytes, as if one had +called self.slice() with the offsets that correspond to subset.

+

This operation is O(1).

+
§Examples
+
use bytes::Bytes;
+
+let bytes = Bytes::from(&b"012345678"[..]);
+let as_slice = bytes.as_ref();
+let subset = &as_slice[2..6];
+let subslice = bytes.slice_ref(&subset);
+assert_eq!(&subslice[..], b"2345");
+
§Panics
+

Requires that the given sub slice is in fact contained within the +Bytes buffer; otherwise this function will panic.

+

pub fn split_off(&mut self, at: usize) -> Bytes

Splits the bytes into two at the given index.

+

Afterwards self contains elements [0, at), and the returned Bytes +contains elements [at, len).

+

This is an O(1) operation that just increases the reference count and +sets a few indices.

+
§Examples
+
use bytes::Bytes;
+
+let mut a = Bytes::from(&b"hello world"[..]);
+let b = a.split_off(5);
+
+assert_eq!(&a[..], b"hello");
+assert_eq!(&b[..], b" world");
+
§Panics
+

Panics if at > len.

+

pub fn split_to(&mut self, at: usize) -> Bytes

Splits the bytes into two at the given index.

+

Afterwards self contains elements [at, len), and the returned +Bytes contains elements [0, at).

+

This is an O(1) operation that just increases the reference count and +sets a few indices.

+
§Examples
+
use bytes::Bytes;
+
+let mut a = Bytes::from(&b"hello world"[..]);
+let b = a.split_to(5);
+
+assert_eq!(&a[..], b" world");
+assert_eq!(&b[..], b"hello");
+
§Panics
+

Panics if at > len.

+

pub fn truncate(&mut self, len: usize)

Shortens the buffer, keeping the first len bytes and dropping the +rest.

+

If len is greater than the buffer’s current length, this has no +effect.

+

The split_off method can emulate truncate, but this causes the +excess bytes to be returned instead of dropped.

+
§Examples
+
use bytes::Bytes;
+
+let mut buf = Bytes::from(&b"hello world"[..]);
+buf.truncate(5);
+assert_eq!(buf, b"hello"[..]);
+

pub fn clear(&mut self)

Clears the buffer, removing all data.

+
§Examples
+
use bytes::Bytes;
+
+let mut buf = Bytes::from(&b"hello world"[..]);
+buf.clear();
+assert!(buf.is_empty());
+

Methods from Deref<Target = [u8]>§

1.80.0 · source

pub fn as_flattened(&self) -> &[T]

Takes a &[[T; N]], and flattens it to a &[T].

+
§Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
§Examples
+
assert_eq!([[1, 2, 3], [4, 5, 6]].as_flattened(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+    [[1, 2, 3], [4, 5, 6]].as_flattened(),
+    [[1, 2], [3, 4], [5, 6]].as_flattened(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.as_flattened().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.as_flattened().is_empty());
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the slice.

+
§Examples
+
let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the slice has a length of 0.

+
§Examples
+
let a = [1, 2, 3];
+assert!(!a.is_empty());
+
+let b: &[i32] = &[];
+assert!(b.is_empty());
+
1.0.0 · source

pub fn first(&self) -> Option<&T>

Returns the first element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
+
1.5.0 · source

pub fn split_first(&self) -> Option<(&T, &[T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first() {
+    assert_eq!(first, &0);
+    assert_eq!(elements, &[1, 2]);
+}
+
1.5.0 · source

pub fn split_last(&self) -> Option<(&T, &[T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+    assert_eq!(last, &2);
+    assert_eq!(elements, &[0, 1]);
+}
+
1.0.0 · source

pub fn last(&self) -> Option<&T>

Returns the last element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
+
1.77.0 · source

pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the first N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.first_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.first_chunk::<0>());
+
1.77.0 · source

pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

Return an array reference to the first N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk::<2>() {
+    assert_eq!(first, &[0, 1]);
+    assert_eq!(elements, &[2]);
+}
+
+assert_eq!(None, x.split_first_chunk::<4>());
+
1.77.0 · source

pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>

Return an array reference to the last N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((elements, last)) = x.split_last_chunk::<2>() {
+    assert_eq!(elements, &[0]);
+    assert_eq!(last, &[1, 2]);
+}
+
+assert_eq!(None, x.split_last_chunk::<4>());
+
1.77.0 · source

pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the last N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.last_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.last_chunk::<0>());
+
1.0.0 · source

pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice depending on the type of +index.

+
    +
  • If given a position, returns a reference to the element at that +position or None if out of bounds.
  • +
  • If given a range, returns the subslice corresponding to that range, +or None if out of bounds.
  • +
+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
+
1.0.0 · source

pub unsafe fn get_unchecked<I>( + &self, + index: I +) -> &<I as SliceIndex<[T]>>::Output
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice, without doing bounds +checking.

+

For a safe alternative see get.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get(index).unwrap_unchecked(). It’s UB +to call .get_unchecked(len), even if you immediately convert to a +pointer. And it’s UB to call .get_unchecked(..len + 1), +.get_unchecked(..=len), or similar.

+
§Examples
+
let x = &[1, 2, 4];
+
+unsafe {
+    assert_eq!(x.get_unchecked(1), &2);
+}
+
1.0.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
§Examples
+
let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+    }
+}
+
1.48.0 · source

pub fn as_ptr_range(&self) -> Range<*const T>

Returns the two raw pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_ptr for warnings on using these pointers. The end pointer +requires extra caution, as it does not point to a valid element in the +slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+

It can also be useful to check if a pointer to an element refers to an +element of this slice:

+ +
let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
+
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
+
1.0.0 · source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the slice.

+

The iterator yields all items from start to end.

+
§Examples
+
let x = &[1, 2, 4];
+let mut iterator = x.iter();
+
+assert_eq!(iterator.next(), Some(&1));
+assert_eq!(iterator.next(), Some(&2));
+assert_eq!(iterator.next(), Some(&4));
+assert_eq!(iterator.next(), None);
+
1.0.0 · source

pub fn windows(&self, size: usize) -> Windows<'_, T>

Returns an iterator over all contiguous windows of length +size. The windows overlap. If the slice is shorter than +size, the iterator returns no values.

+
§Panics
+

Panics if size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.windows(3);
+assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']);
+assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']);
+assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']);
+assert!(iter.next().is_none());
+

If the slice is shorter than size:

+ +
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
+

There’s no windows_mut, as that existing would let safe code violate the +“only one &mut at a time to the same thing” rule. However, you can sometimes +use Cell::as_slice_of_cells in +conjunction with windows to accomplish something similar:

+ +
use std::cell::Cell;
+
+let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
+let slice = &mut array[..];
+let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
+for w in slice_of_cells.windows(3) {
+    Cell::swap(&w[0], &w[2]);
+}
+assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
+
1.0.0 · source

pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See chunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and rchunks for the same iterator but starting at the end of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks.

+

See chunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
source

pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
§Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
§Examples
+
#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+
source

pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
+

If you expect the slice to be an exact multiple, you can combine +let-else with an empty slice pattern:

+ +
#![feature(slice_as_chunks)]
+let slice = ['R', 'u', 's', 't'];
+let (chunks, []) = slice.as_chunks::<2>() else {
+    panic!("slice didn't have even length")
+};
+assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
+
source

pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+
source

pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are array references and do not overlap. If N does not divide the +length of the slice, then the last up to N-1 elements will be omitted and can be +retrieved from the remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
source

pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>

🔬This is a nightly-only experimental API. (array_windows)

Returns an iterator over overlapping windows of N elements of a slice, +starting at the beginning of the slice.

+

This is the const generic equivalent of windows.

+

If N is greater than the size of the slice, it will return no windows.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and chunks for the same iterator but starting at the beginning +of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +end of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of rchunks.

+

See rchunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and chunks_exact for the same iterator but starting at the beginning of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
+
1.77.0 · source

pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
where + F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping runs +of elements using the predicate to separate them.

+

The predicate is called for every pair of consecutive elements, +meaning that it is called on slice[0] and slice[1], +followed by slice[1] and slice[2], and so on.

+
§Examples
+
let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.chunk_by(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.chunk_by(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.0.0 · source

pub fn split_at(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
§Panics
+

Panics if mid > len. For a non-panicking alternative see +split_at_checked.

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+{
+   let (left, right) = v.split_at(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.79.0 · source

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+unsafe {
+   let (left, right) = v.split_at_unchecked(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.80.0 · source

pub fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])>

Divides one slice into two at an index, returning None if the slice is +too short.

+

If mid ≤ len returns a pair of slices where the first will contain all +indices from [0, mid) (excluding the index mid itself) and the +second will contain all indices from [mid, len) (excluding the index +len itself).

+

Otherwise, if mid > len, returns None.

+
§Examples
+
let v = [1, -2, 3, -4, 5, -6];
+
+{
+   let (left, right) = v.split_at_checked(0).unwrap();
+   assert_eq!(left, []);
+   assert_eq!(right, [1, -2, 3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(2).unwrap();
+    assert_eq!(left, [1, -2]);
+    assert_eq!(right, [3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(6).unwrap();
+    assert_eq!(left, [1, -2, 3, -4, 5, -6]);
+    assert_eq!(right, []);
+}
+
+assert_eq!(None, v.split_at_checked(7));
+
1.0.0 · source

pub fn split<F>(&self, pred: F) -> Split<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is not contained in the subslices.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the first element is matched, an empty slice will be the first item +returned by the iterator. Similarly, if the last element in the slice +is matched, an empty slice will be the last item returned by the +iterator:

+ +
let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
+

If two matched elements are directly adjacent, an empty slice will be +present between them:

+ +
let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+
1.51.0 · source

pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is contained in the end of the previous +subslice as a terminator.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the last element of the slice is matched, +that element will be considered the terminator of the preceding slice. +That slice will be the last item returned by the iterator.

+ +
let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
+
1.27.0 · source

pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, starting at the end of the slice and working backwards. +The matched element is not contained in the subslices.

+
§Examples
+
let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
+
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
+

As with split(), if the first or last element is matched, an empty +slice will be the first (or last) item returned by the iterator.

+ +
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
+
1.0.0 · source

pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], +[20, 60, 50]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once, starting from the end, by numbers divisible +by 3 (i.e., [50], [10, 40, 30, 20]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
source

pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the first element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.split_once(|&x| x == 2), Some((
+    &[1][..],
+    &[3, 2, 4][..]
+)));
+assert_eq!(s.split_once(|&x| x == 0), None);
+
source

pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the last element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.rsplit_once(|&x| x == 2), Some((
+    &[1, 2, 3][..],
+    &[4][..]
+)));
+assert_eq!(s.rsplit_once(|&x| x == 0), None);
+
1.0.0 · source

pub fn contains(&self, x: &T) -> bool
where + T: PartialEq,

Returns true if the slice contains an element with the given value.

+

This operation is O(n).

+

Note that if you have a sorted slice, binary_search may be faster.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
+

If you do not have a &T, but some other value that you can compare +with one (for example, String implements PartialEq<str>), you can +use iter().any:

+ +
let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
+
1.0.0 · source

pub fn starts_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a prefix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(v.starts_with(&v));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
+
1.0.0 · source

pub fn ends_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a suffix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(v.ends_with(&v));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
+
1.51.0 · source

pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the prefix removed.

+

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. +If prefix is empty, simply returns the original slice. If prefix is equal to the +original slice, returns an empty slice.

+

If the slice does not start with prefix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
+
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+           Some(b"llo".as_ref()));
+
1.51.0 · source

pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the suffix removed.

+

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. +If suffix is empty, simply returns the original slice. If suffix is equal to the +original slice, returns an empty slice.

+

If the slice does not end with suffix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
+

Binary searches this slice for a given element. +If the slice is not sorted, the returned result is unspecified and +meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search_by, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+assert_eq!(s.binary_search(&13),  Ok(9));
+assert_eq!(s.binary_search(&4),   Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

If you want to find that whole range of matching items, rather than +an arbitrary matching one, that can be done using partition_point:

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
+

If you want to insert an item to a sorted vector, while maintaining +sort order, consider using partition_point:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+// If `num` is unique, `s.partition_point(|&x| x < num)` (with `<`) is equivalent to
+// `s.binary_search(&num).unwrap_or_else(|x| x)`, but using `<=` will allow `insert`
+// to shift less elements.
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
1.0.0 · source

pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
where + F: FnMut(&'a T) -> Ordering,

Binary searches this slice with a comparator function.

+

The comparator function should return an order code that indicates +whether its argument is Less, Equal or Greater the desired +target. +If the slice is not sorted or if the comparator function does not +implement an order consistent with the sort order of the underlying +slice, the returned result is unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.10.0 · source

pub fn binary_search_by_key<'a, B, F>( + &'a self, + b: &B, + f: F +) -> Result<usize, usize>
where + F: FnMut(&'a T) -> B, + B: Ord,

Binary searches this slice with a key extraction function.

+

Assumes that the slice is sorted by the key, for instance with +sort_by_key using the same key extraction function. +If the slice is not sorted by the key, the returned result is +unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by, and partition_point.

+
§Examples
+

Looks up a series of four elements in a slice of pairs sorted by +their second elements. The first is found, with a uniquely +determined position; the second and third are not found; the +fourth could match any position in [1, 4].

+ +
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+         (1, 21), (2, 34), (4, 55)];
+
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.30.0 · source

pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

Transmute the slice to a slice of another type, ensuring alignment of the types is +maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The middle part will be as big as possible under +the given alignment constraint and element size.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
§Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
§Examples
+

Basic usage:

+ +
unsafe {
+    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
source

pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
where + Simd<T, LANES>: AsRef<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.

+

This is a safe wrapper around slice::align_to, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+
§Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
§Examples
+
#![feature(portable_simd)]
+use core::simd::prelude::*;
+
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
+
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+
+fn basic_simd_sum(x: &[f32]) -> f32 {
+    use std::ops::Add;
+    let (prefix, middle, suffix) = x.as_simd();
+    let sums = f32x4::from_array([
+        prefix.iter().copied().sum(),
+        0.0,
+        0.0,
+        suffix.iter().copied().sum(),
+    ]);
+    let sums = middle.iter().copied().fold(sums, f32x4::add);
+    sums.reduce_sum()
+}
+
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+
source

pub fn is_sorted(&self) -> bool
where + T: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted.

+

That is, for each element a and its following element b, a <= b must hold. If the +slice yields exactly zero or one element, true is returned.

+

Note that if Self::Item is only PartialOrd, but not Ord, the above definition +implies that this function returns false if any two consecutive items are not +comparable.

+
§Examples
+
#![feature(is_sorted)]
+let empty: [i32; 0] = [];
+
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
+
source

pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> bool
where + F: FnMut(&'a T, &'a T) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given comparator function.

+

Instead of using PartialOrd::partial_cmp, this function uses the given compare +function to determine whether two elements are to be considered in sorted order.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!([1, 2, 2, 9].is_sorted_by(|a, b| a <= b));
+assert!(![1, 2, 2, 9].is_sorted_by(|a, b| a < b));
+
+assert!([0].is_sorted_by(|a, b| true));
+assert!([0].is_sorted_by(|a, b| false));
+
+let empty: [i32; 0] = [];
+assert!(empty.is_sorted_by(|a, b| false));
+assert!(empty.is_sorted_by(|a, b| true));
+
source

pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
where + F: FnMut(&'a T) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given key extraction function.

+

Instead of comparing the slice’s elements directly, this function compares the keys of the +elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its +documentation for more information.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+
1.52.0 · source

pub fn partition_point<P>(&self, pred: P) -> usize
where + P: FnMut(&T) -> bool,

Returns the index of the partition point according to the given predicate +(the index of the first element of the second partition).

+

The slice is assumed to be partitioned according to the given predicate. +This means that all elements for which the predicate returns true are at the start of the slice +and all elements for which the predicate returns false are at the end. +For example, [7, 15, 3, 5, 4, 12, 6] is partitioned under the predicate x % 2 != 0 +(all odd numbers are at the start, all even at the end).

+

If this slice is not partitioned, the returned result is unspecified and meaningless, +as this method performs a kind of binary search.

+

See also binary_search, binary_search_by, and binary_search_by_key.

+
§Examples
+
let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
+
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
+

If all elements of the slice match the predicate, including if the slice +is empty, then the length of the slice will be returned:

+ +
let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
+

If you want to insert an item to a sorted vector, while maintaining +sort order:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
1.79.0 · source

pub fn utf8_chunks(&self) -> Utf8Chunks<'_>

Creates an iterator over the contiguous valid UTF-8 ranges of this +slice, and the non-UTF-8 fragments in between.

+
§Examples
+

This function formats arbitrary but mostly-UTF-8 bytes into Rust source +code in the form of a C-string literal (c"...").

+ +
use std::fmt::Write as _;
+
+pub fn cstr_literal(bytes: &[u8]) -> String {
+    let mut repr = String::new();
+    repr.push_str("c\"");
+    for chunk in bytes.utf8_chunks() {
+        for ch in chunk.valid().chars() {
+            // Escapes \0, \t, \r, \n, \\, \', \", and uses \u{...} for non-printable characters.
+            write!(repr, "{}", ch.escape_debug()).unwrap();
+        }
+        for byte in chunk.invalid() {
+            write!(repr, "\\x{:02X}", byte).unwrap();
+        }
+    }
+    repr.push('"');
+    repr
+}
+
+fn main() {
+    let lit = cstr_literal(b"\xferris the \xf0\x9f\xa6\x80\x07");
+    let expected = stringify!(c"\xFErris the 🦀\u{7}");
+    assert_eq!(lit, expected);
+}
+
1.23.0 · source

pub fn is_ascii(&self) -> bool

Checks if all bytes in this slice are within the ASCII range.

+
source

pub fn as_ascii(&self) -> Option<&[AsciiChar]>

🔬This is a nightly-only experimental API. (ascii_char)

If this slice is_ascii, returns it as a slice of +ASCII characters, otherwise returns None.

+
source

pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]

🔬This is a nightly-only experimental API. (ascii_char)

Converts this slice of bytes into a slice of ASCII characters, +without checking whether they’re valid.

+
§Safety
+

Every byte in the slice must be in 0..=127, or else this is UB.

+
1.23.0 · source

pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool

Checks that two slices are an ASCII case-insensitive match.

+

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), +but without allocating and copying temporaries.

+
1.60.0 · source

pub fn escape_ascii(&self) -> EscapeAscii<'_>

Returns an iterator that produces an escaped version of this slice, +treating it as an ASCII string.

+
§Examples
+

+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
+
1.80.0 · source

pub fn trim_ascii_start(&self) -> &[u8]

Returns a byte slice with leading ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b"  ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
+
1.80.0 · source

pub fn trim_ascii_end(&self) -> &[u8]

Returns a byte slice with trailing ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b"  ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
+
1.80.0 · source

pub fn trim_ascii(&self) -> &[u8]

Returns a byte slice with leading and trailing ASCII whitespace bytes +removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b"  ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
+
source

pub fn as_str(&self) -> &str

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a UTF-8 str.

+
source

pub fn as_bytes(&self) -> &[u8]

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a slice of u8 bytes.

+
1.0.0 · source

pub fn to_vec(&self) -> Vec<T>
where + T: Clone,

Available on non-no_global_oom_handling only.

Copies self into a new Vec.

+
§Examples
+
let s = [10, 40, 30];
+let x = s.to_vec();
+// Here, `s` and `x` can be modified independently.
+
source

pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>
where + A: Allocator, + T: Clone,

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Copies self into a new Vec with an allocator.

+
§Examples
+
#![feature(allocator_api)]
+
+use std::alloc::System;
+
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
+// Here, `s` and `x` can be modified independently.
+
1.40.0 · source

pub fn repeat(&self, n: usize) -> Vec<T>
where + T: Copy,

Available on non-no_global_oom_handling only.

Creates a vector by copying a slice n times.

+
§Panics
+

This function will panic if the capacity would overflow.

+
§Examples
+

Basic usage:

+ +
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
+

A panic upon overflow:

+ +
// this will panic at runtime
+b"0123456789abcdef".repeat(usize::MAX);
+
1.0.0 · source

pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output
where + [T]: Concat<Item>, + Item: ?Sized,

Flattens a slice of T into a single value Self::Output.

+
§Examples
+
assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+
1.3.0 · source

pub fn join<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+
1.0.0 · source

pub fn connect<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

👎Deprecated since 1.3.0: renamed to join

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+
1.23.0 · source

pub fn to_ascii_uppercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII upper case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To uppercase the value in-place, use make_ascii_uppercase.

+
1.23.0 · source

pub fn to_ascii_lowercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII lower case equivalent.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To lowercase the value in-place, use make_ascii_lowercase.

+

Trait Implementations§

§

impl AsRef<[u8]> for Bytes

§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
§

impl Borrow<[u8]> for Bytes

§

fn borrow(&self) -> &[u8]

Immutably borrows from an owned value. Read more
§

impl Buf for Bytes

§

fn remaining(&self) -> usize

Returns the number of bytes between the current position and the end of +the buffer. Read more
§

fn chunk(&self) -> &[u8]

Returns a slice starting at the current position and of length between 0 +and Buf::remaining(). Note that this can return shorter slice (this allows +non-continuous internal representation). Read more
§

fn advance(&mut self, cnt: usize)

Advance the internal cursor of the Buf Read more
§

fn copy_to_bytes(&mut self, len: usize) -> Bytes

Consumes len bytes inside self and returns new instance of Bytes +with this data. Read more
§

fn chunks_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize

Available on crate feature std only.
Fills dst with potentially multiple slices starting at self’s +current position. Read more
§

fn has_remaining(&self) -> bool

Returns true if there are any more bytes to consume Read more
§

fn copy_to_slice(&mut self, dst: &mut [u8])

Copies bytes from self into dst. Read more
§

fn get_u8(&mut self) -> u8

Gets an unsigned 8 bit integer from self. Read more
§

fn get_i8(&mut self) -> i8

Gets a signed 8 bit integer from self. Read more
§

fn get_u16(&mut self) -> u16

Gets an unsigned 16 bit integer from self in big-endian byte order. Read more
§

fn get_u16_le(&mut self) -> u16

Gets an unsigned 16 bit integer from self in little-endian byte order. Read more
§

fn get_u16_ne(&mut self) -> u16

Gets an unsigned 16 bit integer from self in native-endian byte order. Read more
§

fn get_i16(&mut self) -> i16

Gets a signed 16 bit integer from self in big-endian byte order. Read more
§

fn get_i16_le(&mut self) -> i16

Gets a signed 16 bit integer from self in little-endian byte order. Read more
§

fn get_i16_ne(&mut self) -> i16

Gets a signed 16 bit integer from self in native-endian byte order. Read more
§

fn get_u32(&mut self) -> u32

Gets an unsigned 32 bit integer from self in the big-endian byte order. Read more
§

fn get_u32_le(&mut self) -> u32

Gets an unsigned 32 bit integer from self in the little-endian byte order. Read more
§

fn get_u32_ne(&mut self) -> u32

Gets an unsigned 32 bit integer from self in native-endian byte order. Read more
§

fn get_i32(&mut self) -> i32

Gets a signed 32 bit integer from self in big-endian byte order. Read more
§

fn get_i32_le(&mut self) -> i32

Gets a signed 32 bit integer from self in little-endian byte order. Read more
§

fn get_i32_ne(&mut self) -> i32

Gets a signed 32 bit integer from self in native-endian byte order. Read more
§

fn get_u64(&mut self) -> u64

Gets an unsigned 64 bit integer from self in big-endian byte order. Read more
§

fn get_u64_le(&mut self) -> u64

Gets an unsigned 64 bit integer from self in little-endian byte order. Read more
§

fn get_u64_ne(&mut self) -> u64

Gets an unsigned 64 bit integer from self in native-endian byte order. Read more
§

fn get_i64(&mut self) -> i64

Gets a signed 64 bit integer from self in big-endian byte order. Read more
§

fn get_i64_le(&mut self) -> i64

Gets a signed 64 bit integer from self in little-endian byte order. Read more
§

fn get_i64_ne(&mut self) -> i64

Gets a signed 64 bit integer from self in native-endian byte order. Read more
§

fn get_u128(&mut self) -> u128

Gets an unsigned 128 bit integer from self in big-endian byte order. Read more
§

fn get_u128_le(&mut self) -> u128

Gets an unsigned 128 bit integer from self in little-endian byte order. Read more
§

fn get_u128_ne(&mut self) -> u128

Gets an unsigned 128 bit integer from self in native-endian byte order. Read more
§

fn get_i128(&mut self) -> i128

Gets a signed 128 bit integer from self in big-endian byte order. Read more
§

fn get_i128_le(&mut self) -> i128

Gets a signed 128 bit integer from self in little-endian byte order. Read more
§

fn get_i128_ne(&mut self) -> i128

Gets a signed 128 bit integer from self in native-endian byte order. Read more
§

fn get_uint(&mut self, nbytes: usize) -> u64

Gets an unsigned n-byte integer from self in big-endian byte order. Read more
§

fn get_uint_le(&mut self, nbytes: usize) -> u64

Gets an unsigned n-byte integer from self in little-endian byte order. Read more
§

fn get_uint_ne(&mut self, nbytes: usize) -> u64

Gets an unsigned n-byte integer from self in native-endian byte order. Read more
§

fn get_int(&mut self, nbytes: usize) -> i64

Gets a signed n-byte integer from self in big-endian byte order. Read more
§

fn get_int_le(&mut self, nbytes: usize) -> i64

Gets a signed n-byte integer from self in little-endian byte order. Read more
§

fn get_int_ne(&mut self, nbytes: usize) -> i64

Gets a signed n-byte integer from self in native-endian byte order. Read more
§

fn get_f32(&mut self) -> f32

Gets an IEEE754 single-precision (4 bytes) floating point number from +self in big-endian byte order. Read more
§

fn get_f32_le(&mut self) -> f32

Gets an IEEE754 single-precision (4 bytes) floating point number from +self in little-endian byte order. Read more
§

fn get_f32_ne(&mut self) -> f32

Gets an IEEE754 single-precision (4 bytes) floating point number from +self in native-endian byte order. Read more
§

fn get_f64(&mut self) -> f64

Gets an IEEE754 double-precision (8 bytes) floating point number from +self in big-endian byte order. Read more
§

fn get_f64_le(&mut self) -> f64

Gets an IEEE754 double-precision (8 bytes) floating point number from +self in little-endian byte order. Read more
§

fn get_f64_ne(&mut self) -> f64

Gets an IEEE754 double-precision (8 bytes) floating point number from +self in native-endian byte order. Read more
§

fn take(self, limit: usize) -> Take<Self>
where + Self: Sized,

Creates an adaptor which will read at most limit bytes from self. Read more
§

fn chain<U>(self, next: U) -> Chain<Self, U>
where + U: Buf, + Self: Sized,

Creates an adaptor which will chain this buffer with another. Read more
§

fn reader(self) -> Reader<Self>
where + Self: Sized,

Available on crate feature std only.
Creates an adaptor which implements the Read trait for self. Read more
§

impl Clone for Bytes

§

fn clone(&self) -> Bytes

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Bytes

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for Bytes

§

fn default() -> Bytes

Returns the “default value” for a type. Read more
§

impl Deref for Bytes

§

type Target = [u8]

The resulting type after dereferencing.
§

fn deref(&self) -> &[u8]

Dereferences the value.
§

impl Drop for Bytes

§

fn drop(&mut self)

Executes the destructor for this type. Read more
§

impl Extend<Bytes> for BytesMut

§

fn extend<T>(&mut self, iter: T)
where + T: IntoIterator<Item = Bytes>,

Extends a collection with the contents of an iterator. Read more
source§

fn extend_one(&mut self, item: A)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
§

impl From<&'static [u8]> for Bytes

§

fn from(slice: &'static [u8]) -> Bytes

Converts to this type from the input type.
§

impl From<&'static str> for Bytes

§

fn from(slice: &'static str) -> Bytes

Converts to this type from the input type.
§

impl From<Box<[u8]>> for Bytes

§

fn from(slice: Box<[u8]>) -> Bytes

Converts to this type from the input type.
source§

impl From<ByteStr> for Bytes

source§

fn from(src: ByteStr) -> Bytes

Converts to this type from the input type.
§

impl From<ByteStr> for Bytes

§

fn from(src: ByteStr) -> Bytes

Converts to this type from the input type.
source§

impl From<Bytes> for Response<Bytes>

source§

fn from(val: Bytes) -> Response<Bytes>

Converts to this type from the input type.
§

impl From<Bytes> for Vec<u8>

§

fn from(bytes: Bytes) -> Vec<u8>

Converts to this type from the input type.
§

impl From<BytesMut> for Bytes

§

fn from(src: BytesMut) -> Bytes

Converts to this type from the input type.
source§

impl From<Custom> for Bytes

source§

fn from(_: Custom) -> Bytes

Converts to this type from the input type.
§

impl From<Custom> for Bytes

§

fn from(_: Custom) -> Bytes

Converts to this type from the input type.
§

impl From<String> for Bytes

§

fn from(s: String) -> Bytes

Converts to this type from the input type.
§

impl From<Vec<u8>> for Bytes

§

fn from(vec: Vec<u8>) -> Bytes

Converts to this type from the input type.
§

impl FromIterator<u8> for Bytes

§

fn from_iter<T>(into_iter: T) -> Bytes
where + T: IntoIterator<Item = u8>,

Creates a value from an iterator. Read more
source§

impl FromRequest for Bytes

Extract binary data from a request’s payload.

+

Collects request payload stream into a Bytes instance.

+

Use PayloadConfig to configure extraction process.

+

§Examples

+
use actix_web::{post, web};
+
+/// extract binary data from request
+#[post("/")]
+async fn index(body: web::Bytes) -> String {
+    format!("Body {:?}!", body)
+}
+
§

type Error = Error

The associated error which can be returned.
§

type Future = Either<BytesExtractFut, Ready<Result<Bytes, Error>>>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more
§

impl Hash for Bytes

§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl<'a> IntoIterator for &'a Bytes

§

type Item = &'a u8

The type of the elements being iterated over.
§

type IntoIter = Iter<'a, u8>

Which kind of iterator are we turning this into?
§

fn into_iter(self) -> <&'a Bytes as IntoIterator>::IntoIter

Creates an iterator from a value. Read more
§

impl IntoIterator for Bytes

§

type Item = u8

The type of the elements being iterated over.
§

type IntoIter = IntoIter<Bytes>

Which kind of iterator are we turning this into?
§

fn into_iter(self) -> <Bytes as IntoIterator>::IntoIter

Creates an iterator from a value. Read more
§

impl IoBuf for Bytes

Available on crate feature bytes only.
§

fn stable_ptr(&self) -> *const u8

Returns a raw pointer to the vector’s buffer. Read more
§

fn bytes_init(&self) -> usize

Number of initialized bytes. Read more
§

fn bytes_total(&self) -> usize

Total size of the buffer, including uninitialized memory, if any. Read more
§

fn slice(self, range: impl RangeBounds<usize>) -> Slice<Self>
where + Self: Sized,

Returns a view of the buffer with the specified range. Read more
§

impl LowerHex for Bytes

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl MessageBody for Bytes

§

type Error = Infallible

The type of error that will be returned if streaming body fails. Read more
source§

fn size(&self) -> BodySize

Body size hint. Read more
source§

fn poll_next( + self: Pin<&mut Bytes>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <Bytes as MessageBody>::Error>>>

Attempt to pull out the next chunk of body bytes. Read more
source§

fn try_into_bytes(self) -> Result<Bytes, Bytes>

Try to convert into the complete chunk of body bytes. Read more
source§

fn boxed(self) -> BoxBody
where + Self: Sized + 'static,

Wraps this body into a BoxBody. Read more
§

impl Ord for Bytes

§

fn cmp(&self, other: &Bytes) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
§

impl<'a, T> PartialEq<&'a T> for Bytes
where + Bytes: PartialEq<T>, + T: ?Sized,

§

fn eq(&self, other: &&'a T) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<[u8]> for Bytes

§

fn eq(&self, other: &[u8]) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<Bytes> for &[u8]

§

fn eq(&self, other: &Bytes) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<Bytes> for &str

§

fn eq(&self, other: &Bytes) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<Bytes> for [u8]

§

fn eq(&self, other: &Bytes) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<Bytes> for BytesMut

§

fn eq(&self, other: &Bytes) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<Bytes> for Vec<u8>

§

fn eq(&self, other: &Bytes) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<Bytes> for str

§

fn eq(&self, other: &Bytes) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<BytesMut> for Bytes

§

fn eq(&self, other: &BytesMut) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<String> for Bytes

§

fn eq(&self, other: &String) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<Vec<u8>> for Bytes

§

fn eq(&self, other: &Vec<u8>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<str> for Bytes

§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq for Bytes

§

fn eq(&self, other: &Bytes) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, T> PartialOrd<&'a T> for Bytes
where + Bytes: PartialOrd<T>, + T: ?Sized,

§

fn partial_cmp(&self, other: &&'a T) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<[u8]> for Bytes

§

fn partial_cmp(&self, other: &[u8]) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<Bytes> for &[u8]

§

fn partial_cmp(&self, other: &Bytes) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<Bytes> for &str

§

fn partial_cmp(&self, other: &Bytes) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<Bytes> for [u8]

§

fn partial_cmp(&self, other: &Bytes) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<Bytes> for Vec<u8>

§

fn partial_cmp(&self, other: &Bytes) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<Bytes> for str

§

fn partial_cmp(&self, other: &Bytes) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<String> for Bytes

§

fn partial_cmp(&self, other: &String) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<Vec<u8>> for Bytes

§

fn partial_cmp(&self, other: &Vec<u8>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<str> for Bytes

§

fn partial_cmp(&self, other: &str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd for Bytes

§

fn partial_cmp(&self, other: &Bytes) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl Responder for Bytes

§

type Body = Bytes

source§

fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body>

Convert self to HttpResponse.
source§

fn customize(self) -> CustomizeResponder<Self>
where + Self: Sized,

Wraps responder to allow alteration of its response. Read more
source§

impl TryIntoHeaderValue for Bytes

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_into_value( + self +) -> Result<HeaderValue, <Bytes as TryIntoHeaderValue>::Error>

Try to convert value to a HeaderValue.
§

impl UpperHex for Bytes

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Eq for Bytes

§

impl Send for Bytes

§

impl Sync for Bytes

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/web/struct.BytesMut.html b/actix_web/web/struct.BytesMut.html new file mode 100644 index 000000000..ac9018feb --- /dev/null +++ b/actix_web/web/struct.BytesMut.html @@ -0,0 +1,2826 @@ +BytesMut in actix_web::web - Rust

Struct actix_web::web::BytesMut

pub struct BytesMut { /* private fields */ }
Expand description

A unique reference to a contiguous slice of memory.

+

BytesMut represents a unique view into a potentially shared memory region. +Given the uniqueness guarantee, owners of BytesMut handles are able to +mutate the memory.

+

BytesMut can be thought of as containing a buf: Arc<Vec<u8>>, an offset +into buf, a slice length, and a guarantee that no other BytesMut for the +same buf overlaps with its slice. That guarantee means that a write lock +is not required.

+

§Growth

+

BytesMut’s BufMut implementation will implicitly grow its buffer as +necessary. However, explicitly reserving the required space up-front before +a series of inserts will be more efficient.

+

§Examples

+
use bytes::{BytesMut, BufMut};
+
+let mut buf = BytesMut::with_capacity(64);
+
+buf.put_u8(b'h');
+buf.put_u8(b'e');
+buf.put(&b"llo"[..]);
+
+assert_eq!(&buf[..], b"hello");
+
+// Freeze the buffer so that it can be shared
+let a = buf.freeze();
+
+// This does not allocate, instead `b` points to the same memory.
+let b = a.clone();
+
+assert_eq!(&a[..], b"hello");
+assert_eq!(&b[..], b"hello");
+

Implementations§

§

impl BytesMut

pub fn with_capacity(capacity: usize) -> BytesMut

Creates a new BytesMut with the specified capacity.

+

The returned BytesMut will be able to hold at least capacity bytes +without reallocating.

+

It is important to note that this function does not specify the length +of the returned BytesMut, but only the capacity.

+
§Examples
+
use bytes::{BytesMut, BufMut};
+
+let mut bytes = BytesMut::with_capacity(64);
+
+// `bytes` contains no data, even though there is capacity
+assert_eq!(bytes.len(), 0);
+
+bytes.put(&b"hello world"[..]);
+
+assert_eq!(&bytes[..], b"hello world");
+

pub fn new() -> BytesMut

Creates a new BytesMut with default capacity.

+

Resulting object has length 0 and unspecified capacity. +This function does not allocate.

+
§Examples
+
use bytes::{BytesMut, BufMut};
+
+let mut bytes = BytesMut::new();
+
+assert_eq!(0, bytes.len());
+
+bytes.reserve(2);
+bytes.put_slice(b"xy");
+
+assert_eq!(&b"xy"[..], &bytes[..]);
+

pub fn len(&self) -> usize

Returns the number of bytes contained in this BytesMut.

+
§Examples
+
use bytes::BytesMut;
+
+let b = BytesMut::from(&b"hello"[..]);
+assert_eq!(b.len(), 5);
+

pub fn is_empty(&self) -> bool

Returns true if the BytesMut has a length of 0.

+
§Examples
+
use bytes::BytesMut;
+
+let b = BytesMut::with_capacity(64);
+assert!(b.is_empty());
+

pub fn capacity(&self) -> usize

Returns the number of bytes the BytesMut can hold without reallocating.

+
§Examples
+
use bytes::BytesMut;
+
+let b = BytesMut::with_capacity(64);
+assert_eq!(b.capacity(), 64);
+

pub fn freeze(self) -> Bytes

Converts self into an immutable Bytes.

+

The conversion is zero cost and is used to indicate that the slice +referenced by the handle will no longer be mutated. Once the conversion +is done, the handle can be cloned and shared across threads.

+
§Examples
+
use bytes::{BytesMut, BufMut};
+use std::thread;
+
+let mut b = BytesMut::with_capacity(64);
+b.put(&b"hello world"[..]);
+let b1 = b.freeze();
+let b2 = b1.clone();
+
+let th = thread::spawn(move || {
+    assert_eq!(&b1[..], b"hello world");
+});
+
+assert_eq!(&b2[..], b"hello world");
+th.join().unwrap();
+

pub fn zeroed(len: usize) -> BytesMut

Creates a new BytesMut, which is initialized with zero.

+
§Examples
+
use bytes::BytesMut;
+
+let zeros = BytesMut::zeroed(42);
+
+assert_eq!(zeros.len(), 42);
+zeros.into_iter().for_each(|x| assert_eq!(x, 0));
+

pub fn split_off(&mut self, at: usize) -> BytesMut

Splits the bytes into two at the given index.

+

Afterwards self contains elements [0, at), and the returned +BytesMut contains elements [at, capacity).

+

This is an O(1) operation that just increases the reference count +and sets a few indices.

+
§Examples
+
use bytes::BytesMut;
+
+let mut a = BytesMut::from(&b"hello world"[..]);
+let mut b = a.split_off(5);
+
+a[0] = b'j';
+b[0] = b'!';
+
+assert_eq!(&a[..], b"jello");
+assert_eq!(&b[..], b"!world");
+
§Panics
+

Panics if at > capacity.

+

pub fn split(&mut self) -> BytesMut

Removes the bytes from the current view, returning them in a new +BytesMut handle.

+

Afterwards, self will be empty, but will retain any additional +capacity that it had before the operation. This is identical to +self.split_to(self.len()).

+

This is an O(1) operation that just increases the reference count and +sets a few indices.

+
§Examples
+
use bytes::{BytesMut, BufMut};
+
+let mut buf = BytesMut::with_capacity(1024);
+buf.put(&b"hello world"[..]);
+
+let other = buf.split();
+
+assert!(buf.is_empty());
+assert_eq!(1013, buf.capacity());
+
+assert_eq!(other, b"hello world"[..]);
+

pub fn split_to(&mut self, at: usize) -> BytesMut

Splits the buffer into two at the given index.

+

Afterwards self contains elements [at, len), and the returned BytesMut +contains elements [0, at).

+

This is an O(1) operation that just increases the reference count and +sets a few indices.

+
§Examples
+
use bytes::BytesMut;
+
+let mut a = BytesMut::from(&b"hello world"[..]);
+let mut b = a.split_to(5);
+
+a[0] = b'!';
+b[0] = b'j';
+
+assert_eq!(&a[..], b"!world");
+assert_eq!(&b[..], b"jello");
+
§Panics
+

Panics if at > len.

+

pub fn truncate(&mut self, len: usize)

Shortens the buffer, keeping the first len bytes and dropping the +rest.

+

If len is greater than the buffer’s current length, this has no +effect.

+

Existing underlying capacity is preserved.

+

The split_off method can emulate truncate, but this causes the +excess bytes to be returned instead of dropped.

+
§Examples
+
use bytes::BytesMut;
+
+let mut buf = BytesMut::from(&b"hello world"[..]);
+buf.truncate(5);
+assert_eq!(buf, b"hello"[..]);
+

pub fn clear(&mut self)

Clears the buffer, removing all data. Existing capacity is preserved.

+
§Examples
+
use bytes::BytesMut;
+
+let mut buf = BytesMut::from(&b"hello world"[..]);
+buf.clear();
+assert!(buf.is_empty());
+

pub fn resize(&mut self, new_len: usize, value: u8)

Resizes the buffer so that len is equal to new_len.

+

If new_len is greater than len, the buffer is extended by the +difference with each additional byte set to value. If new_len is +less than len, the buffer is simply truncated.

+
§Examples
+
use bytes::BytesMut;
+
+let mut buf = BytesMut::new();
+
+buf.resize(3, 0x1);
+assert_eq!(&buf[..], &[0x1, 0x1, 0x1]);
+
+buf.resize(2, 0x2);
+assert_eq!(&buf[..], &[0x1, 0x1]);
+
+buf.resize(4, 0x3);
+assert_eq!(&buf[..], &[0x1, 0x1, 0x3, 0x3]);
+

pub unsafe fn set_len(&mut self, len: usize)

Sets the length of the buffer.

+

This will explicitly set the size of the buffer without actually +modifying the data, so it is up to the caller to ensure that the data +has been initialized.

+
§Examples
+
use bytes::BytesMut;
+
+let mut b = BytesMut::from(&b"hello world"[..]);
+
+unsafe {
+    b.set_len(5);
+}
+
+assert_eq!(&b[..], b"hello");
+
+unsafe {
+    b.set_len(11);
+}
+
+assert_eq!(&b[..], b"hello world");
+

pub fn reserve(&mut self, additional: usize)

Reserves capacity for at least additional more bytes to be inserted +into the given BytesMut.

+

More than additional bytes may be reserved in order to avoid frequent +reallocations. A call to reserve may result in an allocation.

+

Before allocating new buffer space, the function will attempt to reclaim +space in the existing buffer. If the current handle references a view +into a larger original buffer, and all other handles referencing part +of the same original buffer have been dropped, then the current view +can be copied/shifted to the front of the buffer and the handle can take +ownership of the full buffer, provided that the full buffer is large +enough to fit the requested additional capacity.

+

This optimization will only happen if shifting the data from the current +view to the front of the buffer is not too expensive in terms of the +(amortized) time required. The precise condition is subject to change; +as of now, the length of the data being shifted needs to be at least as +large as the distance that it’s shifted by. If the current view is empty +and the original buffer is large enough to fit the requested additional +capacity, then reallocations will never happen.

+
§Examples
+

In the following example, a new buffer is allocated.

+ +
use bytes::BytesMut;
+
+let mut buf = BytesMut::from(&b"hello"[..]);
+buf.reserve(64);
+assert!(buf.capacity() >= 69);
+

In the following example, the existing buffer is reclaimed.

+ +
use bytes::{BytesMut, BufMut};
+
+let mut buf = BytesMut::with_capacity(128);
+buf.put(&[0; 64][..]);
+
+let ptr = buf.as_ptr();
+let other = buf.split();
+
+assert!(buf.is_empty());
+assert_eq!(buf.capacity(), 64);
+
+drop(other);
+buf.reserve(128);
+
+assert_eq!(buf.capacity(), 128);
+assert_eq!(buf.as_ptr(), ptr);
+
§Panics
+

Panics if the new capacity overflows usize.

+

pub fn extend_from_slice(&mut self, extend: &[u8])

Appends given bytes to this BytesMut.

+

If this BytesMut object does not have enough capacity, it is resized +first.

+
§Examples
+
use bytes::BytesMut;
+
+let mut buf = BytesMut::with_capacity(0);
+buf.extend_from_slice(b"aaabbb");
+buf.extend_from_slice(b"cccddd");
+
+assert_eq!(b"aaabbbcccddd", &buf[..]);
+

pub fn unsplit(&mut self, other: BytesMut)

Absorbs a BytesMut that was previously split off.

+

If the two BytesMut objects were previously contiguous and not mutated +in a way that causes re-allocation i.e., if other was created by +calling split_off on this BytesMut, then this is an O(1) operation +that just decreases a reference count and sets a few indices. +Otherwise this method degenerates to +self.extend_from_slice(other.as_ref()).

+
§Examples
+
use bytes::BytesMut;
+
+let mut buf = BytesMut::with_capacity(64);
+buf.extend_from_slice(b"aaabbbcccddd");
+
+let split = buf.split_off(6);
+assert_eq!(b"aaabbb", &buf[..]);
+assert_eq!(b"cccddd", &split[..]);
+
+buf.unsplit(split);
+assert_eq!(b"aaabbbcccddd", &buf[..]);
+

pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<u8>]

Returns the remaining spare capacity of the buffer as a slice of MaybeUninit<u8>.

+

The returned slice can be used to fill the buffer with data (e.g. by +reading from a file) before marking the data as initialized using the +set_len method.

+
§Examples
+
use bytes::BytesMut;
+
+// Allocate buffer big enough for 10 bytes.
+let mut buf = BytesMut::with_capacity(10);
+
+// Fill in the first 3 elements.
+let uninit = buf.spare_capacity_mut();
+uninit[0].write(0);
+uninit[1].write(1);
+uninit[2].write(2);
+
+// Mark the first 3 bytes of the buffer as being initialized.
+unsafe {
+    buf.set_len(3);
+}
+
+assert_eq!(&buf[..], &[0, 1, 2]);
+

Methods from Deref<Target = [u8]>§

1.80.0 · source

pub fn as_flattened(&self) -> &[T]

Takes a &[[T; N]], and flattens it to a &[T].

+
§Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
§Examples
+
assert_eq!([[1, 2, 3], [4, 5, 6]].as_flattened(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+    [[1, 2, 3], [4, 5, 6]].as_flattened(),
+    [[1, 2], [3, 4], [5, 6]].as_flattened(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.as_flattened().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.as_flattened().is_empty());
+
1.80.0 · source

pub fn as_flattened_mut(&mut self) -> &mut [T]

Takes a &mut [[T; N]], and flattens it to a &mut [T].

+
§Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
§Examples
+
fn add_5_to_all(slice: &mut [i32]) {
+    for i in slice {
+        *i += 5;
+    }
+}
+
+let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
+add_5_to_all(array.as_flattened_mut());
+assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f32::total_cmp.

+
§Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
§Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the slice.

+
§Examples
+
let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the slice has a length of 0.

+
§Examples
+
let a = [1, 2, 3];
+assert!(!a.is_empty());
+
+let b: &[i32] = &[];
+assert!(b.is_empty());
+
1.0.0 · source

pub fn first(&self) -> Option<&T>

Returns the first element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
+
1.0.0 · source

pub fn first_mut(&mut self) -> Option<&mut T>

Returns a mutable pointer to the first element of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_mut() {
+    *first = 5;
+}
+assert_eq!(x, &[5, 1, 2]);
+
+let y: &mut [i32] = &mut [];
+assert_eq!(None, y.first_mut());
+
1.5.0 · source

pub fn split_first(&self) -> Option<(&T, &[T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first() {
+    assert_eq!(first, &0);
+    assert_eq!(elements, &[1, 2]);
+}
+
1.5.0 · source

pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_mut() {
+    *first = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
1.5.0 · source

pub fn split_last(&self) -> Option<(&T, &[T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+    assert_eq!(last, &2);
+    assert_eq!(elements, &[0, 1]);
+}
+
1.5.0 · source

pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_mut() {
+    *last = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[4, 5, 3]);
+
1.0.0 · source

pub fn last(&self) -> Option<&T>

Returns the last element of the slice, or None if it is empty.

+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
+
1.0.0 · source

pub fn last_mut(&mut self) -> Option<&mut T>

Returns a mutable reference to the last item in the slice, or None if it is empty.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_mut() {
+    *last = 10;
+}
+assert_eq!(x, &[0, 1, 10]);
+
+let y: &mut [i32] = &mut [];
+assert_eq!(None, y.last_mut());
+
1.77.0 · source

pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the first N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.first_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.first_chunk::<0>());
+
1.77.0 · source

pub fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

Return a mutable array reference to the first N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_chunk_mut::<2>() {
+    first[0] = 5;
+    first[1] = 4;
+}
+assert_eq!(x, &[5, 4, 2]);
+
+assert_eq!(None, x.first_chunk_mut::<4>());
+
1.77.0 · source

pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

Return an array reference to the first N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk::<2>() {
+    assert_eq!(first, &[0, 1]);
+    assert_eq!(elements, &[2]);
+}
+
+assert_eq!(None, x.split_first_chunk::<4>());
+
1.77.0 · source

pub fn split_first_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T; N], &mut [T])>

Return a mutable array reference to the first N items in the slice and the remaining +slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk_mut::<2>() {
+    first[0] = 3;
+    first[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
+assert_eq!(None, x.split_first_chunk_mut::<4>());
+
1.77.0 · source

pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])>

Return an array reference to the last N items in the slice and the remaining slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &[0, 1, 2];
+
+if let Some((elements, last)) = x.split_last_chunk::<2>() {
+    assert_eq!(elements, &[0]);
+    assert_eq!(last, &[1, 2]);
+}
+
+assert_eq!(None, x.split_last_chunk::<4>());
+
1.77.0 · source

pub fn split_last_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T], &mut [T; N])>

Return a mutable array reference to the last N items in the slice and the remaining +slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((elements, last)) = x.split_last_chunk_mut::<2>() {
+    last[0] = 3;
+    last[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[5, 3, 4]);
+
+assert_eq!(None, x.split_last_chunk_mut::<4>());
+
1.77.0 · source

pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>

Return an array reference to the last N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let u = [10, 40, 30];
+assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.last_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.last_chunk::<0>());
+
1.77.0 · source

pub fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]>

Return a mutable array reference to the last N items in the slice.

+

If the slice is not at least N in length, this will return None.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_chunk_mut::<2>() {
+    last[0] = 10;
+    last[1] = 20;
+}
+assert_eq!(x, &[0, 10, 20]);
+
+assert_eq!(None, x.last_chunk_mut::<4>());
+
1.0.0 · source

pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice depending on the type of +index.

+
    +
  • If given a position, returns a reference to the element at that +position or None if out of bounds.
  • +
  • If given a range, returns the subslice corresponding to that range, +or None if out of bounds.
  • +
+
§Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
+
1.0.0 · source

pub fn get_mut<I>( + &mut self, + index: I +) -> Option<&mut <I as SliceIndex<[T]>>::Output>
where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice depending on the +type of index (see get) or None if the index is out of bounds.

+
§Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(elem) = x.get_mut(1) {
+    *elem = 42;
+}
+assert_eq!(x, &[0, 42, 2]);
+
1.0.0 · source

pub unsafe fn get_unchecked<I>( + &self, + index: I +) -> &<I as SliceIndex<[T]>>::Output
where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice, without doing bounds +checking.

+

For a safe alternative see get.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get(index).unwrap_unchecked(). It’s UB +to call .get_unchecked(len), even if you immediately convert to a +pointer. And it’s UB to call .get_unchecked(..len + 1), +.get_unchecked(..=len), or similar.

+
§Examples
+
let x = &[1, 2, 4];
+
+unsafe {
+    assert_eq!(x.get_unchecked(1), &2);
+}
+
1.0.0 · source

pub unsafe fn get_unchecked_mut<I>( + &mut self, + index: I +) -> &mut <I as SliceIndex<[T]>>::Output
where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice, without doing +bounds checking.

+

For a safe alternative see get_mut.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+

You can think of this like .get_mut(index).unwrap_unchecked(). It’s +UB to call .get_unchecked_mut(len), even if you immediately convert +to a pointer. And it’s UB to call .get_unchecked_mut(..len + 1), +.get_unchecked_mut(..=len), or similar.

+
§Examples
+
let x = &mut [1, 2, 4];
+
+unsafe {
+    let elem = x.get_unchecked_mut(1);
+    *elem = 13;
+}
+assert_eq!(x, &[1, 13, 4]);
+
1.0.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
§Examples
+
let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+    }
+}
+
1.0.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
§Examples
+
let x = &mut [1, 2, 4];
+let x_ptr = x.as_mut_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        *x_ptr.add(i) += 2;
+    }
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.48.0 · source

pub fn as_ptr_range(&self) -> Range<*const T>

Returns the two raw pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_ptr for warnings on using these pointers. The end pointer +requires extra caution, as it does not point to a valid element in the +slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+

It can also be useful to check if a pointer to an element refers to an +element of this slice:

+ +
let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
+
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
+
1.48.0 · source

pub fn as_mut_ptr_range(&mut self) -> Range<*mut T>

Returns the two unsafe mutable pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_mut_ptr for warnings on using these pointers. The end +pointer requires extra caution, as it does not point to a valid element +in the slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+
1.0.0 · source

pub fn swap(&mut self, a: usize, b: usize)

Swaps two elements in the slice.

+

If a equals to b, it’s guaranteed that elements won’t change value.

+
§Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
§Panics
+

Panics if a or b are out of bounds.

+
§Examples
+
let mut v = ["a", "b", "c", "d", "e"];
+v.swap(2, 4);
+assert!(v == ["a", "b", "e", "d", "c"]);
+
source

pub unsafe fn swap_unchecked(&mut self, a: usize, b: usize)

🔬This is a nightly-only experimental API. (slice_swap_unchecked)

Swaps two elements in the slice, without doing bounds checking.

+

For a safe alternative see swap.

+
§Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior. +The caller has to ensure that a < self.len() and b < self.len().

+
§Examples
+
#![feature(slice_swap_unchecked)]
+
+let mut v = ["a", "b", "c", "d"];
+// SAFETY: we know that 1 and 3 are both indices of the slice
+unsafe { v.swap_unchecked(1, 3) };
+assert!(v == ["a", "d", "c", "b"]);
+
1.0.0 · source

pub fn reverse(&mut self)

Reverses the order of elements in the slice, in place.

+
§Examples
+
let mut v = [1, 2, 3];
+v.reverse();
+assert!(v == [3, 2, 1]);
+
1.0.0 · source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the slice.

+

The iterator yields all items from start to end.

+
§Examples
+
let x = &[1, 2, 4];
+let mut iterator = x.iter();
+
+assert_eq!(iterator.next(), Some(&1));
+assert_eq!(iterator.next(), Some(&2));
+assert_eq!(iterator.next(), Some(&4));
+assert_eq!(iterator.next(), None);
+
1.0.0 · source

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Returns an iterator that allows modifying each value.

+

The iterator yields all items from start to end.

+
§Examples
+
let x = &mut [1, 2, 4];
+for elem in x.iter_mut() {
+    *elem += 2;
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.0.0 · source

pub fn windows(&self, size: usize) -> Windows<'_, T>

Returns an iterator over all contiguous windows of length +size. The windows overlap. If the slice is shorter than +size, the iterator returns no values.

+
§Panics
+

Panics if size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.windows(3);
+assert_eq!(iter.next().unwrap(), &['l', 'o', 'r']);
+assert_eq!(iter.next().unwrap(), &['o', 'r', 'e']);
+assert_eq!(iter.next().unwrap(), &['r', 'e', 'm']);
+assert!(iter.next().is_none());
+

If the slice is shorter than size:

+ +
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
+

There’s no windows_mut, as that existing would let safe code violate the +“only one &mut at a time to the same thing” rule. However, you can sometimes +use Cell::as_slice_of_cells in +conjunction with windows to accomplish something similar:

+ +
use std::cell::Cell;
+
+let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
+let slice = &mut array[..];
+let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
+for w in slice_of_cells.windows(3) {
+    Cell::swap(&w[0], &w[2]);
+}
+assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
+
1.0.0 · source

pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See chunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and rchunks for the same iterator but starting at the end of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See chunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and rchunks_mut for the same iterator but starting at +the end of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 3]);
+
1.31.0 · source

pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks.

+

See chunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
1.31.0 · source

pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See chunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and rchunks_exact_mut for the same iterator but starting at the end of +the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
§Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
§Examples
+
#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+
source

pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
+

If you expect the slice to be an exact multiple, you can combine +let-else with an empty slice pattern:

+ +
#![feature(slice_as_chunks)]
+let slice = ['R', 'u', 's', 't'];
+let (chunks, []) = slice.as_chunks::<2>() else {
+    panic!("slice didn't have even length")
+};
+assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
+
source

pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+
source

pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are array references and do not overlap. If N does not divide the +length of the slice, then the last up to N-1 elements will be omitted and can be +retrieved from the remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
source

pub unsafe fn as_chunks_unchecked_mut<const N: usize>( + &mut self +) -> &mut [[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
§Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
§Examples
+
#![feature(slice_as_chunks)]
+let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &mut [[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[0] = ['L'];
+assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &mut [[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[1] = ['a', 'x', '?'];
+assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
+
source

pub fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (chunks, remainder) = v.as_chunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 9]);
+
source

pub fn as_rchunks_mut<const N: usize>(&mut self) -> (&mut [T], &mut [[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (remainder, chunks) = v.as_rchunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[9, 1, 1, 2, 2]);
+
source

pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable array references and do not overlap. If N does not divide +the length of the slice, then the last up to N-1 elements will be omitted and +can be retrieved from the into_remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact_mut.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.array_chunks_mut() {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>

🔬This is a nightly-only experimental API. (array_windows)

Returns an iterator over overlapping windows of N elements of a slice, +starting at the beginning of the slice.

+

This is the const generic equivalent of windows.

+

If N is greater than the size of the slice, it will return no windows.

+
§Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
§Examples
+
#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and chunks for the same iterator but starting at the beginning +of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and chunks_mut for the same iterator but starting at the +beginning of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[3, 2, 2, 1, 1]);
+
1.31.0 · source

pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +end of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of rchunks.

+

See rchunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and chunks_exact for the same iterator but starting at the beginning of the +slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
+
1.31.0 · source

pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See rchunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and chunks_exact_mut for the same iterator but starting at the beginning +of the slice.

+
§Panics
+

Panics if chunk_size is 0.

+
§Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[0, 2, 2, 1, 1]);
+
1.77.0 · source

pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
where + F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping runs +of elements using the predicate to separate them.

+

The predicate is called for every pair of consecutive elements, +meaning that it is called on slice[0] and slice[1], +followed by slice[1] and slice[2], and so on.

+
§Examples
+
let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.chunk_by(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.chunk_by(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.77.0 · source

pub fn chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F>
where + F: FnMut(&T, &T) -> bool,

Returns an iterator over the slice producing non-overlapping mutable +runs of elements using the predicate to separate them.

+

The predicate is called for every pair of consecutive elements, +meaning that it is called on slice[0] and slice[1], +followed by slice[1] and slice[2], and so on.

+
§Examples
+
let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.chunk_by_mut(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&mut [3, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.chunk_by_mut(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.0.0 · source

pub fn split_at(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
§Panics
+

Panics if mid > len. For a non-panicking alternative see +split_at_checked.

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+{
+   let (left, right) = v.split_at(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.0.0 · source

pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
§Panics
+

Panics if mid > len. For a non-panicking alternative see +split_at_mut_checked.

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+let (left, right) = v.split_at_mut(2);
+assert_eq!(left, [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.79.0 · source

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
§Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+unsafe {
+   let (left, right) = v.split_at_unchecked(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.79.0 · source

pub unsafe fn split_at_mut_unchecked( + &mut self, + mid: usize +) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at_mut.

+
§Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+// scoped to restrict the lifetime of the borrows
+unsafe {
+    let (left, right) = v.split_at_mut_unchecked(2);
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.80.0 · source

pub fn split_at_checked(&self, mid: usize) -> Option<(&[T], &[T])>

Divides one slice into two at an index, returning None if the slice is +too short.

+

If mid ≤ len returns a pair of slices where the first will contain all +indices from [0, mid) (excluding the index mid itself) and the +second will contain all indices from [mid, len) (excluding the index +len itself).

+

Otherwise, if mid > len, returns None.

+
§Examples
+
let v = [1, -2, 3, -4, 5, -6];
+
+{
+   let (left, right) = v.split_at_checked(0).unwrap();
+   assert_eq!(left, []);
+   assert_eq!(right, [1, -2, 3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(2).unwrap();
+    assert_eq!(left, [1, -2]);
+    assert_eq!(right, [3, -4, 5, -6]);
+}
+
+{
+    let (left, right) = v.split_at_checked(6).unwrap();
+    assert_eq!(left, [1, -2, 3, -4, 5, -6]);
+    assert_eq!(right, []);
+}
+
+assert_eq!(None, v.split_at_checked(7));
+
1.80.0 · source

pub fn split_at_mut_checked( + &mut self, + mid: usize +) -> Option<(&mut [T], &mut [T])>

Divides one mutable slice into two at an index, returning None if the +slice is too short.

+

If mid ≤ len returns a pair of slices where the first will contain all +indices from [0, mid) (excluding the index mid itself) and the +second will contain all indices from [mid, len) (excluding the index +len itself).

+

Otherwise, if mid > len, returns None.

+
§Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+
+if let Some((left, right)) = v.split_at_mut_checked(2) {
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
+assert_eq!(None, v.split_at_mut_checked(7));
+
1.0.0 · source

pub fn split<F>(&self, pred: F) -> Split<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is not contained in the subslices.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the first element is matched, an empty slice will be the first item +returned by the iterator. Similarly, if the last element in the slice +is matched, an empty slice will be the last item returned by the +iterator:

+ +
let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
+

If two matched elements are directly adjacent, an empty slice will be +present between them:

+ +
let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is not contained in the subslices.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_mut(|num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 1]);
+
1.51.0 · source

pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is contained in the end of the previous +subslice as a terminator.

+
§Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the last element of the slice is matched, +that element will be considered the terminator of the preceding slice. +That slice will be the last item returned by the iterator.

+ +
let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
+
1.51.0 · source

pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is contained in the previous +subslice as a terminator.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
+    let terminator_idx = group.len()-1;
+    group[terminator_idx] = 1;
+}
+assert_eq!(v, [10, 40, 1, 20, 1, 1]);
+
1.27.0 · source

pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, starting at the end of the slice and working backwards. +The matched element is not contained in the subslices.

+
§Examples
+
let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
+
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
+

As with split(), if the first or last element is matched, an empty +slice will be the first (or last) item returned by the iterator.

+ +
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
+
1.27.0 · source

pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred, starting at the end of the slice and working +backwards. The matched element is not contained in the subslices.

+
§Examples
+
let mut v = [100, 400, 300, 200, 600, 500];
+
+let mut count = 0;
+for group in v.rsplit_mut(|num| *num % 3 == 0) {
+    count += 1;
+    group[0] = count;
+}
+assert_eq!(v, [3, 400, 300, 2, 600, 1]);
+
1.0.0 · source

pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], +[20, 60, 50]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 50]);
+
1.0.0 · source

pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+

Print the slice split once, starting from the end, by numbers divisible +by 3 (i.e., [50], [10, 40, 30, 20]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>
where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
§Examples
+
let mut s = [10, 40, 30, 20, 60, 50];
+
+for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(s, [1, 40, 30, 20, 60, 1]);
+
source

pub fn split_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the first element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.split_once(|&x| x == 2), Some((
+    &[1][..],
+    &[3, 2, 4][..]
+)));
+assert_eq!(s.split_once(|&x| x == 0), None);
+
source

pub fn rsplit_once<F>(&self, pred: F) -> Option<(&[T], &[T])>
where + F: FnMut(&T) -> bool,

🔬This is a nightly-only experimental API. (slice_split_once)

Splits the slice on the last element that matches the specified +predicate.

+

If any matching elements are present in the slice, returns the prefix +before the match and suffix after. The matching element itself is not +included. If no elements match, returns None.

+
§Examples
+
#![feature(slice_split_once)]
+let s = [1, 2, 3, 2, 4];
+assert_eq!(s.rsplit_once(|&x| x == 2), Some((
+    &[1, 2, 3][..],
+    &[4][..]
+)));
+assert_eq!(s.rsplit_once(|&x| x == 0), None);
+
1.0.0 · source

pub fn contains(&self, x: &T) -> bool
where + T: PartialEq,

Returns true if the slice contains an element with the given value.

+

This operation is O(n).

+

Note that if you have a sorted slice, binary_search may be faster.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
+

If you do not have a &T, but some other value that you can compare +with one (for example, String implements PartialEq<str>), you can +use iter().any:

+ +
let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
+
1.0.0 · source

pub fn starts_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a prefix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(v.starts_with(&v));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
+
1.0.0 · source

pub fn ends_with(&self, needle: &[T]) -> bool
where + T: PartialEq,

Returns true if needle is a suffix of the slice or equal to the slice.

+
§Examples
+
let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(v.ends_with(&v));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
+
1.51.0 · source

pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the prefix removed.

+

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. +If prefix is empty, simply returns the original slice. If prefix is equal to the +original slice, returns an empty slice.

+

If the slice does not start with prefix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
+
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+           Some(b"llo".as_ref()));
+
1.51.0 · source

pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>
where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq,

Returns a subslice with the suffix removed.

+

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. +If suffix is empty, simply returns the original slice. If suffix is equal to the +original slice, returns an empty slice.

+

If the slice does not end with suffix, returns None.

+
§Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[10, 40, 30]), Some(&[][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
+

Binary searches this slice for a given element. +If the slice is not sorted, the returned result is unspecified and +meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search_by, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+assert_eq!(s.binary_search(&13),  Ok(9));
+assert_eq!(s.binary_search(&4),   Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

If you want to find that whole range of matching items, rather than +an arbitrary matching one, that can be done using partition_point:

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
+

If you want to insert an item to a sorted vector, while maintaining +sort order, consider using partition_point:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+// If `num` is unique, `s.partition_point(|&x| x < num)` (with `<`) is equivalent to
+// `s.binary_search(&num).unwrap_or_else(|x| x)`, but using `<=` will allow `insert`
+// to shift less elements.
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
1.0.0 · source

pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
where + F: FnMut(&'a T) -> Ordering,

Binary searches this slice with a comparator function.

+

The comparator function should return an order code that indicates +whether its argument is Less, Equal or Greater the desired +target. +If the slice is not sorted or if the comparator function does not +implement an order consistent with the sort order of the underlying +slice, the returned result is unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by_key, and partition_point.

+
§Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.10.0 · source

pub fn binary_search_by_key<'a, B, F>( + &'a self, + b: &B, + f: F +) -> Result<usize, usize>
where + F: FnMut(&'a T) -> B, + B: Ord,

Binary searches this slice with a key extraction function.

+

Assumes that the slice is sorted by the key, for instance with +sort_by_key using the same key extraction function. +If the slice is not sorted by the key, the returned result is +unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by, and partition_point.

+
§Examples
+

Looks up a series of four elements in a slice of pairs sorted by +their second elements. The first is found, with a uniquely +determined position; the second and third are not found; the +fourth could match any position in [1, 4].

+ +
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+         (1, 21), (2, 34), (4, 55)];
+
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.20.0 · source

pub fn sort_unstable(&mut self)
where + T: Ord,

Sorts the slice, but might not preserve the order of equal elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
§Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort_unstable();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.20.0 · source

pub fn sort_unstable_by<F>(&mut self, compare: F)
where + F: FnMut(&T, &T) -> Ordering,

Sorts the slice with a comparator function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
§Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_unstable_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_unstable_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.20.0 · source

pub fn sort_unstable_by_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(m * n * log(n)) worst-case, where the key function is +O(m).

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

Due to its key calling strategy, sort_unstable_by_key +is likely to be slower than sort_by_cached_key in +cases where the key function is expensive.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_unstable_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.49.0 · source

pub fn select_nth_unstable( + &mut self, + index: usize +) -> (&mut [T], &mut T, &mut [T])
where + T: Ord,

Reorder the slice such that the element at index after the reordering is at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index. Additionally, this reordering is +unstable (i.e. any number of equal elements may end up at position index), in-place +(i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from the reordered slice: +the subslice prior to index, the element at index, and the subslice after index; +accordingly, the values in those two subslices will respectively all be less-than-or-equal-to +and greater-than-or-equal-to the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 2, -3, 1];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median.
+let (lesser, median, greater) = v.select_nth_unstable(2);
+
+assert!(lesser == [-3, -5] || lesser == [-5, -3]);
+assert_eq!(median, &mut 1);
+assert!(greater == [4, 2] || greater == [2, 4]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [-3, -5, 1, 2, 4] ||
+        v == [-5, -3, 1, 2, 4] ||
+        v == [-3, -5, 1, 4, 2] ||
+        v == [-5, -3, 1, 4, 2]);
+
1.49.0 · source

pub fn select_nth_unstable_by<F>( + &mut self, + index: usize, + compare: F +) -> (&mut [T], &mut T, &mut [T])
where + F: FnMut(&T, &T) -> Ordering,

Reorder the slice with a comparator function such that the element at index after the reordering is at +its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the comparator function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided comparator function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 2, -3, 1];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median as if the slice were sorted in descending order.
+let (lesser, median, greater) = v.select_nth_unstable_by(2, |a, b| b.cmp(a));
+
+assert!(lesser == [4, 2] || lesser == [2, 4]);
+assert_eq!(median, &mut 1);
+assert!(greater == [-3, -5] || greater == [-5, -3]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [2, 4, 1, -5, -3] ||
+        v == [2, 4, 1, -3, -5] ||
+        v == [4, 2, 1, -5, -3] ||
+        v == [4, 2, 1, -3, -5]);
+
1.49.0 · source

pub fn select_nth_unstable_by_key<K, F>( + &mut self, + index: usize, + f: F +) -> (&mut [T], &mut T, &mut [T])
where + F: FnMut(&T) -> K, + K: Ord,

Reorder the slice with a key extraction function such that the element at index after the reordering is +at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the key extraction function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided key extraction function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
§Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
§Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the items less than or equal to the median, the median, and greater than or equal to
+// the median as if the slice were sorted according to absolute value.
+let (lesser, median, greater) = v.select_nth_unstable_by_key(2, |a| a.abs());
+
+assert!(lesser == [1, 2] || lesser == [2, 1]);
+assert_eq!(median, &mut -3);
+assert!(greater == [4, -5] || greater == [-5, 4]);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [1, 2, -3, 4, -5] ||
+        v == [1, 2, -3, -5, 4] ||
+        v == [2, 1, -3, 4, -5] ||
+        v == [2, 1, -3, -5, 4]);
+
source

pub fn partition_dedup(&mut self) -> (&mut [T], &mut [T])
where + T: PartialEq,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all consecutive repeated elements to the end of the slice according to the +PartialEq trait implementation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
+
+let (dedup, duplicates) = slice.partition_dedup();
+
+assert_eq!(dedup, [1, 2, 3, 2, 1]);
+assert_eq!(duplicates, [2, 3, 1]);
+
source

pub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T])
where + F: FnMut(&mut T, &mut T) -> bool,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice satisfying +a given equality relation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

The same_bucket function is passed references to two elements from the slice and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is moved +at the end of the slice.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
+
+let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
+assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
+
source

pub fn partition_dedup_by_key<K, F>(&mut self, key: F) -> (&mut [T], &mut [T])
where + F: FnMut(&mut T) -> K, + K: PartialEq,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice that resolve +to the same key.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
§Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
+
+let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
+
+assert_eq!(dedup, [10, 20, 30, 20, 11]);
+assert_eq!(duplicates, [21, 30, 13]);
+
1.26.0 · source

pub fn rotate_left(&mut self, mid: usize)

Rotates the slice in-place such that the first mid elements of the +slice move to the end while the last self.len() - mid elements move to +the front. After calling rotate_left, the element previously at index +mid will become the first element in the slice.

+
§Panics
+

This function will panic if mid is greater than the length of the +slice. Note that mid == self.len() does not panic and is a no-op +rotation.

+
§Complexity
+

Takes linear (in self.len()) time.

+
§Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_left(2);
+assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_left(1);
+assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+
1.26.0 · source

pub fn rotate_right(&mut self, k: usize)

Rotates the slice in-place such that the first self.len() - k +elements of the slice move to the end while the last k elements move +to the front. After calling rotate_right, the element previously at +index self.len() - k will become the first element in the slice.

+
§Panics
+

This function will panic if k is greater than the length of the +slice. Note that k == self.len() does not panic and is a no-op +rotation.

+
§Complexity
+

Takes linear (in self.len()) time.

+
§Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_right(2);
+assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_right(1);
+assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
+
1.50.0 · source

pub fn fill(&mut self, value: T)
where + T: Clone,

Fills self with elements by cloning value.

+
§Examples
+
let mut buf = vec![0; 10];
+buf.fill(1);
+assert_eq!(buf, vec![1; 10]);
+
1.51.0 · source

pub fn fill_with<F>(&mut self, f: F)
where + F: FnMut() -> T,

Fills self with elements returned by calling a closure repeatedly.

+

This method uses a closure to create new values. If you’d rather +Clone a given value, use fill. If you want to use the Default +trait to generate values, you can pass Default::default as the +argument.

+
§Examples
+
let mut buf = vec![1; 10];
+buf.fill_with(Default::default);
+assert_eq!(buf, vec![0; 10]);
+
1.7.0 · source

pub fn clone_from_slice(&mut self, src: &[T])
where + T: Clone,

Copies the elements from src into self.

+

The length of src must be the same as self.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Examples
+

Cloning two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.clone_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use clone_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].clone_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.clone_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.9.0 · source

pub fn copy_from_slice(&mut self, src: &[T])
where + T: Copy,

Copies all elements from src into self, using a memcpy.

+

The length of src must be the same as self.

+

If T does not implement Copy, use clone_from_slice.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Examples
+

Copying two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.copy_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use copy_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].copy_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.copy_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.37.0 · source

pub fn copy_within<R>(&mut self, src: R, dest: usize)
where + R: RangeBounds<usize>, + T: Copy,

Copies elements from one part of the slice to another part of itself, +using a memmove.

+

src is the range within self to copy from. dest is the starting +index of the range within self to copy to, which will have the same +length as src. The two ranges may overlap. The ends of the two ranges +must be less than or equal to self.len().

+
§Panics
+

This function will panic if either range exceeds the end of the slice, +or if the end of src is before the start.

+
§Examples
+

Copying four bytes within a slice:

+ +
let mut bytes = *b"Hello, World!";
+
+bytes.copy_within(1..5, 8);
+
+assert_eq!(&bytes, b"Hello, Wello!");
+
1.27.0 · source

pub fn swap_with_slice(&mut self, other: &mut [T])

Swaps all elements in self with those in other.

+

The length of other must be the same as self.

+
§Panics
+

This function will panic if the two slices have different lengths.

+
§Example
+

Swapping two elements across slices:

+ +
let mut slice1 = [0, 0];
+let mut slice2 = [1, 2, 3, 4];
+
+slice1.swap_with_slice(&mut slice2[2..]);
+
+assert_eq!(slice1, [3, 4]);
+assert_eq!(slice2, [1, 2, 0, 0]);
+

Rust enforces that there can only be one mutable reference to a +particular piece of data in a particular scope. Because of this, +attempting to use swap_with_slice on a single slice will result in +a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +mutable sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.swap_with_slice(&mut right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 1, 2]);
+
1.30.0 · source

pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

Transmute the slice to a slice of another type, ensuring alignment of the types is +maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The middle part will be as big as possible under +the given alignment constraint and element size.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
§Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
§Examples
+

Basic usage:

+ +
unsafe {
+    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
1.30.0 · source

pub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T])

Transmute the mutable slice to a mutable slice of another type, ensuring alignment of the +types is maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. The middle part will be as big as possible under +the given alignment constraint and element size.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
§Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
§Examples
+

Basic usage:

+ +
unsafe {
+    let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
source

pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])
where + Simd<T, LANES>: AsRef<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.

+

This is a safe wrapper around slice::align_to, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+
§Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
§Examples
+
#![feature(portable_simd)]
+use core::simd::prelude::*;
+
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
+
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+
+fn basic_simd_sum(x: &[f32]) -> f32 {
+    use std::ops::Add;
+    let (prefix, middle, suffix) = x.as_simd();
+    let sums = f32x4::from_array([
+        prefix.iter().copied().sum(),
+        0.0,
+        0.0,
+        suffix.iter().copied().sum(),
+    ]);
+    let sums = middle.iter().copied().fold(sums, f32x4::add);
+    sums.reduce_sum()
+}
+
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+
source

pub fn as_simd_mut<const LANES: usize>( + &mut self +) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T])
where + Simd<T, LANES>: AsMut<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a mutable slice into a mutable prefix, a middle of aligned SIMD types, +and a mutable suffix.

+

This is a safe wrapper around slice::align_to_mut, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+

This is the mutable version of slice::as_simd; see that for examples.

+
§Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
source

pub fn is_sorted(&self) -> bool
where + T: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted.

+

That is, for each element a and its following element b, a <= b must hold. If the +slice yields exactly zero or one element, true is returned.

+

Note that if Self::Item is only PartialOrd, but not Ord, the above definition +implies that this function returns false if any two consecutive items are not +comparable.

+
§Examples
+
#![feature(is_sorted)]
+let empty: [i32; 0] = [];
+
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
+
source

pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> bool
where + F: FnMut(&'a T, &'a T) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given comparator function.

+

Instead of using PartialOrd::partial_cmp, this function uses the given compare +function to determine whether two elements are to be considered in sorted order.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!([1, 2, 2, 9].is_sorted_by(|a, b| a <= b));
+assert!(![1, 2, 2, 9].is_sorted_by(|a, b| a < b));
+
+assert!([0].is_sorted_by(|a, b| true));
+assert!([0].is_sorted_by(|a, b| false));
+
+let empty: [i32; 0] = [];
+assert!(empty.is_sorted_by(|a, b| false));
+assert!(empty.is_sorted_by(|a, b| true));
+
source

pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> bool
where + F: FnMut(&'a T) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given key extraction function.

+

Instead of comparing the slice’s elements directly, this function compares the keys of the +elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its +documentation for more information.

+
§Examples
+
#![feature(is_sorted)]
+
+assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+
1.52.0 · source

pub fn partition_point<P>(&self, pred: P) -> usize
where + P: FnMut(&T) -> bool,

Returns the index of the partition point according to the given predicate +(the index of the first element of the second partition).

+

The slice is assumed to be partitioned according to the given predicate. +This means that all elements for which the predicate returns true are at the start of the slice +and all elements for which the predicate returns false are at the end. +For example, [7, 15, 3, 5, 4, 12, 6] is partitioned under the predicate x % 2 != 0 +(all odd numbers are at the start, all even at the end).

+

If this slice is not partitioned, the returned result is unspecified and meaningless, +as this method performs a kind of binary search.

+

See also binary_search, binary_search_by, and binary_search_by_key.

+
§Examples
+
let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
+
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
+

If all elements of the slice match the predicate, including if the slice +is empty, then the length of the slice will be returned:

+ +
let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
+

If you want to insert an item to a sorted vector, while maintaining +sort order:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x <= num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
source

pub fn take<'a, R>(self: &mut &'a [T], range: R) -> Option<&'a [T]>
where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
§Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut first_three = slice.take(..3).unwrap();
+
+assert_eq!(slice, &['d']);
+assert_eq!(first_three, &['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut tail = slice.take(2..).unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(tail, &['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take(5..));
+assert_eq!(None, slice.take(..5));
+assert_eq!(None, slice.take(..=4));
+let expected: &[char] = &['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take(..4));
+
source

pub fn take_mut<'a, R>(self: &mut &'a mut [T], range: R) -> Option<&'a mut [T]>
where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a mutable reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
§Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut first_three = slice.take_mut(..3).unwrap();
+
+assert_eq!(slice, &mut ['d']);
+assert_eq!(first_three, &mut ['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut tail = slice.take_mut(2..).unwrap();
+
+assert_eq!(slice, &mut ['a', 'b']);
+assert_eq!(tail, &mut ['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take_mut(5..));
+assert_eq!(None, slice.take_mut(..5));
+assert_eq!(None, slice.take_mut(..=4));
+let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take_mut(..4));
+
source

pub fn take_first<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let first = slice.take_first().unwrap();
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'a');
+
source

pub fn take_first_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let first = slice.take_first_mut().unwrap();
+*first = 'd';
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'d');
+
source

pub fn take_last<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let last = slice.take_last().unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'c');
+
source

pub fn take_last_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
§Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let last = slice.take_last_mut().unwrap();
+*last = 'd';
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'d');
+
source

pub unsafe fn get_many_unchecked_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> [&mut T; N]

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once, without doing any checks.

+

For a safe alternative see get_many_mut.

+
§Safety
+

Calling this method with overlapping or out-of-bounds indices is undefined behavior +even if the resulting references are not used.

+
§Examples
+
#![feature(get_many_mut)]
+
+let x = &mut [1, 2, 4];
+
+unsafe {
+    let [a, b] = x.get_many_unchecked_mut([0, 2]);
+    *a *= 10;
+    *b *= 100;
+}
+assert_eq!(x, &[10, 2, 400]);
+
source

pub fn get_many_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> Result<[&mut T; N], GetManyMutError<N>>

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once.

+

Returns an error if any index is out-of-bounds, or if the same index was +passed more than once.

+
§Examples
+
#![feature(get_many_mut)]
+
+let v = &mut [1, 2, 3];
+if let Ok([a, b]) = v.get_many_mut([0, 2]) {
+    *a = 413;
+    *b = 612;
+}
+assert_eq!(v, &[413, 2, 612]);
+
1.79.0 · source

pub fn utf8_chunks(&self) -> Utf8Chunks<'_>

Creates an iterator over the contiguous valid UTF-8 ranges of this +slice, and the non-UTF-8 fragments in between.

+
§Examples
+

This function formats arbitrary but mostly-UTF-8 bytes into Rust source +code in the form of a C-string literal (c"...").

+ +
use std::fmt::Write as _;
+
+pub fn cstr_literal(bytes: &[u8]) -> String {
+    let mut repr = String::new();
+    repr.push_str("c\"");
+    for chunk in bytes.utf8_chunks() {
+        for ch in chunk.valid().chars() {
+            // Escapes \0, \t, \r, \n, \\, \', \", and uses \u{...} for non-printable characters.
+            write!(repr, "{}", ch.escape_debug()).unwrap();
+        }
+        for byte in chunk.invalid() {
+            write!(repr, "\\x{:02X}", byte).unwrap();
+        }
+    }
+    repr.push('"');
+    repr
+}
+
+fn main() {
+    let lit = cstr_literal(b"\xferris the \xf0\x9f\xa6\x80\x07");
+    let expected = stringify!(c"\xFErris the 🦀\u{7}");
+    assert_eq!(lit, expected);
+}
+
1.23.0 · source

pub fn is_ascii(&self) -> bool

Checks if all bytes in this slice are within the ASCII range.

+
source

pub fn as_ascii(&self) -> Option<&[AsciiChar]>

🔬This is a nightly-only experimental API. (ascii_char)

If this slice is_ascii, returns it as a slice of +ASCII characters, otherwise returns None.

+
source

pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]

🔬This is a nightly-only experimental API. (ascii_char)

Converts this slice of bytes into a slice of ASCII characters, +without checking whether they’re valid.

+
§Safety
+

Every byte in the slice must be in 0..=127, or else this is UB.

+
1.23.0 · source

pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool

Checks that two slices are an ASCII case-insensitive match.

+

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), +but without allocating and copying temporaries.

+
1.23.0 · source

pub fn make_ascii_uppercase(&mut self)

Converts this slice to its ASCII upper case equivalent in-place.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To return a new uppercased value without modifying the existing one, use +to_ascii_uppercase.

+
1.23.0 · source

pub fn make_ascii_lowercase(&mut self)

Converts this slice to its ASCII lower case equivalent in-place.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To return a new lowercased value without modifying the existing one, use +to_ascii_lowercase.

+
1.60.0 · source

pub fn escape_ascii(&self) -> EscapeAscii<'_>

Returns an iterator that produces an escaped version of this slice, +treating it as an ASCII string.

+
§Examples
+

+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
+
1.80.0 · source

pub fn trim_ascii_start(&self) -> &[u8]

Returns a byte slice with leading ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b"  ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
+
1.80.0 · source

pub fn trim_ascii_end(&self) -> &[u8]

Returns a byte slice with trailing ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b"  ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
+
1.80.0 · source

pub fn trim_ascii(&self) -> &[u8]

Returns a byte slice with leading and trailing ASCII whitespace bytes +removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
§Examples
+
assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b"  ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f64::total_cmp.

+
§Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
§Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
source

pub fn as_str(&self) -> &str

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a UTF-8 str.

+
source

pub fn as_bytes(&self) -> &[u8]

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a slice of u8 bytes.

+
1.0.0 · source

pub fn sort(&mut self)
where + T: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.0.0 · source

pub fn sort_by<F>(&mut self, compare: F)
where + F: FnMut(&T, &T) -> Ordering,

Available on non-no_global_oom_handling only.

Sorts the slice with a comparator function.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.7.0 · source

pub fn sort_by_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n * log(n)) +worst-case, where the key function is O(m).

+

For expensive key functions (e.g. functions that are not simple property accesses or +basic operations), sort_by_cached_key is likely to be +significantly faster, as it does not recompute element keys.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by_key.

+
§Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
§Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.34.0 · source

pub fn sort_by_cached_key<K, F>(&mut self, f: F)
where + F: FnMut(&T) -> K, + K: Ord,

Available on non-no_global_oom_handling only.

Sorts the slice with a key extraction function.

+

During sorting, the key function is called at most once per element, by using +temporary storage to remember the results of key evaluation. +The order of calls to the key function is unspecified and may change in future versions +of the standard library.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n + n * log(n)) +worst-case, where the key function is O(m).

+

For simple key functions (e.g., functions that are property accesses or +basic operations), sort_by_key is likely to be +faster.

+
§Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

In the worst case, the algorithm allocates temporary storage in a Vec<(K, usize)> the +length of the slice.

+
§Examples
+
let mut v = [-5i32, 4, 32, -3, 2];
+
+v.sort_by_cached_key(|k| k.to_string());
+assert!(v == [-3, -5, 2, 32, 4]);
+
1.0.0 · source

pub fn to_vec(&self) -> Vec<T>
where + T: Clone,

Available on non-no_global_oom_handling only.

Copies self into a new Vec.

+
§Examples
+
let s = [10, 40, 30];
+let x = s.to_vec();
+// Here, `s` and `x` can be modified independently.
+
source

pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>
where + A: Allocator, + T: Clone,

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Copies self into a new Vec with an allocator.

+
§Examples
+
#![feature(allocator_api)]
+
+use std::alloc::System;
+
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
+// Here, `s` and `x` can be modified independently.
+
1.40.0 · source

pub fn repeat(&self, n: usize) -> Vec<T>
where + T: Copy,

Available on non-no_global_oom_handling only.

Creates a vector by copying a slice n times.

+
§Panics
+

This function will panic if the capacity would overflow.

+
§Examples
+

Basic usage:

+ +
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
+

A panic upon overflow:

+ +
// this will panic at runtime
+b"0123456789abcdef".repeat(usize::MAX);
+
1.0.0 · source

pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output
where + [T]: Concat<Item>, + Item: ?Sized,

Flattens a slice of T into a single value Self::Output.

+
§Examples
+
assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+
1.3.0 · source

pub fn join<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+
1.0.0 · source

pub fn connect<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output
where + [T]: Join<Separator>,

👎Deprecated since 1.3.0: renamed to join

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
§Examples
+
assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+
1.23.0 · source

pub fn to_ascii_uppercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII upper case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To uppercase the value in-place, use make_ascii_uppercase.

+
1.23.0 · source

pub fn to_ascii_lowercase(&self) -> Vec<u8>

Available on non-no_global_oom_handling only.

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII lower case equivalent.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To lowercase the value in-place, use make_ascii_lowercase.

+

Trait Implementations§

§

impl AsMut<[u8]> for BytesMut

§

fn as_mut(&mut self) -> &mut [u8]

Converts this type into a mutable reference of the (usually inferred) input type.
§

impl AsRef<[u8]> for BytesMut

§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
§

impl Borrow<[u8]> for BytesMut

§

fn borrow(&self) -> &[u8]

Immutably borrows from an owned value. Read more
§

impl BorrowMut<[u8]> for BytesMut

§

fn borrow_mut(&mut self) -> &mut [u8]

Mutably borrows from an owned value. Read more
§

impl Buf for BytesMut

§

fn remaining(&self) -> usize

Returns the number of bytes between the current position and the end of +the buffer. Read more
§

fn chunk(&self) -> &[u8]

Returns a slice starting at the current position and of length between 0 +and Buf::remaining(). Note that this can return shorter slice (this allows +non-continuous internal representation). Read more
§

fn advance(&mut self, cnt: usize)

Advance the internal cursor of the Buf Read more
§

fn copy_to_bytes(&mut self, len: usize) -> Bytes

Consumes len bytes inside self and returns new instance of Bytes +with this data. Read more
§

fn chunks_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize

Available on crate feature std only.
Fills dst with potentially multiple slices starting at self’s +current position. Read more
§

fn has_remaining(&self) -> bool

Returns true if there are any more bytes to consume Read more
§

fn copy_to_slice(&mut self, dst: &mut [u8])

Copies bytes from self into dst. Read more
§

fn get_u8(&mut self) -> u8

Gets an unsigned 8 bit integer from self. Read more
§

fn get_i8(&mut self) -> i8

Gets a signed 8 bit integer from self. Read more
§

fn get_u16(&mut self) -> u16

Gets an unsigned 16 bit integer from self in big-endian byte order. Read more
§

fn get_u16_le(&mut self) -> u16

Gets an unsigned 16 bit integer from self in little-endian byte order. Read more
§

fn get_u16_ne(&mut self) -> u16

Gets an unsigned 16 bit integer from self in native-endian byte order. Read more
§

fn get_i16(&mut self) -> i16

Gets a signed 16 bit integer from self in big-endian byte order. Read more
§

fn get_i16_le(&mut self) -> i16

Gets a signed 16 bit integer from self in little-endian byte order. Read more
§

fn get_i16_ne(&mut self) -> i16

Gets a signed 16 bit integer from self in native-endian byte order. Read more
§

fn get_u32(&mut self) -> u32

Gets an unsigned 32 bit integer from self in the big-endian byte order. Read more
§

fn get_u32_le(&mut self) -> u32

Gets an unsigned 32 bit integer from self in the little-endian byte order. Read more
§

fn get_u32_ne(&mut self) -> u32

Gets an unsigned 32 bit integer from self in native-endian byte order. Read more
§

fn get_i32(&mut self) -> i32

Gets a signed 32 bit integer from self in big-endian byte order. Read more
§

fn get_i32_le(&mut self) -> i32

Gets a signed 32 bit integer from self in little-endian byte order. Read more
§

fn get_i32_ne(&mut self) -> i32

Gets a signed 32 bit integer from self in native-endian byte order. Read more
§

fn get_u64(&mut self) -> u64

Gets an unsigned 64 bit integer from self in big-endian byte order. Read more
§

fn get_u64_le(&mut self) -> u64

Gets an unsigned 64 bit integer from self in little-endian byte order. Read more
§

fn get_u64_ne(&mut self) -> u64

Gets an unsigned 64 bit integer from self in native-endian byte order. Read more
§

fn get_i64(&mut self) -> i64

Gets a signed 64 bit integer from self in big-endian byte order. Read more
§

fn get_i64_le(&mut self) -> i64

Gets a signed 64 bit integer from self in little-endian byte order. Read more
§

fn get_i64_ne(&mut self) -> i64

Gets a signed 64 bit integer from self in native-endian byte order. Read more
§

fn get_u128(&mut self) -> u128

Gets an unsigned 128 bit integer from self in big-endian byte order. Read more
§

fn get_u128_le(&mut self) -> u128

Gets an unsigned 128 bit integer from self in little-endian byte order. Read more
§

fn get_u128_ne(&mut self) -> u128

Gets an unsigned 128 bit integer from self in native-endian byte order. Read more
§

fn get_i128(&mut self) -> i128

Gets a signed 128 bit integer from self in big-endian byte order. Read more
§

fn get_i128_le(&mut self) -> i128

Gets a signed 128 bit integer from self in little-endian byte order. Read more
§

fn get_i128_ne(&mut self) -> i128

Gets a signed 128 bit integer from self in native-endian byte order. Read more
§

fn get_uint(&mut self, nbytes: usize) -> u64

Gets an unsigned n-byte integer from self in big-endian byte order. Read more
§

fn get_uint_le(&mut self, nbytes: usize) -> u64

Gets an unsigned n-byte integer from self in little-endian byte order. Read more
§

fn get_uint_ne(&mut self, nbytes: usize) -> u64

Gets an unsigned n-byte integer from self in native-endian byte order. Read more
§

fn get_int(&mut self, nbytes: usize) -> i64

Gets a signed n-byte integer from self in big-endian byte order. Read more
§

fn get_int_le(&mut self, nbytes: usize) -> i64

Gets a signed n-byte integer from self in little-endian byte order. Read more
§

fn get_int_ne(&mut self, nbytes: usize) -> i64

Gets a signed n-byte integer from self in native-endian byte order. Read more
§

fn get_f32(&mut self) -> f32

Gets an IEEE754 single-precision (4 bytes) floating point number from +self in big-endian byte order. Read more
§

fn get_f32_le(&mut self) -> f32

Gets an IEEE754 single-precision (4 bytes) floating point number from +self in little-endian byte order. Read more
§

fn get_f32_ne(&mut self) -> f32

Gets an IEEE754 single-precision (4 bytes) floating point number from +self in native-endian byte order. Read more
§

fn get_f64(&mut self) -> f64

Gets an IEEE754 double-precision (8 bytes) floating point number from +self in big-endian byte order. Read more
§

fn get_f64_le(&mut self) -> f64

Gets an IEEE754 double-precision (8 bytes) floating point number from +self in little-endian byte order. Read more
§

fn get_f64_ne(&mut self) -> f64

Gets an IEEE754 double-precision (8 bytes) floating point number from +self in native-endian byte order. Read more
§

fn take(self, limit: usize) -> Take<Self>
where + Self: Sized,

Creates an adaptor which will read at most limit bytes from self. Read more
§

fn chain<U>(self, next: U) -> Chain<Self, U>
where + U: Buf, + Self: Sized,

Creates an adaptor which will chain this buffer with another. Read more
§

fn reader(self) -> Reader<Self>
where + Self: Sized,

Available on crate feature std only.
Creates an adaptor which implements the Read trait for self. Read more
§

impl BufMut for BytesMut

§

fn remaining_mut(&self) -> usize

Returns the number of bytes that can be written from the current +position until the end of the buffer is reached. Read more
§

unsafe fn advance_mut(&mut self, cnt: usize)

Advance the internal cursor of the BufMut Read more
§

fn chunk_mut(&mut self) -> &mut UninitSlice

Returns a mutable slice starting at the current BufMut position and of +length between 0 and BufMut::remaining_mut(). Note that this can be shorter than the +whole remainder of the buffer (this allows non-continuous implementation). Read more
§

fn put<T>(&mut self, src: T)
where + T: Buf, + BytesMut: Sized,

Transfer bytes into self from src and advance the cursor by the +number of bytes written. Read more
§

fn put_slice(&mut self, src: &[u8])

Transfer bytes into self from src and advance the cursor by the +number of bytes written. Read more
§

fn put_bytes(&mut self, val: u8, cnt: usize)

Put cnt bytes val into self. Read more
§

fn has_remaining_mut(&self) -> bool

Returns true if there is space in self for more bytes. Read more
§

fn put_u8(&mut self, n: u8)

Writes an unsigned 8 bit integer to self. Read more
§

fn put_i8(&mut self, n: i8)

Writes a signed 8 bit integer to self. Read more
§

fn put_u16(&mut self, n: u16)

Writes an unsigned 16 bit integer to self in big-endian byte order. Read more
§

fn put_u16_le(&mut self, n: u16)

Writes an unsigned 16 bit integer to self in little-endian byte order. Read more
§

fn put_u16_ne(&mut self, n: u16)

Writes an unsigned 16 bit integer to self in native-endian byte order. Read more
§

fn put_i16(&mut self, n: i16)

Writes a signed 16 bit integer to self in big-endian byte order. Read more
§

fn put_i16_le(&mut self, n: i16)

Writes a signed 16 bit integer to self in little-endian byte order. Read more
§

fn put_i16_ne(&mut self, n: i16)

Writes a signed 16 bit integer to self in native-endian byte order. Read more
§

fn put_u32(&mut self, n: u32)

Writes an unsigned 32 bit integer to self in big-endian byte order. Read more
§

fn put_u32_le(&mut self, n: u32)

Writes an unsigned 32 bit integer to self in little-endian byte order. Read more
§

fn put_u32_ne(&mut self, n: u32)

Writes an unsigned 32 bit integer to self in native-endian byte order. Read more
§

fn put_i32(&mut self, n: i32)

Writes a signed 32 bit integer to self in big-endian byte order. Read more
§

fn put_i32_le(&mut self, n: i32)

Writes a signed 32 bit integer to self in little-endian byte order. Read more
§

fn put_i32_ne(&mut self, n: i32)

Writes a signed 32 bit integer to self in native-endian byte order. Read more
§

fn put_u64(&mut self, n: u64)

Writes an unsigned 64 bit integer to self in the big-endian byte order. Read more
§

fn put_u64_le(&mut self, n: u64)

Writes an unsigned 64 bit integer to self in little-endian byte order. Read more
§

fn put_u64_ne(&mut self, n: u64)

Writes an unsigned 64 bit integer to self in native-endian byte order. Read more
§

fn put_i64(&mut self, n: i64)

Writes a signed 64 bit integer to self in the big-endian byte order. Read more
§

fn put_i64_le(&mut self, n: i64)

Writes a signed 64 bit integer to self in little-endian byte order. Read more
§

fn put_i64_ne(&mut self, n: i64)

Writes a signed 64 bit integer to self in native-endian byte order. Read more
§

fn put_u128(&mut self, n: u128)

Writes an unsigned 128 bit integer to self in the big-endian byte order. Read more
§

fn put_u128_le(&mut self, n: u128)

Writes an unsigned 128 bit integer to self in little-endian byte order. Read more
§

fn put_u128_ne(&mut self, n: u128)

Writes an unsigned 128 bit integer to self in native-endian byte order. Read more
§

fn put_i128(&mut self, n: i128)

Writes a signed 128 bit integer to self in the big-endian byte order. Read more
§

fn put_i128_le(&mut self, n: i128)

Writes a signed 128 bit integer to self in little-endian byte order. Read more
§

fn put_i128_ne(&mut self, n: i128)

Writes a signed 128 bit integer to self in native-endian byte order. Read more
§

fn put_uint(&mut self, n: u64, nbytes: usize)

Writes an unsigned n-byte integer to self in big-endian byte order. Read more
§

fn put_uint_le(&mut self, n: u64, nbytes: usize)

Writes an unsigned n-byte integer to self in the little-endian byte order. Read more
§

fn put_uint_ne(&mut self, n: u64, nbytes: usize)

Writes an unsigned n-byte integer to self in the native-endian byte order. Read more
§

fn put_int(&mut self, n: i64, nbytes: usize)

Writes low nbytes of a signed integer to self in big-endian byte order. Read more
§

fn put_int_le(&mut self, n: i64, nbytes: usize)

Writes low nbytes of a signed integer to self in little-endian byte order. Read more
§

fn put_int_ne(&mut self, n: i64, nbytes: usize)

Writes low nbytes of a signed integer to self in native-endian byte order. Read more
§

fn put_f32(&mut self, n: f32)

Writes an IEEE754 single-precision (4 bytes) floating point number to +self in big-endian byte order. Read more
§

fn put_f32_le(&mut self, n: f32)

Writes an IEEE754 single-precision (4 bytes) floating point number to +self in little-endian byte order. Read more
§

fn put_f32_ne(&mut self, n: f32)

Writes an IEEE754 single-precision (4 bytes) floating point number to +self in native-endian byte order. Read more
§

fn put_f64(&mut self, n: f64)

Writes an IEEE754 double-precision (8 bytes) floating point number to +self in big-endian byte order. Read more
§

fn put_f64_le(&mut self, n: f64)

Writes an IEEE754 double-precision (8 bytes) floating point number to +self in little-endian byte order. Read more
§

fn put_f64_ne(&mut self, n: f64)

Writes an IEEE754 double-precision (8 bytes) floating point number to +self in native-endian byte order. Read more
§

fn limit(self, limit: usize) -> Limit<Self>
where + Self: Sized,

Creates an adaptor which can write at most limit bytes to self. Read more
§

fn writer(self) -> Writer<Self>
where + Self: Sized,

Available on crate feature std only.
Creates an adaptor which implements the Write trait for self. Read more
§

fn chain_mut<U>(self, next: U) -> Chain<Self, U>
where + U: BufMut, + Self: Sized,

Creates an adapter which will chain this buffer with another. Read more
§

impl Clone for BytesMut

§

fn clone(&self) -> BytesMut

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for BytesMut

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for BytesMut

§

fn default() -> BytesMut

Returns the “default value” for a type. Read more
§

impl Deref for BytesMut

§

type Target = [u8]

The resulting type after dereferencing.
§

fn deref(&self) -> &[u8]

Dereferences the value.
§

impl DerefMut for BytesMut

§

fn deref_mut(&mut self) -> &mut [u8]

Mutably dereferences the value.
§

impl Drop for BytesMut

§

fn drop(&mut self)

Executes the destructor for this type. Read more
§

impl<'a> Extend<&'a u8> for BytesMut

§

fn extend<T>(&mut self, iter: T)
where + T: IntoIterator<Item = &'a u8>,

Extends a collection with the contents of an iterator. Read more
source§

fn extend_one(&mut self, item: A)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
§

impl Extend<Bytes> for BytesMut

§

fn extend<T>(&mut self, iter: T)
where + T: IntoIterator<Item = Bytes>,

Extends a collection with the contents of an iterator. Read more
source§

fn extend_one(&mut self, item: A)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
§

impl Extend<u8> for BytesMut

§

fn extend<T>(&mut self, iter: T)
where + T: IntoIterator<Item = u8>,

Extends a collection with the contents of an iterator. Read more
source§

fn extend_one(&mut self, item: A)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
§

impl<'a> From<&'a [u8]> for BytesMut

§

fn from(src: &'a [u8]) -> BytesMut

Converts to this type from the input type.
§

impl<'a> From<&'a str> for BytesMut

§

fn from(src: &'a str) -> BytesMut

Converts to this type from the input type.
§

impl From<BytesMut> for Bytes

§

fn from(src: BytesMut) -> Bytes

Converts to this type from the input type.
source§

impl From<BytesMut> for Response<BytesMut>

source§

fn from(val: BytesMut) -> Response<BytesMut>

Converts to this type from the input type.
§

impl From<BytesMut> for Vec<u8>

§

fn from(bytes: BytesMut) -> Vec<u8>

Converts to this type from the input type.
§

impl<'a> FromIterator<&'a u8> for BytesMut

§

fn from_iter<T>(into_iter: T) -> BytesMut
where + T: IntoIterator<Item = &'a u8>,

Creates a value from an iterator. Read more
§

impl FromIterator<u8> for BytesMut

§

fn from_iter<T>(into_iter: T) -> BytesMut
where + T: IntoIterator<Item = u8>,

Creates a value from an iterator. Read more
§

impl Hash for BytesMut

§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl<'a> IntoIterator for &'a BytesMut

§

type Item = &'a u8

The type of the elements being iterated over.
§

type IntoIter = Iter<'a, u8>

Which kind of iterator are we turning this into?
§

fn into_iter(self) -> <&'a BytesMut as IntoIterator>::IntoIter

Creates an iterator from a value. Read more
§

impl IntoIterator for BytesMut

§

type Item = u8

The type of the elements being iterated over.
§

type IntoIter = IntoIter<BytesMut>

Which kind of iterator are we turning this into?
§

fn into_iter(self) -> <BytesMut as IntoIterator>::IntoIter

Creates an iterator from a value. Read more
§

impl IoBuf for BytesMut

Available on crate feature bytes only.
§

fn stable_ptr(&self) -> *const u8

Returns a raw pointer to the vector’s buffer. Read more
§

fn bytes_init(&self) -> usize

Number of initialized bytes. Read more
§

fn bytes_total(&self) -> usize

Total size of the buffer, including uninitialized memory, if any. Read more
§

fn slice(self, range: impl RangeBounds<usize>) -> Slice<Self>
where + Self: Sized,

Returns a view of the buffer with the specified range. Read more
§

impl IoBufMut for BytesMut

Available on crate feature bytes only.
§

fn stable_mut_ptr(&mut self) -> *mut u8

Returns a raw mutable pointer to the vector’s buffer. Read more
§

unsafe fn set_init(&mut self, init_len: usize)

Updates the number of initialized bytes. Read more
§

impl LowerHex for BytesMut

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl MessageBody for BytesMut

§

type Error = Infallible

The type of error that will be returned if streaming body fails. Read more
source§

fn size(&self) -> BodySize

Body size hint. Read more
source§

fn poll_next( + self: Pin<&mut BytesMut>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <BytesMut as MessageBody>::Error>>>

Attempt to pull out the next chunk of body bytes. Read more
source§

fn try_into_bytes(self) -> Result<Bytes, BytesMut>

Try to convert into the complete chunk of body bytes. Read more
source§

fn boxed(self) -> BoxBody
where + Self: Sized + 'static,

Wraps this body into a BoxBody. Read more
§

impl Ord for BytesMut

§

fn cmp(&self, other: &BytesMut) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
§

impl<'a, T> PartialEq<&'a T> for BytesMut
where + BytesMut: PartialEq<T>, + T: ?Sized,

§

fn eq(&self, other: &&'a T) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<[u8]> for BytesMut

§

fn eq(&self, other: &[u8]) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<Bytes> for BytesMut

§

fn eq(&self, other: &Bytes) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<BytesMut> for &[u8]

§

fn eq(&self, other: &BytesMut) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<BytesMut> for &str

§

fn eq(&self, other: &BytesMut) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<BytesMut> for [u8]

§

fn eq(&self, other: &BytesMut) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<BytesMut> for Bytes

§

fn eq(&self, other: &BytesMut) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<BytesMut> for Vec<u8>

§

fn eq(&self, other: &BytesMut) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<BytesMut> for str

§

fn eq(&self, other: &BytesMut) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<String> for BytesMut

§

fn eq(&self, other: &String) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<Vec<u8>> for BytesMut

§

fn eq(&self, other: &Vec<u8>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq<str> for BytesMut

§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialEq for BytesMut

§

fn eq(&self, other: &BytesMut) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<'a, T> PartialOrd<&'a T> for BytesMut
where + BytesMut: PartialOrd<T>, + T: ?Sized,

§

fn partial_cmp(&self, other: &&'a T) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<[u8]> for BytesMut

§

fn partial_cmp(&self, other: &[u8]) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<BytesMut> for &[u8]

§

fn partial_cmp(&self, other: &BytesMut) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<BytesMut> for &str

§

fn partial_cmp(&self, other: &BytesMut) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<BytesMut> for [u8]

§

fn partial_cmp(&self, other: &BytesMut) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<BytesMut> for Vec<u8>

§

fn partial_cmp(&self, other: &BytesMut) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<BytesMut> for str

§

fn partial_cmp(&self, other: &BytesMut) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<String> for BytesMut

§

fn partial_cmp(&self, other: &String) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<Vec<u8>> for BytesMut

§

fn partial_cmp(&self, other: &Vec<u8>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd<str> for BytesMut

§

fn partial_cmp(&self, other: &str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl PartialOrd for BytesMut

§

fn partial_cmp(&self, other: &BytesMut) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl Responder for BytesMut

§

type Body = BytesMut

source§

fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body>

Convert self to HttpResponse.
source§

fn customize(self) -> CustomizeResponder<Self>
where + Self: Sized,

Wraps responder to allow alteration of its response. Read more
§

impl UpperHex for BytesMut

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Write for BytesMut

§

fn write_str(&mut self, s: &str) -> Result<(), Error>

Writes a string slice into this writer, returning whether the write +succeeded. Read more
§

fn write_fmt(&mut self, args: Arguments<'_>) -> Result<(), Error>

Glue for usage of the write! macro with implementors of this trait. Read more
1.1.0 · source§

fn write_char(&mut self, c: char) -> Result<(), Error>

Writes a char into this writer, returning whether the write succeeded. Read more
§

impl Eq for BytesMut

§

impl Send for BytesMut

§

impl Sync for BytesMut

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/web/struct.Data.html b/actix_web/web/struct.Data.html new file mode 100644 index 000000000..f51a471e8 --- /dev/null +++ b/actix_web/web/struct.Data.html @@ -0,0 +1,90 @@ +Data in actix_web::web - Rust

Struct actix_web::web::Data

source ·
pub struct Data<T: ?Sized>(/* private fields */);
Expand description

Application data wrapper and extractor.

+

§Setting Data

+

Data is set using the app_data methods on App, Scope, and Resource. If data is wrapped +in this Data type for those calls, it can be used as an extractor.

+

Note that Data should be constructed outside the HttpServer::new closure if shared, +potentially mutable state is desired. Data is cheap to clone; internally, it uses an Arc.

+

See also App::app_data, Scope::app_data, +and Resource::app_data.

+

§Extracting Data

+

Since the Actix Web router layers application data, the returned object will reference the +“closest” instance of the type. For example, if an App stores a u32, a nested Scope +also stores a u32, and the delegated request handler falls within that Scope, then +extracting a web::Data<u32> for that handler will return the Scope’s instance. However, +using the same router set up and a request that does not get captured by the Scope, +web::<Data<u32>> would return the App’s instance.

+

If route data is not set for a handler, using Data<T> extractor would cause a 500 Internal Server Error response.

+

See also HttpRequest::app_data +and ServiceRequest::app_data.

+

§Unsized Data

+

For types that are unsized, most commonly dyn T, Data can wrap these types by first +constructing an Arc<dyn T> and using the From implementation to convert it.

+ +
let displayable_arc: Arc<dyn Display> = Arc::new(42usize);
+let displayable_data: Data<dyn Display> = Data::from(displayable_arc);
+

§Examples

+
use std::sync::Mutex;
+use actix_web::{App, HttpRequest, HttpResponse, Responder, web::{self, Data}};
+
+struct MyData {
+    counter: usize,
+}
+
+/// Use the `Data<T>` extractor to access data in a handler.
+async fn index(data: Data<Mutex<MyData>>) -> impl Responder {
+    let mut my_data = data.lock().unwrap();
+    my_data.counter += 1;
+    HttpResponse::Ok()
+}
+
+/// Alternatively, use the `HttpRequest::app_data` method to access data in a handler.
+async fn index_alt(req: HttpRequest) -> impl Responder {
+    let data = req.app_data::<Data<Mutex<MyData>>>().unwrap();
+    let mut my_data = data.lock().unwrap();
+    my_data.counter += 1;
+    HttpResponse::Ok()
+}
+
+let data = Data::new(Mutex::new(MyData { counter: 0 }));
+
+let app = App::new()
+    // Store `MyData` in application storage.
+    .app_data(Data::clone(&data))
+    .route("/index.html", web::get().to(index))
+    .route("/index-alt.html", web::get().to(index_alt));
+

Implementations§

source§

impl<T> Data<T>

source

pub fn new(state: T) -> Data<T>

Create new Data instance.

+
source§

impl<T: ?Sized> Data<T>

source

pub fn get_ref(&self) -> &T

Returns reference to inner T.

+
source

pub fn into_inner(self) -> Arc<T>

Unwraps to the internal Arc<T>

+

Trait Implementations§

source§

impl<T: ?Sized> Clone for Data<T>

source§

fn clone(&self) -> Data<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug + ?Sized> Debug for Data<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: Default> Default for Data<T>

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<T: ?Sized> Deref for Data<T>

§

type Target = Arc<T>

The resulting type after dereferencing.
source§

fn deref(&self) -> &Arc<T>

Dereferences the value.
source§

impl<'de, T> Deserialize<'de> for Data<T>
where + T: Deserialize<'de>,

source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where + D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<T: ?Sized> From<Arc<T>> for Data<T>

source§

fn from(arc: Arc<T>) -> Self

Converts to this type from the input type.
source§

impl<T: ?Sized + 'static> FromRequest for Data<T>

§

type Error = Error

The associated error which can be returned.
§

type Future = Ready<Result<Data<T>, Error>>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more
source§

impl<T> Serialize for Data<T>
where + T: Serialize,

source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where + S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<T> Freeze for Data<T>
where + T: ?Sized,

§

impl<T> RefUnwindSafe for Data<T>
where + T: RefUnwindSafe + ?Sized,

§

impl<T> Send for Data<T>
where + T: Sync + Send + ?Sized,

§

impl<T> Sync for Data<T>
where + T: Sync + Send + ?Sized,

§

impl<T> Unpin for Data<T>
where + T: ?Sized,

§

impl<T> UnwindSafe for Data<T>
where + T: RefUnwindSafe + ?Sized,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
source§

impl<T> DeserializeOwned for T
where + T: for<'de> Deserialize<'de>,

§

impl<T> Formattable for T
where + T: Deref, + <T as Deref>::Target: Formattable,

§

impl<T> Parsable for T
where + T: Deref, + <T as Deref>::Target: Parsable,

\ No newline at end of file diff --git a/actix_web/web/struct.Form.html b/actix_web/web/struct.Form.html new file mode 100644 index 000000000..1f202fe90 --- /dev/null +++ b/actix_web/web/struct.Form.html @@ -0,0 +1,99 @@ +Form in actix_web::web - Rust

Struct actix_web::web::Form

source ·
pub struct Form<T>(pub T);
Expand description

URL encoded payload extractor and responder.

+

Form has two uses: URL encoded responses, and extracting typed data from URL request payloads.

+

§Extractor

+

To extract typed data from a request body, the inner type T must implement the +DeserializeOwned trait.

+

Use FormConfig to configure extraction options.

+

§Examples

+
use actix_web::{post, web};
+use serde::Deserialize;
+
+#[derive(Deserialize)]
+struct Info {
+    name: String,
+}
+
+// This handler is only called if:
+// - request headers declare the content type as `application/x-www-form-urlencoded`
+// - request payload deserializes into an `Info` struct from the URL encoded format
+#[post("/")]
+async fn index(web::Form(form): web::Form<Info>) -> String {
+    format!("Welcome {}!", form.name)
+}
+

§Responder

+

The Form type also allows you to create URL encoded responses by returning a value of type +Form<T> where T is the type to be URL encoded, as long as T implements Serialize.

+

§Examples

+
use actix_web::{get, web};
+use serde::Serialize;
+
+#[derive(Serialize)]
+struct SomeForm {
+    name: String,
+    age: u8
+}
+
+// Response will have:
+// - status: 200 OK
+// - header: `Content-Type: application/x-www-form-urlencoded`
+// - body: `name=actix&age=123`
+#[get("/")]
+async fn index() -> web::Form<SomeForm> {
+    web::Form(SomeForm {
+        name: "actix".to_owned(),
+        age: 123
+    })
+}
+

§Panics

+

URL encoded forms consist of unordered key=value pairs, therefore they cannot be decoded into +any type which depends upon data ordering (eg. tuples). Trying to do so will result in a panic.

+

Tuple Fields§

§0: T

Implementations§

source§

impl<T> Form<T>

source

pub fn into_inner(self) -> T

Unwrap into inner T value.

+

Trait Implementations§

source§

impl<T: Debug> Debug for Form<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> Deref for Form<T>

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &T

Dereferences the value.
source§

impl<T> DerefMut for Form<T>

source§

fn deref_mut(&mut self) -> &mut T

Mutably dereferences the value.
source§

impl<T: Display> Display for Form<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> FromRequest for Form<T>
where + T: DeserializeOwned + 'static,

See here for example of usage as an extractor.

+
§

type Error = Error

The associated error which can be returned.
§

type Future = FormExtractFut<T>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more
source§

impl<T: Ord> Ord for Form<T>

source§

fn cmp(&self, other: &Form<T>) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl<T: PartialEq> PartialEq for Form<T>

source§

fn eq(&self, other: &Form<T>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<T: PartialOrd> PartialOrd for Form<T>

source§

fn partial_cmp(&self, other: &Form<T>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<T: Serialize> Responder for Form<T>

See here for example of usage as a handler return type.

+
§

type Body = EitherBody<String>

source§

fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body>

Convert self to HttpResponse.
source§

fn customize(self) -> CustomizeResponder<Self>
where + Self: Sized,

Wraps responder to allow alteration of its response. Read more
source§

impl<T> Serialize for Form<T>
where + T: Serialize,

source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where + S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<T: Eq> Eq for Form<T>

source§

impl<T> StructuralPartialEq for Form<T>

Auto Trait Implementations§

§

impl<T> Freeze for Form<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for Form<T>
where + T: RefUnwindSafe,

§

impl<T> Send for Form<T>
where + T: Send,

§

impl<T> Sync for Form<T>
where + T: Sync,

§

impl<T> Unpin for Form<T>
where + T: Unpin,

§

impl<T> UnwindSafe for Form<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, P> Resource for T
where + T: DerefMut<Target = Path<P>>, + P: ResourcePath,

§

type Path = P

Type of resource’s path returned in resource_path.
source§

fn resource_path(&mut self) -> &mut Path<<T as Resource>::Path>

source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

impl<T> Formattable for T
where + T: Deref, + <T as Deref>::Target: Formattable,

§

impl<T> Parsable for T
where + T: Deref, + <T as Deref>::Target: Parsable,

\ No newline at end of file diff --git a/actix_web/web/struct.FormConfig.html b/actix_web/web/struct.FormConfig.html new file mode 100644 index 000000000..d0286107c --- /dev/null +++ b/actix_web/web/struct.FormConfig.html @@ -0,0 +1,41 @@ +FormConfig in actix_web::web - Rust

Struct actix_web::web::FormConfig

source ·
pub struct FormConfig { /* private fields */ }
Expand description

Form extractor configuration.

+ +
use actix_web::{post, web, App, FromRequest, Result};
+use serde::Deserialize;
+
+#[derive(Deserialize)]
+struct Info {
+    username: String,
+}
+
+// Custom `FormConfig` is applied to App.
+// Max payload size for URL encoded forms is set to 4kB.
+#[post("/")]
+async fn index(form: web::Form<Info>) -> Result<String> {
+    Ok(format!("Welcome {}!", form.username))
+}
+
+App::new()
+    .app_data(web::FormConfig::default().limit(4096))
+    .service(index);
+

Implementations§

source§

impl FormConfig

source

pub fn limit(self, limit: usize) -> Self

Set maximum accepted payload size. By default this limit is 16kB.

+
source

pub fn error_handler<F>(self, f: F) -> Self
where + F: Fn(UrlencodedError, &HttpRequest) -> Error + 'static,

Set custom error handler

+

Trait Implementations§

source§

impl Clone for FormConfig

source§

fn clone(&self) -> FormConfig

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Default for FormConfig

source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/web/struct.Header.html b/actix_web/web/struct.Header.html new file mode 100644 index 000000000..2dffee002 --- /dev/null +++ b/actix_web/web/struct.Header.html @@ -0,0 +1,57 @@ +Header in actix_web::web - Rust

Struct actix_web::web::Header

source ·
pub struct Header<T>(pub T);
Expand description

Extract typed headers from the request.

+

To extract a header, the inner type T must implement the +Header trait.

+

§Examples

+
use actix_web::{get, web, http::header};
+
+#[get("/")]
+async fn index(date: web::Header<header::Date>) -> String {
+    format!("Request was sent at {}", date.to_string())
+}
+

Tuple Fields§

§0: T

Implementations§

source§

impl<T> Header<T>

source

pub fn into_inner(self) -> T

Unwrap into the inner T value.

+

Trait Implementations§

source§

impl<T: Clone> Clone for Header<T>

source§

fn clone(&self) -> Header<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for Header<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> Deref for Header<T>

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &T

Dereferences the value.
source§

impl<T> DerefMut for Header<T>

source§

fn deref_mut(&mut self) -> &mut T

Mutably dereferences the value.
source§

impl<T> Display for Header<T>
where + T: Display,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> FromRequest for Header<T>
where + T: ParseHeader,

§

type Error = ParseError

The associated error which can be returned.
§

type Future = Ready<Result<Header<T>, <Header<T> as FromRequest>::Error>>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more
source§

impl<T: Ord> Ord for Header<T>

source§

fn cmp(&self, other: &Header<T>) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl<T: PartialEq> PartialEq for Header<T>

source§

fn eq(&self, other: &Header<T>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<T: PartialOrd> PartialOrd for Header<T>

source§

fn partial_cmp(&self, other: &Header<T>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<T: Eq> Eq for Header<T>

source§

impl<T> StructuralPartialEq for Header<T>

Auto Trait Implementations§

§

impl<T> Freeze for Header<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for Header<T>
where + T: RefUnwindSafe,

§

impl<T> Send for Header<T>
where + T: Send,

§

impl<T> Sync for Header<T>
where + T: Sync,

§

impl<T> Unpin for Header<T>
where + T: Unpin,

§

impl<T> UnwindSafe for Header<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, P> Resource for T
where + T: DerefMut<Target = Path<P>>, + P: ResourcePath,

§

type Path = P

Type of resource’s path returned in resource_path.
source§

fn resource_path(&mut self) -> &mut Path<<T as Resource>::Path>

source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

impl<T> Formattable for T
where + T: Deref, + <T as Deref>::Target: Formattable,

§

impl<T> Parsable for T
where + T: Deref, + <T as Deref>::Target: Parsable,

\ No newline at end of file diff --git a/actix_web/web/struct.Json.html b/actix_web/web/struct.Json.html new file mode 100644 index 000000000..91e52551a --- /dev/null +++ b/actix_web/web/struct.Json.html @@ -0,0 +1,75 @@ +Json in actix_web::web - Rust

Struct actix_web::web::Json

source ·
pub struct Json<T>(pub T);
Expand description

JSON extractor and responder.

+

Json has two uses: JSON responses, and extracting typed data from JSON request payloads.

+

§Extractor

+

To extract typed data from a request body, the inner type T must implement the +serde::Deserialize trait.

+

Use JsonConfig to configure extraction options.

+ +
use actix_web::{post, web, App};
+use serde::Deserialize;
+
+#[derive(Deserialize)]
+struct Info {
+    username: String,
+}
+
+/// deserialize `Info` from request's body
+#[post("/")]
+async fn index(info: web::Json<Info>) -> String {
+    format!("Welcome {}!", info.username)
+}
+

§Responder

+

The Json type JSON formatted responses. A handler may return a value of type +Json<T> where T is the type of a structure to serialize into JSON. The type T must +implement serde::Serialize.

+ +
use actix_web::{post, web, HttpRequest};
+use serde::Serialize;
+
+#[derive(Serialize)]
+struct Info {
+    name: String,
+}
+
+#[post("/{name}")]
+async fn index(req: HttpRequest) -> web::Json<Info> {
+    web::Json(Info {
+        name: req.match_info().get("name").unwrap().to_owned(),
+    })
+}
+

Tuple Fields§

§0: T

Implementations§

source§

impl<T> Json<T>

source

pub fn into_inner(self) -> T

Unwrap into inner T value.

+

Trait Implementations§

source§

impl<T: Debug> Debug for Json<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> Deref for Json<T>

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &T

Dereferences the value.
source§

impl<T> DerefMut for Json<T>

source§

fn deref_mut(&mut self) -> &mut T

Mutably dereferences the value.
source§

impl<T: Display> Display for Json<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: DeserializeOwned> FromRequest for Json<T>

See here for example of usage as an extractor.

+
§

type Error = Error

The associated error which can be returned.
§

type Future = JsonExtractFut<T>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more
source§

impl<T: Serialize> Responder for Json<T>

Creates response with OK status code, correct content type header, and serialized JSON payload.

+

If serialization failed

+
§

type Body = EitherBody<String>

source§

fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body>

Convert self to HttpResponse.
source§

fn customize(self) -> CustomizeResponder<Self>
where + Self: Sized,

Wraps responder to allow alteration of its response. Read more
source§

impl<T: Serialize> Serialize for Json<T>

source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where + S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<T> Freeze for Json<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for Json<T>
where + T: RefUnwindSafe,

§

impl<T> Send for Json<T>
where + T: Send,

§

impl<T> Sync for Json<T>
where + T: Sync,

§

impl<T> Unpin for Json<T>
where + T: Unpin,

§

impl<T> UnwindSafe for Json<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, P> Resource for T
where + T: DerefMut<Target = Path<P>>, + P: ResourcePath,

§

type Path = P

Type of resource’s path returned in resource_path.
source§

fn resource_path(&mut self) -> &mut Path<<T as Resource>::Path>

source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

impl<T> Formattable for T
where + T: Deref, + <T as Deref>::Target: Formattable,

§

impl<T> Parsable for T
where + T: Deref, + <T as Deref>::Target: Parsable,

\ No newline at end of file diff --git a/actix_web/web/struct.JsonConfig.html b/actix_web/web/struct.JsonConfig.html new file mode 100644 index 000000000..27f60de48 --- /dev/null +++ b/actix_web/web/struct.JsonConfig.html @@ -0,0 +1,54 @@ +JsonConfig in actix_web::web - Rust

Struct actix_web::web::JsonConfig

source ·
pub struct JsonConfig { /* private fields */ }
Expand description

Json extractor configuration.

+

§Examples

+
use actix_web::{error, post, web, App, FromRequest, HttpResponse};
+use serde::Deserialize;
+
+#[derive(Deserialize)]
+struct Info {
+    name: String,
+}
+
+// `Json` extraction is bound by custom `JsonConfig` applied to App.
+#[post("/")]
+async fn index(info: web::Json<Info>) -> String {
+    format!("Welcome {}!", info.name)
+}
+
+// custom `Json` extractor configuration
+let json_cfg = web::JsonConfig::default()
+    // limit request payload size
+    .limit(4096)
+    // only accept text/plain content type
+    .content_type(|mime| mime == mime::TEXT_PLAIN)
+    // use custom error handler
+    .error_handler(|err, req| {
+        error::InternalError::from_response(err, HttpResponse::Conflict().into()).into()
+    });
+
+App::new()
+    .app_data(json_cfg)
+    .service(index);
+

Implementations§

source§

impl JsonConfig

source

pub fn limit(self, limit: usize) -> Self

Set maximum accepted payload size. By default this limit is 2MB.

+
source

pub fn error_handler<F>(self, f: F) -> Self
where + F: Fn(JsonPayloadError, &HttpRequest) -> Error + Send + Sync + 'static,

Set custom error handler.

+
source

pub fn content_type<F>(self, predicate: F) -> Self
where + F: Fn(Mime) -> bool + Send + Sync + 'static,

Set predicate for allowed content types.

+
source

pub fn content_type_required(self, content_type_required: bool) -> Self

Sets whether or not the request must have a Content-Type header to be parsed.

+

Trait Implementations§

source§

impl Clone for JsonConfig

source§

fn clone(&self) -> JsonConfig

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Default for JsonConfig

source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/web/struct.Path.html b/actix_web/web/struct.Path.html new file mode 100644 index 000000000..c97e8caaa --- /dev/null +++ b/actix_web/web/struct.Path.html @@ -0,0 +1,78 @@ +Path in actix_web::web - Rust

Struct actix_web::web::Path

source ·
pub struct Path<T>(/* private fields */);
Expand description

Extract typed data from request path segments.

+

Use PathConfig to configure extraction option.

+

Unlike, HttpRequest::match_info, this extractor will fully percent-decode dynamic segments, +including /, %, and +.

+

§Examples

+
use actix_web::{get, web};
+
+// extract path info from "/{name}/{count}/index.html" into tuple
+// {name}  - deserialize a String
+// {count} - deserialize a u32
+#[get("/{name}/{count}/index.html")]
+async fn index(path: web::Path<(String, u32)>) -> String {
+    let (name, count) = path.into_inner();
+    format!("Welcome {}! {}", name, count)
+}
+

Path segments also can be deserialized into any type that implements serde::Deserialize. +Path segment labels will be matched with struct field names.

+ +
use actix_web::{get, web};
+use serde::Deserialize;
+
+#[derive(Deserialize)]
+struct Info {
+    name: String,
+}
+
+// extract `Info` from a path using serde
+#[get("/{name}")]
+async fn index(info: web::Path<Info>) -> String {
+    format!("Welcome {}!", info.name)
+}
+

Implementations§

source§

impl<T> Path<T>

source

pub fn into_inner(self) -> T

Unwrap into inner T value.

+

Trait Implementations§

source§

impl<T> AsRef<T> for Path<T>

source§

fn as_ref(&self) -> &T

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl<T: Debug> Debug for Path<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> Deref for Path<T>

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl<T> DerefMut for Path<T>

source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
source§

impl<T> Display for Path<T>
where + T: Display,

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> From<T> for Path<T>

source§

fn from(original: T) -> Path<T>

Converts to this type from the input type.
source§

impl<T> FromRequest for Path<T>
where + T: DeserializeOwned,

See here for example of usage as an extractor.

+
§

type Error = Error

The associated error which can be returned.
§

type Future = Ready<Result<Path<T>, <Path<T> as FromRequest>::Error>>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more
source§

impl<T: Ord> Ord for Path<T>

source§

fn cmp(&self, other: &Path<T>) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl<T: PartialEq> PartialEq for Path<T>

source§

fn eq(&self, other: &Path<T>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<T: PartialOrd> PartialOrd for Path<T>

source§

fn partial_cmp(&self, other: &Path<T>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<T: Eq> Eq for Path<T>

source§

impl<T> StructuralPartialEq for Path<T>

Auto Trait Implementations§

§

impl<T> Freeze for Path<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for Path<T>
where + T: RefUnwindSafe,

§

impl<T> Send for Path<T>
where + T: Send,

§

impl<T> Sync for Path<T>
where + T: Sync,

§

impl<T> Unpin for Path<T>
where + T: Unpin,

§

impl<T> UnwindSafe for Path<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<!> for T

source§

fn from(t: !) -> T

Converts to this type from the input type.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, P> Resource for T
where + T: DerefMut<Target = Path<P>>, + P: ResourcePath,

§

type Path = P

Type of resource’s path returned in resource_path.
source§

fn resource_path(&mut self) -> &mut Path<<T as Resource>::Path>

source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

impl<T> Formattable for T
where + T: Deref, + <T as Deref>::Target: Formattable,

§

impl<T> Parsable for T
where + T: Deref, + <T as Deref>::Target: Parsable,

\ No newline at end of file diff --git a/actix_web/web/struct.PathConfig.html b/actix_web/web/struct.PathConfig.html new file mode 100644 index 000000000..424dff9aa --- /dev/null +++ b/actix_web/web/struct.PathConfig.html @@ -0,0 +1,51 @@ +PathConfig in actix_web::web - Rust

Struct actix_web::web::PathConfig

source ·
pub struct PathConfig { /* private fields */ }
Expand description

Path extractor configuration

+ +
use actix_web::web::PathConfig;
+use actix_web::{error, web, App, FromRequest, HttpResponse};
+use serde::Deserialize;
+
+#[derive(Deserialize, Debug)]
+enum Folder {
+    #[serde(rename = "inbox")]
+    Inbox,
+
+    #[serde(rename = "outbox")]
+    Outbox,
+}
+
+// deserialize `Info` from request's path
+async fn index(folder: web::Path<Folder>) -> String {
+    format!("Selected folder: {:?}!", folder)
+}
+
+let app = App::new().service(
+    web::resource("/messages/{folder}")
+        .app_data(PathConfig::default().error_handler(|err, req| {
+            error::InternalError::from_response(
+                err,
+                HttpResponse::Conflict().into(),
+            )
+            .into()
+        }))
+        .route(web::post().to(index)),
+);
+

Implementations§

source§

impl PathConfig

source

pub fn error_handler<F>(self, f: F) -> Self
where + F: Fn(PathError, &HttpRequest) -> Error + Send + Sync + 'static,

Set custom error handler.

+

Trait Implementations§

source§

impl Clone for PathConfig

source§

fn clone(&self) -> PathConfig

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Default for PathConfig

source§

fn default() -> PathConfig

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/web/struct.Payload.html b/actix_web/web/struct.Payload.html new file mode 100644 index 000000000..61ef2ec77 --- /dev/null +++ b/actix_web/web/struct.Payload.html @@ -0,0 +1,312 @@ +Payload in actix_web::web - Rust

Struct actix_web::web::Payload

source ·
pub struct Payload(/* private fields */);
Expand description

Extract a request’s raw payload stream.

+

See PayloadConfig for important notes when using this advanced extractor.

+

§Examples

+
use std::future::Future;
+use futures_util::StreamExt as _;
+use actix_web::{post, web};
+
+// `body: web::Payload` parameter extracts raw payload stream from request
+#[post("/")]
+async fn index(mut body: web::Payload) -> actix_web::Result<String> {
+    // for demonstration only; in a normal case use the `Bytes` extractor
+    // collect payload stream into a bytes object
+    let mut bytes = web::BytesMut::new();
+    while let Some(item) = body.next().await {
+        bytes.extend_from_slice(&item?);
+    }
+
+    Ok(format!("Request Body Bytes:\n{:?}", bytes))
+}
+

Implementations§

source§

impl Payload

source

pub fn into_inner(self) -> Payload

Unwrap to inner Payload type.

+
source

pub async fn to_bytes_limited( + self, + limit: usize +) -> Result<Result<Bytes>, BodyLimitExceeded>

Buffers payload from request up to limit bytes.

+

This method is preferred over Payload::to_bytes() since it will not lead to unexpected +memory exhaustion from massive payloads. Note that the other primitive extractors such as +Bytes and String, as well as extractors built on top of them, already have this sort +of protection according to the configured (or default) PayloadConfig.

+
§Errors
+
    +
  • The outer error type, BodyLimitExceeded, is returned when the +payload is larger than limit.
  • +
  • The inner error type is the normal Actix Web error and is only returned if +the payload stream yields an error for some reason. Such cases are usually caused by +unrecoverable connection issues.
  • +
+
§Examples
+
use actix_web::{error, web::Payload, Responder};
+
+async fn limited_payload_handler(pl: Payload) -> actix_web::Result<impl Responder> {
+    match pl.to_bytes_limited(5).await {
+        Ok(res) => res,
+        Err(err) => Err(error::ErrorPayloadTooLarge(err)),
+    }
+}
+
source

pub async fn to_bytes(self) -> Result<Bytes>

Buffers entire payload from request.

+

Use of this method is discouraged unless you know for certain that requests will not be +large enough to exhaust memory. If this is not known, prefer Payload::to_bytes_limited() +or one of the higher level extractors like Bytes or String that implement size +limits according to the configured (or default) PayloadConfig.

+
§Errors
+

An error is only returned if the payload stream yields an error for some reason. Such cases +are usually caused by unrecoverable connection issues.

+
§Examples
+
use actix_web::{error, web::Payload, Responder};
+
+async fn payload_handler(pl: Payload) -> actix_web::Result<impl Responder> {
+    pl.to_bytes().await
+}
+

Trait Implementations§

source§

impl FromRequest for Payload

See here for example of usage as an extractor.

+
§

type Error = Error

The associated error which can be returned.
§

type Future = Ready<Result<Payload, <Payload as FromRequest>::Error>>

Future that resolves to a Self. Read more
source§

fn from_request(_: &HttpRequest, payload: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more
source§

impl Stream for Payload

§

type Item = Result<Bytes, PayloadError>

Values yielded by the stream.
source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Self::Item>>

Attempt to pull out the next value of this stream, registering the +current task for wakeup if the value is not yet available, and returning +None if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more

Auto Trait Implementations§

§

impl Freeze for Payload

§

impl !RefUnwindSafe for Payload

§

impl !Send for Payload

§

impl !Sync for Payload

§

impl Unpin for Payload

§

impl !UnwindSafe for Payload

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<T> StreamExt for T
where + T: Stream + ?Sized,

§

fn next(&mut self) -> Next<'_, Self>
where + Self: Unpin,

Creates a future that resolves to the next item in the stream. Read more
§

fn into_future(self) -> StreamFuture<Self>
where + Self: Sized + Unpin,

Converts this stream into a future of (next_item, tail_of_stream). +If the stream terminates, then the next item is None. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + F: FnMut(Self::Item) -> T, + Self: Sized,

Maps this stream’s items to a different type, returning a new stream of +the resulting type. Read more
§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates a stream which gives the current iteration count as well as +the next value. Read more
§

fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Filters the values produced by this stream according to the provided +asynchronous predicate. Read more
§

fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = Option<T>>, + Self: Sized,

Filters the values produced by this stream while simultaneously mapping +them to a different type according to the provided asynchronous closure. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized,

Computes from this stream’s items new items of a different type using +an asynchronous closure. Read more
§

fn collect<C>(self) -> Collect<Self, C>
where + C: Default + Extend<Self::Item>, + Self: Sized,

Transforms a stream into a collection, returning a +future representing the result of that computation. Read more
§

fn unzip<A, B, FromA, FromB>(self) -> Unzip<Self, FromA, FromB>
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Stream<Item = (A, B)>,

Converts a stream of pairs into a future, which +resolves to pair of containers. Read more
§

fn concat(self) -> Concat<Self>
where + Self: Sized, + Self::Item: Extend<<Self::Item as IntoIterator>::Item> + IntoIterator + Default,

Concatenate all items of a stream into a single extendable +destination, returning a future representing the end result. Read more
§

fn count(self) -> Count<Self>
where + Self: Sized,

Drives the stream to completion, counting the number of items. Read more
§

fn cycle(self) -> Cycle<Self>
where + Self: Sized + Clone,

Repeats a stream endlessly. Read more
§

fn fold<T, Fut, F>(self, init: T, f: F) -> Fold<Self, Fut, T, F>
where + F: FnMut(T, Self::Item) -> Fut, + Fut: Future<Output = T>, + Self: Sized,

Execute an accumulating asynchronous computation over a stream, +collecting all the values into one final result. Read more
§

fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if any element in stream satisfied a predicate. Read more
§

fn all<Fut, F>(self, f: F) -> All<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if all element in stream satisfied a predicate. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Item: Stream, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> FlattenUnorderedWithFlowController<Self, ()>
where + Self::Item: Stream + Unpin, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Polls +inner streams produced by the base stream concurrently. Read more
§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + F: FnMut(Self::Item) -> U, + U: Stream, + Self: Sized,

Maps a stream like [StreamExt::map] but flattens nested Streams. Read more
§

fn flat_map_unordered<U, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> FlatMapUnordered<Self, U, F>
where + U: Stream + Unpin, + F: FnMut(Self::Item) -> U, + Self: Sized,

Available on crate feature alloc only.
Maps a stream like [StreamExt::map] but flattens nested Streams +and polls them concurrently, yielding items in any order, as they made +available. Read more
§

fn scan<S, B, Fut, F>(self, initial_state: S, f: F) -> Scan<Self, S, Fut, F>
where + F: FnMut(&mut S, Self::Item) -> Fut, + Fut: Future<Output = Option<B>>, + Self: Sized,

Combinator similar to [StreamExt::fold] that holds internal state +and produces a new stream. Read more
§

fn skip_while<Fut, F>(self, f: F) -> SkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_while<Fut, F>(self, f: F) -> TakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Take elements from this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_until<Fut>(self, fut: Fut) -> TakeUntil<Self, Fut>
where + Fut: Future, + Self: Sized,

Take elements from this stream until the provided future resolves. Read more
§

fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream. Read more
§

fn for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> ForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Available on crate feature alloc only.
Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates a new stream of at most n items of the underlying stream. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates a new stream which skips n items of the underlying stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a stream such that poll_next will never +again be called once it has finished. This method can be used to turn +any Stream into a FusedStream. Read more
§

fn by_ref(&mut self) -> &mut Self

Borrows a stream, rather than consuming it. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the stream. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn buffered(self, n: usize) -> Buffered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures. Read more
§

fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures (unordered). Read more
§

fn zip<St>(self, other: St) -> Zip<Self, St>
where + St: Stream, + Self: Sized,

An adapter for zipping two streams together. Read more
§

fn chain<St>(self, other: St) -> Chain<Self, St>
where + St: Stream<Item = Self::Item>, + Self: Sized,

Adapter for chaining two streams. Read more
§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates a new stream which exposes a peek method. Read more
§

fn chunks(self, capacity: usize) -> Chunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up items of the stream inside a vector. Read more
§

fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up ready items of the stream inside a vector. Read more
§

fn forward<S>(self, sink: S) -> Forward<Self, S>
where + S: Sink<Self::Ok, Error = Self::Error>, + Self: Sized + TryStream,

Available on crate feature sink only.
A future that completes after the given stream has been fully processed +into the sink and the sink has been flushed and closed. Read more
§

fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
where + Self: Sized + Sink<Item>,

Available on crate features sink and alloc only.
Splits this Stream + Sink object into separate Sink and Stream +objects. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnMut(&Self::Item), + Self: Sized,

Do something with each item of this stream, afterwards passing it on. Read more
§

fn left_stream<B>(self) -> Either<Self, B>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the left-hand variant +of that Either. Read more
§

fn right_stream<B>(self) -> Either<B, Self>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the right-hand variant +of that Either. Read more
§

fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>
where + Self: Unpin,

A convenience method for calling [Stream::poll_next] on Unpin +stream types.
§

fn select_next_some(&mut self) -> SelectNextSome<'_, Self>
where + Self: Unpin + FusedStream,

Returns a Future that resolves when the next item in this stream is +ready. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<S, T, E> TryStream for S
where + S: Stream<Item = 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
§

fn try_poll_next( + self: Pin<&mut S>, + cx: &mut Context<'_> +) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>>

Poll this TryStream as if it were a Stream. Read more
§

impl<S> TryStreamExt for S
where + S: TryStream + ?Sized,

§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Wraps the current stream in a new stream which converts the error type +into the one provided. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> T,

Wraps the current stream in a new stream which maps the success value +using the provided closure. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + Self: Sized, + F: FnMut(Self::Error) -> E,

Wraps the current stream in a new stream which maps the error value +using the provided closure. Read more
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Chain on a computation for when a value is ready, passing the successful +results to the provided closure f. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnMut(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Chain on a computation for when an error happens, passing the +erroneous result to the provided closure f. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnMut(&Self::Ok), + Self: Sized,

Do something with the success value of this stream, afterwards passing +it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnMut(&Self::Error), + Self: Sized,

Do something with the error value of this stream, afterwards passing it on. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Wraps a [TryStream] into a type that implements +Stream Read more
§

fn try_next(&mut self) -> TryNext<'_, Self>
where + Self: Unpin,

Creates a future that attempts to resolve the next item in the stream. +If an error is encountered before the next item, the error is returned +instead. Read more
§

fn try_for_each<Fut, F>(self, f: F) -> TryForEach<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Ok = (), Error = Self::Error>, + Self: Sized,

Attempts to run this stream to completion, executing the provided +asynchronous closure for each element on the stream. Read more
§

fn try_skip_while<Fut, F>(self, f: F) -> TrySkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_take_while<Fut, F>(self, f: F) -> TryTakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Take elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> TryForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = Result<(), Self::Error>>, + Self: Sized,

Available on crate feature alloc only.
Attempts to run this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available, exiting as soon as an error occurs. Read more
§

fn try_collect<C>(self) -> TryCollect<Self, C>
where + C: Default + Extend<Self::Ok>, + Self: Sized,

Attempt to transform a stream into a collection, +returning a future representing the result of that computation. Read more
§

fn try_chunks(self, capacity: usize) -> TryChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful items of the stream inside a vector. Read more
§

fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful, ready items of the stream inside a vector. Read more
§

fn try_filter<Fut, F>(self, f: F) -> TryFilter<Self, Fut, F>
where + Fut: Future<Output = bool>, + F: FnMut(&Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream according to the +provided asynchronous closure. Read more
§

fn try_filter_map<Fut, F, T>(self, f: F) -> TryFilterMap<Self, Fut, F>
where + Fut: TryFuture<Ok = Option<T>, Error = Self::Error>, + F: FnMut(Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream while +simultaneously mapping them to a different type according to the +provided asynchronous closure. Read more
§

fn try_flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> TryFlattenUnordered<Self>
where + Self::Ok: TryStream + Unpin, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Produced streams +will be polled concurrently and any errors will be passed through without looking at them. +If the underlying base stream returns an error, it will be immediately propagated. Read more
§

fn try_flatten(self) -> TryFlatten<Self>
where + Self::Ok: TryStream, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn try_fold<T, Fut, F>(self, init: T, f: F) -> TryFold<Self, Fut, T, F>
where + F: FnMut(T, Self::Ok) -> Fut, + Fut: TryFuture<Ok = T, Error = Self::Error>, + Self: Sized,

Attempt to execute an accumulating asynchronous computation over a +stream, collecting all the values into one final result. Read more
§

fn try_concat(self) -> TryConcat<Self>
where + Self: Sized, + Self::Ok: Extend<<Self::Ok as IntoIterator>::Item> + IntoIterator + Default,

Attempt to concatenate all items of a stream into a single +extendable destination, returning a future representing the end result. Read more
§

fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently (unordered). Read more
§

fn try_buffered(self, n: usize) -> TryBuffered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently. Read more
§

fn try_poll_next_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Option<Result<Self::Ok, Self::Error>>>
where + Self: Unpin,

A convenience method for calling [TryStream::try_poll_next] on Unpin +stream types.
§

fn try_all<Fut, F>(self, f: F) -> TryAll<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if all items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that does not satisfy the predicate. Read more
§

fn try_any<Fut, F>(self, f: F) -> TryAny<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if any items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that satisfies the predicate. Read more
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/web/struct.PayloadConfig.html b/actix_web/web/struct.PayloadConfig.html new file mode 100644 index 000000000..79ef36616 --- /dev/null +++ b/actix_web/web/struct.PayloadConfig.html @@ -0,0 +1,29 @@ +PayloadConfig in actix_web::web - Rust

Struct actix_web::web::PayloadConfig

source ·
pub struct PayloadConfig { /* private fields */ }
Expand description

Configuration for request payloads.

+

Applies to the built-in Bytes and String extractors. +Note that the Payload extractor does not automatically check +conformance with this configuration to allow more flexibility when +building extractors on top of Payload.

+

By default, the payload size limit is 256kB and there is no mime type condition.

+

To use this, add an instance of it to your app, scope +or resource through the associated .app_data() method.

+

Implementations§

source§

impl PayloadConfig

source

pub fn new(limit: usize) -> Self

Create new instance with a size limit (in bytes) and no mime type condition.

+
source

pub fn limit(self, limit: usize) -> Self

Set maximum accepted payload size in bytes. The default limit is 256KiB.

+
source

pub fn mimetype(self, mt: Mime) -> Self

Set required mime type of the request. By default mime type is not enforced.

+

Trait Implementations§

source§

impl Clone for PayloadConfig

source§

fn clone(&self) -> PayloadConfig

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Default for PayloadConfig

source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/web/struct.Query.html b/actix_web/web/struct.Query.html new file mode 100644 index 000000000..fe47ef6ea --- /dev/null +++ b/actix_web/web/struct.Query.html @@ -0,0 +1,96 @@ +Query in actix_web::web - Rust

Struct actix_web::web::Query

source ·
pub struct Query<T>(pub T);
Expand description

Extract typed information from the request’s query.

+

To extract typed data from the URL query string, the inner type T must implement the +DeserializeOwned trait.

+

Use QueryConfig to configure extraction process.

+

§Panics

+

A query string consists of unordered key=value pairs, therefore it cannot be decoded into any +type which depends upon data ordering (eg. tuples). Trying to do so will result in a panic.

+

§Examples

+
use actix_web::{get, web};
+use serde::Deserialize;
+
+#[derive(Debug, Deserialize)]
+pub enum ResponseType {
+   Token,
+   Code
+}
+
+#[derive(Debug, Deserialize)]
+pub struct AuthRequest {
+   id: u64,
+   response_type: ResponseType,
+}
+
+// Deserialize `AuthRequest` struct from query string.
+// This handler gets called only if the request's query parameters contain both fields.
+// A valid request path for this handler would be `/?id=64&response_type=Code"`.
+#[get("/")]
+async fn index(info: web::Query<AuthRequest>) -> String {
+    format!("Authorization request for id={} and type={:?}!", info.id, info.response_type)
+}
+
+// To access the entire underlying query struct, use `.into_inner()`.
+#[get("/debug1")]
+async fn debug1(info: web::Query<AuthRequest>) -> String {
+    dbg!("Authorization object = {:?}", info.into_inner());
+    "OK".to_string()
+}
+
+// Or use destructuring, which is equivalent to `.into_inner()`.
+#[get("/debug2")]
+async fn debug2(web::Query(info): web::Query<AuthRequest>) -> String {
+    dbg!("Authorization object = {:?}", info);
+    "OK".to_string()
+}
+

Tuple Fields§

§0: T

Implementations§

source§

impl<T> Query<T>

source

pub fn into_inner(self) -> T

Unwrap into inner T value.

+
source§

impl<T: DeserializeOwned> Query<T>

source

pub fn from_query(query_str: &str) -> Result<Self, QueryPayloadError>

Deserialize a T from the URL encoded query parameter string.

+ +
let numbers = Query::<HashMap<String, u32>>::from_query("one=1&two=2").unwrap();
+assert_eq!(numbers.get("one"), Some(&1));
+assert_eq!(numbers.get("two"), Some(&2));
+assert!(numbers.get("three").is_none());
+

Trait Implementations§

source§

impl<T: Clone> Clone for Query<T>

source§

fn clone(&self) -> Query<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for Query<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T> Deref for Query<T>

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &T

Dereferences the value.
source§

impl<T> DerefMut for Query<T>

source§

fn deref_mut(&mut self) -> &mut T

Mutably dereferences the value.
source§

impl<T: Display> Display for Query<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: DeserializeOwned> FromRequest for Query<T>

See here for example of usage as an extractor.

+
§

type Error = Error

The associated error which can be returned.
§

type Future = Ready<Result<Query<T>, Error>>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more
source§

impl<T: Ord> Ord for Query<T>

source§

fn cmp(&self, other: &Query<T>) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl<T: PartialEq> PartialEq for Query<T>

source§

fn eq(&self, other: &Query<T>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<T: PartialOrd> PartialOrd for Query<T>

source§

fn partial_cmp(&self, other: &Query<T>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<T: Eq> Eq for Query<T>

source§

impl<T> StructuralPartialEq for Query<T>

Auto Trait Implementations§

§

impl<T> Freeze for Query<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for Query<T>
where + T: RefUnwindSafe,

§

impl<T> Send for Query<T>
where + T: Send,

§

impl<T> Sync for Query<T>
where + T: Sync,

§

impl<T> Unpin for Query<T>
where + T: Unpin,

§

impl<T> UnwindSafe for Query<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T, P> Resource for T
where + T: DerefMut<Target = Path<P>>, + P: ResourcePath,

§

type Path = P

Type of resource’s path returned in resource_path.
source§

fn resource_path(&mut self) -> &mut Path<<T as Resource>::Path>

source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

impl<T> Formattable for T
where + T: Deref, + <T as Deref>::Target: Formattable,

§

impl<T> Parsable for T
where + T: Deref, + <T as Deref>::Target: Parsable,

\ No newline at end of file diff --git a/actix_web/web/struct.QueryConfig.html b/actix_web/web/struct.QueryConfig.html new file mode 100644 index 000000000..a825f51d0 --- /dev/null +++ b/actix_web/web/struct.QueryConfig.html @@ -0,0 +1,46 @@ +QueryConfig in actix_web::web - Rust

Struct actix_web::web::QueryConfig

source ·
pub struct QueryConfig { /* private fields */ }
Expand description

Query extractor configuration.

+

§Examples

+
use actix_web::{error, get, web, App, FromRequest, HttpResponse};
+use serde::Deserialize;
+
+#[derive(Deserialize)]
+struct Info {
+    username: String,
+}
+
+/// deserialize `Info` from request's querystring
+#[get("/")]
+async fn index(info: web::Query<Info>) -> String {
+    format!("Welcome {}!", info.username)
+}
+
+// custom `Query` extractor configuration
+let query_cfg = web::QueryConfig::default()
+    // use custom error handler
+    .error_handler(|err, req| {
+        error::InternalError::from_response(err, HttpResponse::Conflict().finish()).into()
+    });
+
+App::new()
+    .app_data(query_cfg)
+    .service(index);
+

Implementations§

source§

impl QueryConfig

source

pub fn error_handler<F>(self, f: F) -> Self
where + F: Fn(QueryPayloadError, &HttpRequest) -> Error + Send + Sync + 'static,

Set custom error handler

+

Trait Implementations§

source§

impl Clone for QueryConfig

source§

fn clone(&self) -> QueryConfig

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Default for QueryConfig

source§

fn default() -> QueryConfig

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/web/struct.Readlines.html b/actix_web/web/struct.Readlines.html new file mode 100644 index 000000000..08a508372 --- /dev/null +++ b/actix_web/web/struct.Readlines.html @@ -0,0 +1,260 @@ +Readlines in actix_web::web - Rust

Struct actix_web::web::Readlines

source ·
pub struct Readlines<T: HttpMessage> { /* private fields */ }
Expand description

Stream that reads request line by line.

+

Implementations§

source§

impl<T> Readlines<T>
where + T: HttpMessage, + T::Stream: Stream<Item = Result<Bytes, PayloadError>> + Unpin,

source

pub fn new(req: &mut T) -> Self

Create a new stream to read request line by line.

+
source

pub fn limit(self, limit: usize) -> Self

Set maximum accepted payload size. The default limit is 256kB.

+

Trait Implementations§

source§

impl<T> Stream for Readlines<T>
where + T: HttpMessage, + T::Stream: Stream<Item = Result<Bytes, PayloadError>> + Unpin,

§

type Item = Result<String, ReadlinesError>

Values yielded by the stream.
source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Self::Item>>

Attempt to pull out the next value of this stream, registering the +current task for wakeup if the value is not yet available, and returning +None if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more

Auto Trait Implementations§

§

impl<T> !Freeze for Readlines<T>

§

impl<T> !RefUnwindSafe for Readlines<T>

§

impl<T> !Send for Readlines<T>

§

impl<T> !Sync for Readlines<T>

§

impl<T> Unpin for Readlines<T>
where + <T as HttpMessage>::Stream: Unpin,

§

impl<T> !UnwindSafe for Readlines<T>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<T> StreamExt for T
where + T: Stream + ?Sized,

§

fn next(&mut self) -> Next<'_, Self>
where + Self: Unpin,

Creates a future that resolves to the next item in the stream. Read more
§

fn into_future(self) -> StreamFuture<Self>
where + Self: Sized + Unpin,

Converts this stream into a future of (next_item, tail_of_stream). +If the stream terminates, then the next item is None. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + F: FnMut(Self::Item) -> T, + Self: Sized,

Maps this stream’s items to a different type, returning a new stream of +the resulting type. Read more
§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates a stream which gives the current iteration count as well as +the next value. Read more
§

fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Filters the values produced by this stream according to the provided +asynchronous predicate. Read more
§

fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = Option<T>>, + Self: Sized,

Filters the values produced by this stream while simultaneously mapping +them to a different type according to the provided asynchronous closure. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized,

Computes from this stream’s items new items of a different type using +an asynchronous closure. Read more
§

fn collect<C>(self) -> Collect<Self, C>
where + C: Default + Extend<Self::Item>, + Self: Sized,

Transforms a stream into a collection, returning a +future representing the result of that computation. Read more
§

fn unzip<A, B, FromA, FromB>(self) -> Unzip<Self, FromA, FromB>
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Stream<Item = (A, B)>,

Converts a stream of pairs into a future, which +resolves to pair of containers. Read more
§

fn concat(self) -> Concat<Self>
where + Self: Sized, + Self::Item: Extend<<Self::Item as IntoIterator>::Item> + IntoIterator + Default,

Concatenate all items of a stream into a single extendable +destination, returning a future representing the end result. Read more
§

fn count(self) -> Count<Self>
where + Self: Sized,

Drives the stream to completion, counting the number of items. Read more
§

fn cycle(self) -> Cycle<Self>
where + Self: Sized + Clone,

Repeats a stream endlessly. Read more
§

fn fold<T, Fut, F>(self, init: T, f: F) -> Fold<Self, Fut, T, F>
where + F: FnMut(T, Self::Item) -> Fut, + Fut: Future<Output = T>, + Self: Sized,

Execute an accumulating asynchronous computation over a stream, +collecting all the values into one final result. Read more
§

fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if any element in stream satisfied a predicate. Read more
§

fn all<Fut, F>(self, f: F) -> All<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if all element in stream satisfied a predicate. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Item: Stream, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> FlattenUnorderedWithFlowController<Self, ()>
where + Self::Item: Stream + Unpin, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Polls +inner streams produced by the base stream concurrently. Read more
§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + F: FnMut(Self::Item) -> U, + U: Stream, + Self: Sized,

Maps a stream like [StreamExt::map] but flattens nested Streams. Read more
§

fn flat_map_unordered<U, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> FlatMapUnordered<Self, U, F>
where + U: Stream + Unpin, + F: FnMut(Self::Item) -> U, + Self: Sized,

Available on crate feature alloc only.
Maps a stream like [StreamExt::map] but flattens nested Streams +and polls them concurrently, yielding items in any order, as they made +available. Read more
§

fn scan<S, B, Fut, F>(self, initial_state: S, f: F) -> Scan<Self, S, Fut, F>
where + F: FnMut(&mut S, Self::Item) -> Fut, + Fut: Future<Output = Option<B>>, + Self: Sized,

Combinator similar to [StreamExt::fold] that holds internal state +and produces a new stream. Read more
§

fn skip_while<Fut, F>(self, f: F) -> SkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_while<Fut, F>(self, f: F) -> TakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Take elements from this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_until<Fut>(self, fut: Fut) -> TakeUntil<Self, Fut>
where + Fut: Future, + Self: Sized,

Take elements from this stream until the provided future resolves. Read more
§

fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream. Read more
§

fn for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> ForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Available on crate feature alloc only.
Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates a new stream of at most n items of the underlying stream. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates a new stream which skips n items of the underlying stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a stream such that poll_next will never +again be called once it has finished. This method can be used to turn +any Stream into a FusedStream. Read more
§

fn by_ref(&mut self) -> &mut Self

Borrows a stream, rather than consuming it. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the stream. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn buffered(self, n: usize) -> Buffered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures. Read more
§

fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures (unordered). Read more
§

fn zip<St>(self, other: St) -> Zip<Self, St>
where + St: Stream, + Self: Sized,

An adapter for zipping two streams together. Read more
§

fn chain<St>(self, other: St) -> Chain<Self, St>
where + St: Stream<Item = Self::Item>, + Self: Sized,

Adapter for chaining two streams. Read more
§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates a new stream which exposes a peek method. Read more
§

fn chunks(self, capacity: usize) -> Chunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up items of the stream inside a vector. Read more
§

fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up ready items of the stream inside a vector. Read more
§

fn forward<S>(self, sink: S) -> Forward<Self, S>
where + S: Sink<Self::Ok, Error = Self::Error>, + Self: Sized + TryStream,

Available on crate feature sink only.
A future that completes after the given stream has been fully processed +into the sink and the sink has been flushed and closed. Read more
§

fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
where + Self: Sized + Sink<Item>,

Available on crate features sink and alloc only.
Splits this Stream + Sink object into separate Sink and Stream +objects. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnMut(&Self::Item), + Self: Sized,

Do something with each item of this stream, afterwards passing it on. Read more
§

fn left_stream<B>(self) -> Either<Self, B>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the left-hand variant +of that Either. Read more
§

fn right_stream<B>(self) -> Either<B, Self>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the right-hand variant +of that Either. Read more
§

fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>
where + Self: Unpin,

A convenience method for calling [Stream::poll_next] on Unpin +stream types.
§

fn select_next_some(&mut self) -> SelectNextSome<'_, Self>
where + Self: Unpin + FusedStream,

Returns a Future that resolves when the next item in this stream is +ready. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<S, T, E> TryStream for S
where + S: Stream<Item = 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
§

fn try_poll_next( + self: Pin<&mut S>, + cx: &mut Context<'_> +) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>>

Poll this TryStream as if it were a Stream. Read more
§

impl<S> TryStreamExt for S
where + S: TryStream + ?Sized,

§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Wraps the current stream in a new stream which converts the error type +into the one provided. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> T,

Wraps the current stream in a new stream which maps the success value +using the provided closure. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + Self: Sized, + F: FnMut(Self::Error) -> E,

Wraps the current stream in a new stream which maps the error value +using the provided closure. Read more
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Chain on a computation for when a value is ready, passing the successful +results to the provided closure f. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnMut(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Chain on a computation for when an error happens, passing the +erroneous result to the provided closure f. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnMut(&Self::Ok), + Self: Sized,

Do something with the success value of this stream, afterwards passing +it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnMut(&Self::Error), + Self: Sized,

Do something with the error value of this stream, afterwards passing it on. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Wraps a [TryStream] into a type that implements +Stream Read more
§

fn try_next(&mut self) -> TryNext<'_, Self>
where + Self: Unpin,

Creates a future that attempts to resolve the next item in the stream. +If an error is encountered before the next item, the error is returned +instead. Read more
§

fn try_for_each<Fut, F>(self, f: F) -> TryForEach<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Ok = (), Error = Self::Error>, + Self: Sized,

Attempts to run this stream to completion, executing the provided +asynchronous closure for each element on the stream. Read more
§

fn try_skip_while<Fut, F>(self, f: F) -> TrySkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_take_while<Fut, F>(self, f: F) -> TryTakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Take elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> TryForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = Result<(), Self::Error>>, + Self: Sized,

Available on crate feature alloc only.
Attempts to run this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available, exiting as soon as an error occurs. Read more
§

fn try_collect<C>(self) -> TryCollect<Self, C>
where + C: Default + Extend<Self::Ok>, + Self: Sized,

Attempt to transform a stream into a collection, +returning a future representing the result of that computation. Read more
§

fn try_chunks(self, capacity: usize) -> TryChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful items of the stream inside a vector. Read more
§

fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful, ready items of the stream inside a vector. Read more
§

fn try_filter<Fut, F>(self, f: F) -> TryFilter<Self, Fut, F>
where + Fut: Future<Output = bool>, + F: FnMut(&Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream according to the +provided asynchronous closure. Read more
§

fn try_filter_map<Fut, F, T>(self, f: F) -> TryFilterMap<Self, Fut, F>
where + Fut: TryFuture<Ok = Option<T>, Error = Self::Error>, + F: FnMut(Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream while +simultaneously mapping them to a different type according to the +provided asynchronous closure. Read more
§

fn try_flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> TryFlattenUnordered<Self>
where + Self::Ok: TryStream + Unpin, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Produced streams +will be polled concurrently and any errors will be passed through without looking at them. +If the underlying base stream returns an error, it will be immediately propagated. Read more
§

fn try_flatten(self) -> TryFlatten<Self>
where + Self::Ok: TryStream, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn try_fold<T, Fut, F>(self, init: T, f: F) -> TryFold<Self, Fut, T, F>
where + F: FnMut(T, Self::Ok) -> Fut, + Fut: TryFuture<Ok = T, Error = Self::Error>, + Self: Sized,

Attempt to execute an accumulating asynchronous computation over a +stream, collecting all the values into one final result. Read more
§

fn try_concat(self) -> TryConcat<Self>
where + Self: Sized, + Self::Ok: Extend<<Self::Ok as IntoIterator>::Item> + IntoIterator + Default,

Attempt to concatenate all items of a stream into a single +extendable destination, returning a future representing the end result. Read more
§

fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently (unordered). Read more
§

fn try_buffered(self, n: usize) -> TryBuffered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently. Read more
§

fn try_poll_next_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Option<Result<Self::Ok, Self::Error>>>
where + Self: Unpin,

A convenience method for calling [TryStream::try_poll_next] on Unpin +stream types.
§

fn try_all<Fut, F>(self, f: F) -> TryAll<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if all items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that does not satisfy the predicate. Read more
§

fn try_any<Fut, F>(self, f: F) -> TryAny<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if any items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that satisfies the predicate. Read more
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/web/struct.Redirect.html b/actix_web/web/struct.Redirect.html new file mode 100644 index 000000000..7ddf098a4 --- /dev/null +++ b/actix_web/web/struct.Redirect.html @@ -0,0 +1,86 @@ +Redirect in actix_web::web - Rust

Struct actix_web::web::Redirect

source ·
pub struct Redirect { /* private fields */ }
Expand description

An HTTP service for redirecting one path to another path or URL.

+

By default, the “307 Temporary Redirect” status is used when responding. See this MDN +article on why 307 is preferred over 302.

+

§Examples

+

As service:

+ +
use actix_web::{web, App};
+
+App::new()
+    // redirect "/duck" to DuckDuckGo
+    .service(web::redirect("/duck", "https://duck.com"))
+    .service(
+        // redirect "/api/old" to "/api/new"
+        web::scope("/api").service(web::redirect("/old", "/new"))
+    );
+

As responder:

+ +
use actix_web::{web::Redirect, Responder};
+
+async fn handler() -> impl Responder {
+    // sends a permanent (308) redirect to duck.com
+    Redirect::to("https://duck.com").permanent()
+}
+

Implementations§

source§

impl Redirect

source

pub fn new( + from: impl Into<Cow<'static, str>>, + to: impl Into<Cow<'static, str>> +) -> Self

Construct a new Redirect service that matches a path.

+

This service will match exact paths equal to from within the current scope. I.e., when +registered on the root App, it will match exact, whole paths. But when registered on a +Scope, it will match paths under that scope, ignoring the defined scope prefix, just like +a normal Resource or Route.

+

The to argument can be path or URL; whatever is provided shall be used verbatim when +setting the redirect location. This means that relative paths can be used to navigate +relatively to matched paths.

+

Prefer Redirect::to() when using Redirect as a responder since from has +no meaning in that context.

+
§Examples
+
App::new()
+    // redirects "/oh/hi/mark" to "/oh/bye/johnny"
+    .service(Redirect::new("/oh/hi/mark", "../../bye/johnny"));
+
source

pub fn to(to: impl Into<Cow<'static, str>>) -> Self

Construct a new Redirect to use as a responder.

+

Only receives the to argument since responders do not need to do route matching.

+
§Examples
+
use actix_web::{web::Redirect, Responder};
+
+async fn admin_page() -> impl Responder {
+    // sends a temporary 307 redirect to the login path
+    Redirect::to("/login")
+}
+
source

pub fn permanent(self) -> Self

Use the “308 Permanent Redirect” status when responding.

+

See this MDN article on why 308 is preferred over 301.

+
source

pub fn temporary(self) -> Self

Use the “307 Temporary Redirect” status when responding.

+

See this MDN article on why 307 is preferred over 302.

+
source

pub fn see_other(self) -> Self

Use the “303 See Other” status when responding.

+

This status code is semantically correct as the response to a successful login, for example.

+
source

pub fn using_status_code(self, status: StatusCode) -> Self

Allows the use of custom status codes for less common redirect types.

+

In most cases, the default status (“308 Permanent Redirect”) or using the temporary +method, which uses the “307 Temporary Redirect” status have more consistent behavior than +301 and 302 codes, respectively.

+ +
// redirects would use "301 Moved Permanently" status code
+Redirect::new("/old", "/new")
+    .using_status_code(StatusCode::MOVED_PERMANENTLY);
+
+// redirects would use "302 Found" status code
+Redirect::new("/old", "/new")
+    .using_status_code(StatusCode::FOUND);
+

Trait Implementations§

source§

impl Clone for Redirect

source§

fn clone(&self) -> Redirect

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Redirect

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl HttpServiceFactory for Redirect

source§

fn register(self, config: &mut AppService)

source§

impl Responder for Redirect

§

type Body = ()

source§

fn respond_to(self, _req: &HttpRequest) -> HttpResponse<Self::Body>

Convert self to HttpResponse.
source§

fn customize(self) -> CustomizeResponder<Self>
where + Self: Sized,

Wraps responder to allow alteration of its response. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/web/struct.ReqData.html b/actix_web/web/struct.ReqData.html new file mode 100644 index 000000000..800890907 --- /dev/null +++ b/actix_web/web/struct.ReqData.html @@ -0,0 +1,58 @@ +ReqData in actix_web::web - Rust

Struct actix_web::web::ReqData

source ·
pub struct ReqData<T: Clone + 'static>(/* private fields */);
Expand description

Request-local data extractor.

+

Request-local data is arbitrary data attached to an individual request, usually +by middleware. It can be set via extensions_mut on HttpRequest +or ServiceRequest.

+

Unlike app data, request data is dropped when the request has finished processing. This makes it +useful as a kind of messaging system between middleware and request handlers. It uses the same +types-as-keys storage system as app data.

+

§Mutating Request Data

+

Note that since extractors must output owned data, only types that impl Clone can use this +extractor. A clone is taken of the required request data and can, therefore, not be directly +mutated in-place. To mutate request data, continue to use HttpRequest::extensions_mut or +re-insert the cloned data back into the extensions map. A DerefMut impl is intentionally not +provided to make this potential foot-gun more obvious.

+

§Examples

+
#[derive(Debug, Clone, PartialEq)]
+struct FlagFromMiddleware(String);
+
+/// Use the `ReqData<T>` extractor to access request data in a handler.
+async fn handler(
+    req: HttpRequest,
+    opt_flag: Option<web::ReqData<FlagFromMiddleware>>,
+) -> impl Responder {
+    // use an option extractor if middleware is not guaranteed to add this type of req data
+    if let Some(flag) = opt_flag {
+        assert_eq!(&flag.into_inner(), req.extensions().get::<FlagFromMiddleware>().unwrap());
+    }
+
+    HttpResponse::Ok()
+}
+

Implementations§

source§

impl<T: Clone + 'static> ReqData<T>

source

pub fn into_inner(self) -> T

Consumes the ReqData, returning its wrapped data.

+

Trait Implementations§

source§

impl<T: Clone + Clone + 'static> Clone for ReqData<T>

source§

fn clone(&self) -> ReqData<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug + Clone + 'static> Debug for ReqData<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: Clone + 'static> Deref for ReqData<T>

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &T

Dereferences the value.
source§

impl<T: Clone + 'static> FromRequest for ReqData<T>

§

type Error = Error

The associated error which can be returned.
§

type Future = Ready<Result<ReqData<T>, Error>>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more

Auto Trait Implementations§

§

impl<T> Freeze for ReqData<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for ReqData<T>
where + T: RefUnwindSafe,

§

impl<T> Send for ReqData<T>
where + T: Send,

§

impl<T> Sync for ReqData<T>
where + T: Sync,

§

impl<T> Unpin for ReqData<T>
where + T: Unpin,

§

impl<T> UnwindSafe for ReqData<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

impl<T> Formattable for T
where + T: Deref, + <T as Deref>::Target: Formattable,

§

impl<T> Parsable for T
where + T: Deref, + <T as Deref>::Target: Parsable,

\ No newline at end of file diff --git a/actix_web/web/struct.ServiceConfig.html b/actix_web/web/struct.ServiceConfig.html new file mode 100644 index 000000000..ff5d12cb2 --- /dev/null +++ b/actix_web/web/struct.ServiceConfig.html @@ -0,0 +1,58 @@ +ServiceConfig in actix_web::web - Rust

Struct actix_web::web::ServiceConfig

source ·
pub struct ServiceConfig { /* private fields */ }
Expand description

Enables parts of app configuration to be declared separately from the app itself. Helpful for +modularizing large applications.

+

Merge a ServiceConfig into an app using App::configure. Scope and +resources services have similar methods.

+ +
use actix_web::{web, App, HttpResponse};
+
+// this function could be located in different module
+fn config(cfg: &mut web::ServiceConfig) {
+    cfg.service(web::resource("/test")
+        .route(web::get().to(|| HttpResponse::Ok()))
+        .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
+    );
+}
+
+// merge `/test` routes from config function to App
+App::new().configure(config);
+

Implementations§

source§

impl ServiceConfig

source

pub fn data<U: 'static>(&mut self, data: U) -> &mut Self

👎Deprecated since 4.0.0: Use .app_data(Data::new(val)) instead.

Add shared app data item.

+

Counterpart to App::data().

+
source

pub fn app_data<U: 'static>(&mut self, ext: U) -> &mut Self

Add arbitrary app data item.

+

Counterpart to App::app_data().

+
source

pub fn default_service<F, U>(&mut self, f: F) -> &mut Self
where + F: IntoServiceFactory<U, ServiceRequest>, + U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error> + 'static, + U::InitError: Debug,

Default service to be used if no matching resource could be found.

+

Counterpart to App::default_service().

+
source

pub fn configure<F>(&mut self, f: F) -> &mut Self
where + F: FnOnce(&mut ServiceConfig),

Run external configuration as part of the application building process

+

Counterpart to App::configure() that allows for easy nesting.

+
source

pub fn route(&mut self, path: &str, route: Route) -> &mut Self

Configure route for a specific path.

+

Counterpart to App::route().

+
source

pub fn service<F>(&mut self, factory: F) -> &mut Self
where + F: HttpServiceFactory + 'static,

Register HTTP service factory.

+

Counterpart to App::service().

+
source

pub fn external_resource<N, U>(&mut self, name: N, url: U) -> &mut Self
where + N: AsRef<str>, + U: AsRef<str>,

Register an external resource.

+

External resources are useful for URL generation purposes only and are never considered for +matching at request time. Calls to HttpRequest::url_for() +will work as expected.

+

Counterpart to App::external_resource().

+

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/web/struct.UrlEncoded.html b/actix_web/web/struct.UrlEncoded.html new file mode 100644 index 000000000..9b88d07cc --- /dev/null +++ b/actix_web/web/struct.UrlEncoded.html @@ -0,0 +1,121 @@ +UrlEncoded in actix_web::web - Rust

Struct actix_web::web::UrlEncoded

source ·
pub struct UrlEncoded<T> { /* private fields */ }
Expand description

Future that resolves to some T when parsed from a URL encoded payload.

+

Form can be deserialized from any type T that implements serde::Deserialize.

+

Returns error if:

+
    +
  • content type is not application/x-www-form-urlencoded
  • +
  • content length is greater than limit
  • +
+

Implementations§

source§

impl<T> UrlEncoded<T>

source

pub fn new(req: &HttpRequest, payload: &mut Payload) -> Self

Create a new future to decode a URL encoded request payload.

+
source

pub fn limit(self, limit: usize) -> Self

Set maximum accepted payload size. The default limit is 256kB.

+

Trait Implementations§

source§

impl<T> Future for UrlEncoded<T>
where + T: DeserializeOwned + 'static,

§

type Output = Result<T, UrlencodedError>

The type of value produced on completion.
source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more

Auto Trait Implementations§

§

impl<T> !Freeze for UrlEncoded<T>

§

impl<T> !RefUnwindSafe for UrlEncoded<T>

§

impl<T> !Send for UrlEncoded<T>

§

impl<T> !Sync for UrlEncoded<T>

§

impl<T> Unpin for UrlEncoded<T>

§

impl<T> !UnwindSafe for UrlEncoded<T>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> FutureExt for T
where + T: Future + ?Sized,

§

fn map<U, F>(self, f: F) -> Map<Self, F>
where + F: FnOnce(Self::Output) -> U, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn map_into<U>(self) -> MapInto<Self, U>
where + Self::Output: Into<U>, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnOnce(Self::Output) -> Fut, + Fut: Future, + Self: Sized,

Chain on a computation for when a future finished, passing the result of +the future to the provided closure f. Read more
§

fn left_future<B>(self) -> Either<Self, B>
where + B: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the left-hand variant +of that Either. Read more
§

fn right_future<A>(self) -> Either<A, Self>
where + A: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the right-hand variant +of that Either. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Convert this future into a single element stream. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Output: Future, + Self: Sized,

Flatten the execution of this future when the output of this +future is itself another future. Read more
§

fn flatten_stream(self) -> FlattenStream<Self>
where + Self::Output: Stream, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a future such that poll will never again be called once it has +completed. This method can be used to turn any Future into a +FusedFuture. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnOnce(&Self::Output), + Self: Sized,

Do something with the output of a future before passing it on. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the future. Read more
§

fn shared(self) -> Shared<Self>
where + Self: Sized, + Self::Output: Clone,

Available on crate feature std only.
Create a cloneable handle to this future where all handles will resolve +to the same result. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn unit_error(self) -> UnitError<Self>
where + Self: Sized,

§

fn never_error(self) -> NeverError<Self>
where + Self: Sized,

§

fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where + Self: Unpin,

A convenience for calling Future::poll on Unpin future types.
§

fn now_or_never(self) -> Option<Self::Output>
where + Self: Sized,

Evaluates and consumes the future, returning the resulting output if +the future is ready after the first call to Future::poll. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<F> IntoFuture for F
where + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

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
§

fn try_poll( + self: Pin<&mut F>, + cx: &mut Context<'_> +) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
§

impl<Fut> TryFutureExt for Fut
where + Fut: TryFuture + ?Sized,

§

fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>
where + Self::Ok: Sink<Item, Error = Self::Error>, + Self: Sized,

Available on crate feature sink only.
Flattens the execution of this future when the successful result of this +future is a [Sink]. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + F: FnOnce(Self::Ok) -> T, + Self: Sized,

Maps this future’s success value to a different value. Read more
§

fn map_ok_or_else<T, E, F>(self, e: E, f: F) -> MapOkOrElse<Self, F, E>
where + F: FnOnce(Self::Ok) -> T, + E: FnOnce(Self::Error) -> T, + Self: Sized,

Maps this future’s success value to a different value, and permits for error handling resulting in the same type. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + F: FnOnce(Self::Error) -> E, + Self: Sized,

Maps this future’s error value to a different value. Read more
§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Maps this future’s Error to a new error type +using the Into trait. Read more
§

fn ok_into<U>(self) -> OkInto<Self, U>
where + Self: Sized, + Self::Ok: Into<U>,

Maps this future’s Ok to a new type +using the Into trait.
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnOnce(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Executes another future after this one resolves successfully. The +success value is passed to a closure to create this subsequent future. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnOnce(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Executes another future if this one resolves to an error. The +error value is passed to a closure to create this subsequent future. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnOnce(&Self::Ok), + Self: Sized,

Do something with the success value of a future before passing it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnOnce(&Self::Error), + Self: Sized,

Do something with the error value of a future before passing it on. Read more
§

fn try_flatten(self) -> TryFlatten<Self, Self::Ok>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is another future. Read more
§

fn try_flatten_stream(self) -> TryFlattenStream<Self>
where + Self::Ok: TryStream<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F>
where + Self: Sized, + F: FnOnce(Self::Error) -> Self::Ok,

Unwraps this future’s output, producing a future with this future’s +Ok type as its +Output type. Read more
§

fn into_future(self) -> IntoFuture<Self>
where + Self: Sized,

Wraps a [TryFuture] into a type that implements +Future. Read more
§

fn try_poll_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Result<Self::Ok, Self::Error>>
where + Self: Unpin,

A convenience method for calling [TryFuture::try_poll] on Unpin +future types.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web/web/trait.Buf.html b/actix_web/web/trait.Buf.html new file mode 100644 index 000000000..fc3af8526 --- /dev/null +++ b/actix_web/web/trait.Buf.html @@ -0,0 +1,632 @@ +Buf in actix_web::web - Rust

Trait actix_web::web::Buf

pub trait Buf {
+
Show 48 methods // Required methods + fn remaining(&self) -> usize; + fn chunk(&self) -> &[u8] ; + fn advance(&mut self, cnt: usize); + + // Provided methods + fn chunks_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize { ... } + fn has_remaining(&self) -> bool { ... } + fn copy_to_slice(&mut self, dst: &mut [u8]) { ... } + fn get_u8(&mut self) -> u8 { ... } + fn get_i8(&mut self) -> i8 { ... } + fn get_u16(&mut self) -> u16 { ... } + fn get_u16_le(&mut self) -> u16 { ... } + fn get_u16_ne(&mut self) -> u16 { ... } + fn get_i16(&mut self) -> i16 { ... } + fn get_i16_le(&mut self) -> i16 { ... } + fn get_i16_ne(&mut self) -> i16 { ... } + fn get_u32(&mut self) -> u32 { ... } + fn get_u32_le(&mut self) -> u32 { ... } + fn get_u32_ne(&mut self) -> u32 { ... } + fn get_i32(&mut self) -> i32 { ... } + fn get_i32_le(&mut self) -> i32 { ... } + fn get_i32_ne(&mut self) -> i32 { ... } + fn get_u64(&mut self) -> u64 { ... } + fn get_u64_le(&mut self) -> u64 { ... } + fn get_u64_ne(&mut self) -> u64 { ... } + fn get_i64(&mut self) -> i64 { ... } + fn get_i64_le(&mut self) -> i64 { ... } + fn get_i64_ne(&mut self) -> i64 { ... } + fn get_u128(&mut self) -> u128 { ... } + fn get_u128_le(&mut self) -> u128 { ... } + fn get_u128_ne(&mut self) -> u128 { ... } + fn get_i128(&mut self) -> i128 { ... } + fn get_i128_le(&mut self) -> i128 { ... } + fn get_i128_ne(&mut self) -> i128 { ... } + fn get_uint(&mut self, nbytes: usize) -> u64 { ... } + fn get_uint_le(&mut self, nbytes: usize) -> u64 { ... } + fn get_uint_ne(&mut self, nbytes: usize) -> u64 { ... } + fn get_int(&mut self, nbytes: usize) -> i64 { ... } + fn get_int_le(&mut self, nbytes: usize) -> i64 { ... } + fn get_int_ne(&mut self, nbytes: usize) -> i64 { ... } + fn get_f32(&mut self) -> f32 { ... } + fn get_f32_le(&mut self) -> f32 { ... } + fn get_f32_ne(&mut self) -> f32 { ... } + fn get_f64(&mut self) -> f64 { ... } + fn get_f64_le(&mut self) -> f64 { ... } + fn get_f64_ne(&mut self) -> f64 { ... } + fn copy_to_bytes(&mut self, len: usize) -> Bytes { ... } + fn take(self, limit: usize) -> Take<Self> + where Self: Sized { ... } + fn chain<U>(self, next: U) -> Chain<Self, U> + where U: Buf, + Self: Sized { ... } + fn reader(self) -> Reader<Self> + where Self: Sized { ... } +
}
Expand description

Read bytes from a buffer.

+

A buffer stores bytes in memory such that read operations are infallible. +The underlying storage may or may not be in contiguous memory. A Buf value +is a cursor into the buffer. Reading from Buf advances the cursor +position. It can be thought of as an efficient Iterator for collections of +bytes.

+

The simplest Buf is a &[u8].

+ +
use bytes::Buf;
+
+let mut buf = &b"hello world"[..];
+
+assert_eq!(b'h', buf.get_u8());
+assert_eq!(b'e', buf.get_u8());
+assert_eq!(b'l', buf.get_u8());
+
+let mut rest = [0; 8];
+buf.copy_to_slice(&mut rest);
+
+assert_eq!(&rest[..], &b"lo world"[..]);
+

Required Methods§

fn remaining(&self) -> usize

Returns the number of bytes between the current position and the end of +the buffer.

+

This value is greater than or equal to the length of the slice returned +by chunk().

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"hello world"[..];
+
+assert_eq!(buf.remaining(), 11);
+
+buf.get_u8();
+
+assert_eq!(buf.remaining(), 10);
+
§Implementer notes
+

Implementations of remaining should ensure that the return value does +not change unless a call is made to advance or any other function that +is documented to change the Buf’s current position.

+

fn chunk(&self) -> &[u8]

Returns a slice starting at the current position and of length between 0 +and Buf::remaining(). Note that this can return shorter slice (this allows +non-continuous internal representation).

+

This is a lower level function. Most operations are done with other +functions.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"hello world"[..];
+
+assert_eq!(buf.chunk(), &b"hello world"[..]);
+
+buf.advance(6);
+
+assert_eq!(buf.chunk(), &b"world"[..]);
+
§Implementer notes
+

This function should never panic. Once the end of the buffer is reached, +i.e., Buf::remaining returns 0, calls to chunk() should return an +empty slice.

+

fn advance(&mut self, cnt: usize)

Advance the internal cursor of the Buf

+

The next call to chunk() will return a slice starting cnt bytes +further into the underlying buffer.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"hello world"[..];
+
+assert_eq!(buf.chunk(), &b"hello world"[..]);
+
+buf.advance(6);
+
+assert_eq!(buf.chunk(), &b"world"[..]);
+
§Panics
+

This function may panic if cnt > self.remaining().

+
§Implementer notes
+

It is recommended for implementations of advance to panic if cnt > self.remaining(). If the implementation does not panic, the call must +behave as if cnt == self.remaining().

+

A call with cnt == 0 should never panic and be a no-op.

+

Provided Methods§

fn chunks_vectored<'a>(&'a self, dst: &mut [IoSlice<'a>]) -> usize

Available on crate feature std only.

Fills dst with potentially multiple slices starting at self’s +current position.

+

If the Buf is backed by disjoint slices of bytes, chunk_vectored enables +fetching more than one slice at once. dst is a slice of IoSlice +references, enabling the slice to be directly used with writev +without any further conversion. The sum of the lengths of all the +buffers in dst will be less than or equal to Buf::remaining().

+

The entries in dst will be overwritten, but the data contained by +the slices will not be modified. If chunk_vectored does not fill every +entry in dst, then dst is guaranteed to contain all remaining slices +in `self.

+

This is a lower level function. Most operations are done with other +functions.

+
§Implementer notes
+

This function should never panic. Once the end of the buffer is reached, +i.e., Buf::remaining returns 0, calls to chunk_vectored must return 0 +without mutating dst.

+

Implementations should also take care to properly handle being called +with dst being a zero length slice.

+

fn has_remaining(&self) -> bool

Returns true if there are any more bytes to consume

+

This is equivalent to self.remaining() != 0.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"a"[..];
+
+assert!(buf.has_remaining());
+
+buf.get_u8();
+
+assert!(!buf.has_remaining());
+

fn copy_to_slice(&mut self, dst: &mut [u8])

Copies bytes from self into dst.

+

The cursor is advanced by the number of bytes copied. self must have +enough remaining bytes to fill dst.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"hello world"[..];
+let mut dst = [0; 5];
+
+buf.copy_to_slice(&mut dst);
+assert_eq!(&b"hello"[..], &dst);
+assert_eq!(6, buf.remaining());
+
§Panics
+

This function panics if self.remaining() < dst.len().

+

fn get_u8(&mut self) -> u8

Gets an unsigned 8 bit integer from self.

+

The current position is advanced by 1.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08 hello"[..];
+assert_eq!(8, buf.get_u8());
+
§Panics
+

This function panics if there is no more remaining data in self.

+

fn get_i8(&mut self) -> i8

Gets a signed 8 bit integer from self.

+

The current position is advanced by 1.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08 hello"[..];
+assert_eq!(8, buf.get_i8());
+
§Panics
+

This function panics if there is no more remaining data in self.

+

fn get_u16(&mut self) -> u16

Gets an unsigned 16 bit integer from self in big-endian byte order.

+

The current position is advanced by 2.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x09 hello"[..];
+assert_eq!(0x0809, buf.get_u16());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_u16_le(&mut self) -> u16

Gets an unsigned 16 bit integer from self in little-endian byte order.

+

The current position is advanced by 2.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x09\x08 hello"[..];
+assert_eq!(0x0809, buf.get_u16_le());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_u16_ne(&mut self) -> u16

Gets an unsigned 16 bit integer from self in native-endian byte order.

+

The current position is advanced by 2.

+
§Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x08\x09 hello",
+    false => b"\x09\x08 hello",
+};
+assert_eq!(0x0809, buf.get_u16_ne());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_i16(&mut self) -> i16

Gets a signed 16 bit integer from self in big-endian byte order.

+

The current position is advanced by 2.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x09 hello"[..];
+assert_eq!(0x0809, buf.get_i16());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_i16_le(&mut self) -> i16

Gets a signed 16 bit integer from self in little-endian byte order.

+

The current position is advanced by 2.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x09\x08 hello"[..];
+assert_eq!(0x0809, buf.get_i16_le());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_i16_ne(&mut self) -> i16

Gets a signed 16 bit integer from self in native-endian byte order.

+

The current position is advanced by 2.

+
§Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x08\x09 hello",
+    false => b"\x09\x08 hello",
+};
+assert_eq!(0x0809, buf.get_i16_ne());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_u32(&mut self) -> u32

Gets an unsigned 32 bit integer from self in the big-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
+assert_eq!(0x0809A0A1, buf.get_u32());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_u32_le(&mut self) -> u32

Gets an unsigned 32 bit integer from self in the little-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
+assert_eq!(0x0809A0A1, buf.get_u32_le());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_u32_ne(&mut self) -> u32

Gets an unsigned 32 bit integer from self in native-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x08\x09\xA0\xA1 hello",
+    false => b"\xA1\xA0\x09\x08 hello",
+};
+assert_eq!(0x0809A0A1, buf.get_u32_ne());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_i32(&mut self) -> i32

Gets a signed 32 bit integer from self in big-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x09\xA0\xA1 hello"[..];
+assert_eq!(0x0809A0A1, buf.get_i32());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_i32_le(&mut self) -> i32

Gets a signed 32 bit integer from self in little-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\xA1\xA0\x09\x08 hello"[..];
+assert_eq!(0x0809A0A1, buf.get_i32_le());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_i32_ne(&mut self) -> i32

Gets a signed 32 bit integer from self in native-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x08\x09\xA0\xA1 hello",
+    false => b"\xA1\xA0\x09\x08 hello",
+};
+assert_eq!(0x0809A0A1, buf.get_i32_ne());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_u64(&mut self) -> u64

Gets an unsigned 64 bit integer from self in big-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
+assert_eq!(0x0102030405060708, buf.get_u64());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_u64_le(&mut self) -> u64

Gets an unsigned 64 bit integer from self in little-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
+assert_eq!(0x0102030405060708, buf.get_u64_le());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_u64_ne(&mut self) -> u64

Gets an unsigned 64 bit integer from self in native-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03\x04\x05\x06\x07\x08 hello",
+    false => b"\x08\x07\x06\x05\x04\x03\x02\x01 hello",
+};
+assert_eq!(0x0102030405060708, buf.get_u64_ne());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_i64(&mut self) -> i64

Gets a signed 64 bit integer from self in big-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08 hello"[..];
+assert_eq!(0x0102030405060708, buf.get_i64());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_i64_le(&mut self) -> i64

Gets a signed 64 bit integer from self in little-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
+assert_eq!(0x0102030405060708, buf.get_i64_le());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_i64_ne(&mut self) -> i64

Gets a signed 64 bit integer from self in native-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03\x04\x05\x06\x07\x08 hello",
+    false => b"\x08\x07\x06\x05\x04\x03\x02\x01 hello",
+};
+assert_eq!(0x0102030405060708, buf.get_i64_ne());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_u128(&mut self) -> u128

Gets an unsigned 128 bit integer from self in big-endian byte order.

+

The current position is advanced by 16.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
+assert_eq!(0x01020304050607080910111213141516, buf.get_u128());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_u128_le(&mut self) -> u128

Gets an unsigned 128 bit integer from self in little-endian byte order.

+

The current position is advanced by 16.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
+assert_eq!(0x01020304050607080910111213141516, buf.get_u128_le());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_u128_ne(&mut self) -> u128

Gets an unsigned 128 bit integer from self in native-endian byte order.

+

The current position is advanced by 16.

+
§Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello",
+    false => b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello",
+};
+assert_eq!(0x01020304050607080910111213141516, buf.get_u128_ne());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_i128(&mut self) -> i128

Gets a signed 128 bit integer from self in big-endian byte order.

+

The current position is advanced by 16.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello"[..];
+assert_eq!(0x01020304050607080910111213141516, buf.get_i128());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_i128_le(&mut self) -> i128

Gets a signed 128 bit integer from self in little-endian byte order.

+

The current position is advanced by 16.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello"[..];
+assert_eq!(0x01020304050607080910111213141516, buf.get_i128_le());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_i128_ne(&mut self) -> i128

Gets a signed 128 bit integer from self in native-endian byte order.

+

The current position is advanced by 16.

+
§Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16 hello",
+    false => b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01 hello",
+};
+assert_eq!(0x01020304050607080910111213141516, buf.get_i128_ne());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_uint(&mut self, nbytes: usize) -> u64

Gets an unsigned n-byte integer from self in big-endian byte order.

+

The current position is advanced by nbytes.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03 hello"[..];
+assert_eq!(0x010203, buf.get_uint(3));
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_uint_le(&mut self, nbytes: usize) -> u64

Gets an unsigned n-byte integer from self in little-endian byte order.

+

The current position is advanced by nbytes.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x03\x02\x01 hello"[..];
+assert_eq!(0x010203, buf.get_uint_le(3));
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_uint_ne(&mut self, nbytes: usize) -> u64

Gets an unsigned n-byte integer from self in native-endian byte order.

+

The current position is advanced by nbytes.

+
§Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03 hello",
+    false => b"\x03\x02\x01 hello",
+};
+assert_eq!(0x010203, buf.get_uint_ne(3));
+
§Panics
+

This function panics if there is not enough remaining data in self, or +if nbytes is greater than 8.

+

fn get_int(&mut self, nbytes: usize) -> i64

Gets a signed n-byte integer from self in big-endian byte order.

+

The current position is advanced by nbytes.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x01\x02\x03 hello"[..];
+assert_eq!(0x010203, buf.get_int(3));
+
§Panics
+

This function panics if there is not enough remaining data in self, or +if nbytes is greater than 8.

+

fn get_int_le(&mut self, nbytes: usize) -> i64

Gets a signed n-byte integer from self in little-endian byte order.

+

The current position is advanced by nbytes.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x03\x02\x01 hello"[..];
+assert_eq!(0x010203, buf.get_int_le(3));
+
§Panics
+

This function panics if there is not enough remaining data in self, or +if nbytes is greater than 8.

+

fn get_int_ne(&mut self, nbytes: usize) -> i64

Gets a signed n-byte integer from self in native-endian byte order.

+

The current position is advanced by nbytes.

+
§Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x01\x02\x03 hello",
+    false => b"\x03\x02\x01 hello",
+};
+assert_eq!(0x010203, buf.get_int_ne(3));
+
§Panics
+

This function panics if there is not enough remaining data in self, or +if nbytes is greater than 8.

+

fn get_f32(&mut self) -> f32

Gets an IEEE754 single-precision (4 bytes) floating point number from +self in big-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x3F\x99\x99\x9A hello"[..];
+assert_eq!(1.2f32, buf.get_f32());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_f32_le(&mut self) -> f32

Gets an IEEE754 single-precision (4 bytes) floating point number from +self in little-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x9A\x99\x99\x3F hello"[..];
+assert_eq!(1.2f32, buf.get_f32_le());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_f32_ne(&mut self) -> f32

Gets an IEEE754 single-precision (4 bytes) floating point number from +self in native-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x3F\x99\x99\x9A hello",
+    false => b"\x9A\x99\x99\x3F hello",
+};
+assert_eq!(1.2f32, buf.get_f32_ne());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_f64(&mut self) -> f64

Gets an IEEE754 double-precision (8 bytes) floating point number from +self in big-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello"[..];
+assert_eq!(1.2f64, buf.get_f64());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_f64_le(&mut self) -> f64

Gets an IEEE754 double-precision (8 bytes) floating point number from +self in little-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::Buf;
+
+let mut buf = &b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello"[..];
+assert_eq!(1.2f64, buf.get_f64_le());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn get_f64_ne(&mut self) -> f64

Gets an IEEE754 double-precision (8 bytes) floating point number from +self in native-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::Buf;
+
+let mut buf: &[u8] = match cfg!(target_endian = "big") {
+    true => b"\x3F\xF3\x33\x33\x33\x33\x33\x33 hello",
+    false => b"\x33\x33\x33\x33\x33\x33\xF3\x3F hello",
+};
+assert_eq!(1.2f64, buf.get_f64_ne());
+
§Panics
+

This function panics if there is not enough remaining data in self.

+

fn copy_to_bytes(&mut self, len: usize) -> Bytes

Consumes len bytes inside self and returns new instance of Bytes +with this data.

+

This function may be optimized by the underlying type to avoid actual +copies. For example, Bytes implementation will do a shallow copy +(ref-count increment).

+
§Examples
+
use bytes::Buf;
+
+let bytes = (&b"hello world"[..]).copy_to_bytes(5);
+assert_eq!(&bytes[..], &b"hello"[..]);
+
§Panics
+

This function panics if len > self.remaining().

+

fn take(self, limit: usize) -> Take<Self>
where + Self: Sized,

Creates an adaptor which will read at most limit bytes from self.

+

This function returns a new instance of Buf which will read at most +limit bytes.

+
§Examples
+
use bytes::{Buf, BufMut};
+
+let mut buf = b"hello world"[..].take(5);
+let mut dst = vec![];
+
+dst.put(&mut buf);
+assert_eq!(dst, b"hello");
+
+let mut buf = buf.into_inner();
+dst.clear();
+dst.put(&mut buf);
+assert_eq!(dst, b" world");
+

fn chain<U>(self, next: U) -> Chain<Self, U>
where + U: Buf, + Self: Sized,

Creates an adaptor which will chain this buffer with another.

+

The returned Buf instance will first consume all bytes from self. +Afterwards the output is equivalent to the output of next.

+
§Examples
+
use bytes::Buf;
+
+let mut chain = b"hello "[..].chain(&b"world"[..]);
+
+let full = chain.copy_to_bytes(11);
+assert_eq!(full.chunk(), b"hello world");
+

fn reader(self) -> Reader<Self>
where + Self: Sized,

Available on crate feature std only.

Creates an adaptor which implements the Read trait for self.

+

This function returns a new value which implements Read by adapting +the Read trait functions to the Buf trait functions. Given that +Buf operations are infallible, none of the Read functions will +return with Err.

+
§Examples
+
use bytes::{Bytes, Buf};
+use std::io::Read;
+
+let buf = Bytes::from("hello world");
+
+let mut reader = buf.reader();
+let mut dst = [0; 1024];
+
+let num = reader.read(&mut dst).unwrap();
+
+assert_eq!(11, num);
+assert_eq!(&dst[..11], &b"hello world"[..]);
+

Implementations on Foreign Types§

§

impl Buf for &[u8]

§

fn remaining(&self) -> usize

§

fn chunk(&self) -> &[u8]

§

fn advance(&mut self, cnt: usize)

§

fn copy_to_slice(&mut self, dst: &mut [u8])

§

impl Buf for VecDeque<u8>

§

fn remaining(&self) -> usize

§

fn chunk(&self) -> &[u8]

§

fn advance(&mut self, cnt: usize)

§

impl<T> Buf for &mut T
where + T: Buf + ?Sized,

§

fn remaining(&self) -> usize

§

fn chunk(&self) -> &[u8]

§

fn chunks_vectored<'b>(&'b self, dst: &mut [IoSlice<'b>]) -> usize

Available on crate feature std only.
§

fn advance(&mut self, cnt: usize)

§

fn has_remaining(&self) -> bool

§

fn copy_to_slice(&mut self, dst: &mut [u8])

§

fn get_u8(&mut self) -> u8

§

fn get_i8(&mut self) -> i8

§

fn get_u16(&mut self) -> u16

§

fn get_u16_le(&mut self) -> u16

§

fn get_u16_ne(&mut self) -> u16

§

fn get_i16(&mut self) -> i16

§

fn get_i16_le(&mut self) -> i16

§

fn get_i16_ne(&mut self) -> i16

§

fn get_u32(&mut self) -> u32

§

fn get_u32_le(&mut self) -> u32

§

fn get_u32_ne(&mut self) -> u32

§

fn get_i32(&mut self) -> i32

§

fn get_i32_le(&mut self) -> i32

§

fn get_i32_ne(&mut self) -> i32

§

fn get_u64(&mut self) -> u64

§

fn get_u64_le(&mut self) -> u64

§

fn get_u64_ne(&mut self) -> u64

§

fn get_i64(&mut self) -> i64

§

fn get_i64_le(&mut self) -> i64

§

fn get_i64_ne(&mut self) -> i64

§

fn get_uint(&mut self, nbytes: usize) -> u64

§

fn get_uint_le(&mut self, nbytes: usize) -> u64

§

fn get_uint_ne(&mut self, nbytes: usize) -> u64

§

fn get_int(&mut self, nbytes: usize) -> i64

§

fn get_int_le(&mut self, nbytes: usize) -> i64

§

fn get_int_ne(&mut self, nbytes: usize) -> i64

§

fn copy_to_bytes(&mut self, len: usize) -> Bytes

§

impl<T> Buf for Box<T>
where + T: Buf + ?Sized,

§

fn remaining(&self) -> usize

§

fn chunk(&self) -> &[u8]

§

fn chunks_vectored<'b>(&'b self, dst: &mut [IoSlice<'b>]) -> usize

Available on crate feature std only.
§

fn advance(&mut self, cnt: usize)

§

fn has_remaining(&self) -> bool

§

fn copy_to_slice(&mut self, dst: &mut [u8])

§

fn get_u8(&mut self) -> u8

§

fn get_i8(&mut self) -> i8

§

fn get_u16(&mut self) -> u16

§

fn get_u16_le(&mut self) -> u16

§

fn get_u16_ne(&mut self) -> u16

§

fn get_i16(&mut self) -> i16

§

fn get_i16_le(&mut self) -> i16

§

fn get_i16_ne(&mut self) -> i16

§

fn get_u32(&mut self) -> u32

§

fn get_u32_le(&mut self) -> u32

§

fn get_u32_ne(&mut self) -> u32

§

fn get_i32(&mut self) -> i32

§

fn get_i32_le(&mut self) -> i32

§

fn get_i32_ne(&mut self) -> i32

§

fn get_u64(&mut self) -> u64

§

fn get_u64_le(&mut self) -> u64

§

fn get_u64_ne(&mut self) -> u64

§

fn get_i64(&mut self) -> i64

§

fn get_i64_le(&mut self) -> i64

§

fn get_i64_ne(&mut self) -> i64

§

fn get_uint(&mut self, nbytes: usize) -> u64

§

fn get_uint_le(&mut self, nbytes: usize) -> u64

§

fn get_uint_ne(&mut self, nbytes: usize) -> u64

§

fn get_int(&mut self, nbytes: usize) -> i64

§

fn get_int_le(&mut self, nbytes: usize) -> i64

§

fn get_int_ne(&mut self, nbytes: usize) -> i64

§

fn copy_to_bytes(&mut self, len: usize) -> Bytes

§

impl<T> Buf for Cursor<T>
where + T: AsRef<[u8]>,

Available on crate feature std only.
§

fn remaining(&self) -> usize

§

fn chunk(&self) -> &[u8]

§

fn advance(&mut self, cnt: usize)

Implementors§

§

impl Buf for Bytes

§

impl Buf for BytesMut

§

impl<T> Buf for Take<T>
where + T: Buf,

§

impl<T, U> Buf for Chain<T, U>
where + T: Buf, + U: Buf,

\ No newline at end of file diff --git a/actix_web/web/trait.BufMut.html b/actix_web/web/trait.BufMut.html new file mode 100644 index 000000000..1369eb775 --- /dev/null +++ b/actix_web/web/trait.BufMut.html @@ -0,0 +1,749 @@ +BufMut in actix_web::web - Rust

Trait actix_web::web::BufMut

pub unsafe trait BufMut {
+
Show 48 methods // Required methods + fn remaining_mut(&self) -> usize; + unsafe fn advance_mut(&mut self, cnt: usize); + fn chunk_mut(&mut self) -> &mut UninitSlice; + + // Provided methods + fn has_remaining_mut(&self) -> bool { ... } + fn put<T>(&mut self, src: T) + where T: Buf, + Self: Sized { ... } + fn put_slice(&mut self, src: &[u8]) { ... } + fn put_bytes(&mut self, val: u8, cnt: usize) { ... } + fn put_u8(&mut self, n: u8) { ... } + fn put_i8(&mut self, n: i8) { ... } + fn put_u16(&mut self, n: u16) { ... } + fn put_u16_le(&mut self, n: u16) { ... } + fn put_u16_ne(&mut self, n: u16) { ... } + fn put_i16(&mut self, n: i16) { ... } + fn put_i16_le(&mut self, n: i16) { ... } + fn put_i16_ne(&mut self, n: i16) { ... } + fn put_u32(&mut self, n: u32) { ... } + fn put_u32_le(&mut self, n: u32) { ... } + fn put_u32_ne(&mut self, n: u32) { ... } + fn put_i32(&mut self, n: i32) { ... } + fn put_i32_le(&mut self, n: i32) { ... } + fn put_i32_ne(&mut self, n: i32) { ... } + fn put_u64(&mut self, n: u64) { ... } + fn put_u64_le(&mut self, n: u64) { ... } + fn put_u64_ne(&mut self, n: u64) { ... } + fn put_i64(&mut self, n: i64) { ... } + fn put_i64_le(&mut self, n: i64) { ... } + fn put_i64_ne(&mut self, n: i64) { ... } + fn put_u128(&mut self, n: u128) { ... } + fn put_u128_le(&mut self, n: u128) { ... } + fn put_u128_ne(&mut self, n: u128) { ... } + fn put_i128(&mut self, n: i128) { ... } + fn put_i128_le(&mut self, n: i128) { ... } + fn put_i128_ne(&mut self, n: i128) { ... } + fn put_uint(&mut self, n: u64, nbytes: usize) { ... } + fn put_uint_le(&mut self, n: u64, nbytes: usize) { ... } + fn put_uint_ne(&mut self, n: u64, nbytes: usize) { ... } + fn put_int(&mut self, n: i64, nbytes: usize) { ... } + fn put_int_le(&mut self, n: i64, nbytes: usize) { ... } + fn put_int_ne(&mut self, n: i64, nbytes: usize) { ... } + fn put_f32(&mut self, n: f32) { ... } + fn put_f32_le(&mut self, n: f32) { ... } + fn put_f32_ne(&mut self, n: f32) { ... } + fn put_f64(&mut self, n: f64) { ... } + fn put_f64_le(&mut self, n: f64) { ... } + fn put_f64_ne(&mut self, n: f64) { ... } + fn limit(self, limit: usize) -> Limit<Self> + where Self: Sized { ... } + fn writer(self) -> Writer<Self> + where Self: Sized { ... } + fn chain_mut<U>(self, next: U) -> Chain<Self, U> + where U: BufMut, + Self: Sized { ... } +
}
Expand description

A trait for values that provide sequential write access to bytes.

+

Write bytes to a buffer

+

A buffer stores bytes in memory such that write operations are infallible. +The underlying storage may or may not be in contiguous memory. A BufMut +value is a cursor into the buffer. Writing to BufMut advances the cursor +position.

+

The simplest BufMut is a Vec<u8>.

+ +
use bytes::BufMut;
+
+let mut buf = vec![];
+
+buf.put(&b"hello world"[..]);
+
+assert_eq!(buf, b"hello world");
+

Required Methods§

fn remaining_mut(&self) -> usize

Returns the number of bytes that can be written from the current +position until the end of the buffer is reached.

+

This value is greater than or equal to the length of the slice returned +by chunk_mut().

+

Writing to a BufMut may involve allocating more memory on the fly. +Implementations may fail before reaching the number of bytes indicated +by this method if they encounter an allocation failure.

+
§Examples
+
use bytes::BufMut;
+
+let mut dst = [0; 10];
+let mut buf = &mut dst[..];
+
+let original_remaining = buf.remaining_mut();
+buf.put(&b"hello"[..]);
+
+assert_eq!(original_remaining - 5, buf.remaining_mut());
+
§Implementer notes
+

Implementations of remaining_mut should ensure that the return value +does not change unless a call is made to advance_mut or any other +function that is documented to change the BufMut’s current position.

+
§Note
+

remaining_mut may return value smaller than actual available space.

+

unsafe fn advance_mut(&mut self, cnt: usize)

Advance the internal cursor of the BufMut

+

The next call to chunk_mut will return a slice starting cnt bytes +further into the underlying buffer.

+
§Safety
+

The caller must ensure that the next cnt bytes of chunk are +initialized.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = Vec::with_capacity(16);
+
+// Write some data
+buf.chunk_mut()[0..2].copy_from_slice(b"he");
+unsafe { buf.advance_mut(2) };
+
+// write more bytes
+buf.chunk_mut()[0..3].copy_from_slice(b"llo");
+
+unsafe { buf.advance_mut(3); }
+
+assert_eq!(5, buf.len());
+assert_eq!(buf, b"hello");
+
§Panics
+

This function may panic if cnt > self.remaining_mut().

+
§Implementer notes
+

It is recommended for implementations of advance_mut to panic if +cnt > self.remaining_mut(). If the implementation does not panic, +the call must behave as if cnt == self.remaining_mut().

+

A call with cnt == 0 should never panic and be a no-op.

+

fn chunk_mut(&mut self) -> &mut UninitSlice

Returns a mutable slice starting at the current BufMut position and of +length between 0 and BufMut::remaining_mut(). Note that this can be shorter than the +whole remainder of the buffer (this allows non-continuous implementation).

+

This is a lower level function. Most operations are done with other +functions.

+

The returned byte slice may represent uninitialized memory.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = Vec::with_capacity(16);
+
+unsafe {
+    // MaybeUninit::as_mut_ptr
+    buf.chunk_mut()[0..].as_mut_ptr().write(b'h');
+    buf.chunk_mut()[1..].as_mut_ptr().write(b'e');
+
+    buf.advance_mut(2);
+
+    buf.chunk_mut()[0..].as_mut_ptr().write(b'l');
+    buf.chunk_mut()[1..].as_mut_ptr().write(b'l');
+    buf.chunk_mut()[2..].as_mut_ptr().write(b'o');
+
+    buf.advance_mut(3);
+}
+
+assert_eq!(5, buf.len());
+assert_eq!(buf, b"hello");
+
§Implementer notes
+

This function should never panic. chunk_mut should return an empty +slice if and only if remaining_mut() returns 0. In other words, +chunk_mut() returning an empty slice implies that remaining_mut() will +return 0 and remaining_mut() returning 0 implies that chunk_mut() will +return an empty slice.

+

This function may trigger an out-of-memory abort if it tries to allocate +memory and fails to do so.

+

Provided Methods§

fn has_remaining_mut(&self) -> bool

Returns true if there is space in self for more bytes.

+

This is equivalent to self.remaining_mut() != 0.

+
§Examples
+
use bytes::BufMut;
+
+let mut dst = [0; 5];
+let mut buf = &mut dst[..];
+
+assert!(buf.has_remaining_mut());
+
+buf.put(&b"hello"[..]);
+
+assert!(!buf.has_remaining_mut());
+

fn put<T>(&mut self, src: T)
where + T: Buf, + Self: Sized,

Transfer bytes into self from src and advance the cursor by the +number of bytes written.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+
+buf.put_u8(b'h');
+buf.put(&b"ello"[..]);
+buf.put(&b" world"[..]);
+
+assert_eq!(buf, b"hello world");
+
§Panics
+

Panics if self does not have enough capacity to contain src.

+

fn put_slice(&mut self, src: &[u8])

Transfer bytes into self from src and advance the cursor by the +number of bytes written.

+

self must have enough remaining capacity to contain all of src.

+ +
use bytes::BufMut;
+
+let mut dst = [0; 6];
+
+{
+    let mut buf = &mut dst[..];
+    buf.put_slice(b"hello");
+
+    assert_eq!(1, buf.remaining_mut());
+}
+
+assert_eq!(b"hello\0", &dst);
+

fn put_bytes(&mut self, val: u8, cnt: usize)

Put cnt bytes val into self.

+

Logically equivalent to calling self.put_u8(val) cnt times, but may work faster.

+

self must have at least cnt remaining capacity.

+ +
use bytes::BufMut;
+
+let mut dst = [0; 6];
+
+{
+    let mut buf = &mut dst[..];
+    buf.put_bytes(b'a', 4);
+
+    assert_eq!(2, buf.remaining_mut());
+}
+
+assert_eq!(b"aaaa\0\0", &dst);
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_u8(&mut self, n: u8)

Writes an unsigned 8 bit integer to self.

+

The current position is advanced by 1.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u8(0x01);
+assert_eq!(buf, b"\x01");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_i8(&mut self, n: i8)

Writes a signed 8 bit integer to self.

+

The current position is advanced by 1.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i8(0x01);
+assert_eq!(buf, b"\x01");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_u16(&mut self, n: u16)

Writes an unsigned 16 bit integer to self in big-endian byte order.

+

The current position is advanced by 2.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u16(0x0809);
+assert_eq!(buf, b"\x08\x09");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_u16_le(&mut self, n: u16)

Writes an unsigned 16 bit integer to self in little-endian byte order.

+

The current position is advanced by 2.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u16_le(0x0809);
+assert_eq!(buf, b"\x09\x08");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_u16_ne(&mut self, n: u16)

Writes an unsigned 16 bit integer to self in native-endian byte order.

+

The current position is advanced by 2.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u16_ne(0x0809);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x08\x09");
+} else {
+    assert_eq!(buf, b"\x09\x08");
+}
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_i16(&mut self, n: i16)

Writes a signed 16 bit integer to self in big-endian byte order.

+

The current position is advanced by 2.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i16(0x0809);
+assert_eq!(buf, b"\x08\x09");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_i16_le(&mut self, n: i16)

Writes a signed 16 bit integer to self in little-endian byte order.

+

The current position is advanced by 2.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i16_le(0x0809);
+assert_eq!(buf, b"\x09\x08");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_i16_ne(&mut self, n: i16)

Writes a signed 16 bit integer to self in native-endian byte order.

+

The current position is advanced by 2.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i16_ne(0x0809);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x08\x09");
+} else {
+    assert_eq!(buf, b"\x09\x08");
+}
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_u32(&mut self, n: u32)

Writes an unsigned 32 bit integer to self in big-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u32(0x0809A0A1);
+assert_eq!(buf, b"\x08\x09\xA0\xA1");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_u32_le(&mut self, n: u32)

Writes an unsigned 32 bit integer to self in little-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u32_le(0x0809A0A1);
+assert_eq!(buf, b"\xA1\xA0\x09\x08");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_u32_ne(&mut self, n: u32)

Writes an unsigned 32 bit integer to self in native-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u32_ne(0x0809A0A1);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x08\x09\xA0\xA1");
+} else {
+    assert_eq!(buf, b"\xA1\xA0\x09\x08");
+}
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_i32(&mut self, n: i32)

Writes a signed 32 bit integer to self in big-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i32(0x0809A0A1);
+assert_eq!(buf, b"\x08\x09\xA0\xA1");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_i32_le(&mut self, n: i32)

Writes a signed 32 bit integer to self in little-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i32_le(0x0809A0A1);
+assert_eq!(buf, b"\xA1\xA0\x09\x08");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_i32_ne(&mut self, n: i32)

Writes a signed 32 bit integer to self in native-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i32_ne(0x0809A0A1);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x08\x09\xA0\xA1");
+} else {
+    assert_eq!(buf, b"\xA1\xA0\x09\x08");
+}
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_u64(&mut self, n: u64)

Writes an unsigned 64 bit integer to self in the big-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u64(0x0102030405060708);
+assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_u64_le(&mut self, n: u64)

Writes an unsigned 64 bit integer to self in little-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u64_le(0x0102030405060708);
+assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_u64_ne(&mut self, n: u64)

Writes an unsigned 64 bit integer to self in native-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u64_ne(0x0102030405060708);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
+} else {
+    assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
+}
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_i64(&mut self, n: i64)

Writes a signed 64 bit integer to self in the big-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i64(0x0102030405060708);
+assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_i64_le(&mut self, n: i64)

Writes a signed 64 bit integer to self in little-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i64_le(0x0102030405060708);
+assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_i64_ne(&mut self, n: i64)

Writes a signed 64 bit integer to self in native-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i64_ne(0x0102030405060708);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08");
+} else {
+    assert_eq!(buf, b"\x08\x07\x06\x05\x04\x03\x02\x01");
+}
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_u128(&mut self, n: u128)

Writes an unsigned 128 bit integer to self in the big-endian byte order.

+

The current position is advanced by 16.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u128(0x01020304050607080910111213141516);
+assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_u128_le(&mut self, n: u128)

Writes an unsigned 128 bit integer to self in little-endian byte order.

+

The current position is advanced by 16.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u128_le(0x01020304050607080910111213141516);
+assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_u128_ne(&mut self, n: u128)

Writes an unsigned 128 bit integer to self in native-endian byte order.

+

The current position is advanced by 16.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_u128_ne(0x01020304050607080910111213141516);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+} else {
+    assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+}
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_i128(&mut self, n: i128)

Writes a signed 128 bit integer to self in the big-endian byte order.

+

The current position is advanced by 16.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i128(0x01020304050607080910111213141516);
+assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_i128_le(&mut self, n: i128)

Writes a signed 128 bit integer to self in little-endian byte order.

+

The current position is advanced by 16.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i128_le(0x01020304050607080910111213141516);
+assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_i128_ne(&mut self, n: i128)

Writes a signed 128 bit integer to self in native-endian byte order.

+

The current position is advanced by 16.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_i128_ne(0x01020304050607080910111213141516);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16");
+} else {
+    assert_eq!(buf, b"\x16\x15\x14\x13\x12\x11\x10\x09\x08\x07\x06\x05\x04\x03\x02\x01");
+}
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_uint(&mut self, n: u64, nbytes: usize)

Writes an unsigned n-byte integer to self in big-endian byte order.

+

The current position is advanced by nbytes.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_uint(0x010203, 3);
+assert_eq!(buf, b"\x01\x02\x03");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

fn put_uint_le(&mut self, n: u64, nbytes: usize)

Writes an unsigned n-byte integer to self in the little-endian byte order.

+

The current position is advanced by nbytes.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_uint_le(0x010203, 3);
+assert_eq!(buf, b"\x03\x02\x01");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

fn put_uint_ne(&mut self, n: u64, nbytes: usize)

Writes an unsigned n-byte integer to self in the native-endian byte order.

+

The current position is advanced by nbytes.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_uint_ne(0x010203, 3);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03");
+} else {
+    assert_eq!(buf, b"\x03\x02\x01");
+}
+
§Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

fn put_int(&mut self, n: i64, nbytes: usize)

Writes low nbytes of a signed integer to self in big-endian byte order.

+

The current position is advanced by nbytes.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_int(0x0504010203, 3);
+assert_eq!(buf, b"\x01\x02\x03");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

fn put_int_le(&mut self, n: i64, nbytes: usize)

Writes low nbytes of a signed integer to self in little-endian byte order.

+

The current position is advanced by nbytes.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_int_le(0x0504010203, 3);
+assert_eq!(buf, b"\x03\x02\x01");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

fn put_int_ne(&mut self, n: i64, nbytes: usize)

Writes low nbytes of a signed integer to self in native-endian byte order.

+

The current position is advanced by nbytes.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_int_ne(0x010203, 3);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x01\x02\x03");
+} else {
+    assert_eq!(buf, b"\x03\x02\x01");
+}
+
§Panics
+

This function panics if there is not enough remaining capacity in +self or if nbytes is greater than 8.

+

fn put_f32(&mut self, n: f32)

Writes an IEEE754 single-precision (4 bytes) floating point number to +self in big-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f32(1.2f32);
+assert_eq!(buf, b"\x3F\x99\x99\x9A");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_f32_le(&mut self, n: f32)

Writes an IEEE754 single-precision (4 bytes) floating point number to +self in little-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f32_le(1.2f32);
+assert_eq!(buf, b"\x9A\x99\x99\x3F");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_f32_ne(&mut self, n: f32)

Writes an IEEE754 single-precision (4 bytes) floating point number to +self in native-endian byte order.

+

The current position is advanced by 4.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f32_ne(1.2f32);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x3F\x99\x99\x9A");
+} else {
+    assert_eq!(buf, b"\x9A\x99\x99\x3F");
+}
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_f64(&mut self, n: f64)

Writes an IEEE754 double-precision (8 bytes) floating point number to +self in big-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f64(1.2f64);
+assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_f64_le(&mut self, n: f64)

Writes an IEEE754 double-precision (8 bytes) floating point number to +self in little-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f64_le(1.2f64);
+assert_eq!(buf, b"\x33\x33\x33\x33\x33\x33\xF3\x3F");
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn put_f64_ne(&mut self, n: f64)

Writes an IEEE754 double-precision (8 bytes) floating point number to +self in native-endian byte order.

+

The current position is advanced by 8.

+
§Examples
+
use bytes::BufMut;
+
+let mut buf = vec![];
+buf.put_f64_ne(1.2f64);
+if cfg!(target_endian = "big") {
+    assert_eq!(buf, b"\x3F\xF3\x33\x33\x33\x33\x33\x33");
+} else {
+    assert_eq!(buf, b"\x33\x33\x33\x33\x33\x33\xF3\x3F");
+}
+
§Panics
+

This function panics if there is not enough remaining capacity in +self.

+

fn limit(self, limit: usize) -> Limit<Self>
where + Self: Sized,

Creates an adaptor which can write at most limit bytes to self.

+
§Examples
+
use bytes::BufMut;
+
+let arr = &mut [0u8; 128][..];
+assert_eq!(arr.remaining_mut(), 128);
+
+let dst = arr.limit(10);
+assert_eq!(dst.remaining_mut(), 10);
+

fn writer(self) -> Writer<Self>
where + Self: Sized,

Available on crate feature std only.

Creates an adaptor which implements the Write trait for self.

+

This function returns a new value which implements Write by adapting +the Write trait functions to the BufMut trait functions. Given that +BufMut operations are infallible, none of the Write functions will +return with Err.

+
§Examples
+
use bytes::BufMut;
+use std::io::Write;
+
+let mut buf = vec![].writer();
+
+let num = buf.write(&b"hello world"[..]).unwrap();
+assert_eq!(11, num);
+
+let buf = buf.into_inner();
+
+assert_eq!(*buf, b"hello world"[..]);
+

fn chain_mut<U>(self, next: U) -> Chain<Self, U>
where + U: BufMut, + Self: Sized,

Creates an adapter which will chain this buffer with another.

+

The returned BufMut instance will first write to all bytes from +self. Afterwards, it will write to next.

+
§Examples
+
use bytes::BufMut;
+
+let mut a = [0u8; 5];
+let mut b = [0u8; 6];
+
+let mut chain = (&mut a[..]).chain_mut(&mut b[..]);
+
+chain.put_slice(b"hello world");
+
+assert_eq!(&a[..], b"hello");
+assert_eq!(&b[..], b" world");
+

Implementations on Foreign Types§

§

impl BufMut for &mut [u8]

§

fn remaining_mut(&self) -> usize

§

fn chunk_mut(&mut self) -> &mut UninitSlice

§

unsafe fn advance_mut(&mut self, cnt: usize)

§

fn put_slice(&mut self, src: &[u8])

§

fn put_bytes(&mut self, val: u8, cnt: usize)

§

impl BufMut for &mut [MaybeUninit<u8>]

§

fn remaining_mut(&self) -> usize

§

fn chunk_mut(&mut self) -> &mut UninitSlice

§

unsafe fn advance_mut(&mut self, cnt: usize)

§

fn put_slice(&mut self, src: &[u8])

§

fn put_bytes(&mut self, val: u8, cnt: usize)

§

impl BufMut for Vec<u8>

§

fn remaining_mut(&self) -> usize

§

unsafe fn advance_mut(&mut self, cnt: usize)

§

fn chunk_mut(&mut self) -> &mut UninitSlice

§

fn put<T>(&mut self, src: T)
where + T: Buf, + Vec<u8>: Sized,

§

fn put_slice(&mut self, src: &[u8])

§

fn put_bytes(&mut self, val: u8, cnt: usize)

§

impl<'a> BufMut for ReadBuf<'a>

Available on crate feature io-util only.
§

fn remaining_mut(&self) -> usize

§

unsafe fn advance_mut(&mut self, cnt: usize)

§

fn chunk_mut(&mut self) -> &mut UninitSlice

§

impl<T> BufMut for &mut T
where + T: BufMut + ?Sized,

§

fn remaining_mut(&self) -> usize

§

fn chunk_mut(&mut self) -> &mut UninitSlice

§

unsafe fn advance_mut(&mut self, cnt: usize)

§

fn put_slice(&mut self, src: &[u8])

§

fn put_u8(&mut self, n: u8)

§

fn put_i8(&mut self, n: i8)

§

fn put_u16(&mut self, n: u16)

§

fn put_u16_le(&mut self, n: u16)

§

fn put_u16_ne(&mut self, n: u16)

§

fn put_i16(&mut self, n: i16)

§

fn put_i16_le(&mut self, n: i16)

§

fn put_i16_ne(&mut self, n: i16)

§

fn put_u32(&mut self, n: u32)

§

fn put_u32_le(&mut self, n: u32)

§

fn put_u32_ne(&mut self, n: u32)

§

fn put_i32(&mut self, n: i32)

§

fn put_i32_le(&mut self, n: i32)

§

fn put_i32_ne(&mut self, n: i32)

§

fn put_u64(&mut self, n: u64)

§

fn put_u64_le(&mut self, n: u64)

§

fn put_u64_ne(&mut self, n: u64)

§

fn put_i64(&mut self, n: i64)

§

fn put_i64_le(&mut self, n: i64)

§

fn put_i64_ne(&mut self, n: i64)

§

impl<T> BufMut for Box<T>
where + T: BufMut + ?Sized,

§

fn remaining_mut(&self) -> usize

§

fn chunk_mut(&mut self) -> &mut UninitSlice

§

unsafe fn advance_mut(&mut self, cnt: usize)

§

fn put_slice(&mut self, src: &[u8])

§

fn put_u8(&mut self, n: u8)

§

fn put_i8(&mut self, n: i8)

§

fn put_u16(&mut self, n: u16)

§

fn put_u16_le(&mut self, n: u16)

§

fn put_u16_ne(&mut self, n: u16)

§

fn put_i16(&mut self, n: i16)

§

fn put_i16_le(&mut self, n: i16)

§

fn put_i16_ne(&mut self, n: i16)

§

fn put_u32(&mut self, n: u32)

§

fn put_u32_le(&mut self, n: u32)

§

fn put_u32_ne(&mut self, n: u32)

§

fn put_i32(&mut self, n: i32)

§

fn put_i32_le(&mut self, n: i32)

§

fn put_i32_ne(&mut self, n: i32)

§

fn put_u64(&mut self, n: u64)

§

fn put_u64_le(&mut self, n: u64)

§

fn put_u64_ne(&mut self, n: u64)

§

fn put_i64(&mut self, n: i64)

§

fn put_i64_le(&mut self, n: i64)

§

fn put_i64_ne(&mut self, n: i64)

Implementors§

§

impl BufMut for BytesMut

§

impl<T> BufMut for Limit<T>
where + T: BufMut,

§

impl<T, U> BufMut for Chain<T, U>
where + T: BufMut, + U: BufMut,

\ No newline at end of file diff --git a/actix_web_actors/all.html b/actix_web_actors/all.html new file mode 100644 index 000000000..688d35c2d --- /dev/null +++ b/actix_web_actors/all.html @@ -0,0 +1 @@ +List of all items in this crate
\ No newline at end of file diff --git a/actix_web_actors/context/struct.HttpContext.html b/actix_web_actors/context/struct.HttpContext.html new file mode 100644 index 000000000..a9981965b --- /dev/null +++ b/actix_web_actors/context/struct.HttpContext.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../actix_web_actors/struct.HttpContext.html...

+ + + \ No newline at end of file diff --git a/actix_web_actors/index.html b/actix_web_actors/index.html new file mode 100644 index 000000000..538c45c6b --- /dev/null +++ b/actix_web_actors/index.html @@ -0,0 +1,55 @@ +actix_web_actors - Rust

Crate actix_web_actors

source ·
Expand description

Actix actors support for Actix Web.

+

§Examples

+
use actix::{Actor, StreamHandler};
+use actix_web::{get, web, App, Error, HttpRequest, HttpResponse, HttpServer};
+use actix_web_actors::ws;
+
+/// Define Websocket actor
+struct MyWs;
+
+impl Actor for MyWs {
+    type Context = ws::WebsocketContext<Self>;
+}
+
+/// Handler for ws::Message message
+impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for MyWs {
+    fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, ctx: &mut Self::Context) {
+        match msg {
+            Ok(ws::Message::Ping(msg)) => ctx.pong(&msg),
+            Ok(ws::Message::Text(text)) => ctx.text(text),
+            Ok(ws::Message::Binary(bin)) => ctx.binary(bin),
+            _ => (),
+        }
+    }
+}
+
+#[get("/ws")]
+async fn index(req: HttpRequest, stream: web::Payload) -> Result<HttpResponse, Error> {
+    ws::start(MyWs, &req, stream)
+}
+
+#[actix_web::main]
+async fn main() -> std::io::Result<()> {
+    HttpServer::new(|| App::new().service(index))
+        .bind(("127.0.0.1", 8080))?
+        .run()
+        .await
+}
+

§Documentation & Community Resources

+

In addition to this API documentation, several other resources are available:

+ +

To get started navigating the API docs, you may consider looking at the following pages first:

+
    +
  • +

    ws: This module provides actor support for WebSockets.

    +
  • +
  • +

    HttpContext: This struct provides actor support for streaming HTTP responses.

    +
  • +
+

Modules§

  • Websocket integration.

Structs§

\ No newline at end of file diff --git a/actix_web_actors/sidebar-items.js b/actix_web_actors/sidebar-items.js new file mode 100644 index 000000000..fc6896e32 --- /dev/null +++ b/actix_web_actors/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"mod":["ws"],"struct":["HttpContext"]}; \ No newline at end of file diff --git a/actix_web_actors/struct.HttpContext.html b/actix_web_actors/struct.HttpContext.html new file mode 100644 index 000000000..acb8a8344 --- /dev/null +++ b/actix_web_actors/struct.HttpContext.html @@ -0,0 +1,102 @@ +HttpContext in actix_web_actors - Rust

Struct actix_web_actors::HttpContext

source ·
pub struct HttpContext<A>
where + A: Actor<Context = HttpContext<A>>,
{ /* private fields */ }
Expand description

Execution context for HTTP actors

+

§Example

+

A demonstration of server-sent events using actors:

+ +
use std::time::Duration;
+
+use actix::{Actor, AsyncContext};
+use actix_web::{get, http::header, App, HttpResponse, HttpServer};
+use actix_web_actors::HttpContext;
+use bytes::Bytes;
+
+struct MyActor {
+    count: usize,
+}
+
+impl Actor for MyActor {
+    type Context = HttpContext<Self>;
+
+    fn started(&mut self, ctx: &mut Self::Context) {
+        ctx.run_later(Duration::from_millis(100), Self::write);
+    }
+}
+
+impl MyActor {
+    fn write(&mut self, ctx: &mut HttpContext<Self>) {
+        self.count += 1;
+        if self.count > 3 {
+            ctx.write_eof()
+        } else {
+            ctx.write(Bytes::from(format!("event: count\ndata: {}\n\n", self.count)));
+            ctx.run_later(Duration::from_millis(100), Self::write);
+        }
+    }
+}
+
+#[get("/")]
+async fn index() -> HttpResponse {
+    HttpResponse::Ok()
+        .insert_header(header::ContentType(mime::TEXT_EVENT_STREAM))
+        .streaming(HttpContext::create(MyActor { count: 0 }))
+}
+
+#[actix_web::main]
+async fn main() -> std::io::Result<()> {
+    HttpServer::new(|| App::new().service(index))
+        .bind(("127.0.0.1", 8080))?
+        .run()
+        .await
+}
+

Implementations§

source§

impl<A> HttpContext<A>
where + A: Actor<Context = Self>,

source

pub fn create(actor: A) -> impl Stream<Item = Result<Bytes, Error>>

Create a new HTTP Context from a request and an actor

+
source

pub fn with_factory<F>(f: F) -> impl Stream<Item = Result<Bytes, Error>>
where + F: FnOnce(&mut Self) -> A + 'static,

Create a new HTTP Context

+
source§

impl<A> HttpContext<A>
where + A: Actor<Context = Self>,

source

pub fn write(&mut self, data: Bytes)

Write payload

+
source

pub fn write_eof(&mut self)

Indicate end of streaming payload. Also this method calls Self::close.

+
source

pub fn handle(&self) -> SpawnHandle

Handle of the running future

+

SpawnHandle is the handle returned by AsyncContext::spawn() method.

+

Trait Implementations§

source§

impl<A> ActorContext for HttpContext<A>
where + A: Actor<Context = Self>,

source§

fn stop(&mut self)

Immediately stop processing incoming messages and switch to a +stopping state. This only affects actors that are currently +running. Future attempts to queue messages will fail.
source§

fn terminate(&mut self)

Terminate actor execution unconditionally. This sets the actor +into the stopped state. This causes future attempts to queue +messages to fail.
source§

fn state(&self) -> ActorState

Retrieve the current Actor execution state.
source§

impl<A> AsyncContext<A> for HttpContext<A>
where + A: Actor<Context = Self>,

source§

fn spawn<F>(&mut self, fut: F) -> SpawnHandle
where + F: ActorFuture<A, Output = ()> + 'static,

Spawns a future into the context. Read more
source§

fn wait<F>(&mut self, fut: F)
where + F: ActorFuture<A, Output = ()> + 'static,

Spawns a future into the context, waiting for it to resolve. Read more
source§

fn cancel_future(&mut self, handle: SpawnHandle) -> bool

Cancels a spawned future. Read more
source§

fn address(&self) -> Addr<A>

Returns the address of the context.
§

fn waiting(&self) -> bool

Checks if the context is paused (waiting for future completion or stopping).
§

fn add_stream<S>(&mut self, fut: S) -> SpawnHandle
where + S: Stream + 'static, + A: StreamHandler<<S as Stream>::Item>,

Registers a stream with the context. Read more
§

fn add_message_stream<S>(&mut self, fut: S)
where + S: Stream + 'static, + <S as Stream>::Item: Message, + A: Handler<<S as Stream>::Item>,

Registers a stream with the context, ignoring errors. Read more
§

fn notify<M>(&mut self, msg: M)
where + A: Handler<M>, + M: Message + 'static,

Sends the message msg to self. This bypasses the mailbox capacity, and +will always queue the message. If the actor is in the stopped state, an +error will be raised.
§

fn notify_later<M>(&mut self, msg: M, after: Duration) -> SpawnHandle
where + A: Handler<M>, + M: Message + 'static,

Sends the message msg to self after a specified period of time. Read more
§

fn run_later<F>(&mut self, dur: Duration, f: F) -> SpawnHandle
where + F: FnOnce(&mut A, &mut <A as Actor>::Context) + 'static,

Executes a closure after a specified period of time. Read more
§

fn run_interval<F>(&mut self, dur: Duration, f: F) -> SpawnHandle
where + F: FnMut(&mut A, &mut <A as Actor>::Context) + 'static,

Spawns a job to execute the given closure periodically, at a +specified fixed interval.
source§

impl<A> AsyncContextParts<A> for HttpContext<A>
where + A: Actor<Context = Self>,

source§

fn parts(&mut self) -> &mut ContextParts<A>

source§

impl<A, M> ToEnvelope<A, M> for HttpContext<A>
where + A: Actor<Context = HttpContext<A>> + Handler<M>, + M: Message + Send + 'static, + M::Result: Send,

source§

fn pack(msg: M, tx: Option<Sender<M::Result>>) -> Envelope<A>

Pack message into suitable envelope

Auto Trait Implementations§

§

impl<A> Freeze for HttpContext<A>

§

impl<A> !RefUnwindSafe for HttpContext<A>

§

impl<A> !Send for HttpContext<A>

§

impl<A> !Sync for HttpContext<A>

§

impl<A> Unpin for HttpContext<A>

§

impl<A> !UnwindSafe for HttpContext<A>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web_actors/ws/enum.CloseCode.html b/actix_web_actors/ws/enum.CloseCode.html new file mode 100644 index 000000000..4efc5194a --- /dev/null +++ b/actix_web_actors/ws/enum.CloseCode.html @@ -0,0 +1,72 @@ +CloseCode in actix_web_actors::ws - Rust

Enum actix_web_actors::ws::CloseCode

pub enum CloseCode {
+    Normal,
+    Away,
+    Protocol,
+    Unsupported,
+    Abnormal,
+    Invalid,
+    Policy,
+    Size,
+    Extension,
+    Error,
+    Restart,
+    Again,
+    // some variants omitted
+}
Expand description

Status code used to indicate why an endpoint is closing the WebSocket connection.

+

Variants§

§

Normal

Indicates a normal closure, meaning that the purpose for which the connection was +established has been fulfilled.

+
§

Away

Indicates that an endpoint is “going away”, such as a server going down or a browser having +navigated away from a page.

+
§

Protocol

Indicates that an endpoint is terminating the connection due to a protocol error.

+
§

Unsupported

Indicates that an endpoint is terminating the connection because it has received a type of +data it cannot accept (e.g., an endpoint that understands only text data MAY send this if it +receives a binary message).

+
§

Abnormal

Indicates an abnormal closure. If the abnormal closure was due to an error, this close code +will not be used. Instead, the on_error method of the handler will be called with +the error. However, if the connection is simply dropped, without an error, this close code +will be sent to the handler.

+
§

Invalid

Indicates that an endpoint is terminating the connection because it has received data within +a message that was not consistent with the type of the message (e.g., non-UTF-8 [RFC 3629] +data within a text message).

+
§

Policy

Indicates that an endpoint is terminating the connection because it has received a message +that violates its policy. This is a generic status code that can be returned when there is +no other more suitable status code (e.g., Unsupported or Size) or if there is a need to hide +specific details about the policy.

+
§

Size

Indicates that an endpoint is terminating the connection because it has received a message +that is too big for it to process.

+
§

Extension

Indicates that an endpoint (client) is terminating the connection because it has expected +the server to negotiate one or more extension, but the server didn’t return them in the +response message of the WebSocket handshake. The list of extensions that are needed should +be given as the reason for closing. Note that this status code is not used by the server, +because it can fail the WebSocket handshake instead.

+
§

Error

Indicates that a server is terminating the connection because it encountered an unexpected +condition that prevented it from fulfilling the request.

+
§

Restart

Indicates that the server is restarting. A client may choose to reconnect, and if it does, +it should use a randomized delay of 5-30 seconds between attempts.

+
§

Again

Indicates that the server is overloaded and the client should either connect to a different +IP (when multiple targets exist), or reconnect to the same IP when a user has performed +an action.

+

Trait Implementations§

§

impl Clone for CloseCode

§

fn clone(&self) -> CloseCode

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for CloseCode

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl From<CloseCode> for CloseReason

§

fn from(code: CloseCode) -> CloseReason

Converts to this type from the input type.
§

impl From<u16> for CloseCode

§

fn from(code: u16) -> CloseCode

Converts to this type from the input type.
§

impl PartialEq for CloseCode

§

fn eq(&self, other: &CloseCode) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for CloseCode

§

impl Eq for CloseCode

§

impl StructuralPartialEq for CloseCode

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web_actors/ws/enum.Frame.html b/actix_web_actors/ws/enum.Frame.html new file mode 100644 index 000000000..7b03af957 --- /dev/null +++ b/actix_web_actors/ws/enum.Frame.html @@ -0,0 +1,37 @@ +Frame in actix_web_actors::ws - Rust

Enum actix_web_actors::ws::Frame

pub enum Frame {
+    Text(Bytes),
+    Binary(Bytes),
+    Continuation(Item),
+    Ping(Bytes),
+    Pong(Bytes),
+    Close(Option<CloseReason>),
+}
Expand description

A WebSocket frame.

+

Variants§

§

Text(Bytes)

Text frame. Note that the codec does not validate UTF-8 encoding.

+
§

Binary(Bytes)

Binary frame.

+
§

Continuation(Item)

Continuation.

+
§

Ping(Bytes)

Ping message.

+
§

Pong(Bytes)

Pong message.

+
§

Close(Option<CloseReason>)

Close message with optional reason.

+

Trait Implementations§

§

impl Debug for Frame

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl PartialEq for Frame

§

fn eq(&self, other: &Frame) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Eq for Frame

§

impl StructuralPartialEq for Frame

Auto Trait Implementations§

§

impl !Freeze for Frame

§

impl RefUnwindSafe for Frame

§

impl Send for Frame

§

impl Sync for Frame

§

impl Unpin for Frame

§

impl UnwindSafe for Frame

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web_actors/ws/enum.HandshakeError.html b/actix_web_actors/ws/enum.HandshakeError.html new file mode 100644 index 000000000..6785863e7 --- /dev/null +++ b/actix_web_actors/ws/enum.HandshakeError.html @@ -0,0 +1,42 @@ +HandshakeError in actix_web_actors::ws - Rust

Enum actix_web_actors::ws::HandshakeError

pub enum HandshakeError {
+    GetMethodRequired,
+    NoWebsocketUpgrade,
+    NoConnectionUpgrade,
+    NoVersionHeader,
+    UnsupportedVersion,
+    BadWebsocketKey,
+}
Expand description

WebSocket handshake errors

+

Variants§

§

GetMethodRequired

Only get method is allowed.

+
§

NoWebsocketUpgrade

Upgrade header if not set to WebSocket.

+
§

NoConnectionUpgrade

Connection header is not set to upgrade.

+
§

NoVersionHeader

WebSocket version header is not set.

+
§

UnsupportedVersion

Unsupported WebSocket version.

+
§

BadWebsocketKey

WebSocket key is not set or wrong.

+

Trait Implementations§

§

impl Clone for HandshakeError

§

fn clone(&self) -> HandshakeError

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for HandshakeError

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for HandshakeError

§

fn fmt( + &self, + _derive_more_display_formatter: &mut Formatter<'_> +) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for HandshakeError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl PartialEq for HandshakeError

§

fn eq(&self, other: &HandshakeError) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl ResponseError for HandshakeError

§

fn error_response(&self) -> HttpResponse

Creates full response for error. Read more
§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
§

impl Copy for HandshakeError

§

impl Eq for HandshakeError

§

impl StructuralPartialEq for HandshakeError

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web_actors/ws/enum.Message.html b/actix_web_actors/ws/enum.Message.html new file mode 100644 index 000000000..7c31ac611 --- /dev/null +++ b/actix_web_actors/ws/enum.Message.html @@ -0,0 +1,39 @@ +Message in actix_web_actors::ws - Rust

Enum actix_web_actors::ws::Message

pub enum Message {
+    Text(ByteString),
+    Binary(Bytes),
+    Continuation(Item),
+    Ping(Bytes),
+    Pong(Bytes),
+    Close(Option<CloseReason>),
+    Nop,
+}
Expand description

A WebSocket message.

+

Variants§

§

Text(ByteString)

Text message.

+
§

Binary(Bytes)

Binary message.

+
§

Continuation(Item)

Continuation.

+
§

Ping(Bytes)

Ping message.

+
§

Pong(Bytes)

Pong message.

+
§

Close(Option<CloseReason>)

Close message with optional reason.

+
§

Nop

No-op. Useful for low-level services.

+

Trait Implementations§

§

impl Debug for Message

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl PartialEq for Message

§

fn eq(&self, other: &Message) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Eq for Message

§

impl StructuralPartialEq for Message

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web_actors/ws/enum.ProtocolError.html b/actix_web_actors/ws/enum.ProtocolError.html new file mode 100644 index 000000000..0adef1f26 --- /dev/null +++ b/actix_web_actors/ws/enum.ProtocolError.html @@ -0,0 +1,43 @@ +ProtocolError in actix_web_actors::ws - Rust

Enum actix_web_actors::ws::ProtocolError

pub enum ProtocolError {
+    UnmaskedFrame,
+    MaskedFrame,
+    InvalidOpcode(u8),
+    InvalidLength(usize),
+    BadOpCode,
+    Overflow,
+    ContinuationNotStarted,
+    ContinuationStarted,
+    ContinuationFragment(OpCode),
+    Io(Error),
+}
Expand description

WebSocket protocol errors.

+

Variants§

§

UnmaskedFrame

Received an unmasked frame from client.

+
§

MaskedFrame

Received a masked frame from server.

+
§

InvalidOpcode(u8)

Encountered invalid opcode.

+
§

InvalidLength(usize)

Invalid control frame length

+
§

BadOpCode

Bad opcode.

+
§

Overflow

A payload reached size limit.

+
§

ContinuationNotStarted

Continuation has not started.

+
§

ContinuationStarted

Received new continuation but it is already started.

+
§

ContinuationFragment(OpCode)

Unknown continuation fragment.

+
§

Io(Error)

I/O error.

+

Trait Implementations§

§

impl Debug for ProtocolError

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for ProtocolError

§

fn fmt( + &self, + _derive_more_display_formatter: &mut Formatter<'_> +) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for ProtocolError

§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<Error> for ProtocolError

§

fn from(original: Error) -> ProtocolError

Converts to this type from the input type.
§

impl From<OpCode> for ProtocolError

§

fn from(original: OpCode) -> ProtocolError

Converts to this type from the input type.
§

impl From<u8> for ProtocolError

§

fn from(original: u8) -> ProtocolError

Converts to this type from the input type.
§

impl From<usize> for ProtocolError

§

fn from(original: usize) -> ProtocolError

Converts to this type from the input type.
§

impl ResponseError for ProtocolError

§

fn status_code(&self) -> StatusCode

Returns appropriate status code for error. Read more
§

fn error_response(&self) -> HttpResponse

Creates full response for error. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web_actors/ws/fn.handshake.html b/actix_web_actors/ws/fn.handshake.html new file mode 100644 index 000000000..fc0431fe9 --- /dev/null +++ b/actix_web_actors/ws/fn.handshake.html @@ -0,0 +1,6 @@ +handshake in actix_web_actors::ws - Rust

Function actix_web_actors::ws::handshake

source ·
pub fn handshake(
+    req: &HttpRequest
+) -> Result<HttpResponseBuilder, HandshakeError>
Expand description

Prepare WebSocket handshake response.

+

This function returns handshake HttpResponse, ready to send to peer. It does not perform +any IO.

+
\ No newline at end of file diff --git a/actix_web_actors/ws/fn.handshake_with_protocols.html b/actix_web_actors/ws/fn.handshake_with_protocols.html new file mode 100644 index 000000000..cf431d4c5 --- /dev/null +++ b/actix_web_actors/ws/fn.handshake_with_protocols.html @@ -0,0 +1,9 @@ +handshake_with_protocols in actix_web_actors::ws - Rust

Function actix_web_actors::ws::handshake_with_protocols

source ·
pub fn handshake_with_protocols(
+    req: &HttpRequest,
+    protocols: &[&str]
+) -> Result<HttpResponseBuilder, HandshakeError>
Expand description

Prepare WebSocket handshake response.

+

This function returns handshake HttpResponse, ready to send to peer. It does not perform +any IO.

+

protocols is a sequence of known protocols. On successful handshake, the returned response +headers contain the first protocol in this list which the server also knows.

+
\ No newline at end of file diff --git a/actix_web_actors/ws/fn.start.html b/actix_web_actors/ws/fn.start.html new file mode 100644 index 000000000..6552c6dac --- /dev/null +++ b/actix_web_actors/ws/fn.start.html @@ -0,0 +1,9 @@ +start in actix_web_actors::ws - Rust

Function actix_web_actors::ws::start

source ·
pub fn start<A, T>(
+    actor: A,
+    req: &HttpRequest,
+    stream: T
+) -> Result<HttpResponse, Error>
where + A: Actor<Context = WebsocketContext<A>> + StreamHandler<Result<Message, ProtocolError>>, + T: Stream<Item = Result<Bytes, PayloadError>> + 'static,
Expand description

Perform WebSocket handshake and start actor.

+

To customize options, see WsResponseBuilder.

+
\ No newline at end of file diff --git a/actix_web_actors/ws/fn.start_with_addr.html b/actix_web_actors/ws/fn.start_with_addr.html new file mode 100644 index 000000000..40e023186 --- /dev/null +++ b/actix_web_actors/ws/fn.start_with_addr.html @@ -0,0 +1,14 @@ +start_with_addr in actix_web_actors::ws - Rust

Function actix_web_actors::ws::start_with_addr

source ·
pub fn start_with_addr<A, T>(
+    actor: A,
+    req: &HttpRequest,
+    stream: T
+) -> Result<(Addr<A>, HttpResponse), Error>
where + A: Actor<Context = WebsocketContext<A>> + StreamHandler<Result<Message, ProtocolError>>, + T: Stream<Item = Result<Bytes, PayloadError>> + 'static,
👎Deprecated since 4.0.0: Prefer WsResponseBuilder::start_with_addr.
Expand description

Perform WebSocket handshake and start actor.

+

req is an HTTP Request that should be requesting a websocket protocol change. stream should +be a Bytes stream (such as actix_web::web::Payload) that contains a stream of the +body request.

+

If there is a problem with the handshake, an error is returned.

+

If successful, returns a pair where the first item is an address for the created actor and the +second item is the response that should be returned from the WebSocket request.

+
\ No newline at end of file diff --git a/actix_web_actors/ws/fn.start_with_protocols.html b/actix_web_actors/ws/fn.start_with_protocols.html new file mode 100644 index 000000000..95a392e15 --- /dev/null +++ b/actix_web_actors/ws/fn.start_with_protocols.html @@ -0,0 +1,10 @@ +start_with_protocols in actix_web_actors::ws - Rust

Function actix_web_actors::ws::start_with_protocols

source ·
pub fn start_with_protocols<A, T>(
+    actor: A,
+    protocols: &[&str],
+    req: &HttpRequest,
+    stream: T
+) -> Result<HttpResponse, Error>
where + A: Actor<Context = WebsocketContext<A>> + StreamHandler<Result<Message, ProtocolError>>, + T: Stream<Item = Result<Bytes, PayloadError>> + 'static,
👎Deprecated since 4.0.0: Prefer WsResponseBuilder for setting protocols.
Expand description

Do WebSocket handshake and start ws actor.

+

protocols is a sequence of known protocols.

+
\ No newline at end of file diff --git a/actix_web_actors/ws/index.html b/actix_web_actors/ws/index.html new file mode 100644 index 000000000..c2e117dc6 --- /dev/null +++ b/actix_web_actors/ws/index.html @@ -0,0 +1,53 @@ +actix_web_actors::ws - Rust

Module actix_web_actors::ws

source ·
Expand description

Websocket integration.

+

§Examples

+
use actix::{Actor, StreamHandler};
+use actix_web::{get, web, App, Error, HttpRequest, HttpResponse, HttpServer};
+use actix_web_actors::ws;
+
+/// Define Websocket actor
+struct MyWs;
+
+impl Actor for MyWs {
+    type Context = ws::WebsocketContext<Self>;
+}
+
+/// Handler for ws::Message message
+impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for MyWs {
+    fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, ctx: &mut Self::Context) {
+        match msg {
+            Ok(ws::Message::Ping(msg)) => ctx.pong(&msg),
+            Ok(ws::Message::Text(text)) => ctx.text(text),
+            Ok(ws::Message::Binary(bin)) => ctx.binary(bin),
+            _ => (),
+        }
+    }
+}
+
+#[get("/ws")]
+async fn websocket(req: HttpRequest, stream: web::Payload) -> Result<HttpResponse, Error> {
+    ws::start(MyWs, &req, stream)
+}
+
+const MAX_FRAME_SIZE: usize = 16_384; // 16KiB
+
+#[get("/custom-ws")]
+async fn custom_websocket(req: HttpRequest, stream: web::Payload) -> Result<HttpResponse, Error> {
+    // Create a Websocket session with a specific max frame size, and protocols.
+    ws::WsResponseBuilder::new(MyWs, &req, stream)
+        .frame_size(MAX_FRAME_SIZE)
+        .protocols(&["A", "B"])
+        .start()
+}
+
+#[actix_web::main]
+async fn main() -> std::io::Result<()> {
+    HttpServer::new(|| {
+            App::new()
+                .service(websocket)
+                .service(custom_websocket)
+        })
+        .bind(("127.0.0.1", 8080))?
+        .run()
+        .await
+}
+

Structs§

Enums§

Functions§

\ No newline at end of file diff --git a/actix_web_actors/ws/sidebar-items.js b/actix_web_actors/ws/sidebar-items.js new file mode 100644 index 000000000..cfbbb98e7 --- /dev/null +++ b/actix_web_actors/ws/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["CloseCode","Frame","HandshakeError","Message","ProtocolError"],"fn":["handshake","handshake_with_protocols","start","start_with_addr","start_with_protocols"],"struct":["CloseReason","WebsocketContext","WsResponseBuilder"]}; \ No newline at end of file diff --git a/actix_web_actors/ws/struct.CloseReason.html b/actix_web_actors/ws/struct.CloseReason.html new file mode 100644 index 000000000..c3e3a0715 --- /dev/null +++ b/actix_web_actors/ws/struct.CloseReason.html @@ -0,0 +1,31 @@ +CloseReason in actix_web_actors::ws - Rust

Struct actix_web_actors::ws::CloseReason

pub struct CloseReason {
+    pub code: CloseCode,
+    pub description: Option<String>,
+}
Expand description

Reason for closing the connection

+

Fields§

§code: CloseCode

Exit code

+
§description: Option<String>

Optional description of the exit code

+

Trait Implementations§

§

impl Clone for CloseReason

§

fn clone(&self) -> CloseReason

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for CloseReason

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<T> From<(CloseCode, T)> for CloseReason
where + T: Into<String>,

§

fn from(info: (CloseCode, T)) -> CloseReason

Converts to this type from the input type.
§

impl From<CloseCode> for CloseReason

§

fn from(code: CloseCode) -> CloseReason

Converts to this type from the input type.
§

impl PartialEq for CloseReason

§

fn eq(&self, other: &CloseReason) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Eq for CloseReason

§

impl StructuralPartialEq for CloseReason

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web_actors/ws/struct.WebsocketContext.html b/actix_web_actors/ws/struct.WebsocketContext.html new file mode 100644 index 000000000..4bafe1442 --- /dev/null +++ b/actix_web_actors/ws/struct.WebsocketContext.html @@ -0,0 +1,90 @@ +WebsocketContext in actix_web_actors::ws - Rust

Struct actix_web_actors::ws::WebsocketContext

source ·
pub struct WebsocketContext<A>
where + A: Actor<Context = WebsocketContext<A>>,
{ /* private fields */ }
Expand description

Execution context for WebSockets actors

+

Implementations§

source§

impl<A> WebsocketContext<A>
where + A: Actor<Context = Self>,

source

pub fn create<S>( + actor: A, + stream: S +) -> impl Stream<Item = Result<Bytes, Error>>
where + A: StreamHandler<Result<Message, ProtocolError>>, + S: Stream<Item = Result<Bytes, PayloadError>> + 'static,

Create a new Websocket context from a request and an actor.

+
source

pub fn create_with_addr<S>( + actor: A, + stream: S +) -> (Addr<A>, impl Stream<Item = Result<Bytes, Error>>)
where + A: StreamHandler<Result<Message, ProtocolError>>, + S: Stream<Item = Result<Bytes, PayloadError>> + 'static,

Create a new Websocket context from a request and an actor.

+

Returns a pair, where the first item is an addr for the created actor, and the second item +is a stream intended to be set as part of the response +via [HttpResponseBuilder::streaming()].

+
source

pub fn with_codec<S>( + actor: A, + stream: S, + codec: Codec +) -> impl Stream<Item = Result<Bytes, Error>>
where + A: StreamHandler<Result<Message, ProtocolError>>, + S: Stream<Item = Result<Bytes, PayloadError>> + 'static,

Create a new Websocket context from a request, an actor, and a codec

+
source

pub fn with_factory<S, F>( + stream: S, + f: F +) -> impl Stream<Item = Result<Bytes, Error>>
where + F: FnOnce(&mut Self) -> A + 'static, + A: StreamHandler<Result<Message, ProtocolError>>, + S: Stream<Item = Result<Bytes, PayloadError>> + 'static,

Create a new Websocket context

+
source§

impl<A> WebsocketContext<A>
where + A: Actor<Context = Self>,

source

pub fn write_raw(&mut self, msg: Message)

Write payload

+

This is a low-level function that accepts framed messages that should +be created using Frame::message(). If you want to send text or binary +data you should prefer the text() or binary() convenience functions +that handle the framing for you.

+
source

pub fn text(&mut self, text: impl Into<ByteString>)

Send text frame

+
source

pub fn binary(&mut self, data: impl Into<Bytes>)

Send binary frame

+
source

pub fn ping(&mut self, message: &[u8])

Send ping frame

+
source

pub fn pong(&mut self, message: &[u8])

Send pong frame

+
source

pub fn close(&mut self, reason: Option<CloseReason>)

Send close frame

+
source

pub fn handle(&self) -> SpawnHandle

Handle of the running future

+

SpawnHandle is the handle returned by AsyncContext::spawn() method.

+
source

pub fn set_mailbox_capacity(&mut self, cap: usize)

Set mailbox capacity

+

By default mailbox capacity is 16 messages.

+

Trait Implementations§

source§

impl<A> ActorContext for WebsocketContext<A>
where + A: Actor<Context = Self>,

source§

fn stop(&mut self)

Immediately stop processing incoming messages and switch to a +stopping state. This only affects actors that are currently +running. Future attempts to queue messages will fail.
source§

fn terminate(&mut self)

Terminate actor execution unconditionally. This sets the actor +into the stopped state. This causes future attempts to queue +messages to fail.
source§

fn state(&self) -> ActorState

Retrieve the current Actor execution state.
source§

impl<A> AsyncContext<A> for WebsocketContext<A>
where + A: Actor<Context = Self>,

source§

fn spawn<F>(&mut self, fut: F) -> SpawnHandle
where + F: ActorFuture<A, Output = ()> + 'static,

Spawns a future into the context. Read more
source§

fn wait<F>(&mut self, fut: F)
where + F: ActorFuture<A, Output = ()> + 'static,

Spawns a future into the context, waiting for it to resolve. Read more
source§

fn cancel_future(&mut self, handle: SpawnHandle) -> bool

Cancels a spawned future. Read more
source§

fn address(&self) -> Addr<A>

Returns the address of the context.
§

fn waiting(&self) -> bool

Checks if the context is paused (waiting for future completion or stopping).
§

fn add_stream<S>(&mut self, fut: S) -> SpawnHandle
where + S: Stream + 'static, + A: StreamHandler<<S as Stream>::Item>,

Registers a stream with the context. Read more
§

fn add_message_stream<S>(&mut self, fut: S)
where + S: Stream + 'static, + <S as Stream>::Item: Message, + A: Handler<<S as Stream>::Item>,

Registers a stream with the context, ignoring errors. Read more
§

fn notify<M>(&mut self, msg: M)
where + A: Handler<M>, + M: Message + 'static,

Sends the message msg to self. This bypasses the mailbox capacity, and +will always queue the message. If the actor is in the stopped state, an +error will be raised.
§

fn notify_later<M>(&mut self, msg: M, after: Duration) -> SpawnHandle
where + A: Handler<M>, + M: Message + 'static,

Sends the message msg to self after a specified period of time. Read more
§

fn run_later<F>(&mut self, dur: Duration, f: F) -> SpawnHandle
where + F: FnOnce(&mut A, &mut <A as Actor>::Context) + 'static,

Executes a closure after a specified period of time. Read more
§

fn run_interval<F>(&mut self, dur: Duration, f: F) -> SpawnHandle
where + F: FnMut(&mut A, &mut <A as Actor>::Context) + 'static,

Spawns a job to execute the given closure periodically, at a +specified fixed interval.
source§

impl<A> AsyncContextParts<A> for WebsocketContext<A>
where + A: Actor<Context = Self>,

source§

fn parts(&mut self) -> &mut ContextParts<A>

source§

impl<A, M> ToEnvelope<A, M> for WebsocketContext<A>
where + A: Actor<Context = WebsocketContext<A>> + Handler<M>, + M: ActixMessage + Send + 'static, + M::Result: Send,

source§

fn pack(msg: M, tx: Option<Sender<M::Result>>) -> Envelope<A>

Pack message into suitable envelope

Auto Trait Implementations§

§

impl<A> Freeze for WebsocketContext<A>

§

impl<A> !RefUnwindSafe for WebsocketContext<A>

§

impl<A> !Send for WebsocketContext<A>

§

impl<A> !Sync for WebsocketContext<A>

§

impl<A> Unpin for WebsocketContext<A>

§

impl<A> !UnwindSafe for WebsocketContext<A>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web_actors/ws/struct.WsResponseBuilder.html b/actix_web_actors/ws/struct.WsResponseBuilder.html new file mode 100644 index 000000000..36911437c --- /dev/null +++ b/actix_web_actors/ws/struct.WsResponseBuilder.html @@ -0,0 +1,64 @@ +WsResponseBuilder in actix_web_actors::ws - Rust

Struct actix_web_actors::ws::WsResponseBuilder

source ·
pub struct WsResponseBuilder<'a, A, T>
where + A: Actor<Context = WebsocketContext<A>> + StreamHandler<Result<Message, ProtocolError>>, + T: Stream<Item = Result<Bytes, PayloadError>> + 'static,
{ /* private fields */ }
Expand description

Builder for Websocket session response.

+

§Examples

+
#[get("/ws")]
+async fn websocket(req: HttpRequest, stream: web::Payload) -> Result<HttpResponse, Error> {
+    ws::WsResponseBuilder::new(MyWs, &req, stream).start()
+}
+
+const MAX_FRAME_SIZE: usize = 16_384; // 16KiB
+
+#[get("/custom-ws")]
+async fn custom_websocket(req: HttpRequest, stream: web::Payload) -> Result<HttpResponse, Error> {
+    // Create a Websocket session with a specific max frame size, codec, and protocols.
+    ws::WsResponseBuilder::new(MyWs, &req, stream)
+        .codec(actix_http::ws::Codec::new())
+        // This will overwrite the codec's max frame-size
+        .frame_size(MAX_FRAME_SIZE)
+        .protocols(&["A", "B"])
+        .start()
+}
+

Implementations§

source§

impl<'a, A, T> WsResponseBuilder<'a, A, T>
where + A: Actor<Context = WebsocketContext<A>> + StreamHandler<Result<Message, ProtocolError>>, + T: Stream<Item = Result<Bytes, PayloadError>> + 'static,

source

pub fn new(actor: A, req: &'a HttpRequest, stream: T) -> Self

Construct a new WsResponseBuilder with actor, request, and payload stream.

+

For usage example, see docs on WsResponseBuilder struct.

+
source

pub fn protocols(self, protocols: &'a [&'a str]) -> Self

Set the protocols for the session.

+
source

pub fn frame_size(self, frame_size: usize) -> Self

Set the max frame size for each message (in bytes).

+

Note: This will override any given [Codec]’s max frame size.

+
source

pub fn codec(self, codec: Codec) -> Self

Set the [Codec] for the session. If Self::frame_size is also set, the given +[Codec]’s max frame size will be overridden.

+
source

pub fn start(self) -> Result<HttpResponse, Error>

Perform WebSocket handshake and start actor.

+

req is an [HttpRequest] that should be requesting a websocket protocol change. +stream should be a [Bytes] stream (such as actix_web::web::Payload) that contains a +stream of the body request.

+

If there is a problem with the handshake, an error is returned.

+

If successful, consume the WsResponseBuilder and return a [HttpResponse] wrapped in +a Result.

+
source

pub fn start_with_addr(self) -> Result<(Addr<A>, HttpResponse), Error>

Perform WebSocket handshake and start actor.

+

req is an [HttpRequest] that should be requesting a websocket protocol change. +stream should be a [Bytes] stream (such as actix_web::web::Payload) that contains a +stream of the body request.

+

If there is a problem with the handshake, an error is returned.

+

If successful, returns a pair where the first item is an address for the created actor and +the second item is the [HttpResponse] that should be returned from the websocket request.

+

Auto Trait Implementations§

§

impl<'a, A, T> Freeze for WsResponseBuilder<'a, A, T>
where + A: Freeze, + T: Freeze,

§

impl<'a, A, T> !RefUnwindSafe for WsResponseBuilder<'a, A, T>

§

impl<'a, A, T> !Send for WsResponseBuilder<'a, A, T>

§

impl<'a, A, T> !Sync for WsResponseBuilder<'a, A, T>

§

impl<'a, A, T> Unpin for WsResponseBuilder<'a, A, T>
where + T: Unpin,

§

impl<'a, A, T> !UnwindSafe for WsResponseBuilder<'a, A, T>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/actix_web_codegen/all.html b/actix_web_codegen/all.html new file mode 100644 index 000000000..4a0c8480f --- /dev/null +++ b/actix_web_codegen/all.html @@ -0,0 +1 @@ +List of all items in this crate
\ No newline at end of file diff --git a/actix_web_codegen/attr.connect.html b/actix_web_codegen/attr.connect.html new file mode 100644 index 000000000..7017b1e7b --- /dev/null +++ b/actix_web_codegen/attr.connect.html @@ -0,0 +1,19 @@ +connect in actix_web_codegen - Rust

Attribute Macro actix_web_codegen::connect

source ·
#[connect]
Expand description

Creates route handler with actix_web::guard::Connect.

+

§Syntax

#[connect("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[connect("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web_codegen/attr.delete.html b/actix_web_codegen/attr.delete.html new file mode 100644 index 000000000..6f3029479 --- /dev/null +++ b/actix_web_codegen/attr.delete.html @@ -0,0 +1,19 @@ +delete in actix_web_codegen - Rust

Attribute Macro actix_web_codegen::delete

source ·
#[delete]
Expand description

Creates route handler with actix_web::guard::Delete.

+

§Syntax

#[delete("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[delete("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web_codegen/attr.get.html b/actix_web_codegen/attr.get.html new file mode 100644 index 000000000..1f8b6646c --- /dev/null +++ b/actix_web_codegen/attr.get.html @@ -0,0 +1,19 @@ +get in actix_web_codegen - Rust

Attribute Macro actix_web_codegen::get

source ·
#[get]
Expand description

Creates route handler with actix_web::guard::Get.

+

§Syntax

#[get("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[get("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web_codegen/attr.head.html b/actix_web_codegen/attr.head.html new file mode 100644 index 000000000..305142f17 --- /dev/null +++ b/actix_web_codegen/attr.head.html @@ -0,0 +1,19 @@ +head in actix_web_codegen - Rust

Attribute Macro actix_web_codegen::head

source ·
#[head]
Expand description

Creates route handler with actix_web::guard::Head.

+

§Syntax

#[head("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[head("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web_codegen/attr.main.html b/actix_web_codegen/attr.main.html new file mode 100644 index 000000000..b3b12904f --- /dev/null +++ b/actix_web_codegen/attr.main.html @@ -0,0 +1,10 @@ +main in actix_web_codegen - Rust

Attribute Macro actix_web_codegen::main

source ·
#[main]
Expand description

Marks async main function as the Actix Web system entry-point.

+

Note that Actix Web also works under #[tokio::main] since version 4.0. However, this macro is +still necessary for actor support (since actors use a System). Read more in the +actix_web::rt module docs.

+

§Examples

+
#[actix_web::main]
+async fn main() {
+    async { println!("Hello world"); }.await
+}
+
\ No newline at end of file diff --git a/actix_web_codegen/attr.options.html b/actix_web_codegen/attr.options.html new file mode 100644 index 000000000..e6bbd36f2 --- /dev/null +++ b/actix_web_codegen/attr.options.html @@ -0,0 +1,19 @@ +options in actix_web_codegen - Rust

Attribute Macro actix_web_codegen::options

source ·
#[options]
Expand description

Creates route handler with actix_web::guard::Options.

+

§Syntax

#[options("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[options("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web_codegen/attr.patch.html b/actix_web_codegen/attr.patch.html new file mode 100644 index 000000000..4b78f23c3 --- /dev/null +++ b/actix_web_codegen/attr.patch.html @@ -0,0 +1,19 @@ +patch in actix_web_codegen - Rust

Attribute Macro actix_web_codegen::patch

source ·
#[patch]
Expand description

Creates route handler with actix_web::guard::Patch.

+

§Syntax

#[patch("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[patch("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web_codegen/attr.post.html b/actix_web_codegen/attr.post.html new file mode 100644 index 000000000..d81997541 --- /dev/null +++ b/actix_web_codegen/attr.post.html @@ -0,0 +1,19 @@ +post in actix_web_codegen - Rust

Attribute Macro actix_web_codegen::post

source ·
#[post]
Expand description

Creates route handler with actix_web::guard::Post.

+

§Syntax

#[post("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[post("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web_codegen/attr.put.html b/actix_web_codegen/attr.put.html new file mode 100644 index 000000000..8b5ec942e --- /dev/null +++ b/actix_web_codegen/attr.put.html @@ -0,0 +1,19 @@ +put in actix_web_codegen - Rust

Attribute Macro actix_web_codegen::put

source ·
#[put]
Expand description

Creates route handler with actix_web::guard::Put.

+

§Syntax

#[put("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[put("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web_codegen/attr.route.html b/actix_web_codegen/attr.route.html new file mode 100644 index 000000000..a9761e80c --- /dev/null +++ b/actix_web_codegen/attr.route.html @@ -0,0 +1,21 @@ +route in actix_web_codegen - Rust

Attribute Macro actix_web_codegen::route

source ·
#[route]
Expand description

Creates resource handler, allowing multiple HTTP method guards.

+

§Syntax

#[route("path", method="HTTP_METHOD"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the function +name of handler is used.
  • +
  • method = "HTTP_METHOD": Registers HTTP method to provide guard for. Upper-case string, +“GET”, “POST” for example.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the generate +code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[route("/test", method = "GET", method = "HEAD", method = "CUSTOM")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web_codegen/attr.routes.html b/actix_web_codegen/attr.routes.html new file mode 100644 index 000000000..8e56e9349 --- /dev/null +++ b/actix_web_codegen/attr.routes.html @@ -0,0 +1,18 @@ +routes in actix_web_codegen - Rust

Attribute Macro actix_web_codegen::routes

source ·
#[routes]
Expand description

Creates resource handler, allowing multiple HTTP methods and paths.

+

§Syntax

#[routes]
+#[<method>("path", ...)]
+#[<method>("path", ...)]
+...
+

§Attributes

+

The routes macro itself has no parameters, but allows specifying the attribute macros for +the multiple paths and/or methods, e.g. GET and POST.

+

These helper attributes take the same parameters as the single method handlers.

+

§Examples

+
#[routes]
+#[get("/test")]
+#[get("/test2")]
+#[delete("/test")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web_codegen/attr.test.html b/actix_web_codegen/attr.test.html new file mode 100644 index 000000000..eea4e97cf --- /dev/null +++ b/actix_web_codegen/attr.test.html @@ -0,0 +1,7 @@ +test in actix_web_codegen - Rust

Attribute Macro actix_web_codegen::test

source ·
#[test]
Expand description

Marks async test functions to use the Actix Web system entry-point.

+

§Examples

+
#[actix_web::test]
+async fn test() {
+    assert_eq!(async { "Hello world" }.await, "Hello world");
+}
+
\ No newline at end of file diff --git a/actix_web_codegen/attr.trace.html b/actix_web_codegen/attr.trace.html new file mode 100644 index 000000000..aebd2258d --- /dev/null +++ b/actix_web_codegen/attr.trace.html @@ -0,0 +1,19 @@ +trace in actix_web_codegen - Rust

Attribute Macro actix_web_codegen::trace

source ·
#[trace]
Expand description

Creates route handler with actix_web::guard::Trace.

+

§Syntax

#[trace("path"[, attributes])]
+

§Attributes

+
    +
  • "path": Raw literal string with path for which to register handler.
  • +
  • name = "resource_name": Specifies resource name for the handler. If not set, the +function name of handler is used.
  • +
  • guard = "function_name": Registers function as guard using actix_web::guard::fn_guard.
  • +
  • wrap = "Middleware": Registers a resource middleware.
  • +
+

§Notes

+

Function name can be specified as any expression that is going to be accessible to the +generate code, e.g my_guard or my_module::my_guard.

+

§Examples

+
#[trace("/")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+
\ No newline at end of file diff --git a/actix_web_codegen/index.html b/actix_web_codegen/index.html new file mode 100644 index 000000000..2391ea658 --- /dev/null +++ b/actix_web_codegen/index.html @@ -0,0 +1,43 @@ +actix_web_codegen - Rust

Crate actix_web_codegen

source ·
Expand description

Routing and runtime macros for Actix Web.

+

§Actix Web Re-exports

+

Actix Web re-exports a version of this crate in it’s entirety so you usually don’t have to +specify a dependency on this crate explicitly. Sometimes, however, updates are made to this +crate before the actix-web dependency is updated. Therefore, code examples here will show +explicit imports. Check the latest actix-web attributes docs to see which macros +are re-exported.

+

§Runtime Setup

+

Used for setting up the actix async runtime. See main macro docs.

+ +
#[actix_web_codegen::main] // or `#[actix_web::main]` in Actix Web apps
+async fn main() {
+    async { println!("Hello world"); }.await
+}
+

§Single Method Handler

+

There is a macro to set up a handler for each of the most common HTTP methods that also define +additional guards and route-specific middleware.

+

See docs for: GET, POST, PATCH, PUT, DELETE, HEAD, CONNECT, OPTIONS, TRACE

+ +
#[get("/test")]
+async fn get_handler() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+

§Multiple Method Handlers

+

Similar to the single method handler macro but takes one or more arguments for the HTTP methods +it should respond to. See route macro docs.

+ +
#[route("/test", method = "GET", method = "HEAD")]
+async fn get_and_head_handler() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+

§Multiple Path Handlers

+

Acts as a wrapper for multiple single method handler macros. It takes no arguments and +delegates those to the macros for the individual methods. See routes macro docs.

+ +
#[routes]
+#[get("/test")]
+#[get("/test2")]
+#[delete("/test")]
+async fn example() -> HttpResponse {
+    HttpResponse::Ok().finish()
+}
+

Attribute Macros§

  • Creates route handler with actix_web::guard::Connect.
  • Creates route handler with actix_web::guard::Delete.
  • Creates route handler with actix_web::guard::Get.
  • Creates route handler with actix_web::guard::Head.
  • Marks async main function as the Actix Web system entry-point.
  • Creates route handler with actix_web::guard::Options.
  • Creates route handler with actix_web::guard::Patch.
  • Creates route handler with actix_web::guard::Post.
  • Creates route handler with actix_web::guard::Put.
  • Creates resource handler, allowing multiple HTTP method guards.
  • Creates resource handler, allowing multiple HTTP methods and paths.
  • Marks async test functions to use the Actix Web system entry-point.
  • Creates route handler with actix_web::guard::Trace.
\ No newline at end of file diff --git a/actix_web_codegen/sidebar-items.js b/actix_web_codegen/sidebar-items.js new file mode 100644 index 000000000..5a921a145 --- /dev/null +++ b/actix_web_codegen/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"attr":["connect","delete","get","head","main","options","patch","post","put","route","routes","test","trace"]}; \ No newline at end of file diff --git a/awc/all.html b/awc/all.html new file mode 100644 index 000000000..98b2f08e2 --- /dev/null +++ b/awc/all.html @@ -0,0 +1 @@ +List of all items in this crate

List of all items

Structs

Enums

Traits

Functions

Type Aliases

Constants

\ No newline at end of file diff --git a/awc/body/enum.BodySize.html b/awc/body/enum.BodySize.html new file mode 100644 index 000000000..e8b413d35 --- /dev/null +++ b/awc/body/enum.BodySize.html @@ -0,0 +1,46 @@ +BodySize in awc::body - Rust

Enum awc::body::BodySize

pub enum BodySize {
+    None,
+    Sized(u64),
+    Stream,
+}
Expand description

Body size hint.

+

Variants§

§

None

Implicitly empty body.

+

Will omit the Content-Length header. Used for responses to certain methods (e.g., HEAD) or +with particular status codes (e.g., 204 No Content). Consumers that read this as a body size +hint are allowed to make optimizations that skip reading or writing the payload.

+
§

Sized(u64)

Known size body.

+

Will write Content-Length: N header.

+
§

Stream

Unknown size body.

+

Will not write Content-Length header. Can be used with chunked Transfer-Encoding.

+

Implementations§

§

impl BodySize

pub const ZERO: BodySize = _

Equivalent to BodySize::Sized(0);

+

pub fn is_eof(&self) -> bool

Returns true if size hint indicates omitted or empty body.

+

Streams will return false because it cannot be known without reading the stream.

+ +
assert!(BodySize::None.is_eof());
+assert!(BodySize::Sized(0).is_eof());
+
+assert!(!BodySize::Sized(64).is_eof());
+assert!(!BodySize::Stream.is_eof());
+

Trait Implementations§

§

impl Clone for BodySize

§

fn clone(&self) -> BodySize

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for BodySize

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl PartialEq for BodySize

§

fn eq(&self, other: &BodySize) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for BodySize

§

impl Eq for BodySize

§

impl StructuralPartialEq for BodySize

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/body/enum.EitherBody.html b/awc/body/enum.EitherBody.html new file mode 100644 index 000000000..3c41ea757 --- /dev/null +++ b/awc/body/enum.EitherBody.html @@ -0,0 +1,61 @@ +EitherBody in awc::body - Rust

Enum awc::body::EitherBody

pub enum EitherBody<L, R = BoxBody> {
+    Left {
+        body: L,
+    },
+    Right {
+        body: R,
+    },
+}
Expand description

An “either” type specialized for body types.

+

It is common, in middleware especially, to conditionally return an inner service’s unknown/ +generic body B type or return early with a new response. This type’s “right” variant +defaults to BoxBody since error responses are the common case.

+

For example, middleware will often have type Response = ServiceResponse<EitherBody<B>>. +This means that the inner service’s response body type maps to the Left variant and the +middleware’s own error responses use the default Right variant of BoxBody. Of course, +there’s no reason it couldn’t use EitherBody<B, String> instead if its alternative +responses have a known type.

+

Variants§

§

Left

A body of type L.

+

Fields

§body: L
§

Right

A body of type R.

+

Fields

§body: R

Implementations§

§

impl<L> EitherBody<L>

pub fn new(body: L) -> EitherBody<L>

Creates new EitherBody left variant with a boxed right variant.

+

If the expected R type will be inferred and is not BoxBody then use the +left constructor instead.

+
§

impl<L, R> EitherBody<L, R>

pub fn left(body: L) -> EitherBody<L, R>

Creates new EitherBody using left variant.

+

pub fn right(body: R) -> EitherBody<L, R>

Creates new EitherBody using right variant.

+

Trait Implementations§

§

impl<L, R> Clone for EitherBody<L, R>
where + L: Clone, + R: Clone,

§

fn clone(&self) -> EitherBody<L, R>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl<L, R> Debug for EitherBody<L, R>
where + L: Debug, + R: Debug,

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<L, R> MessageBody for EitherBody<L, R>
where + L: MessageBody + 'static, + R: MessageBody + 'static,

§

type Error = Error

The type of error that will be returned if streaming body fails. Read more
§

fn size(&self) -> BodySize

Body size hint. Read more
§

fn poll_next( + self: Pin<&mut EitherBody<L, R>>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <EitherBody<L, R> as MessageBody>::Error>>>

Attempt to pull out the next chunk of body bytes. Read more
§

fn try_into_bytes(self) -> Result<Bytes, EitherBody<L, R>>

Try to convert into the complete chunk of body bytes. Read more
§

fn boxed(self) -> BoxBody

Wraps this body into a BoxBody. Read more
§

impl<'__pin, L, R> Unpin for EitherBody<L, R>
where + __Origin<'__pin, L, R>: Unpin,

Auto Trait Implementations§

§

impl<L, R> Freeze for EitherBody<L, R>
where + L: Freeze, + R: Freeze,

§

impl<L, R> RefUnwindSafe for EitherBody<L, R>
where + L: RefUnwindSafe, + R: RefUnwindSafe,

§

impl<L, R> Send for EitherBody<L, R>
where + L: Send, + R: Send,

§

impl<L, R> Sync for EitherBody<L, R>
where + L: Sync, + R: Sync,

§

impl<L, R> UnwindSafe for EitherBody<L, R>
where + L: UnwindSafe, + R: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/body/fn.to_bytes.html b/awc/body/fn.to_bytes.html new file mode 100644 index 000000000..71a48122d --- /dev/null +++ b/awc/body/fn.to_bytes.html @@ -0,0 +1,16 @@ +to_bytes in awc::body - Rust

Function awc::body::to_bytes

pub async fn to_bytes<B>(body: B) -> Result<Bytes, <B as MessageBody>::Error>
where + B: MessageBody,
Expand description

Collects all the bytes produced by body.

+

Any errors produced by the body stream are returned immediately.

+

Consider using to_bytes_limited instead to protect against memory exhaustion.

+

§Examples

+
use actix_http::body::{self, to_bytes};
+use bytes::Bytes;
+
+let body = body::None::new();
+let bytes = to_bytes(body).await.unwrap();
+assert!(bytes.is_empty());
+
+let body = Bytes::from_static(b"123");
+let bytes = to_bytes(body).await.unwrap();
+assert_eq!(bytes, "123");
+
\ No newline at end of file diff --git a/awc/body/fn.to_bytes_limited.html b/awc/body/fn.to_bytes_limited.html new file mode 100644 index 000000000..6e5b0ace2 --- /dev/null +++ b/awc/body/fn.to_bytes_limited.html @@ -0,0 +1,23 @@ +to_bytes_limited in awc::body - Rust

Function awc::body::to_bytes_limited

pub async fn to_bytes_limited<B>(
+    body: B,
+    limit: usize
+) -> Result<Result<Bytes, <B as MessageBody>::Error>, BodyLimitExceeded>
where + B: MessageBody,
Expand description

Collects the bytes produced by body, up to limit bytes.

+

If a chunk read from poll_next causes the total number of bytes read to exceed limit, an +Err(BodyLimitExceeded) is returned.

+

Any errors produced by the body stream are returned immediately as Ok(Err(B::Error)).

+

§Examples

+
use actix_http::body::{self, to_bytes_limited};
+use bytes::Bytes;
+
+let body = body::None::new();
+let bytes = to_bytes_limited(body, 10).await.unwrap().unwrap();
+assert!(bytes.is_empty());
+
+let body = Bytes::from_static(b"123");
+let bytes = to_bytes_limited(body, 10).await.unwrap().unwrap();
+assert_eq!(bytes, "123");
+
+let body = Bytes::from_static(b"123");
+assert!(to_bytes_limited(body, 2).await.is_err());
+
\ No newline at end of file diff --git a/awc/body/index.html b/awc/body/index.html new file mode 100644 index 000000000..53f14b01c --- /dev/null +++ b/awc/body/index.html @@ -0,0 +1,3 @@ +awc::body - Rust

Module awc::body

Expand description

Traits and structures to aid consuming and writing HTTP payloads.

+

“Body” and “payload” are used somewhat interchangeably in this documentation.

+

Structs§

Enums§

Traits§

  • An interface for types that can be used as a response body.

Functions§

\ No newline at end of file diff --git a/awc/body/sidebar-items.js b/awc/body/sidebar-items.js new file mode 100644 index 000000000..02571f400 --- /dev/null +++ b/awc/body/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["BodySize","EitherBody"],"fn":["to_bytes","to_bytes_limited"],"struct":["BodyLimitExceeded","BodyStream","BoxBody","None","SizedStream"],"trait":["MessageBody"]}; \ No newline at end of file diff --git a/awc/body/struct.BodyLimitExceeded.html b/awc/body/struct.BodyLimitExceeded.html new file mode 100644 index 000000000..44c2af542 --- /dev/null +++ b/awc/body/struct.BodyLimitExceeded.html @@ -0,0 +1,22 @@ +BodyLimitExceeded in awc::body - Rust

Struct awc::body::BodyLimitExceeded

#[non_exhaustive]
pub struct BodyLimitExceeded;
Expand description

Error type returned from to_bytes_limited when body produced exceeds limit.

+

Trait Implementations§

§

impl Debug for BodyLimitExceeded

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for BodyLimitExceeded

§

fn fmt( + &self, + _derive_more_display_formatter: &mut Formatter<'_> +) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for BodyLimitExceeded

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/body/struct.BodyStream.html b/awc/body/struct.BodyStream.html new file mode 100644 index 000000000..4d2bd1259 --- /dev/null +++ b/awc/body/struct.BodyStream.html @@ -0,0 +1,37 @@ +BodyStream in awc::body - Rust

Struct awc::body::BodyStream

pub struct BodyStream<S> { /* private fields */ }
Expand description

Streaming response wrapper.

+

Response does not contain Content-Length header and appropriate transfer encoding is used.

+

Implementations§

§

impl<S, E> BodyStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn Error>> + 'static,

pub fn new(stream: S) -> BodyStream<S>

Trait Implementations§

§

impl<S, E> MessageBody for BodyStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn Error>> + 'static,

§

fn poll_next( + self: Pin<&mut BodyStream<S>>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <BodyStream<S> as MessageBody>::Error>>>

Attempts to pull out the next value of the underlying [Stream].

+

Empty values are skipped to prevent BodyStream’s transmission being ended on a +zero-length chunk, but rather proceed until the underlying [Stream] ends.

+
§

type Error = E

The type of error that will be returned if streaming body fails. Read more
§

fn size(&self) -> BodySize

Body size hint. Read more
§

fn try_into_bytes(self) -> Result<Bytes, Self>
where + Self: Sized,

Try to convert into the complete chunk of body bytes. Read more
§

fn boxed(self) -> BoxBody
where + Self: Sized + 'static,

Wraps this body into a BoxBody. Read more
§

impl<'__pin, S> Unpin for BodyStream<S>
where + __Origin<'__pin, S>: Unpin,

Auto Trait Implementations§

§

impl<S> Freeze for BodyStream<S>
where + S: Freeze,

§

impl<S> RefUnwindSafe for BodyStream<S>
where + S: RefUnwindSafe,

§

impl<S> Send for BodyStream<S>
where + S: Send,

§

impl<S> Sync for BodyStream<S>
where + S: Sync,

§

impl<S> UnwindSafe for BodyStream<S>
where + S: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/body/struct.BoxBody.html b/awc/body/struct.BoxBody.html new file mode 100644 index 000000000..663caba1f --- /dev/null +++ b/awc/body/struct.BoxBody.html @@ -0,0 +1,26 @@ +BoxBody in awc::body - Rust

Struct awc::body::BoxBody

pub struct BoxBody(/* private fields */);
Expand description

A boxed message body with boxed errors.

+

Implementations§

§

impl BoxBody

pub fn new<B>(body: B) -> BoxBody
where + B: MessageBody + 'static,

Boxes body type, erasing type information.

+

If the body type to wrap is unknown or generic it is better to use MessageBody::boxed to +avoid double boxing.

+

pub fn as_pin_mut(&mut self) -> Pin<&mut BoxBody>

Returns a mutable pinned reference to the inner message body type.

+

Trait Implementations§

§

impl Debug for BoxBody

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl MessageBody for BoxBody

§

type Error = Box<dyn Error>

The type of error that will be returned if streaming body fails. Read more
§

fn size(&self) -> BodySize

Body size hint. Read more
§

fn poll_next( + self: Pin<&mut BoxBody>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <BoxBody as MessageBody>::Error>>>

Attempt to pull out the next chunk of body bytes. Read more
§

fn try_into_bytes(self) -> Result<Bytes, BoxBody>

Try to convert into the complete chunk of body bytes. Read more
§

fn boxed(self) -> BoxBody

Wraps this body into a BoxBody. Read more

Auto Trait Implementations§

§

impl !Freeze for BoxBody

§

impl !RefUnwindSafe for BoxBody

§

impl !Send for BoxBody

§

impl !Sync for BoxBody

§

impl Unpin for BoxBody

§

impl !UnwindSafe for BoxBody

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/body/struct.None.html b/awc/body/struct.None.html new file mode 100644 index 000000000..d642604b3 --- /dev/null +++ b/awc/body/struct.None.html @@ -0,0 +1,29 @@ +None in awc::body - Rust

Struct awc::body::None

#[non_exhaustive]
pub struct None;
Expand description

Body type for responses that forbid payloads.

+

This is distinct from an “empty” response which would contain a Content-Length header. +For an “empty” body, use () or Bytes::new().

+

For example, the HTTP spec forbids a payload to be sent with a 204 No Content response. +In this case, the payload (or lack thereof) is implicit from the status code, so a +Content-Length header is not required.

+

Implementations§

§

impl None

pub fn new() -> None

Constructs new “none” body.

+

Trait Implementations§

§

impl Clone for None

§

fn clone(&self) -> None

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for None

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for None

§

fn default() -> None

Returns the “default value” for a type. Read more
§

impl MessageBody for None

§

type Error = Infallible

The type of error that will be returned if streaming body fails. Read more
§

fn size(&self) -> BodySize

Body size hint. Read more
§

fn poll_next( + self: Pin<&mut None>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <None as MessageBody>::Error>>>

Attempt to pull out the next chunk of body bytes. Read more
§

fn try_into_bytes(self) -> Result<Bytes, None>

Try to convert into the complete chunk of body bytes. Read more
§

fn boxed(self) -> BoxBody
where + Self: Sized + 'static,

Wraps this body into a BoxBody. Read more
§

impl Copy for None

Auto Trait Implementations§

§

impl Freeze for None

§

impl RefUnwindSafe for None

§

impl Send for None

§

impl Sync for None

§

impl Unpin for None

§

impl UnwindSafe for None

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/body/struct.SizedStream.html b/awc/body/struct.SizedStream.html new file mode 100644 index 000000000..1cc0d4cae --- /dev/null +++ b/awc/body/struct.SizedStream.html @@ -0,0 +1,39 @@ +SizedStream in awc::body - Rust

Struct awc::body::SizedStream

pub struct SizedStream<S> { /* private fields */ }
Expand description

Known sized streaming response wrapper.

+

This body implementation should be used if total size of stream is known. Data is sent as-is +without using chunked transfer encoding.

+

Implementations§

§

impl<S, E> SizedStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn Error>> + 'static,

pub fn new(size: u64, stream: S) -> SizedStream<S>

Trait Implementations§

§

impl<S, E> MessageBody for SizedStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn Error>> + 'static,

§

fn poll_next( + self: Pin<&mut SizedStream<S>>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <SizedStream<S> as MessageBody>::Error>>>

Attempts to pull out the next value of the underlying [Stream].

+

Empty values are skipped to prevent SizedStream’s transmission being +ended on a zero-length chunk, but rather proceed until the underlying +[Stream] ends.

+
§

type Error = E

The type of error that will be returned if streaming body fails. Read more
§

fn size(&self) -> BodySize

Body size hint. Read more
§

fn try_into_bytes(self) -> Result<Bytes, Self>
where + Self: Sized,

Try to convert into the complete chunk of body bytes. Read more
§

fn boxed(self) -> BoxBody
where + Self: Sized + 'static,

Wraps this body into a BoxBody. Read more
§

impl<'__pin, S> Unpin for SizedStream<S>
where + __Origin<'__pin, S>: Unpin,

Auto Trait Implementations§

§

impl<S> Freeze for SizedStream<S>
where + S: Freeze,

§

impl<S> RefUnwindSafe for SizedStream<S>
where + S: RefUnwindSafe,

§

impl<S> Send for SizedStream<S>
where + S: Send,

§

impl<S> Sync for SizedStream<S>
where + S: Sync,

§

impl<S> UnwindSafe for SizedStream<S>
where + S: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/body/trait.MessageBody.html b/awc/body/trait.MessageBody.html new file mode 100644 index 000000000..90be39b3b --- /dev/null +++ b/awc/body/trait.MessageBody.html @@ -0,0 +1,139 @@ +MessageBody in awc::body - Rust

Trait awc::body::MessageBody

pub trait MessageBody {
+    type Error: Into<Box<dyn Error>>;
+
+    // Required methods
+    fn size(&self) -> BodySize;
+    fn poll_next(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>
+    ) -> Poll<Option<Result<Bytes, Self::Error>>>;
+
+    // Provided methods
+    fn try_into_bytes(self) -> Result<Bytes, Self>
+       where Self: Sized { ... }
+    fn boxed(self) -> BoxBody
+       where Self: Sized + 'static { ... }
+}
Expand description

An interface for types that can be used as a response body.

+

It is not usually necessary to create custom body types, this trait is already implemented for +a large number of sensible body types including:

+ +

§Examples

+
struct Repeat {
+    chunk: String,
+    n_times: usize,
+}
+
+impl MessageBody for Repeat {
+    type Error = Infallible;
+
+    fn size(&self) -> BodySize {
+        BodySize::Sized((self.chunk.len() * self.n_times) as u64)
+    }
+
+    fn poll_next(
+        self: Pin<&mut Self>,
+        _cx: &mut Context<'_>,
+    ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+        let payload_string = self.chunk.repeat(self.n_times);
+        let payload_bytes = Bytes::from(payload_string);
+        Poll::Ready(Some(Ok(payload_bytes)))
+    }
+}
+

Required Associated Types§

type Error: Into<Box<dyn Error>>

The type of error that will be returned if streaming body fails.

+

Since it is not appropriate to generate a response mid-stream, it only requires Error for +internal use and logging.

+

Required Methods§

fn size(&self) -> BodySize

Body size hint.

+

If BodySize::None is returned, optimizations that skip reading the body are allowed.

+

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, Self::Error>>>

Attempt to pull out the next chunk of body bytes.

+
§Return Value
+

Similar to the Stream interface, there are several possible return values, each indicating +a distinct state:

+
    +
  • Poll::Pending means that this body’s next chunk is not ready yet. Implementations must +ensure that the current task will be notified when the next chunk may be ready.
  • +
  • Poll::Ready(Some(val)) means that the body has successfully produced a chunk, val, +and may produce further values on subsequent poll_next calls.
  • +
  • Poll::Ready(None) means that the body is complete, and poll_next should not be +invoked again.
  • +
+
§Panics
+

Once a body is complete (i.e., poll_next returned Ready(None)), calling its poll_next +method again may panic, block forever, or cause other kinds of problems; this trait places +no requirements on the effects of such a call. However, as the poll_next method is not +marked unsafe, Rust’s usual rules apply: calls must never cause UB, regardless of its state.

+

Provided Methods§

fn try_into_bytes(self) -> Result<Bytes, Self>
where + Self: Sized,

Try to convert into the complete chunk of body bytes.

+

Override this method if the complete body can be trivially extracted. This is useful for +optimizations where poll_next calls can be avoided.

+

Body types with BodySize::None are allowed to return empty Bytes. Although, if calling +this method, it is recommended to check size first and return early.

+
§Errors
+

The default implementation will error and return the original type back to the caller for +further use.

+

fn boxed(self) -> BoxBody
where + Self: Sized + 'static,

Wraps this body into a BoxBody.

+

No-op when called on a BoxBody, meaning there is no risk of double boxing when calling +this on a generic MessageBody. Prefer this over BoxBody::new when a boxed body +is required.

+

Implementations on Foreign Types§

§

impl MessageBody for &'static str

§

type Error = Infallible

§

fn size(&self) -> BodySize

§

fn poll_next( + self: Pin<&mut &'static str>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <&'static str as MessageBody>::Error>>>

§

fn try_into_bytes(self) -> Result<Bytes, &'static str>

§

impl MessageBody for &'static [u8]

§

type Error = Infallible

§

fn size(&self) -> BodySize

§

fn poll_next( + self: Pin<&mut &'static [u8]>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <&'static [u8] as MessageBody>::Error>>>

§

fn try_into_bytes(self) -> Result<Bytes, &'static [u8]>

§

impl MessageBody for Cow<'static, str>

§

type Error = Infallible

§

fn size(&self) -> BodySize

§

fn poll_next( + self: Pin<&mut Cow<'static, str>>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <Cow<'static, str> as MessageBody>::Error>>>

§

fn try_into_bytes(self) -> Result<Bytes, Cow<'static, str>>

§

impl MessageBody for Cow<'static, [u8]>

§

type Error = Infallible

§

fn size(&self) -> BodySize

§

fn poll_next( + self: Pin<&mut Cow<'static, [u8]>>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <Cow<'static, [u8]> as MessageBody>::Error>>>

§

fn try_into_bytes(self) -> Result<Bytes, Cow<'static, [u8]>>

§

impl MessageBody for Infallible

§

type Error = Infallible

§

fn size(&self) -> BodySize

§

fn poll_next( + self: Pin<&mut Infallible>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <Infallible as MessageBody>::Error>>>

§

impl MessageBody for ()

§

type Error = Infallible

§

fn size(&self) -> BodySize

§

fn poll_next( + self: Pin<&mut ()>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <() as MessageBody>::Error>>>

§

fn try_into_bytes(self) -> Result<Bytes, ()>

§

impl MessageBody for String

§

type Error = Infallible

§

fn size(&self) -> BodySize

§

fn poll_next( + self: Pin<&mut String>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <String as MessageBody>::Error>>>

§

fn try_into_bytes(self) -> Result<Bytes, String>

§

impl MessageBody for Vec<u8>

§

type Error = Infallible

§

fn size(&self) -> BodySize

§

fn poll_next( + self: Pin<&mut Vec<u8>>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <Vec<u8> as MessageBody>::Error>>>

§

fn try_into_bytes(self) -> Result<Bytes, Vec<u8>>

§

impl MessageBody for ByteString

§

type Error = Infallible

§

fn size(&self) -> BodySize

§

fn poll_next( + self: Pin<&mut ByteString>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <ByteString as MessageBody>::Error>>>

§

fn try_into_bytes(self) -> Result<Bytes, ByteString>

§

impl MessageBody for Bytes

§

type Error = Infallible

§

fn size(&self) -> BodySize

§

fn poll_next( + self: Pin<&mut Bytes>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <Bytes as MessageBody>::Error>>>

§

fn try_into_bytes(self) -> Result<Bytes, Bytes>

§

impl MessageBody for BytesMut

§

type Error = Infallible

§

fn size(&self) -> BodySize

§

fn poll_next( + self: Pin<&mut BytesMut>, + _cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <BytesMut as MessageBody>::Error>>>

§

fn try_into_bytes(self) -> Result<Bytes, BytesMut>

§

impl<B> MessageBody for &mut B
where + B: MessageBody + Unpin + ?Sized,

§

type Error = <B as MessageBody>::Error

§

fn size(&self) -> BodySize

§

fn poll_next( + self: Pin<&mut &mut B>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <&mut B as MessageBody>::Error>>>

§

impl<B> MessageBody for Box<B>
where + B: MessageBody + Unpin + ?Sized,

§

type Error = <B as MessageBody>::Error

§

fn size(&self) -> BodySize

§

fn poll_next( + self: Pin<&mut Box<B>>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <Box<B> as MessageBody>::Error>>>

§

impl<T, B> MessageBody for Pin<T>
where + T: DerefMut<Target = B> + Unpin, + B: MessageBody + ?Sized,

§

type Error = <B as MessageBody>::Error

§

fn size(&self) -> BodySize

§

fn poll_next( + self: Pin<&mut Pin<T>>, + cx: &mut Context<'_> +) -> Poll<Option<Result<Bytes, <Pin<T> as MessageBody>::Error>>>

Implementors§

§

impl MessageBody for BoxBody

§

type Error = Box<dyn Error>

§

impl MessageBody for None

§

impl<B> MessageBody for Encoder<B>
where + B: MessageBody,

§

type Error = EncoderError

§

impl<L, R> MessageBody for EitherBody<L, R>
where + L: MessageBody + 'static, + R: MessageBody + 'static,

§

type Error = Error

§

impl<S, E> MessageBody for BodyStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn Error>> + 'static,

§

type Error = E

§

impl<S, E> MessageBody for SizedStream<S>
where + S: Stream<Item = Result<Bytes, E>>, + E: Into<Box<dyn Error>> + 'static,

§

type Error = E

\ No newline at end of file diff --git a/awc/builder/struct.ClientBuilder.html b/awc/builder/struct.ClientBuilder.html new file mode 100644 index 000000000..3b47a6c5b --- /dev/null +++ b/awc/builder/struct.ClientBuilder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../awc/struct.ClientBuilder.html...

+ + + \ No newline at end of file diff --git a/awc/client/connector/struct.Connector.html b/awc/client/connector/struct.Connector.html new file mode 100644 index 000000000..d3cee7081 --- /dev/null +++ b/awc/client/connector/struct.Connector.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../awc/struct.Connector.html...

+ + + \ No newline at end of file diff --git a/awc/client/error/enum.ConnectError.html b/awc/client/error/enum.ConnectError.html new file mode 100644 index 000000000..129c70deb --- /dev/null +++ b/awc/client/error/enum.ConnectError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../awc/error/enum.ConnectError.html...

+ + + \ No newline at end of file diff --git a/awc/client/error/enum.FreezeRequestError.html b/awc/client/error/enum.FreezeRequestError.html new file mode 100644 index 000000000..d4eac25ef --- /dev/null +++ b/awc/client/error/enum.FreezeRequestError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../awc/error/enum.FreezeRequestError.html...

+ + + \ No newline at end of file diff --git a/awc/client/error/enum.InvalidUrl.html b/awc/client/error/enum.InvalidUrl.html new file mode 100644 index 000000000..83d8d753d --- /dev/null +++ b/awc/client/error/enum.InvalidUrl.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../awc/error/enum.InvalidUrl.html...

+ + + \ No newline at end of file diff --git a/awc/client/error/enum.SendRequestError.html b/awc/client/error/enum.SendRequestError.html new file mode 100644 index 000000000..1d4e9be58 --- /dev/null +++ b/awc/client/error/enum.SendRequestError.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../awc/error/enum.SendRequestError.html...

+ + + \ No newline at end of file diff --git a/awc/client/struct.Client.html b/awc/client/struct.Client.html new file mode 100644 index 000000000..be121c956 --- /dev/null +++ b/awc/client/struct.Client.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../awc/struct.Client.html...

+ + + \ No newline at end of file diff --git a/awc/client/struct.Connect.html b/awc/client/struct.Connect.html new file mode 100644 index 000000000..d682f21fc --- /dev/null +++ b/awc/client/struct.Connect.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../awc/struct.Connect.html...

+ + + \ No newline at end of file diff --git a/awc/connect/enum.ConnectRequest.html b/awc/connect/enum.ConnectRequest.html new file mode 100644 index 000000000..4bf91aa9b --- /dev/null +++ b/awc/connect/enum.ConnectRequest.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../awc/enum.ConnectRequest.html...

+ + + \ No newline at end of file diff --git a/awc/connect/enum.ConnectResponse.html b/awc/connect/enum.ConnectResponse.html new file mode 100644 index 000000000..c5fc33604 --- /dev/null +++ b/awc/connect/enum.ConnectResponse.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../awc/enum.ConnectResponse.html...

+ + + \ No newline at end of file diff --git a/awc/connect/type.BoxConnectorService.html b/awc/connect/type.BoxConnectorService.html new file mode 100644 index 000000000..970ad95aa --- /dev/null +++ b/awc/connect/type.BoxConnectorService.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../awc/type.BoxConnectorService.html...

+ + + \ No newline at end of file diff --git a/awc/connect/type.BoxedSocket.html b/awc/connect/type.BoxedSocket.html new file mode 100644 index 000000000..39752199e --- /dev/null +++ b/awc/connect/type.BoxedSocket.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../awc/type.BoxedSocket.html...

+ + + \ No newline at end of file diff --git a/awc/enum.ConnectRequest.html b/awc/enum.ConnectRequest.html new file mode 100644 index 000000000..774376d96 --- /dev/null +++ b/awc/enum.ConnectRequest.html @@ -0,0 +1,26 @@ +ConnectRequest in awc - Rust

Enum awc::ConnectRequest

source ·
pub enum ConnectRequest {
+    Client(RequestHeadType, AnyBody, Option<SocketAddr>),
+    Tunnel(RequestHead, Option<SocketAddr>),
+}
Expand description

Combined HTTP and WebSocket request type received by connection service.

+

Variants§

§

Client(RequestHeadType, AnyBody, Option<SocketAddr>)

Standard HTTP request.

+

Contains the request head, body type, and optional pre-resolved socket address.

+
§

Tunnel(RequestHead, Option<SocketAddr>)

Tunnel used by WebSocket connection requests.

+

Contains the request head and optional pre-resolved socket address.

+

Trait Implementations§

source§

impl<S> Transform<S, ConnectRequest> for Redirect
where + S: Service<ConnectRequest, Response = ConnectResponse, Error = SendRequestError> + 'static,

§

type Transform = RedirectService<S>

source§

fn new_transform(self, service: S) -> Self::Transform

Creates and returns a new Transform component.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/enum.ConnectResponse.html b/awc/enum.ConnectResponse.html new file mode 100644 index 000000000..39000694a --- /dev/null +++ b/awc/enum.ConnectResponse.html @@ -0,0 +1,32 @@ +ConnectResponse in awc - Rust

Enum awc::ConnectResponse

source ·
pub enum ConnectResponse {
+    Client(ClientResponse),
+    Tunnel(ResponseHead, Framed<BoxedSocket, ClientCodec>),
+}
Expand description

Combined HTTP response & WebSocket tunnel type returned from connection service.

+

Variants§

§

Client(ClientResponse)

Standard HTTP response.

+
§

Tunnel(ResponseHead, Framed<BoxedSocket, ClientCodec>)

Tunnel used for WebSocket communication.

+

Contains response head and framed HTTP/1.1 codec.

+

Implementations§

source§

impl ConnectResponse

source

pub fn into_client_response(self) -> ClientResponse

Unwraps type into HTTP response.

+
§Panics
+

Panics if enum variant is not Client.

+
source

pub fn into_tunnel_response( + self +) -> (ResponseHead, Framed<BoxedSocket, ClientCodec>)

Unwraps type into WebSocket tunnel response.

+
§Panics
+

Panics if enum variant is not Tunnel.

+

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/enum.SendClientRequest.html b/awc/enum.SendClientRequest.html new file mode 100644 index 000000000..925c666a1 --- /dev/null +++ b/awc/enum.SendClientRequest.html @@ -0,0 +1,115 @@ +SendClientRequest in awc - Rust

Enum awc::SendClientRequest

source ·
pub enum SendClientRequest {
+    Fut(Pin<Box<dyn Future<Output = Result<ConnectResponse, SendRequestError>>>>, Option<Pin<Box<Sleep>>>, bool),
+    Err(Option<SendRequestError>),
+}
Expand description

Future that sends request’s payload and resolves to a server response.

+

Variants§

Trait Implementations§

source§

impl From<Error> for SendClientRequest

source§

fn from(e: HttpError) -> Self

Converts to this type from the input type.
source§

impl From<SendRequestError> for SendClientRequest

source§

fn from(e: SendRequestError) -> Self

Converts to this type from the input type.
source§

impl Future for SendClientRequest

Available on crate feature __compress only.
§

type Output = Result<ClientResponse<Decoder<Payload>>, SendRequestError>

The type of value produced on completion.
source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> FutureExt for T
where + T: Future + ?Sized,

§

fn map<U, F>(self, f: F) -> Map<Self, F>
where + F: FnOnce(Self::Output) -> U, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn map_into<U>(self) -> MapInto<Self, U>
where + Self::Output: Into<U>, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnOnce(Self::Output) -> Fut, + Fut: Future, + Self: Sized,

Chain on a computation for when a future finished, passing the result of +the future to the provided closure f. Read more
§

fn left_future<B>(self) -> Either<Self, B>
where + B: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the left-hand variant +of that Either. Read more
§

fn right_future<A>(self) -> Either<A, Self>
where + A: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the right-hand variant +of that Either. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Convert this future into a single element stream. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Output: Future, + Self: Sized,

Flatten the execution of this future when the output of this +future is itself another future. Read more
§

fn flatten_stream(self) -> FlattenStream<Self>
where + Self::Output: Stream, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a future such that poll will never again be called once it has +completed. This method can be used to turn any Future into a +FusedFuture. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnOnce(&Self::Output), + Self: Sized,

Do something with the output of a future before passing it on. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the future. Read more
§

fn shared(self) -> Shared<Self>
where + Self: Sized, + Self::Output: Clone,

Available on crate feature std only.
Create a cloneable handle to this future where all handles will resolve +to the same result. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn unit_error(self) -> UnitError<Self>
where + Self: Sized,

§

fn never_error(self) -> NeverError<Self>
where + Self: Sized,

§

fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where + Self: Unpin,

A convenience for calling Future::poll on Unpin future types.
§

fn now_or_never(self) -> Option<Self::Output>
where + Self: Sized,

Evaluates and consumes the future, returning the resulting output if +the future is ready after the first call to Future::poll. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<F> IntoFuture for F
where + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

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
§

fn try_poll( + self: Pin<&mut F>, + cx: &mut Context<'_> +) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
§

impl<Fut> TryFutureExt for Fut
where + Fut: TryFuture + ?Sized,

§

fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>
where + Self::Ok: Sink<Item, Error = Self::Error>, + Self: Sized,

Available on crate feature sink only.
Flattens the execution of this future when the successful result of this +future is a [Sink]. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + F: FnOnce(Self::Ok) -> T, + Self: Sized,

Maps this future’s success value to a different value. Read more
§

fn map_ok_or_else<T, E, F>(self, e: E, f: F) -> MapOkOrElse<Self, F, E>
where + F: FnOnce(Self::Ok) -> T, + E: FnOnce(Self::Error) -> T, + Self: Sized,

Maps this future’s success value to a different value, and permits for error handling resulting in the same type. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + F: FnOnce(Self::Error) -> E, + Self: Sized,

Maps this future’s error value to a different value. Read more
§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Maps this future’s Error to a new error type +using the Into trait. Read more
§

fn ok_into<U>(self) -> OkInto<Self, U>
where + Self: Sized, + Self::Ok: Into<U>,

Maps this future’s Ok to a new type +using the Into trait.
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnOnce(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Executes another future after this one resolves successfully. The +success value is passed to a closure to create this subsequent future. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnOnce(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Executes another future if this one resolves to an error. The +error value is passed to a closure to create this subsequent future. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnOnce(&Self::Ok), + Self: Sized,

Do something with the success value of a future before passing it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnOnce(&Self::Error), + Self: Sized,

Do something with the error value of a future before passing it on. Read more
§

fn try_flatten(self) -> TryFlatten<Self, Self::Ok>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is another future. Read more
§

fn try_flatten_stream(self) -> TryFlattenStream<Self>
where + Self::Ok: TryStream<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F>
where + Self: Sized, + F: FnOnce(Self::Error) -> Self::Ok,

Unwraps this future’s output, producing a future with this future’s +Ok type as its +Output type. Read more
§

fn into_future(self) -> IntoFuture<Self>
where + Self: Sized,

Wraps a [TryFuture] into a type that implements +Future. Read more
§

fn try_poll_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Result<Self::Ok, Self::Error>>
where + Self: Unpin,

A convenience method for calling [TryFuture::try_poll] on Unpin +future types.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/error/enum.ConnectError.html b/awc/error/enum.ConnectError.html new file mode 100644 index 000000000..216bb5ea3 --- /dev/null +++ b/awc/error/enum.ConnectError.html @@ -0,0 +1,38 @@ +ConnectError in awc::error - Rust

Enum awc::error::ConnectError

source ·
#[non_exhaustive]
pub enum ConnectError { + SslIsNotSupported, + SslError(Error), + Resolver(Box<dyn Error>), + NoRecords, + H2(Error), + Timeout, + Disconnected, + Unresolved, + Io(Error), +}
Expand description

A set of errors that can occur while connecting to an HTTP host

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

SslIsNotSupported

SSL feature is not enabled

+
§

SslError(Error)

Available on crate feature openssl only.

SSL error

+
§

Resolver(Box<dyn Error>)

Failed to resolve the hostname

+
§

NoRecords

No dns records

+
§

H2(Error)

Http2 error

+
§

Timeout

Connecting took too long

+
§

Disconnected

Connector has been disconnected

+
§

Unresolved

Unresolved host name

+
§

Io(Error)

Connection io error

+

Trait Implementations§

source§

impl Debug for ConnectError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for ConnectError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for ConnectError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<Box<dyn Error>> for ConnectError

source§

fn from(original: Box<dyn Error>) -> ConnectError

Converts to this type from the input type.
source§

impl From<ConnectError> for ConnectError

source§

fn from(err: ConnectError) -> ConnectError

Converts to this type from the input type.
source§

impl From<ConnectError> for SendRequestError

source§

fn from(original: ConnectError) -> SendRequestError

Converts to this type from the input type.
source§

impl From<Error> for ConnectError

source§

fn from(original: Error) -> ConnectError

Converts to this type from the input type.
source§

impl From<Error> for ConnectError

source§

fn from(original: OpensslError) -> ConnectError

Converts to this type from the input type.
source§

impl From<Error> for ConnectError

source§

fn from(original: Error) -> ConnectError

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/error/enum.FreezeRequestError.html b/awc/error/enum.FreezeRequestError.html new file mode 100644 index 000000000..7c167e556 --- /dev/null +++ b/awc/error/enum.FreezeRequestError.html @@ -0,0 +1,26 @@ +FreezeRequestError in awc::error - Rust

Enum awc::error::FreezeRequestError

source ·
#[non_exhaustive]
pub enum FreezeRequestError { + Url(InvalidUrl), + Http(HttpError), + Custom(Box<dyn Error>, Box<dyn Debug>), +}
Expand description

A set of errors that can occur during freezing a request

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Url(InvalidUrl)

Invalid URL

+
§

Http(HttpError)

HTTP error

+
§

Custom(Box<dyn Error>, Box<dyn Debug>)

Other errors that can occur after submitting a request.

+

Trait Implementations§

source§

impl Debug for FreezeRequestError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for FreezeRequestError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for FreezeRequestError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<(Box<dyn Error>, Box<dyn Debug>)> for FreezeRequestError

source§

fn from(original: (Box<dyn Error>, Box<dyn Debug>)) -> FreezeRequestError

Converts to this type from the input type.
source§

impl From<Error> for FreezeRequestError

source§

fn from(original: HttpError) -> FreezeRequestError

Converts to this type from the input type.
source§

impl From<FreezeRequestError> for SendRequestError

source§

fn from(err: FreezeRequestError) -> Self

Converts to this type from the input type.
source§

impl From<InvalidUrl> for FreezeRequestError

source§

fn from(original: InvalidUrl) -> FreezeRequestError

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/error/enum.InvalidUrl.html b/awc/error/enum.InvalidUrl.html new file mode 100644 index 000000000..68400c222 --- /dev/null +++ b/awc/error/enum.InvalidUrl.html @@ -0,0 +1,23 @@ +InvalidUrl in awc::error - Rust

Enum awc::error::InvalidUrl

source ·
#[non_exhaustive]
pub enum InvalidUrl { + MissingScheme, + UnknownScheme, + MissingHost, + HttpError(Error), +}

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

MissingScheme

§

UnknownScheme

§

MissingHost

§

HttpError(Error)

Trait Implementations§

source§

impl Debug for InvalidUrl

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for InvalidUrl

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for InvalidUrl

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<Error> for InvalidUrl

source§

fn from(original: Error) -> InvalidUrl

Converts to this type from the input type.
source§

impl From<InvalidUrl> for FreezeRequestError

source§

fn from(original: InvalidUrl) -> FreezeRequestError

Converts to this type from the input type.
source§

impl From<InvalidUrl> for SendRequestError

source§

fn from(original: InvalidUrl) -> SendRequestError

Converts to this type from the input type.
source§

impl From<InvalidUrl> for WsClientError

source§

fn from(err: InvalidUrl) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/error/enum.JsonPayloadError.html b/awc/error/enum.JsonPayloadError.html new file mode 100644 index 000000000..fce8715e7 --- /dev/null +++ b/awc/error/enum.JsonPayloadError.html @@ -0,0 +1,26 @@ +JsonPayloadError in awc::error - Rust

Enum awc::error::JsonPayloadError

source ·
pub enum JsonPayloadError {
+    ContentType,
+    Deserialize(Error),
+    Payload(PayloadError),
+}
Expand description

A set of errors that can occur during parsing json payloads

+

Variants§

§

ContentType

Content type error

+
§

Deserialize(Error)

Deserialize error

+
§

Payload(PayloadError)

Payload error

+

Trait Implementations§

source§

impl Debug for JsonPayloadError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for JsonPayloadError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for JsonPayloadError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<()> for JsonPayloadError

source§

fn from(original: ()) -> JsonPayloadError

Converts to this type from the input type.
source§

impl From<Error> for JsonPayloadError

source§

fn from(original: JsonError) -> JsonPayloadError

Converts to this type from the input type.
source§

impl From<PayloadError> for JsonPayloadError

source§

fn from(original: PayloadError) -> JsonPayloadError

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/error/enum.PayloadError.html b/awc/error/enum.PayloadError.html new file mode 100644 index 000000000..cb51a6534 --- /dev/null +++ b/awc/error/enum.PayloadError.html @@ -0,0 +1,35 @@ +PayloadError in awc::error - Rust

Enum awc::error::PayloadError

#[non_exhaustive]
pub enum PayloadError { + Incomplete(Option<Error>), + EncodingCorrupted, + Overflow, + UnknownLength, + Http2Payload(Error), + Io(Error), +}
Expand description

A set of errors that can occur during payload parsing.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Incomplete(Option<Error>)

A payload reached EOF, but is not complete.

+
§

EncodingCorrupted

Content encoding stream corruption.

+
§

Overflow

Payload reached size limit.

+
§

UnknownLength

Payload length is unknown.

+
§

Http2Payload(Error)

Available on crate feature http2 only.

HTTP/2 payload error.

+
§

Io(Error)

Generic I/O error.

+

Trait Implementations§

§

impl Debug for PayloadError

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for PayloadError

§

fn fmt( + &self, + _derive_more_display_formatter: &mut Formatter<'_> +) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for PayloadError

§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<Error> for PayloadError

§

fn from(err: Error) -> PayloadError

Converts to this type from the input type.
§

impl From<Error> for PayloadError

Available on crate feature http2 only.
§

fn from(err: Error) -> PayloadError

Converts to this type from the input type.
§

impl From<Option<Error>> for PayloadError

§

fn from(err: Option<Error>) -> PayloadError

Converts to this type from the input type.
§

impl From<PayloadError> for Error

§

fn from(err: PayloadError) -> Error

Converts to this type from the input type.
source§

impl From<PayloadError> for JsonPayloadError

source§

fn from(original: PayloadError) -> JsonPayloadError

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/error/enum.SendRequestError.html b/awc/error/enum.SendRequestError.html new file mode 100644 index 000000000..30b67a2cd --- /dev/null +++ b/awc/error/enum.SendRequestError.html @@ -0,0 +1,40 @@ +SendRequestError in awc::error - Rust

Enum awc::error::SendRequestError

source ·
#[non_exhaustive]
pub enum SendRequestError { + Url(InvalidUrl), + Connect(ConnectError), + Send(Error), + Response(ParseError), + Http(HttpError), + H2(Error), + Timeout, + TunnelNotSupported, + Body(Box<dyn Error>), + Custom(Box<dyn Error>, Box<dyn Debug>), +}
Expand description

A set of errors that can occur during request sending and response reading

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Url(InvalidUrl)

Invalid URL

+
§

Connect(ConnectError)

Failed to connect to host

+
§

Send(Error)

Error sending request

+
§

Response(ParseError)

Error parsing response

+
§

Http(HttpError)

Http error

+
§

H2(Error)

Http2 error

+
§

Timeout

Response took too long

+
§

TunnelNotSupported

Tunnels are not supported for HTTP/2 connection

+
§

Body(Box<dyn Error>)

Error sending request body

+
§

Custom(Box<dyn Error>, Box<dyn Debug>)

Other errors that can occur after submitting a request.

+

Trait Implementations§

source§

impl Debug for SendRequestError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for SendRequestError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for SendRequestError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<(Box<dyn Error>, Box<dyn Debug>)> for SendRequestError

source§

fn from(original: (Box<dyn Error>, Box<dyn Debug>)) -> SendRequestError

Converts to this type from the input type.
source§

impl From<Box<dyn Error>> for SendRequestError

source§

fn from(original: Box<dyn Error>) -> SendRequestError

Converts to this type from the input type.
source§

impl From<ConnectError> for SendRequestError

source§

fn from(original: ConnectError) -> SendRequestError

Converts to this type from the input type.
source§

impl From<Error> for SendRequestError

source§

fn from(original: HttpError) -> SendRequestError

Converts to this type from the input type.
source§

impl From<Error> for SendRequestError

source§

fn from(original: Error) -> SendRequestError

Converts to this type from the input type.
source§

impl From<Error> for SendRequestError

source§

fn from(original: Error) -> SendRequestError

Converts to this type from the input type.
source§

impl From<FreezeRequestError> for SendRequestError

source§

fn from(err: FreezeRequestError) -> Self

Converts to this type from the input type.
source§

impl From<InvalidUrl> for SendRequestError

source§

fn from(original: InvalidUrl) -> SendRequestError

Converts to this type from the input type.
source§

impl From<ParseError> for SendRequestError

source§

fn from(original: ParseError) -> SendRequestError

Converts to this type from the input type.
source§

impl From<SendRequestError> for SendClientRequest

source§

fn from(e: SendRequestError) -> Self

Converts to this type from the input type.
source§

impl From<SendRequestError> for WsClientError

source§

fn from(original: SendRequestError) -> WsClientError

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/error/enum.WsClientError.html b/awc/error/enum.WsClientError.html new file mode 100644 index 000000000..962acdab9 --- /dev/null +++ b/awc/error/enum.WsClientError.html @@ -0,0 +1,36 @@ +WsClientError in awc::error - Rust

Enum awc::error::WsClientError

source ·
pub enum WsClientError {
+    InvalidResponseStatus(StatusCode),
+    InvalidUpgradeHeader,
+    InvalidConnectionHeader(HeaderValue),
+    MissingConnectionHeader,
+    MissingWebSocketAcceptHeader,
+    InvalidChallengeResponse([u8; 28], HeaderValue),
+    Protocol(WsProtocolError),
+    SendRequest(SendRequestError),
+}
Expand description

Websocket client error

+

Variants§

§

InvalidResponseStatus(StatusCode)

Invalid response status

+
§

InvalidUpgradeHeader

Invalid upgrade header

+
§

InvalidConnectionHeader(HeaderValue)

Invalid connection header

+
§

MissingConnectionHeader

Missing Connection header

+
§

MissingWebSocketAcceptHeader

Missing Sec-Websocket-Accept header

+
§

InvalidChallengeResponse([u8; 28], HeaderValue)

Invalid challenge response

+
§

Protocol(WsProtocolError)

Protocol error

+
§

SendRequest(SendRequestError)

Send request error

+

Trait Implementations§

source§

impl Debug for WsClientError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Display for WsClientError

source§

fn fmt(&self, _derive_more_display_formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl Error for WsClientError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<([u8; 28], HeaderValue)> for WsClientError

source§

fn from(original: ([u8; 28], HeaderValue)) -> WsClientError

Converts to this type from the input type.
source§

impl From<Error> for WsClientError

source§

fn from(err: HttpError) -> Self

Converts to this type from the input type.
source§

impl From<HeaderValue> for WsClientError

source§

fn from(original: HeaderValue) -> WsClientError

Converts to this type from the input type.
source§

impl From<InvalidUrl> for WsClientError

source§

fn from(err: InvalidUrl) -> Self

Converts to this type from the input type.
source§

impl From<ProtocolError> for WsClientError

source§

fn from(original: WsProtocolError) -> WsClientError

Converts to this type from the input type.
source§

impl From<SendRequestError> for WsClientError

source§

fn from(original: SendRequestError) -> WsClientError

Converts to this type from the input type.
source§

impl From<StatusCode> for WsClientError

source§

fn from(original: StatusCode) -> WsClientError

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/error/enum.WsHandshakeError.html b/awc/error/enum.WsHandshakeError.html new file mode 100644 index 000000000..d3f0104ed --- /dev/null +++ b/awc/error/enum.WsHandshakeError.html @@ -0,0 +1,42 @@ +WsHandshakeError in awc::error - Rust

Enum awc::error::WsHandshakeError

pub enum WsHandshakeError {
+    GetMethodRequired,
+    NoWebsocketUpgrade,
+    NoConnectionUpgrade,
+    NoVersionHeader,
+    UnsupportedVersion,
+    BadWebsocketKey,
+}
Expand description

WebSocket handshake errors

+

Variants§

§

GetMethodRequired

Only get method is allowed.

+
§

NoWebsocketUpgrade

Upgrade header if not set to WebSocket.

+
§

NoConnectionUpgrade

Connection header is not set to upgrade.

+
§

NoVersionHeader

WebSocket version header is not set.

+
§

UnsupportedVersion

Unsupported WebSocket version.

+
§

BadWebsocketKey

WebSocket key is not set or wrong.

+

Trait Implementations§

§

impl Clone for HandshakeError

§

fn clone(&self) -> HandshakeError

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for HandshakeError

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for HandshakeError

§

fn fmt( + &self, + _derive_more_display_formatter: &mut Formatter<'_> +) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for HandshakeError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<HandshakeError> for Error

Available on crate feature ws only.
§

fn from(err: HandshakeError) -> Error

Converts to this type from the input type.
§

impl PartialEq for HandshakeError

§

fn eq(&self, other: &HandshakeError) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for HandshakeError

§

impl Eq for HandshakeError

§

impl StructuralPartialEq for HandshakeError

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/error/enum.WsProtocolError.html b/awc/error/enum.WsProtocolError.html new file mode 100644 index 000000000..76938066a --- /dev/null +++ b/awc/error/enum.WsProtocolError.html @@ -0,0 +1,43 @@ +WsProtocolError in awc::error - Rust

Enum awc::error::WsProtocolError

pub enum WsProtocolError {
+    UnmaskedFrame,
+    MaskedFrame,
+    InvalidOpcode(u8),
+    InvalidLength(usize),
+    BadOpCode,
+    Overflow,
+    ContinuationNotStarted,
+    ContinuationStarted,
+    ContinuationFragment(OpCode),
+    Io(Error),
+}
Expand description

WebSocket protocol errors.

+

Variants§

§

UnmaskedFrame

Received an unmasked frame from client.

+
§

MaskedFrame

Received a masked frame from server.

+
§

InvalidOpcode(u8)

Encountered invalid opcode.

+
§

InvalidLength(usize)

Invalid control frame length

+
§

BadOpCode

Bad opcode.

+
§

Overflow

A payload reached size limit.

+
§

ContinuationNotStarted

Continuation has not started.

+
§

ContinuationStarted

Received new continuation but it is already started.

+
§

ContinuationFragment(OpCode)

Unknown continuation fragment.

+
§

Io(Error)

I/O error.

+

Trait Implementations§

§

impl Debug for ProtocolError

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for ProtocolError

§

fn fmt( + &self, + _derive_more_display_formatter: &mut Formatter<'_> +) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for ProtocolError

§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<Error> for ProtocolError

§

fn from(original: Error) -> ProtocolError

Converts to this type from the input type.
§

impl From<OpCode> for ProtocolError

§

fn from(original: OpCode) -> ProtocolError

Converts to this type from the input type.
§

impl From<ProtocolError> for Error

Available on crate feature ws only.
§

fn from(err: ProtocolError) -> Error

Converts to this type from the input type.
source§

impl From<ProtocolError> for WsClientError

source§

fn from(original: WsProtocolError) -> WsClientError

Converts to this type from the input type.
§

impl From<u8> for ProtocolError

§

fn from(original: u8) -> ProtocolError

Converts to this type from the input type.
§

impl From<usize> for ProtocolError

§

fn from(original: usize) -> ProtocolError

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/error/index.html b/awc/error/index.html new file mode 100644 index 000000000..b2b71240b --- /dev/null +++ b/awc/error/index.html @@ -0,0 +1,2 @@ +awc::error - Rust

Module awc::error

source ·
Expand description

HTTP client errors

+

Structs§

  • Represents an HTTP header field value.
  • A generic “error” for HTTP connections
  • An HTTP status code (status-code in RFC 7230 et al.).

Enums§

\ No newline at end of file diff --git a/awc/error/sidebar-items.js b/awc/error/sidebar-items.js new file mode 100644 index 000000000..4ee1447e1 --- /dev/null +++ b/awc/error/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["ConnectError","FreezeRequestError","InvalidUrl","JsonPayloadError","PayloadError","SendRequestError","WsClientError","WsHandshakeError","WsProtocolError"],"struct":["HeaderValue","HttpError","StatusCode"]}; \ No newline at end of file diff --git a/awc/error/struct.HeaderValue.html b/awc/error/struct.HeaderValue.html new file mode 100644 index 000000000..6df1d3d54 --- /dev/null +++ b/awc/error/struct.HeaderValue.html @@ -0,0 +1,208 @@ +HeaderValue in awc::error - Rust

Struct awc::error::HeaderValue

source ·
pub struct HeaderValue { /* private fields */ }
Expand description

Represents an HTTP header field value.

+

In practice, HTTP header field values are usually valid ASCII. However, the +HTTP spec allows for a header value to contain opaque bytes as well. In this +case, the header field value is not able to be represented as a string.

+

To handle this, the HeaderValue is useable as a type and can be compared +with strings and implements Debug. A to_str fn is provided that returns +an Err if the header value contains non visible ascii characters.

+

Implementations§

source§

impl HeaderValue

source

pub const fn from_static(src: &'static str) -> HeaderValue

Convert a static string to a HeaderValue.

+

This function will not perform any copying, however the string is +checked to ensure that no invalid characters are present. Only visible +ASCII characters (32-127) are permitted.

+
§Panics
+

This function panics if the argument contains invalid header value +characters.

+

Until Allow panicking in constants +makes its way into stable, the panic message at compile-time is +going to look cryptic, but should at least point at your header value:

+
error: any use of this value will cause an error
+  --> http/src/header/value.rs:67:17
+   |
+67 |                 ([] as [u8; 0])[0]; // Invalid header value
+   |                 ^^^^^^^^^^^^^^^^^^
+   |                 |
+   |                 index out of bounds: the length is 0 but the index is 0
+   |                 inside `HeaderValue::from_static` at http/src/header/value.rs:67:17
+   |                 inside `INVALID_HEADER` at src/main.rs:73:33
+   |
+  ::: src/main.rs:73:1
+   |
+73 | const INVALID_HEADER: HeaderValue = HeaderValue::from_static("жsome value");
+   | ----------------------------------------------------------------------------
+
§Examples
+
let val = HeaderValue::from_static("hello");
+assert_eq!(val, "hello");
+
source

pub fn from_str(src: &str) -> Result<HeaderValue, InvalidHeaderValue>

Attempt to convert a string to a HeaderValue.

+

If the argument contains invalid header value characters, an error is +returned. Only visible ASCII characters (32-127) are permitted. Use +from_bytes to create a HeaderValue that includes opaque octets +(128-255).

+

This function is intended to be replaced in the future by a TryFrom +implementation once the trait is stabilized in std.

+
§Examples
+
let val = HeaderValue::from_str("hello").unwrap();
+assert_eq!(val, "hello");
+

An invalid value

+ +
let val = HeaderValue::from_str("\n");
+assert!(val.is_err());
+
source

pub fn from_name(name: HeaderName) -> HeaderValue

Converts a HeaderName into a HeaderValue

+

Since every valid HeaderName is a valid HeaderValue this is done infallibly.

+
§Examples
+
let val = HeaderValue::from_name(ACCEPT);
+assert_eq!(val, HeaderValue::from_bytes(b"accept").unwrap());
+
source

pub fn from_bytes(src: &[u8]) -> Result<HeaderValue, InvalidHeaderValue>

Attempt to convert a byte slice to a HeaderValue.

+

If the argument contains invalid header value bytes, an error is +returned. Only byte values between 32 and 255 (inclusive) are permitted, +excluding byte 127 (DEL).

+

This function is intended to be replaced in the future by a TryFrom +implementation once the trait is stabilized in std.

+
§Examples
+
let val = HeaderValue::from_bytes(b"hello\xfa").unwrap();
+assert_eq!(val, &b"hello\xfa"[..]);
+

An invalid value

+ +
let val = HeaderValue::from_bytes(b"\n");
+assert!(val.is_err());
+
source

pub fn from_maybe_shared<T>(src: T) -> Result<HeaderValue, InvalidHeaderValue>
where + T: AsRef<[u8]> + 'static,

Attempt to convert a Bytes buffer to a HeaderValue.

+

This will try to prevent a copy if the type passed is the type used +internally, and will copy the data if it is not.

+
source

pub unsafe fn from_maybe_shared_unchecked<T>(src: T) -> HeaderValue
where + T: AsRef<[u8]> + 'static,

Convert a Bytes directly into a HeaderValue without validating.

+

This function does NOT validate that illegal bytes are not contained +within the buffer.

+
source

pub fn to_str(&self) -> Result<&str, ToStrError>

Yields a &str slice if the HeaderValue only contains visible ASCII +chars.

+

This function will perform a scan of the header value, checking all the +characters.

+
§Examples
+
let val = HeaderValue::from_static("hello");
+assert_eq!(val.to_str().unwrap(), "hello");
+
source

pub fn len(&self) -> usize

Returns the length of self.

+

This length is in bytes.

+
§Examples
+
let val = HeaderValue::from_static("hello");
+assert_eq!(val.len(), 5);
+
source

pub fn is_empty(&self) -> bool

Returns true if the HeaderValue has a length of zero bytes.

+
§Examples
+
let val = HeaderValue::from_static("");
+assert!(val.is_empty());
+
+let val = HeaderValue::from_static("hello");
+assert!(!val.is_empty());
+
source

pub fn as_bytes(&self) -> &[u8]

Converts a HeaderValue to a byte slice.

+
§Examples
+
let val = HeaderValue::from_static("hello");
+assert_eq!(val.as_bytes(), b"hello");
+
source

pub fn set_sensitive(&mut self, val: bool)

Mark that the header value represents sensitive information.

+
§Examples
+
let mut val = HeaderValue::from_static("my secret");
+
+val.set_sensitive(true);
+assert!(val.is_sensitive());
+
+val.set_sensitive(false);
+assert!(!val.is_sensitive());
+
source

pub fn is_sensitive(&self) -> bool

Returns true if the value represents sensitive data.

+

Sensitive data could represent passwords or other data that should not +be stored on disk or in memory. By marking header values as sensitive, +components using this crate can be instructed to treat them with special +care for security reasons. For example, caches can avoid storing +sensitive values, and HPACK encoders used by HTTP/2.0 implementations +can choose not to compress them.

+

Additionally, sensitive values will be masked by the Debug +implementation of HeaderValue.

+

Note that sensitivity is not factored into equality or ordering.

+
§Examples
+
let mut val = HeaderValue::from_static("my secret");
+
+val.set_sensitive(true);
+assert!(val.is_sensitive());
+
+val.set_sensitive(false);
+assert!(!val.is_sensitive());
+

Trait Implementations§

source§

impl AsRef<[u8]> for HeaderValue

source§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for HeaderValue

source§

fn clone(&self) -> HeaderValue

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for HeaderValue

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a HeaderValue> for HeaderValue

source§

fn from(t: &'a HeaderValue) -> HeaderValue

Converts to this type from the input type.
source§

impl From<HeaderName> for HeaderValue

source§

fn from(h: HeaderName) -> HeaderValue

Converts to this type from the input type.
source§

impl From<HeaderValue> for WsClientError

source§

fn from(original: HeaderValue) -> WsClientError

Converts to this type from the input type.
source§

impl From<i16> for HeaderValue

source§

fn from(num: i16) -> HeaderValue

Converts to this type from the input type.
source§

impl From<i32> for HeaderValue

source§

fn from(num: i32) -> HeaderValue

Converts to this type from the input type.
source§

impl From<i64> for HeaderValue

source§

fn from(num: i64) -> HeaderValue

Converts to this type from the input type.
source§

impl From<isize> for HeaderValue

source§

fn from(num: isize) -> HeaderValue

Converts to this type from the input type.
source§

impl From<u16> for HeaderValue

source§

fn from(num: u16) -> HeaderValue

Converts to this type from the input type.
source§

impl From<u32> for HeaderValue

source§

fn from(num: u32) -> HeaderValue

Converts to this type from the input type.
source§

impl From<u64> for HeaderValue

source§

fn from(num: u64) -> HeaderValue

Converts to this type from the input type.
source§

impl From<usize> for HeaderValue

source§

fn from(num: usize) -> HeaderValue

Converts to this type from the input type.
source§

impl FromStr for HeaderValue

§

type Err = InvalidHeaderValue

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<HeaderValue, <HeaderValue as FromStr>::Err>

Parses a string s to return a value of this type. Read more
source§

impl Hash for HeaderValue

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for HeaderValue

source§

fn cmp(&self, other: &HeaderValue) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl<'a, T> PartialEq<&'a T> for HeaderValue
where + HeaderValue: PartialEq<T>, + T: ?Sized,

source§

fn eq(&self, other: &&'a T) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<[u8]> for HeaderValue

source§

fn eq(&self, other: &[u8]) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<HeaderValue> for &'a HeaderValue

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<HeaderValue> for &'a str

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<HeaderValue> for [u8]

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<HeaderValue> for str

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<String> for HeaderValue

source§

fn eq(&self, other: &String) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for HeaderValue

source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for HeaderValue

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a, T> PartialOrd<&'a T> for HeaderValue
where + HeaderValue: PartialOrd<T>, + T: ?Sized,

source§

fn partial_cmp(&self, other: &&'a T) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<[u8]> for HeaderValue

source§

fn partial_cmp(&self, other: &[u8]) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> PartialOrd<HeaderValue> for &'a HeaderValue

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> PartialOrd<HeaderValue> for &'a str

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<HeaderValue> for [u8]

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<HeaderValue> for str

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<String> for HeaderValue

source§

fn partial_cmp(&self, other: &String) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<str> for HeaderValue

source§

fn partial_cmp(&self, other: &str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for HeaderValue

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> TryFrom<&'a [u8]> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + t: &'a [u8] +) -> Result<HeaderValue, <HeaderValue as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a String> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a String +) -> Result<HeaderValue, <HeaderValue as TryFrom<&'a String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + t: &'a str +) -> Result<HeaderValue, <HeaderValue as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + t: String +) -> Result<HeaderValue, <HeaderValue as TryFrom<String>>::Error>

Performs the conversion.
source§

impl TryFrom<Vec<u8>> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + vec: Vec<u8> +) -> Result<HeaderValue, <HeaderValue as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
§

impl TryIntoHeaderValue for &HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
§

fn try_into_value( + self +) -> Result<HeaderValue, <&HeaderValue as TryIntoHeaderValue>::Error>

Try to convert value to a HeaderValue.
§

impl TryIntoHeaderValue for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
§

fn try_into_value( + self +) -> Result<HeaderValue, <HeaderValue as TryIntoHeaderValue>::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for HeaderValue

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/error/struct.HttpError.html b/awc/error/struct.HttpError.html new file mode 100644 index 000000000..184f59578 --- /dev/null +++ b/awc/error/struct.HttpError.html @@ -0,0 +1,26 @@ +HttpError in awc::error - Rust

Struct awc::error::HttpError

source ·
pub struct HttpError { /* private fields */ }
Expand description

A generic “error” for HTTP connections

+

This error type is less specific than the error returned from other +functions in this crate, but all other errors can be converted to this +error. Consumers of this crate can typically consume and work with this form +of error for conversions with the ? operator.

+

Implementations§

source§

impl Error

source

pub fn is<T>(&self) -> bool
where + T: Error + 'static,

Return true if the underlying error has the same type as T.

+
source

pub fn get_ref(&self) -> &(dyn Error + 'static)

Return a reference to the lower level, inner error.

+

Trait Implementations§

source§

impl Debug for Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for Error

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for Error

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<Error> for Error

§

fn from(err: Error) -> Error

Converts to this type from the input type.
source§

impl From<Error> for FreezeRequestError

source§

fn from(original: HttpError) -> FreezeRequestError

Converts to this type from the input type.
source§

impl From<Error> for InvalidUrl

source§

fn from(original: Error) -> InvalidUrl

Converts to this type from the input type.
source§

impl From<Error> for SendClientRequest

source§

fn from(e: HttpError) -> Self

Converts to this type from the input type.
source§

impl From<Error> for SendRequestError

source§

fn from(original: HttpError) -> SendRequestError

Converts to this type from the input type.
source§

impl From<Error> for WsClientError

source§

fn from(err: HttpError) -> Self

Converts to this type from the input type.
source§

impl From<Infallible> for Error

source§

fn from(err: Infallible) -> Error

Converts to this type from the input type.
source§

impl From<InvalidHeaderName> for Error

source§

fn from(err: InvalidHeaderName) -> Error

Converts to this type from the input type.
§

impl From<InvalidHeaderPart> for Error

§

fn from(part_err: InvalidHeaderPart) -> Error

Converts to this type from the input type.
source§

impl From<InvalidHeaderValue> for Error

source§

fn from(err: InvalidHeaderValue) -> Error

Converts to this type from the input type.
source§

impl From<InvalidMethod> for Error

source§

fn from(err: InvalidMethod) -> Error

Converts to this type from the input type.
source§

impl From<InvalidStatusCode> for Error

source§

fn from(err: InvalidStatusCode) -> Error

Converts to this type from the input type.
source§

impl From<InvalidUri> for Error

source§

fn from(err: InvalidUri) -> Error

Converts to this type from the input type.
source§

impl From<InvalidUriParts> for Error

source§

fn from(err: InvalidUriParts) -> Error

Converts to this type from the input type.
source§

impl From<MaxSizeReached> for Error

source§

fn from(err: MaxSizeReached) -> Error

Converts to this type from the input type.

Auto Trait Implementations§

§

impl Freeze for Error

§

impl RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl UnwindSafe for Error

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/error/struct.StatusCode.html b/awc/error/struct.StatusCode.html new file mode 100644 index 000000000..e04453b05 --- /dev/null +++ b/awc/error/struct.StatusCode.html @@ -0,0 +1,221 @@ +StatusCode in awc::error - Rust

Struct awc::error::StatusCode

source ·
pub struct StatusCode(/* private fields */);
Expand description

An HTTP status code (status-code in RFC 7230 et al.).

+

Constants are provided for known status codes, including those in the IANA +HTTP Status Code Registry.

+

Status code values in the range 100-999 (inclusive) are supported by this +type. Values in the range 100-599 are semantically classified by the most +significant digit. See StatusCode::is_success, etc. Values above 599 +are unclassified but allowed for legacy compatibility, though their use is +discouraged. Applications may interpret such values as protocol errors.

+

§Examples

+
use http::StatusCode;
+
+assert_eq!(StatusCode::from_u16(200).unwrap(), StatusCode::OK);
+assert_eq!(StatusCode::NOT_FOUND.as_u16(), 404);
+assert!(StatusCode::OK.is_success());
+

Implementations§

source§

impl StatusCode

source

pub fn from_u16(src: u16) -> Result<StatusCode, InvalidStatusCode>

Converts a u16 to a status code.

+

The function validates the correctness of the supplied u16. It must be +greater or equal to 100 and less than 1000.

+
§Example
+
use http::StatusCode;
+
+let ok = StatusCode::from_u16(200).unwrap();
+assert_eq!(ok, StatusCode::OK);
+
+let err = StatusCode::from_u16(99);
+assert!(err.is_err());
+
source

pub fn from_bytes(src: &[u8]) -> Result<StatusCode, InvalidStatusCode>

Converts a &u8 to a status code

+
source

pub fn as_u16(&self) -> u16

Returns the u16 corresponding to this StatusCode.

+
§Note
+

This is the same as the From<StatusCode> implementation, but +included as an inherent method because that implementation doesn’t +appear in rustdocs, as well as a way to force the type instead of +relying on inference.

+
§Example
+
let status = http::StatusCode::OK;
+assert_eq!(status.as_u16(), 200);
+
source

pub fn as_str(&self) -> &str

Returns a &str representation of the StatusCode

+

The return value only includes a numerical representation of the +status code. The canonical reason is not included.

+
§Example
+
let status = http::StatusCode::OK;
+assert_eq!(status.as_str(), "200");
+
source

pub fn canonical_reason(&self) -> Option<&'static str>

Get the standardised reason-phrase for this status code.

+

This is mostly here for servers writing responses, but could potentially have application +at other times.

+

The reason phrase is defined as being exclusively for human readers. You should avoid +deriving any meaning from it at all costs.

+

Bear in mind also that in HTTP/2.0 and HTTP/3.0 the reason phrase is abolished from +transmission, and so this canonical reason phrase really is the only reason phrase you’ll +find.

+
§Example
+
let status = http::StatusCode::OK;
+assert_eq!(status.canonical_reason(), Some("OK"));
+
source

pub fn is_informational(&self) -> bool

Check if status is within 100-199.

+
source

pub fn is_success(&self) -> bool

Check if status is within 200-299.

+
source

pub fn is_redirection(&self) -> bool

Check if status is within 300-399.

+
source

pub fn is_client_error(&self) -> bool

Check if status is within 400-499.

+
source

pub fn is_server_error(&self) -> bool

Check if status is within 500-599.

+
source§

impl StatusCode

source

pub const CONTINUE: StatusCode = _

100 Continue +[RFC7231, Section 6.2.1]

+
source

pub const SWITCHING_PROTOCOLS: StatusCode = _

101 Switching Protocols +[RFC7231, Section 6.2.2]

+
source

pub const PROCESSING: StatusCode = _

102 Processing +[RFC2518]

+
source

pub const OK: StatusCode = _

source

pub const CREATED: StatusCode = _

201 Created +[RFC7231, Section 6.3.2]

+
source

pub const ACCEPTED: StatusCode = _

202 Accepted +[RFC7231, Section 6.3.3]

+
source

pub const NON_AUTHORITATIVE_INFORMATION: StatusCode = _

203 Non-Authoritative Information +[RFC7231, Section 6.3.4]

+
source

pub const NO_CONTENT: StatusCode = _

204 No Content +[RFC7231, Section 6.3.5]

+
source

pub const RESET_CONTENT: StatusCode = _

205 Reset Content +[RFC7231, Section 6.3.6]

+
source

pub const PARTIAL_CONTENT: StatusCode = _

206 Partial Content +[RFC7233, Section 4.1]

+
source

pub const MULTI_STATUS: StatusCode = _

207 Multi-Status +[RFC4918]

+
source

pub const ALREADY_REPORTED: StatusCode = _

208 Already Reported +[RFC5842]

+
source

pub const IM_USED: StatusCode = _

226 IM Used +[RFC3229]

+
source

pub const MULTIPLE_CHOICES: StatusCode = _

300 Multiple Choices +[RFC7231, Section 6.4.1]

+
source

pub const MOVED_PERMANENTLY: StatusCode = _

301 Moved Permanently +[RFC7231, Section 6.4.2]

+
source

pub const FOUND: StatusCode = _

302 Found +[RFC7231, Section 6.4.3]

+
source

pub const SEE_OTHER: StatusCode = _

303 See Other +[RFC7231, Section 6.4.4]

+
source

pub const NOT_MODIFIED: StatusCode = _

304 Not Modified +[RFC7232, Section 4.1]

+
source

pub const USE_PROXY: StatusCode = _

305 Use Proxy +[RFC7231, Section 6.4.5]

+
source

pub const TEMPORARY_REDIRECT: StatusCode = _

307 Temporary Redirect +[RFC7231, Section 6.4.7]

+
source

pub const PERMANENT_REDIRECT: StatusCode = _

308 Permanent Redirect +[RFC7238]

+
source

pub const BAD_REQUEST: StatusCode = _

400 Bad Request +[RFC7231, Section 6.5.1]

+
source

pub const UNAUTHORIZED: StatusCode = _

401 Unauthorized +[RFC7235, Section 3.1]

+
source

pub const PAYMENT_REQUIRED: StatusCode = _

402 Payment Required +[RFC7231, Section 6.5.2]

+
source

pub const FORBIDDEN: StatusCode = _

403 Forbidden +[RFC7231, Section 6.5.3]

+
source

pub const NOT_FOUND: StatusCode = _

404 Not Found +[RFC7231, Section 6.5.4]

+
source

pub const METHOD_NOT_ALLOWED: StatusCode = _

405 Method Not Allowed +[RFC7231, Section 6.5.5]

+
source

pub const NOT_ACCEPTABLE: StatusCode = _

406 Not Acceptable +[RFC7231, Section 6.5.6]

+
source

pub const PROXY_AUTHENTICATION_REQUIRED: StatusCode = _

407 Proxy Authentication Required +[RFC7235, Section 3.2]

+
source

pub const REQUEST_TIMEOUT: StatusCode = _

408 Request Timeout +[RFC7231, Section 6.5.7]

+
source

pub const CONFLICT: StatusCode = _

409 Conflict +[RFC7231, Section 6.5.8]

+
source

pub const GONE: StatusCode = _

source

pub const LENGTH_REQUIRED: StatusCode = _

411 Length Required +[RFC7231, Section 6.5.10]

+
source

pub const PRECONDITION_FAILED: StatusCode = _

412 Precondition Failed +[RFC7232, Section 4.2]

+
source

pub const PAYLOAD_TOO_LARGE: StatusCode = _

413 Payload Too Large +[RFC7231, Section 6.5.11]

+
source

pub const URI_TOO_LONG: StatusCode = _

414 URI Too Long +[RFC7231, Section 6.5.12]

+
source

pub const UNSUPPORTED_MEDIA_TYPE: StatusCode = _

415 Unsupported Media Type +[RFC7231, Section 6.5.13]

+
source

pub const RANGE_NOT_SATISFIABLE: StatusCode = _

416 Range Not Satisfiable +[RFC7233, Section 4.4]

+
source

pub const EXPECTATION_FAILED: StatusCode = _

417 Expectation Failed +[RFC7231, Section 6.5.14]

+
source

pub const IM_A_TEAPOT: StatusCode = _

418 I’m a teapot +[curiously not registered by IANA but RFC2324]

+
source

pub const MISDIRECTED_REQUEST: StatusCode = _

421 Misdirected Request +RFC7540, Section 9.1.2

+
source

pub const UNPROCESSABLE_ENTITY: StatusCode = _

422 Unprocessable Entity +[RFC4918]

+
source

pub const LOCKED: StatusCode = _

423 Locked +[RFC4918]

+
source

pub const FAILED_DEPENDENCY: StatusCode = _

424 Failed Dependency +[RFC4918]

+
source

pub const UPGRADE_REQUIRED: StatusCode = _

426 Upgrade Required +[RFC7231, Section 6.5.15]

+
source

pub const PRECONDITION_REQUIRED: StatusCode = _

428 Precondition Required +[RFC6585]

+
source

pub const TOO_MANY_REQUESTS: StatusCode = _

429 Too Many Requests +[RFC6585]

+
source

pub const REQUEST_HEADER_FIELDS_TOO_LARGE: StatusCode = _

431 Request Header Fields Too Large +[RFC6585]

+

451 Unavailable For Legal Reasons +[RFC7725]

+
source

pub const INTERNAL_SERVER_ERROR: StatusCode = _

500 Internal Server Error +[RFC7231, Section 6.6.1]

+
source

pub const NOT_IMPLEMENTED: StatusCode = _

501 Not Implemented +[RFC7231, Section 6.6.2]

+
source

pub const BAD_GATEWAY: StatusCode = _

502 Bad Gateway +[RFC7231, Section 6.6.3]

+
source

pub const SERVICE_UNAVAILABLE: StatusCode = _

503 Service Unavailable +[RFC7231, Section 6.6.4]

+
source

pub const GATEWAY_TIMEOUT: StatusCode = _

504 Gateway Timeout +[RFC7231, Section 6.6.5]

+
source

pub const HTTP_VERSION_NOT_SUPPORTED: StatusCode = _

505 HTTP Version Not Supported +[RFC7231, Section 6.6.6]

+
source

pub const VARIANT_ALSO_NEGOTIATES: StatusCode = _

506 Variant Also Negotiates +[RFC2295]

+
source

pub const INSUFFICIENT_STORAGE: StatusCode = _

507 Insufficient Storage +[RFC4918]

+
source

pub const LOOP_DETECTED: StatusCode = _

508 Loop Detected +[RFC5842]

+
source

pub const NOT_EXTENDED: StatusCode = _

510 Not Extended +[RFC2774]

+
source

pub const NETWORK_AUTHENTICATION_REQUIRED: StatusCode = _

511 Network Authentication Required +[RFC6585]

+

Trait Implementations§

source§

impl Clone for StatusCode

source§

fn clone(&self) -> StatusCode

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for StatusCode

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for StatusCode

source§

fn default() -> StatusCode

Returns the “default value” for a type. Read more
source§

impl Display for StatusCode

Formats the status code, including the canonical reason.

+

§Example

+
assert_eq!(format!("{}", StatusCode::OK), "200 OK");
+
source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a StatusCode> for StatusCode

source§

fn from(t: &'a StatusCode) -> StatusCode

Converts to this type from the input type.
source§

impl From<StatusCode> for WsClientError

source§

fn from(original: StatusCode) -> WsClientError

Converts to this type from the input type.
source§

impl FromStr for StatusCode

§

type Err = InvalidStatusCode

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<StatusCode, InvalidStatusCode>

Parses a string s to return a value of this type. Read more
source§

impl Hash for StatusCode

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for StatusCode

source§

fn cmp(&self, other: &StatusCode) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq<u16> for StatusCode

source§

fn eq(&self, other: &u16) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for StatusCode

source§

fn eq(&self, other: &StatusCode) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for StatusCode

source§

fn partial_cmp(&self, other: &StatusCode) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> TryFrom<&'a [u8]> for StatusCode

§

type Error = InvalidStatusCode

The type returned in the event of a conversion error.
source§

fn try_from( + t: &'a [u8] +) -> Result<StatusCode, <StatusCode as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for StatusCode

§

type Error = InvalidStatusCode

The type returned in the event of a conversion error.
source§

fn try_from( + t: &'a str +) -> Result<StatusCode, <StatusCode as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<u16> for StatusCode

§

type Error = InvalidStatusCode

The type returned in the event of a conversion error.
source§

fn try_from(t: u16) -> Result<StatusCode, <StatusCode as TryFrom<u16>>::Error>

Performs the conversion.
source§

impl Copy for StatusCode

source§

impl Eq for StatusCode

source§

impl StructuralPartialEq for StatusCode

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/frozen/struct.FrozenClientRequest.html b/awc/frozen/struct.FrozenClientRequest.html new file mode 100644 index 000000000..b448a6741 --- /dev/null +++ b/awc/frozen/struct.FrozenClientRequest.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../awc/struct.FrozenClientRequest.html...

+ + + \ No newline at end of file diff --git a/awc/frozen/struct.FrozenSendBuilder.html b/awc/frozen/struct.FrozenSendBuilder.html new file mode 100644 index 000000000..9550ab022 --- /dev/null +++ b/awc/frozen/struct.FrozenSendBuilder.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../awc/struct.FrozenSendBuilder.html...

+ + + \ No newline at end of file diff --git a/awc/http/enum.ConnectionType.html b/awc/http/enum.ConnectionType.html new file mode 100644 index 000000000..23e32283b --- /dev/null +++ b/awc/http/enum.ConnectionType.html @@ -0,0 +1,32 @@ +ConnectionType in awc::http - Rust

Enum awc::http::ConnectionType

pub enum ConnectionType {
+    Close,
+    KeepAlive,
+    Upgrade,
+}
Expand description

Represents various types of connection

+

Variants§

§

Close

Close connection after response.

+
§

KeepAlive

Keep connection alive after response.

+
§

Upgrade

Connection is upgraded to different type.

+

Trait Implementations§

§

impl Clone for ConnectionType

§

fn clone(&self) -> ConnectionType

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for ConnectionType

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl PartialEq for ConnectionType

§

fn eq(&self, other: &ConnectionType) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for ConnectionType

§

impl Eq for ConnectionType

§

impl StructuralPartialEq for ConnectionType

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/constant.ACCEPT.html b/awc/http/header/constant.ACCEPT.html new file mode 100644 index 000000000..bf7491401 --- /dev/null +++ b/awc/http/header/constant.ACCEPT.html @@ -0,0 +1,10 @@ +ACCEPT in awc::http::header - Rust

Constant awc::http::header::ACCEPT

source ·
pub const ACCEPT: HeaderName;
Expand description

Advertises which content types the client is able to understand.

+

The Accept request HTTP header advertises which content types, expressed +as MIME types, the client is able to understand. Using content +negotiation, the server then selects one of the proposals, uses it and +informs the client of its choice with the Content-Type response header. +Browsers set adequate values for this header depending of the context +where the request is done: when fetching a CSS stylesheet a different +value is set for the request than when fetching an image, video or a +script.

+
\ No newline at end of file diff --git a/awc/http/header/constant.ACCEPT_CHARSET.html b/awc/http/header/constant.ACCEPT_CHARSET.html new file mode 100644 index 000000000..fde390d21 --- /dev/null +++ b/awc/http/header/constant.ACCEPT_CHARSET.html @@ -0,0 +1,12 @@ +ACCEPT_CHARSET in awc::http::header - Rust

Constant awc::http::header::ACCEPT_CHARSET

source ·
pub const ACCEPT_CHARSET: HeaderName;
Expand description

Advertises which character set the client is able to understand.

+

The Accept-Charset request HTTP header advertises which character set +the client is able to understand. Using content negotiation, the server +then selects one of the proposals, uses it and informs the client of its +choice within the Content-Type response header. Browsers usually don’t +set this header as the default value for each content type is usually +correct and transmitting it would allow easier fingerprinting.

+

If the server cannot serve any matching character set, it can +theoretically send back a 406 (Not Acceptable) error code. But, for a +better user experience, this is rarely done and the more common way is +to ignore the Accept-Charset header in this case.

+
\ No newline at end of file diff --git a/awc/http/header/constant.ACCEPT_ENCODING.html b/awc/http/header/constant.ACCEPT_ENCODING.html new file mode 100644 index 000000000..da0266a3f --- /dev/null +++ b/awc/http/header/constant.ACCEPT_ENCODING.html @@ -0,0 +1,28 @@ +ACCEPT_ENCODING in awc::http::header - Rust

Constant awc::http::header::ACCEPT_ENCODING

source ·
pub const ACCEPT_ENCODING: HeaderName;
Expand description

Advertises which content encoding the client is able to understand.

+

The Accept-Encoding request HTTP header advertises which content +encoding, usually a compression algorithm, the client is able to +understand. Using content negotiation, the server selects one of the +proposals, uses it and informs the client of its choice with the +Content-Encoding response header.

+

Even if both the client and the server supports the same compression +algorithms, the server may choose not to compress the body of a +response, if the identity value is also acceptable. Two common cases +lead to this:

+
    +
  • +

    The data to be sent is already compressed and a second compression +won’t lead to smaller data to be transmitted. This may the case with +some image formats;

    +
  • +
  • +

    The server is overloaded and cannot afford the computational overhead +induced by the compression requirement. Typically, Microsoft recommends +not to compress if a server use more than 80 % of its computational +power.

    +
  • +
+

As long as the identity value, meaning no encryption, is not explicitly +forbidden, by an identity;q=0 or a *;q=0 without another explicitly set +value for identity, the server must never send back a 406 Not Acceptable +error.

+
\ No newline at end of file diff --git a/awc/http/header/constant.ACCEPT_LANGUAGE.html b/awc/http/header/constant.ACCEPT_LANGUAGE.html new file mode 100644 index 000000000..fd42b1a68 --- /dev/null +++ b/awc/http/header/constant.ACCEPT_LANGUAGE.html @@ -0,0 +1,21 @@ +ACCEPT_LANGUAGE in awc::http::header - Rust

Constant awc::http::header::ACCEPT_LANGUAGE

source ·
pub const ACCEPT_LANGUAGE: HeaderName;
Expand description

Advertises which languages the client is able to understand.

+

The Accept-Language request HTTP header advertises which languages the +client is able to understand, and which locale variant is preferred. +Using content negotiation, the server then selects one of the proposals, +uses it and informs the client of its choice with the Content-Language +response header. Browsers set adequate values for this header according +their user interface language and even if a user can change it, this +happens rarely (and is frown upon as it leads to fingerprinting).

+

This header is a hint to be used when the server has no way of +determining the language via another way, like a specific URL, that is +controlled by an explicit user decision. It is recommended that the +server never overrides an explicit decision. The content of the +Accept-Language is often out of the control of the user (like when +traveling and using an Internet Cafe in a different country); the user +may also want to visit a page in another language than the locale of +their user interface.

+

If the server cannot serve any matching language, it can theoretically +send back a 406 (Not Acceptable) error code. But, for a better user +experience, this is rarely done and more common way is to ignore the +Accept-Language header in this case.

+
\ No newline at end of file diff --git a/awc/http/header/constant.ACCEPT_RANGES.html b/awc/http/header/constant.ACCEPT_RANGES.html new file mode 100644 index 000000000..b10a5e06c --- /dev/null +++ b/awc/http/header/constant.ACCEPT_RANGES.html @@ -0,0 +1,7 @@ +ACCEPT_RANGES in awc::http::header - Rust

Constant awc::http::header::ACCEPT_RANGES

source ·
pub const ACCEPT_RANGES: HeaderName;
Expand description

Marker used by the server to advertise partial request support.

+

The Accept-Ranges response HTTP header is a marker used by the server to +advertise its support of partial requests. The value of this field +indicates the unit that can be used to define a range.

+

In presence of an Accept-Ranges header, the browser may try to resume an +interrupted download, rather than to start it from the start again.

+
\ No newline at end of file diff --git a/awc/http/header/constant.ACCESS_CONTROL_ALLOW_CREDENTIALS.html b/awc/http/header/constant.ACCESS_CONTROL_ALLOW_CREDENTIALS.html new file mode 100644 index 000000000..49c7dfcac --- /dev/null +++ b/awc/http/header/constant.ACCESS_CONTROL_ALLOW_CREDENTIALS.html @@ -0,0 +1,20 @@ +ACCESS_CONTROL_ALLOW_CREDENTIALS in awc::http::header - Rust

Constant awc::http::header::ACCESS_CONTROL_ALLOW_CREDENTIALS

source ·
pub const ACCESS_CONTROL_ALLOW_CREDENTIALS: HeaderName;
Expand description

Preflight response indicating if the response to the request can be +exposed to the page.

+

The Access-Control-Allow-Credentials response header indicates whether +or not the response to the request can be exposed to the page. It can be +exposed when the true value is returned; it can’t in other cases.

+

Credentials are cookies, authorization headers or TLS client +certificates.

+

When used as part of a response to a preflight request, this indicates +whether or not the actual request can be made using credentials. Note +that simple GET requests are not preflighted, and so if a request is +made for a resource with credentials, if this header is not returned +with the resource, the response is ignored by the browser and not +returned to web content.

+

The Access-Control-Allow-Credentials header works in conjunction with +the XMLHttpRequest.withCredentials property or with the credentials +option in the Request() constructor of the Fetch API. Credentials must +be set on both sides (the Access-Control-Allow-Credentials header and in +the XHR or Fetch request) in order for the CORS request with credentials +to succeed.

+
\ No newline at end of file diff --git a/awc/http/header/constant.ACCESS_CONTROL_ALLOW_HEADERS.html b/awc/http/header/constant.ACCESS_CONTROL_ALLOW_HEADERS.html new file mode 100644 index 000000000..c21b18f45 --- /dev/null +++ b/awc/http/header/constant.ACCESS_CONTROL_ALLOW_HEADERS.html @@ -0,0 +1,12 @@ +ACCESS_CONTROL_ALLOW_HEADERS in awc::http::header - Rust

Constant awc::http::header::ACCESS_CONTROL_ALLOW_HEADERS

source ·
pub const ACCESS_CONTROL_ALLOW_HEADERS: HeaderName;
Expand description

Preflight response indicating permitted HTTP headers.

+

The Access-Control-Allow-Headers response header is used in response to +a preflight request to indicate which HTTP headers will be available via +Access-Control-Expose-Headers when making the actual request.

+

The simple headers, Accept, Accept-Language, Content-Language, +Content-Type (but only with a MIME type of its parsed value (ignoring +parameters) of either application/x-www-form-urlencoded, +multipart/form-data, or text/plain), are always available and don’t need +to be listed by this header.

+

This header is required if the request has an +Access-Control-Request-Headers header.

+
\ No newline at end of file diff --git a/awc/http/header/constant.ACCESS_CONTROL_ALLOW_METHODS.html b/awc/http/header/constant.ACCESS_CONTROL_ALLOW_METHODS.html new file mode 100644 index 000000000..d26dcdeab --- /dev/null +++ b/awc/http/header/constant.ACCESS_CONTROL_ALLOW_METHODS.html @@ -0,0 +1,5 @@ +ACCESS_CONTROL_ALLOW_METHODS in awc::http::header - Rust

Constant awc::http::header::ACCESS_CONTROL_ALLOW_METHODS

source ·
pub const ACCESS_CONTROL_ALLOW_METHODS: HeaderName;
Expand description

Preflight header response indicating permitted access methods.

+

The Access-Control-Allow-Methods response header specifies the method or +methods allowed when accessing the resource in response to a preflight +request.

+
\ No newline at end of file diff --git a/awc/http/header/constant.ACCESS_CONTROL_ALLOW_ORIGIN.html b/awc/http/header/constant.ACCESS_CONTROL_ALLOW_ORIGIN.html new file mode 100644 index 000000000..4a43f5953 --- /dev/null +++ b/awc/http/header/constant.ACCESS_CONTROL_ALLOW_ORIGIN.html @@ -0,0 +1,3 @@ +ACCESS_CONTROL_ALLOW_ORIGIN in awc::http::header - Rust

Constant awc::http::header::ACCESS_CONTROL_ALLOW_ORIGIN

source ·
pub const ACCESS_CONTROL_ALLOW_ORIGIN: HeaderName;
Expand description

Indicates whether the response can be shared with resources with the +given origin.

+
\ No newline at end of file diff --git a/awc/http/header/constant.ACCESS_CONTROL_EXPOSE_HEADERS.html b/awc/http/header/constant.ACCESS_CONTROL_EXPOSE_HEADERS.html new file mode 100644 index 000000000..7111d0f25 --- /dev/null +++ b/awc/http/header/constant.ACCESS_CONTROL_EXPOSE_HEADERS.html @@ -0,0 +1,3 @@ +ACCESS_CONTROL_EXPOSE_HEADERS in awc::http::header - Rust

Constant awc::http::header::ACCESS_CONTROL_EXPOSE_HEADERS

source ·
pub const ACCESS_CONTROL_EXPOSE_HEADERS: HeaderName;
Expand description

Indicates which headers can be exposed as part of the response by +listing their names.

+
\ No newline at end of file diff --git a/awc/http/header/constant.ACCESS_CONTROL_MAX_AGE.html b/awc/http/header/constant.ACCESS_CONTROL_MAX_AGE.html new file mode 100644 index 000000000..86b2778b3 --- /dev/null +++ b/awc/http/header/constant.ACCESS_CONTROL_MAX_AGE.html @@ -0,0 +1,2 @@ +ACCESS_CONTROL_MAX_AGE in awc::http::header - Rust

Constant awc::http::header::ACCESS_CONTROL_MAX_AGE

source ·
pub const ACCESS_CONTROL_MAX_AGE: HeaderName;
Expand description

Indicates how long the results of a preflight request can be cached.

+
\ No newline at end of file diff --git a/awc/http/header/constant.ACCESS_CONTROL_REQUEST_HEADERS.html b/awc/http/header/constant.ACCESS_CONTROL_REQUEST_HEADERS.html new file mode 100644 index 000000000..730759007 --- /dev/null +++ b/awc/http/header/constant.ACCESS_CONTROL_REQUEST_HEADERS.html @@ -0,0 +1,3 @@ +ACCESS_CONTROL_REQUEST_HEADERS in awc::http::header - Rust

Constant awc::http::header::ACCESS_CONTROL_REQUEST_HEADERS

source ·
pub const ACCESS_CONTROL_REQUEST_HEADERS: HeaderName;
Expand description

Informs the server which HTTP headers will be used when an actual +request is made.

+
\ No newline at end of file diff --git a/awc/http/header/constant.ACCESS_CONTROL_REQUEST_METHOD.html b/awc/http/header/constant.ACCESS_CONTROL_REQUEST_METHOD.html new file mode 100644 index 000000000..bdd92bacd --- /dev/null +++ b/awc/http/header/constant.ACCESS_CONTROL_REQUEST_METHOD.html @@ -0,0 +1,3 @@ +ACCESS_CONTROL_REQUEST_METHOD in awc::http::header - Rust

Constant awc::http::header::ACCESS_CONTROL_REQUEST_METHOD

source ·
pub const ACCESS_CONTROL_REQUEST_METHOD: HeaderName;
Expand description

Informs the server know which HTTP method will be used when the actual +request is made.

+
\ No newline at end of file diff --git a/awc/http/header/constant.AGE.html b/awc/http/header/constant.AGE.html new file mode 100644 index 000000000..177847391 --- /dev/null +++ b/awc/http/header/constant.AGE.html @@ -0,0 +1,6 @@ +AGE in awc::http::header - Rust

Constant awc::http::header::AGE

source ·
pub const AGE: HeaderName;
Expand description

Indicates the time in seconds the object has been in a proxy cache.

+

The Age header is usually close to zero. If it is Age: 0, it was +probably just fetched from the origin server; otherwise It is usually +calculated as a difference between the proxy’s current date and the Date +general header included in the HTTP response.

+
\ No newline at end of file diff --git a/awc/http/header/constant.ALLOW.html b/awc/http/header/constant.ALLOW.html new file mode 100644 index 000000000..4dded60bc --- /dev/null +++ b/awc/http/header/constant.ALLOW.html @@ -0,0 +1,7 @@ +ALLOW in awc::http::header - Rust

Constant awc::http::header::ALLOW

source ·
pub const ALLOW: HeaderName;
Expand description

Lists the set of methods support by a resource.

+

This header must be sent if the server responds with a 405 Method Not +Allowed status code to indicate which request methods can be used. An +empty Allow header indicates that the resource allows no request +methods, which might occur temporarily for a given resource, for +example.

+
\ No newline at end of file diff --git a/awc/http/header/constant.ALT_SVC.html b/awc/http/header/constant.ALT_SVC.html new file mode 100644 index 000000000..8e9e62e53 --- /dev/null +++ b/awc/http/header/constant.ALT_SVC.html @@ -0,0 +1,2 @@ +ALT_SVC in awc::http::header - Rust

Constant awc::http::header::ALT_SVC

source ·
pub const ALT_SVC: HeaderName;
Expand description

Advertises the availability of alternate services to clients.

+
\ No newline at end of file diff --git a/awc/http/header/constant.AUTHORIZATION.html b/awc/http/header/constant.AUTHORIZATION.html new file mode 100644 index 000000000..d25692a42 --- /dev/null +++ b/awc/http/header/constant.AUTHORIZATION.html @@ -0,0 +1,4 @@ +AUTHORIZATION in awc::http::header - Rust

Constant awc::http::header::AUTHORIZATION

source ·
pub const AUTHORIZATION: HeaderName;
Expand description

Contains the credentials to authenticate a user agent with a server.

+

Usually this header is included after the server has responded with a +401 Unauthorized status and the WWW-Authenticate header.

+
\ No newline at end of file diff --git a/awc/http/header/constant.CACHE_CONTROL.html b/awc/http/header/constant.CACHE_CONTROL.html new file mode 100644 index 000000000..841ccba65 --- /dev/null +++ b/awc/http/header/constant.CACHE_CONTROL.html @@ -0,0 +1,6 @@ +CACHE_CONTROL in awc::http::header - Rust

Constant awc::http::header::CACHE_CONTROL

source ·
pub const CACHE_CONTROL: HeaderName;
Expand description

Specifies directives for caching mechanisms in both requests and +responses.

+

Caching directives are unidirectional, meaning that a given directive in +a request is not implying that the same directive is to be given in the +response.

+
\ No newline at end of file diff --git a/awc/http/header/constant.CACHE_STATUS.html b/awc/http/header/constant.CACHE_STATUS.html new file mode 100644 index 000000000..d7edb9aa1 --- /dev/null +++ b/awc/http/header/constant.CACHE_STATUS.html @@ -0,0 +1,4 @@ +CACHE_STATUS in awc::http::header - Rust

Constant awc::http::header::CACHE_STATUS

pub const CACHE_STATUS: HeaderName;
Expand description

Response header field that indicates how caches have handled that response and its corresponding +request.

+

See RFC 9211 for full semantics.

+
\ No newline at end of file diff --git a/awc/http/header/constant.CDN_CACHE_CONTROL.html b/awc/http/header/constant.CDN_CACHE_CONTROL.html new file mode 100644 index 000000000..17a96d2bf --- /dev/null +++ b/awc/http/header/constant.CDN_CACHE_CONTROL.html @@ -0,0 +1,4 @@ +CDN_CACHE_CONTROL in awc::http::header - Rust

Constant awc::http::header::CDN_CACHE_CONTROL

pub const CDN_CACHE_CONTROL: HeaderName;
Expand description

Response header field that allows origin servers to control the behavior of CDN caches +interposed between them and clients separately from other caches that might handle the response.

+

See RFC 9213 for full semantics.

+
\ No newline at end of file diff --git a/awc/http/header/constant.CONNECTION.html b/awc/http/header/constant.CONNECTION.html new file mode 100644 index 000000000..425a752d5 --- /dev/null +++ b/awc/http/header/constant.CONNECTION.html @@ -0,0 +1,12 @@ +CONNECTION in awc::http::header - Rust

Constant awc::http::header::CONNECTION

source ·
pub const CONNECTION: HeaderName;
Expand description

Controls whether or not the network connection stays open after the +current transaction finishes.

+

If the value sent is keep-alive, the connection is persistent and not +closed, allowing for subsequent requests to the same server to be done.

+

Except for the standard hop-by-hop headers (Keep-Alive, +Transfer-Encoding, TE, Connection, Trailer, Upgrade, Proxy-Authorization +and Proxy-Authenticate), any hop-by-hop headers used by the message must +be listed in the Connection header, so that the first proxy knows he has +to consume them and not to forward them further. Standard hop-by-hop +headers can be listed too (it is often the case of Keep-Alive, but this +is not mandatory.

+
\ No newline at end of file diff --git a/awc/http/header/constant.CONTENT_DISPOSITION.html b/awc/http/header/constant.CONTENT_DISPOSITION.html new file mode 100644 index 000000000..83b192339 --- /dev/null +++ b/awc/http/header/constant.CONTENT_DISPOSITION.html @@ -0,0 +1,16 @@ +CONTENT_DISPOSITION in awc::http::header - Rust

Constant awc::http::header::CONTENT_DISPOSITION

source ·
pub const CONTENT_DISPOSITION: HeaderName;
Expand description

Indicates if the content is expected to be displayed inline.

+

In a regular HTTP response, the Content-Disposition response header is a +header indicating if the content is expected to be displayed inline in +the browser, that is, as a Web page or as part of a Web page, or as an +attachment, that is downloaded and saved locally.

+

In a multipart/form-data body, the HTTP Content-Disposition general +header is a header that can be used on the subpart of a multipart body +to give information about the field it applies to. The subpart is +delimited by the boundary defined in the Content-Type header. Used on +the body itself, Content-Disposition has no effect.

+

The Content-Disposition header is defined in the larger context of MIME +messages for e-mail, but only a subset of the possible parameters apply +to HTTP forms and POST requests. Only the value form-data, as well as +the optional directive name and filename, can be used in the HTTP +context.

+
\ No newline at end of file diff --git a/awc/http/header/constant.CONTENT_ENCODING.html b/awc/http/header/constant.CONTENT_ENCODING.html new file mode 100644 index 000000000..5bd958628 --- /dev/null +++ b/awc/http/header/constant.CONTENT_ENCODING.html @@ -0,0 +1,9 @@ +CONTENT_ENCODING in awc::http::header - Rust

Constant awc::http::header::CONTENT_ENCODING

source ·
pub const CONTENT_ENCODING: HeaderName;
Expand description

Used to compress the media-type.

+

When present, its value indicates what additional content encoding has +been applied to the entity-body. It lets the client know, how to decode +in order to obtain the media-type referenced by the Content-Type header.

+

It is recommended to compress data as much as possible and therefore to +use this field, but some types of resources, like jpeg images, are +already compressed. Sometimes using additional compression doesn’t +reduce payload size and can even make the payload longer.

+
\ No newline at end of file diff --git a/awc/http/header/constant.CONTENT_LANGUAGE.html b/awc/http/header/constant.CONTENT_LANGUAGE.html new file mode 100644 index 000000000..c4c1452cf --- /dev/null +++ b/awc/http/header/constant.CONTENT_LANGUAGE.html @@ -0,0 +1,12 @@ +CONTENT_LANGUAGE in awc::http::header - Rust

Constant awc::http::header::CONTENT_LANGUAGE

source ·
pub const CONTENT_LANGUAGE: HeaderName;
Expand description

Used to describe the languages intended for the audience.

+

This header allows a user to differentiate according to the users’ own +preferred language. For example, if “Content-Language: de-DE” is set, it +says that the document is intended for German language speakers +(however, it doesn’t indicate the document is written in German. For +example, it might be written in English as part of a language course for +German speakers).

+

If no Content-Language is specified, the default is that the content is +intended for all language audiences. Multiple language tags are also +possible, as well as applying the Content-Language header to various +media types and not only to textual documents.

+
\ No newline at end of file diff --git a/awc/http/header/constant.CONTENT_LENGTH.html b/awc/http/header/constant.CONTENT_LENGTH.html new file mode 100644 index 000000000..c7eff0ff5 --- /dev/null +++ b/awc/http/header/constant.CONTENT_LENGTH.html @@ -0,0 +1,4 @@ +CONTENT_LENGTH in awc::http::header - Rust

Constant awc::http::header::CONTENT_LENGTH

source ·
pub const CONTENT_LENGTH: HeaderName;
Expand description

Indicates the size of the entity-body.

+

The header value must be a decimal indicating the number of octets sent +to the recipient.

+
\ No newline at end of file diff --git a/awc/http/header/constant.CONTENT_LOCATION.html b/awc/http/header/constant.CONTENT_LOCATION.html new file mode 100644 index 000000000..68c8e6058 --- /dev/null +++ b/awc/http/header/constant.CONTENT_LOCATION.html @@ -0,0 +1,10 @@ +CONTENT_LOCATION in awc::http::header - Rust

Constant awc::http::header::CONTENT_LOCATION

source ·
pub const CONTENT_LOCATION: HeaderName;
Expand description

Indicates an alternate location for the returned data.

+

The principal use case is to indicate the URL of the resource +transmitted as the result of content negotiation.

+

Location and Content-Location are different: Location indicates the +target of a redirection (or the URL of a newly created document), while +Content-Location indicates the direct URL to use to access the resource, +without the need of further content negotiation. Location is a header +associated with the response, while Content-Location is associated with +the entity returned.

+
\ No newline at end of file diff --git a/awc/http/header/constant.CONTENT_RANGE.html b/awc/http/header/constant.CONTENT_RANGE.html new file mode 100644 index 000000000..af30a6a2c --- /dev/null +++ b/awc/http/header/constant.CONTENT_RANGE.html @@ -0,0 +1,2 @@ +CONTENT_RANGE in awc::http::header - Rust

Constant awc::http::header::CONTENT_RANGE

source ·
pub const CONTENT_RANGE: HeaderName;
Expand description

Indicates where in a full body message a partial message belongs.

+
\ No newline at end of file diff --git a/awc/http/header/constant.CONTENT_SECURITY_POLICY.html b/awc/http/header/constant.CONTENT_SECURITY_POLICY.html new file mode 100644 index 000000000..62a0bea9a --- /dev/null +++ b/awc/http/header/constant.CONTENT_SECURITY_POLICY.html @@ -0,0 +1,6 @@ +CONTENT_SECURITY_POLICY in awc::http::header - Rust

Constant awc::http::header::CONTENT_SECURITY_POLICY

source ·
pub const CONTENT_SECURITY_POLICY: HeaderName;
Expand description

Allows controlling resources the user agent is allowed to load for a +given page.

+

With a few exceptions, policies mostly involve specifying server origins +and script endpoints. This helps guard against cross-site scripting +attacks (XSS).

+
\ No newline at end of file diff --git a/awc/http/header/constant.CONTENT_SECURITY_POLICY_REPORT_ONLY.html b/awc/http/header/constant.CONTENT_SECURITY_POLICY_REPORT_ONLY.html new file mode 100644 index 000000000..e39c83a27 --- /dev/null +++ b/awc/http/header/constant.CONTENT_SECURITY_POLICY_REPORT_ONLY.html @@ -0,0 +1,6 @@ +CONTENT_SECURITY_POLICY_REPORT_ONLY in awc::http::header - Rust

Constant awc::http::header::CONTENT_SECURITY_POLICY_REPORT_ONLY

source ·
pub const CONTENT_SECURITY_POLICY_REPORT_ONLY: HeaderName;
Expand description

Allows experimenting with policies by monitoring their effects.

+

The HTTP Content-Security-Policy-Report-Only response header allows web +developers to experiment with policies by monitoring (but not enforcing) +their effects. These violation reports consist of JSON documents sent +via an HTTP POST request to the specified URI.

+
\ No newline at end of file diff --git a/awc/http/header/constant.CONTENT_TYPE.html b/awc/http/header/constant.CONTENT_TYPE.html new file mode 100644 index 000000000..9fb337b90 --- /dev/null +++ b/awc/http/header/constant.CONTENT_TYPE.html @@ -0,0 +1,9 @@ +CONTENT_TYPE in awc::http::header - Rust

Constant awc::http::header::CONTENT_TYPE

source ·
pub const CONTENT_TYPE: HeaderName;
Expand description

Used to indicate the media type of the resource.

+

In responses, a Content-Type header tells the client what the content +type of the returned content actually is. Browsers will do MIME sniffing +in some cases and will not necessarily follow the value of this header; +to prevent this behavior, the header X-Content-Type-Options can be set +to nosniff.

+

In requests, (such as POST or PUT), the client tells the server what +type of data is actually sent.

+
\ No newline at end of file diff --git a/awc/http/header/constant.COOKIE.html b/awc/http/header/constant.COOKIE.html new file mode 100644 index 000000000..45bdbbe8b --- /dev/null +++ b/awc/http/header/constant.COOKIE.html @@ -0,0 +1,5 @@ +COOKIE in awc::http::header - Rust

Constant awc::http::header::COOKIE

source ·
pub const COOKIE: HeaderName;
Expand description

Contains stored HTTP cookies previously sent by the server with the +Set-Cookie header.

+

The Cookie header might be omitted entirely, if the privacy setting of +the browser are set to block them, for example.

+
\ No newline at end of file diff --git a/awc/http/header/constant.CROSS_ORIGIN_EMBEDDER_POLICY.html b/awc/http/header/constant.CROSS_ORIGIN_EMBEDDER_POLICY.html new file mode 100644 index 000000000..f7dab7eb9 --- /dev/null +++ b/awc/http/header/constant.CROSS_ORIGIN_EMBEDDER_POLICY.html @@ -0,0 +1,3 @@ +CROSS_ORIGIN_EMBEDDER_POLICY in awc::http::header - Rust

Constant awc::http::header::CROSS_ORIGIN_EMBEDDER_POLICY

pub const CROSS_ORIGIN_EMBEDDER_POLICY: HeaderName;
Expand description

Response header that prevents a document from loading any cross-origin resources that don’t +explicitly grant the document permission (using CORP or CORS).

+
\ No newline at end of file diff --git a/awc/http/header/constant.CROSS_ORIGIN_OPENER_POLICY.html b/awc/http/header/constant.CROSS_ORIGIN_OPENER_POLICY.html new file mode 100644 index 000000000..caf83014c --- /dev/null +++ b/awc/http/header/constant.CROSS_ORIGIN_OPENER_POLICY.html @@ -0,0 +1,3 @@ +CROSS_ORIGIN_OPENER_POLICY in awc::http::header - Rust

Constant awc::http::header::CROSS_ORIGIN_OPENER_POLICY

pub const CROSS_ORIGIN_OPENER_POLICY: HeaderName;
Expand description

Response header that allows you to ensure a top-level document does not share a browsing context +group with cross-origin documents.

+
\ No newline at end of file diff --git a/awc/http/header/constant.CROSS_ORIGIN_RESOURCE_POLICY.html b/awc/http/header/constant.CROSS_ORIGIN_RESOURCE_POLICY.html new file mode 100644 index 000000000..b9b36b348 --- /dev/null +++ b/awc/http/header/constant.CROSS_ORIGIN_RESOURCE_POLICY.html @@ -0,0 +1,3 @@ +CROSS_ORIGIN_RESOURCE_POLICY in awc::http::header - Rust

Constant awc::http::header::CROSS_ORIGIN_RESOURCE_POLICY

pub const CROSS_ORIGIN_RESOURCE_POLICY: HeaderName;
Expand description

Response header that conveys a desire that the browser blocks no-cors cross-origin/cross-site +requests to the given resource.

+
\ No newline at end of file diff --git a/awc/http/header/constant.DATE.html b/awc/http/header/constant.DATE.html new file mode 100644 index 000000000..46bbe7995 --- /dev/null +++ b/awc/http/header/constant.DATE.html @@ -0,0 +1,2 @@ +DATE in awc::http::header - Rust

Constant awc::http::header::DATE

source ·
pub const DATE: HeaderName;
Expand description

Contains the date and time at which the message was originated.

+
\ No newline at end of file diff --git a/awc/http/header/constant.DNT.html b/awc/http/header/constant.DNT.html new file mode 100644 index 000000000..60e1088c8 --- /dev/null +++ b/awc/http/header/constant.DNT.html @@ -0,0 +1,4 @@ +DNT in awc::http::header - Rust

Constant awc::http::header::DNT

source ·
pub const DNT: HeaderName;
Expand description

Indicates the client’s tracking preference.

+

This header lets users indicate whether they would prefer privacy rather +than personalized content.

+
\ No newline at end of file diff --git a/awc/http/header/constant.ETAG.html b/awc/http/header/constant.ETAG.html new file mode 100644 index 000000000..37f903c43 --- /dev/null +++ b/awc/http/header/constant.ETAG.html @@ -0,0 +1,13 @@ +ETAG in awc::http::header - Rust

Constant awc::http::header::ETAG

source ·
pub const ETAG: HeaderName;
Expand description

Identifier for a specific version of a resource.

+

This header allows caches to be more efficient, and saves bandwidth, as +a web server does not need to send a full response if the content has +not changed. On the other side, if the content has changed, etags are +useful to help prevent simultaneous updates of a resource from +overwriting each other (“mid-air collisions”).

+

If the resource at a given URL changes, a new Etag value must be +generated. Etags are therefore similar to fingerprints and might also be +used for tracking purposes by some servers. A comparison of them allows +to quickly determine whether two representations of a resource are the +same, but they might also be set to persist indefinitely by a tracking +server.

+
\ No newline at end of file diff --git a/awc/http/header/constant.EXPECT.html b/awc/http/header/constant.EXPECT.html new file mode 100644 index 000000000..18e9fd6a2 --- /dev/null +++ b/awc/http/header/constant.EXPECT.html @@ -0,0 +1,19 @@ +EXPECT in awc::http::header - Rust

Constant awc::http::header::EXPECT

source ·
pub const EXPECT: HeaderName;
Expand description

Indicates expectations that need to be fulfilled by the server in order +to properly handle the request.

+

The only expectation defined in the specification is Expect: +100-continue, to which the server shall respond with:

+
    +
  • +

    100 if the information contained in the header is sufficient to cause +an immediate success,

    +
  • +
  • +

    417 (Expectation Failed) if it cannot meet the expectation; or any +other 4xx status otherwise.

    +
  • +
+

For example, the server may reject a request if its Content-Length is +too large.

+

No common browsers send the Expect header, but some other clients such +as cURL do so by default.

+
\ No newline at end of file diff --git a/awc/http/header/constant.EXPIRES.html b/awc/http/header/constant.EXPIRES.html new file mode 100644 index 000000000..d0a827f03 --- /dev/null +++ b/awc/http/header/constant.EXPIRES.html @@ -0,0 +1,6 @@ +EXPIRES in awc::http::header - Rust

Constant awc::http::header::EXPIRES

source ·
pub const EXPIRES: HeaderName;
Expand description

Contains the date/time after which the response is considered stale.

+

Invalid dates, like the value 0, represent a date in the past and mean +that the resource is already expired.

+

If there is a Cache-Control header with the “max-age” or “s-max-age” +directive in the response, the Expires header is ignored.

+
\ No newline at end of file diff --git a/awc/http/header/constant.FORWARDED.html b/awc/http/header/constant.FORWARDED.html new file mode 100644 index 000000000..f30a370d9 --- /dev/null +++ b/awc/http/header/constant.FORWARDED.html @@ -0,0 +1,9 @@ +FORWARDED in awc::http::header - Rust

Constant awc::http::header::FORWARDED

source ·
pub const FORWARDED: HeaderName;
Expand description

Contains information from the client-facing side of proxy servers that +is altered or lost when a proxy is involved in the path of the request.

+

The alternative and de-facto standard versions of this header are the +X-Forwarded-For, X-Forwarded-Host and X-Forwarded-Proto headers.

+

This header is used for debugging, statistics, and generating +location-dependent content and by design it exposes privacy sensitive +information, such as the IP address of the client. Therefore the user’s +privacy must be kept in mind when deploying this header.

+
\ No newline at end of file diff --git a/awc/http/header/constant.FROM.html b/awc/http/header/constant.FROM.html new file mode 100644 index 000000000..a929a20f3 --- /dev/null +++ b/awc/http/header/constant.FROM.html @@ -0,0 +1,7 @@ +FROM in awc::http::header - Rust

Constant awc::http::header::FROM

source ·
pub const FROM: HeaderName;
Expand description

Contains an Internet email address for a human user who controls the +requesting user agent.

+

If you are running a robotic user agent (e.g. a crawler), the From +header should be sent, so you can be contacted if problems occur on +servers, such as if the robot is sending excessive, unwanted, or invalid +requests.

+
\ No newline at end of file diff --git a/awc/http/header/constant.HOST.html b/awc/http/header/constant.HOST.html new file mode 100644 index 000000000..2db6196dd --- /dev/null +++ b/awc/http/header/constant.HOST.html @@ -0,0 +1,8 @@ +HOST in awc::http::header - Rust

Constant awc::http::header::HOST

source ·
pub const HOST: HeaderName;
Expand description

Specifies the domain name of the server and (optionally) the TCP port +number on which the server is listening.

+

If no port is given, the default port for the service requested (e.g., +“80” for an HTTP URL) is implied.

+

A Host header field must be sent in all HTTP/1.1 request messages. A 400 +(Bad Request) status code will be sent to any HTTP/1.1 request message +that lacks a Host header field or contains more than one.

+
\ No newline at end of file diff --git a/awc/http/header/constant.IF_MATCH.html b/awc/http/header/constant.IF_MATCH.html new file mode 100644 index 000000000..196dc80e0 --- /dev/null +++ b/awc/http/header/constant.IF_MATCH.html @@ -0,0 +1,25 @@ +IF_MATCH in awc::http::header - Rust

Constant awc::http::header::IF_MATCH

source ·
pub const IF_MATCH: HeaderName;
Expand description

Makes a request conditional based on the E-Tag.

+

For GET and HEAD methods, the server will send back the requested +resource only if it matches one of the listed ETags. For PUT and other +non-safe methods, it will only upload the resource in this case.

+

The comparison with the stored ETag uses the strong comparison +algorithm, meaning two files are considered identical byte to byte only. +This is weakened when the W/ prefix is used in front of the ETag.

+

There are two common use cases:

+
    +
  • +

    For GET and HEAD methods, used in combination with an Range header, it +can guarantee that the new ranges requested comes from the same resource +than the previous one. If it doesn’t match, then a 416 (Range Not +Satisfiable) response is returned.

    +
  • +
  • +

    For other methods, and in particular for PUT, If-Match can be used to +prevent the lost update problem. It can check if the modification of a +resource that the user wants to upload will not override another change +that has been done since the original resource was fetched. If the +request cannot be fulfilled, the 412 (Precondition Failed) response is +returned.

    +
  • +
+
\ No newline at end of file diff --git a/awc/http/header/constant.IF_MODIFIED_SINCE.html b/awc/http/header/constant.IF_MODIFIED_SINCE.html new file mode 100644 index 000000000..8d3668e73 --- /dev/null +++ b/awc/http/header/constant.IF_MODIFIED_SINCE.html @@ -0,0 +1,13 @@ +IF_MODIFIED_SINCE in awc::http::header - Rust

Constant awc::http::header::IF_MODIFIED_SINCE

source ·
pub const IF_MODIFIED_SINCE: HeaderName;
Expand description

Makes a request conditional based on the modification date.

+

The If-Modified-Since request HTTP header makes the request conditional: +the server will send back the requested resource, with a 200 status, +only if it has been last modified after the given date. If the request +has not been modified since, the response will be a 304 without any +body; the Last-Modified header will contain the date of last +modification. Unlike If-Unmodified-Since, If-Modified-Since can only be +used with a GET or HEAD.

+

When used in combination with If-None-Match, it is ignored, unless the +server doesn’t support If-None-Match.

+

The most common use case is to update a cached entity that has no +associated ETag.

+
\ No newline at end of file diff --git a/awc/http/header/constant.IF_NONE_MATCH.html b/awc/http/header/constant.IF_NONE_MATCH.html new file mode 100644 index 000000000..7eff33d00 --- /dev/null +++ b/awc/http/header/constant.IF_NONE_MATCH.html @@ -0,0 +1,31 @@ +IF_NONE_MATCH in awc::http::header - Rust

Constant awc::http::header::IF_NONE_MATCH

source ·
pub const IF_NONE_MATCH: HeaderName;
Expand description

Makes a request conditional based on the E-Tag.

+

The If-None-Match HTTP request header makes the request conditional. For +GET and HEAD methods, the server will send back the requested resource, +with a 200 status, only if it doesn’t have an ETag matching the given +ones. For other methods, the request will be processed only if the +eventually existing resource’s ETag doesn’t match any of the values +listed.

+

When the condition fails for GET and HEAD methods, then the server must +return HTTP status code 304 (Not Modified). For methods that apply +server-side changes, the status code 412 (Precondition Failed) is used. +Note that the server generating a 304 response MUST generate any of the +following header fields that would have been sent in a 200 (OK) response +to the same request: Cache-Control, Content-Location, Date, ETag, +Expires, and Vary.

+

The comparison with the stored ETag uses the weak comparison algorithm, +meaning two files are considered identical not only if they are +identical byte to byte, but if the content is equivalent. For example, +two pages that would differ only by the date of generation in the footer +would be considered as identical.

+

When used in combination with If-Modified-Since, it has precedence (if +the server supports it).

+

There are two common use cases:

+
    +
  • For GET and HEAD methods, to update a cached entity that has an associated ETag.
  • +
  • For other methods, and in particular for PUT, If-None-Match used with +the * value can be used to save a file not known to exist, +guaranteeing that another upload didn’t happen before, losing the data +of the previous put; this problems is the variation of the lost update +problem.
  • +
+
\ No newline at end of file diff --git a/awc/http/header/constant.IF_RANGE.html b/awc/http/header/constant.IF_RANGE.html new file mode 100644 index 000000000..afaa18e46 --- /dev/null +++ b/awc/http/header/constant.IF_RANGE.html @@ -0,0 +1,12 @@ +IF_RANGE in awc::http::header - Rust

Constant awc::http::header::IF_RANGE

source ·
pub const IF_RANGE: HeaderName;
Expand description

Makes a request conditional based on range.

+

The If-Range HTTP request header makes a range request conditional: if +the condition is fulfilled, the range request will be issued and the +server sends back a 206 Partial Content answer with the appropriate +body. If the condition is not fulfilled, the full resource is sent back, +with a 200 OK status.

+

This header can be used either with a Last-Modified validator, or with +an ETag, but not with both.

+

The most common use case is to resume a download, to guarantee that the +stored resource has not been modified since the last fragment has been +received.

+
\ No newline at end of file diff --git a/awc/http/header/constant.IF_UNMODIFIED_SINCE.html b/awc/http/header/constant.IF_UNMODIFIED_SINCE.html new file mode 100644 index 000000000..b5525a9f4 --- /dev/null +++ b/awc/http/header/constant.IF_UNMODIFIED_SINCE.html @@ -0,0 +1,22 @@ +IF_UNMODIFIED_SINCE in awc::http::header - Rust

Constant awc::http::header::IF_UNMODIFIED_SINCE

source ·
pub const IF_UNMODIFIED_SINCE: HeaderName;
Expand description

Makes the request conditional based on the last modification date.

+

The If-Unmodified-Since request HTTP header makes the request +conditional: the server will send back the requested resource, or accept +it in the case of a POST or another non-safe method, only if it has not +been last modified after the given date. If the request has been +modified after the given date, the response will be a 412 (Precondition +Failed) error.

+

There are two common use cases:

+
    +
  • +

    In conjunction non-safe methods, like POST, it can be used to +implement an optimistic concurrency control, like done by some wikis: +editions are rejected if the stored document has been modified since the +original has been retrieved.

    +
  • +
  • +

    In conjunction with a range request with a If-Range header, it can be +used to ensure that the new fragment requested comes from an unmodified +document.

    +
  • +
+
\ No newline at end of file diff --git a/awc/http/header/constant.LAST_MODIFIED.html b/awc/http/header/constant.LAST_MODIFIED.html new file mode 100644 index 000000000..dd561931b --- /dev/null +++ b/awc/http/header/constant.LAST_MODIFIED.html @@ -0,0 +1,2 @@ +LAST_MODIFIED in awc::http::header - Rust

Constant awc::http::header::LAST_MODIFIED

source ·
pub const LAST_MODIFIED: HeaderName;
Expand description

Content-Types that are acceptable for the response.

+
\ No newline at end of file diff --git a/awc/http/header/constant.LINK.html b/awc/http/header/constant.LINK.html new file mode 100644 index 000000000..79b264eba --- /dev/null +++ b/awc/http/header/constant.LINK.html @@ -0,0 +1,3 @@ +LINK in awc::http::header - Rust

Constant awc::http::header::LINK

source ·
pub const LINK: HeaderName;
Expand description

Allows the server to point an interested client to another resource +containing metadata about the requested resource.

+
\ No newline at end of file diff --git a/awc/http/header/constant.LOCATION.html b/awc/http/header/constant.LOCATION.html new file mode 100644 index 000000000..78c09226e --- /dev/null +++ b/awc/http/header/constant.LOCATION.html @@ -0,0 +1,29 @@ +LOCATION in awc::http::header - Rust

Constant awc::http::header::LOCATION

source ·
pub const LOCATION: HeaderName;
Expand description

Indicates the URL to redirect a page to.

+

The Location response header indicates the URL to redirect a page to. It +only provides a meaning when served with a 3xx status response.

+

The HTTP method used to make the new request to fetch the page pointed +to by Location depends of the original method and of the kind of +redirection:

+
    +
  • +

    If 303 (See Also) responses always lead to the use of a GET method, +307 (Temporary Redirect) and 308 (Permanent Redirect) don’t change the +method used in the original request;

    +
  • +
  • +

    301 (Permanent Redirect) and 302 (Found) doesn’t change the method +most of the time, though older user-agents may (so you basically don’t +know).

    +
  • +
+

All responses with one of these status codes send a Location header.

+

Beside redirect response, messages with 201 (Created) status also +include the Location header. It indicates the URL to the newly created +resource.

+

Location and Content-Location are different: Location indicates the +target of a redirection (or the URL of a newly created resource), while +Content-Location indicates the direct URL to use to access the resource +when content negotiation happened, without the need of further content +negotiation. Location is a header associated with the response, while +Content-Location is associated with the entity returned.

+
\ No newline at end of file diff --git a/awc/http/header/constant.MAX_FORWARDS.html b/awc/http/header/constant.MAX_FORWARDS.html new file mode 100644 index 000000000..0ee12ad61 --- /dev/null +++ b/awc/http/header/constant.MAX_FORWARDS.html @@ -0,0 +1,3 @@ +MAX_FORWARDS in awc::http::header - Rust

Constant awc::http::header::MAX_FORWARDS

source ·
pub const MAX_FORWARDS: HeaderName;
Expand description

Indicates the max number of intermediaries the request should be sent +through.

+
\ No newline at end of file diff --git a/awc/http/header/constant.ORIGIN.html b/awc/http/header/constant.ORIGIN.html new file mode 100644 index 000000000..0f8d1a406 --- /dev/null +++ b/awc/http/header/constant.ORIGIN.html @@ -0,0 +1,6 @@ +ORIGIN in awc::http::header - Rust

Constant awc::http::header::ORIGIN

source ·
pub const ORIGIN: HeaderName;
Expand description

Indicates where a fetch originates from.

+

It doesn’t include any path information, but only the server name. It is +sent with CORS requests, as well as with POST requests. It is similar to +the Referer header, but, unlike this header, it doesn’t disclose the +whole path.

+
\ No newline at end of file diff --git a/awc/http/header/constant.PERMISSIONS_POLICY.html b/awc/http/header/constant.PERMISSIONS_POLICY.html new file mode 100644 index 000000000..2d80c312a --- /dev/null +++ b/awc/http/header/constant.PERMISSIONS_POLICY.html @@ -0,0 +1,3 @@ +PERMISSIONS_POLICY in awc::http::header - Rust

Constant awc::http::header::PERMISSIONS_POLICY

pub const PERMISSIONS_POLICY: HeaderName;
Expand description

Response header that provides a mechanism to allow and deny the use of browser features in a +document or within any <iframe> elements in the document.

+
\ No newline at end of file diff --git a/awc/http/header/constant.PRAGMA.html b/awc/http/header/constant.PRAGMA.html new file mode 100644 index 000000000..ded09fb61 --- /dev/null +++ b/awc/http/header/constant.PRAGMA.html @@ -0,0 +1,6 @@ +PRAGMA in awc::http::header - Rust

Constant awc::http::header::PRAGMA

source ·
pub const PRAGMA: HeaderName;
Expand description

HTTP/1.0 header usually used for backwards compatibility.

+

The Pragma HTTP/1.0 general header is an implementation-specific header +that may have various effects along the request-response chain. It is +used for backwards compatibility with HTTP/1.0 caches where the +Cache-Control HTTP/1.1 header is not yet present.

+
\ No newline at end of file diff --git a/awc/http/header/constant.PROXY_AUTHENTICATE.html b/awc/http/header/constant.PROXY_AUTHENTICATE.html new file mode 100644 index 000000000..41bc63f6a --- /dev/null +++ b/awc/http/header/constant.PROXY_AUTHENTICATE.html @@ -0,0 +1,14 @@ +PROXY_AUTHENTICATE in awc::http::header - Rust

Constant awc::http::header::PROXY_AUTHENTICATE

source ·
pub const PROXY_AUTHENTICATE: HeaderName;
Expand description

Defines the authentication method that should be used to gain access to +a proxy.

+

Unlike www-authenticate, the proxy-authenticate header field applies +only to the next outbound client on the response chain. This is because +only the client that chose a given proxy is likely to have the +credentials necessary for authentication. However, when multiple proxies +are used within the same administrative domain, such as office and +regional caching proxies within a large corporate network, it is common +for credentials to be generated by the user agent and passed through the +hierarchy until consumed. Hence, in such a configuration, it will appear +as if Proxy-Authenticate is being forwarded because each proxy will send +the same challenge set.

+

The proxy-authenticate header is sent along with a 407 Proxy Authentication Required.

+
\ No newline at end of file diff --git a/awc/http/header/constant.PROXY_AUTHORIZATION.html b/awc/http/header/constant.PROXY_AUTHORIZATION.html new file mode 100644 index 000000000..6085762b8 --- /dev/null +++ b/awc/http/header/constant.PROXY_AUTHORIZATION.html @@ -0,0 +1,5 @@ +PROXY_AUTHORIZATION in awc::http::header - Rust

Constant awc::http::header::PROXY_AUTHORIZATION

source ·
pub const PROXY_AUTHORIZATION: HeaderName;
Expand description

Contains the credentials to authenticate a user agent to a proxy server.

+

This header is usually included after the server has responded with a +407 Proxy Authentication Required status and the Proxy-Authenticate +header.

+
\ No newline at end of file diff --git a/awc/http/header/constant.PUBLIC_KEY_PINS.html b/awc/http/header/constant.PUBLIC_KEY_PINS.html new file mode 100644 index 000000000..5034dceca --- /dev/null +++ b/awc/http/header/constant.PUBLIC_KEY_PINS.html @@ -0,0 +1,6 @@ +PUBLIC_KEY_PINS in awc::http::header - Rust

Constant awc::http::header::PUBLIC_KEY_PINS

source ·
pub const PUBLIC_KEY_PINS: HeaderName;
Expand description

Associates a specific cryptographic public key with a certain server.

+

This decreases the risk of MITM attacks with forged certificates. If one +or several keys are pinned and none of them are used by the server, the +browser will not accept the response as legitimate, and will not display +it.

+
\ No newline at end of file diff --git a/awc/http/header/constant.PUBLIC_KEY_PINS_REPORT_ONLY.html b/awc/http/header/constant.PUBLIC_KEY_PINS_REPORT_ONLY.html new file mode 100644 index 000000000..ed5c6c309 --- /dev/null +++ b/awc/http/header/constant.PUBLIC_KEY_PINS_REPORT_ONLY.html @@ -0,0 +1,5 @@ +PUBLIC_KEY_PINS_REPORT_ONLY in awc::http::header - Rust

Constant awc::http::header::PUBLIC_KEY_PINS_REPORT_ONLY

source ·
pub const PUBLIC_KEY_PINS_REPORT_ONLY: HeaderName;
Expand description

Sends reports of pinning violation to the report-uri specified in the +header.

+

Unlike Public-Key-Pins, this header still allows browsers to connect +to the server if the pinning is violated.

+
\ No newline at end of file diff --git a/awc/http/header/constant.RANGE.html b/awc/http/header/constant.RANGE.html new file mode 100644 index 000000000..e8553bd48 --- /dev/null +++ b/awc/http/header/constant.RANGE.html @@ -0,0 +1,8 @@ +RANGE in awc::http::header - Rust

Constant awc::http::header::RANGE

source ·
pub const RANGE: HeaderName;
Expand description

Indicates the part of a document that the server should return.

+

Several parts can be requested with one Range header at once, and the +server may send back these ranges in a multipart document. If the server +sends back ranges, it uses the 206 Partial Content for the response. If +the ranges are invalid, the server returns the 416 Range Not Satisfiable +error. The server can also ignore the Range header and return the whole +document with a 200 status code.

+
\ No newline at end of file diff --git a/awc/http/header/constant.REFERER.html b/awc/http/header/constant.REFERER.html new file mode 100644 index 000000000..04b6ded76 --- /dev/null +++ b/awc/http/header/constant.REFERER.html @@ -0,0 +1,6 @@ +REFERER in awc::http::header - Rust

Constant awc::http::header::REFERER

source ·
pub const REFERER: HeaderName;
Expand description

Contains the address of the previous web page from which a link to the +currently requested page was followed.

+

The Referer header allows servers to identify where people are visiting +them from and may use that data for analytics, logging, or optimized +caching, for example.

+
\ No newline at end of file diff --git a/awc/http/header/constant.REFERRER_POLICY.html b/awc/http/header/constant.REFERRER_POLICY.html new file mode 100644 index 000000000..b30d076a7 --- /dev/null +++ b/awc/http/header/constant.REFERRER_POLICY.html @@ -0,0 +1,3 @@ +REFERRER_POLICY in awc::http::header - Rust

Constant awc::http::header::REFERRER_POLICY

source ·
pub const REFERRER_POLICY: HeaderName;
Expand description

Governs which referrer information should be included with requests +made.

+
\ No newline at end of file diff --git a/awc/http/header/constant.REFRESH.html b/awc/http/header/constant.REFRESH.html new file mode 100644 index 000000000..febe5714d --- /dev/null +++ b/awc/http/header/constant.REFRESH.html @@ -0,0 +1,3 @@ +REFRESH in awc::http::header - Rust

Constant awc::http::header::REFRESH

source ·
pub const REFRESH: HeaderName;
Expand description

Informs the web browser that the current page or frame should be +refreshed.

+
\ No newline at end of file diff --git a/awc/http/header/constant.RETRY_AFTER.html b/awc/http/header/constant.RETRY_AFTER.html new file mode 100644 index 000000000..69bd9eb90 --- /dev/null +++ b/awc/http/header/constant.RETRY_AFTER.html @@ -0,0 +1,15 @@ +RETRY_AFTER in awc::http::header - Rust

Constant awc::http::header::RETRY_AFTER

source ·
pub const RETRY_AFTER: HeaderName;
Expand description

The Retry-After response HTTP header indicates how long the user agent +should wait before making a follow-up request. There are two main cases +this header is used:

+
    +
  • +

    When sent with a 503 (Service Unavailable) response, it indicates how +long the service is expected to be unavailable.

    +
  • +
  • +

    When sent with a redirect response, such as 301 (Moved Permanently), +it indicates the minimum time that the user agent is asked to wait +before issuing the redirected request.

    +
  • +
+
\ No newline at end of file diff --git a/awc/http/header/constant.SEC_WEBSOCKET_ACCEPT.html b/awc/http/header/constant.SEC_WEBSOCKET_ACCEPT.html new file mode 100644 index 000000000..c1e1ef741 --- /dev/null +++ b/awc/http/header/constant.SEC_WEBSOCKET_ACCEPT.html @@ -0,0 +1,5 @@ +SEC_WEBSOCKET_ACCEPT in awc::http::header - Rust

Constant awc::http::header::SEC_WEBSOCKET_ACCEPT

source ·
pub const SEC_WEBSOCKET_ACCEPT: HeaderName;
Expand description

The |Sec-WebSocket-Accept| header field is used in the WebSocket +opening handshake. It is sent from the server to the client to +confirm that the server is willing to initiate the WebSocket +connection.

+
\ No newline at end of file diff --git a/awc/http/header/constant.SEC_WEBSOCKET_EXTENSIONS.html b/awc/http/header/constant.SEC_WEBSOCKET_EXTENSIONS.html new file mode 100644 index 000000000..c2a408ab8 --- /dev/null +++ b/awc/http/header/constant.SEC_WEBSOCKET_EXTENSIONS.html @@ -0,0 +1,6 @@ +SEC_WEBSOCKET_EXTENSIONS in awc::http::header - Rust

Constant awc::http::header::SEC_WEBSOCKET_EXTENSIONS

source ·
pub const SEC_WEBSOCKET_EXTENSIONS: HeaderName;
Expand description

The |Sec-WebSocket-Extensions| header field is used in the WebSocket +opening handshake. It is initially sent from the client to the +server, and then subsequently sent from the server to the client, to +agree on a set of protocol-level extensions to use for the duration +of the connection.

+
\ No newline at end of file diff --git a/awc/http/header/constant.SEC_WEBSOCKET_KEY.html b/awc/http/header/constant.SEC_WEBSOCKET_KEY.html new file mode 100644 index 000000000..09f066601 --- /dev/null +++ b/awc/http/header/constant.SEC_WEBSOCKET_KEY.html @@ -0,0 +1,8 @@ +SEC_WEBSOCKET_KEY in awc::http::header - Rust

Constant awc::http::header::SEC_WEBSOCKET_KEY

source ·
pub const SEC_WEBSOCKET_KEY: HeaderName;
Expand description

The |Sec-WebSocket-Key| header field is used in the WebSocket opening +handshake. It is sent from the client to the server to provide part +of the information used by the server to prove that it received a +valid WebSocket opening handshake. This helps ensure that the server +does not accept connections from non-WebSocket clients (e.g., HTTP +clients) that are being abused to send data to unsuspecting WebSocket +servers.

+
\ No newline at end of file diff --git a/awc/http/header/constant.SEC_WEBSOCKET_PROTOCOL.html b/awc/http/header/constant.SEC_WEBSOCKET_PROTOCOL.html new file mode 100644 index 000000000..b12ebbf2c --- /dev/null +++ b/awc/http/header/constant.SEC_WEBSOCKET_PROTOCOL.html @@ -0,0 +1,6 @@ +SEC_WEBSOCKET_PROTOCOL in awc::http::header - Rust

Constant awc::http::header::SEC_WEBSOCKET_PROTOCOL

source ·
pub const SEC_WEBSOCKET_PROTOCOL: HeaderName;
Expand description

The |Sec-WebSocket-Protocol| header field is used in the WebSocket +opening handshake. It is sent from the client to the server and back +from the server to the client to confirm the subprotocol of the +connection. This enables scripts to both select a subprotocol and be +sure that the server agreed to serve that subprotocol.

+
\ No newline at end of file diff --git a/awc/http/header/constant.SEC_WEBSOCKET_VERSION.html b/awc/http/header/constant.SEC_WEBSOCKET_VERSION.html new file mode 100644 index 000000000..410459184 --- /dev/null +++ b/awc/http/header/constant.SEC_WEBSOCKET_VERSION.html @@ -0,0 +1,7 @@ +SEC_WEBSOCKET_VERSION in awc::http::header - Rust

Constant awc::http::header::SEC_WEBSOCKET_VERSION

source ·
pub const SEC_WEBSOCKET_VERSION: HeaderName;
Expand description

The |Sec-WebSocket-Version| header field is used in the WebSocket +opening handshake. It is sent from the client to the server to +indicate the protocol version of the connection. This enables +servers to correctly interpret the opening handshake and subsequent +data being sent from the data, and close the connection if the server +cannot interpret that data in a safe manner.

+
\ No newline at end of file diff --git a/awc/http/header/constant.SERVER.html b/awc/http/header/constant.SERVER.html new file mode 100644 index 000000000..a925cb1ce --- /dev/null +++ b/awc/http/header/constant.SERVER.html @@ -0,0 +1,7 @@ +SERVER in awc::http::header - Rust

Constant awc::http::header::SERVER

source ·
pub const SERVER: HeaderName;
Expand description

Contains information about the software used by the origin server to +handle the request.

+

Overly long and detailed Server values should be avoided as they +potentially reveal internal implementation details that might make it +(slightly) easier for attackers to find and exploit known security +holes.

+
\ No newline at end of file diff --git a/awc/http/header/constant.SET_COOKIE.html b/awc/http/header/constant.SET_COOKIE.html new file mode 100644 index 000000000..669e8adb9 --- /dev/null +++ b/awc/http/header/constant.SET_COOKIE.html @@ -0,0 +1,2 @@ +SET_COOKIE in awc::http::header - Rust

Constant awc::http::header::SET_COOKIE

source ·
pub const SET_COOKIE: HeaderName;
Expand description

Used to send cookies from the server to the user agent.

+
\ No newline at end of file diff --git a/awc/http/header/constant.STRICT_TRANSPORT_SECURITY.html b/awc/http/header/constant.STRICT_TRANSPORT_SECURITY.html new file mode 100644 index 000000000..460a28988 --- /dev/null +++ b/awc/http/header/constant.STRICT_TRANSPORT_SECURITY.html @@ -0,0 +1,2 @@ +STRICT_TRANSPORT_SECURITY in awc::http::header - Rust

Constant awc::http::header::STRICT_TRANSPORT_SECURITY

source ·
pub const STRICT_TRANSPORT_SECURITY: HeaderName;
Expand description

Tells the client to communicate with HTTPS instead of using HTTP.

+
\ No newline at end of file diff --git a/awc/http/header/constant.TE.html b/awc/http/header/constant.TE.html new file mode 100644 index 000000000..34d2f134b --- /dev/null +++ b/awc/http/header/constant.TE.html @@ -0,0 +1,8 @@ +TE in awc::http::header - Rust

Constant awc::http::header::TE

source ·
pub const TE: HeaderName;
Expand description

Informs the server of transfer encodings willing to be accepted as part +of the response.

+

See also the Transfer-Encoding response header for more details on +transfer encodings. Note that chunked is always acceptable for HTTP/1.1 +recipients and you that don’t have to specify “chunked” using the TE +header. However, it is useful for setting if the client is accepting +trailer fields in a chunked transfer coding using the “trailers” value.

+
\ No newline at end of file diff --git a/awc/http/header/constant.TRAILER.html b/awc/http/header/constant.TRAILER.html new file mode 100644 index 000000000..865dc855f --- /dev/null +++ b/awc/http/header/constant.TRAILER.html @@ -0,0 +1,3 @@ +TRAILER in awc::http::header - Rust

Constant awc::http::header::TRAILER

source ·
pub const TRAILER: HeaderName;
Expand description

Allows the sender to include additional fields at the end of chunked +messages.

+
\ No newline at end of file diff --git a/awc/http/header/constant.TRANSFER_ENCODING.html b/awc/http/header/constant.TRANSFER_ENCODING.html new file mode 100644 index 000000000..3ddcf8f52 --- /dev/null +++ b/awc/http/header/constant.TRANSFER_ENCODING.html @@ -0,0 +1,11 @@ +TRANSFER_ENCODING in awc::http::header - Rust

Constant awc::http::header::TRANSFER_ENCODING

source ·
pub const TRANSFER_ENCODING: HeaderName;
Expand description

Specifies the form of encoding used to safely transfer the entity to the +client.

+

transfer-encoding is a hop-by-hop header, that is applying to a +message between two nodes, not to a resource itself. Each segment of a +multi-node connection can use different transfer-encoding values. If +you want to compress data over the whole connection, use the end-to-end +header content-encoding header instead.

+

When present on a response to a HEAD request that has no body, it +indicates the value that would have applied to the corresponding GET +message.

+
\ No newline at end of file diff --git a/awc/http/header/constant.UPGRADE.html b/awc/http/header/constant.UPGRADE.html new file mode 100644 index 000000000..5bd76693a --- /dev/null +++ b/awc/http/header/constant.UPGRADE.html @@ -0,0 +1,2 @@ +UPGRADE in awc::http::header - Rust

Constant awc::http::header::UPGRADE

source ·
pub const UPGRADE: HeaderName;
Expand description

Used as part of the exchange to upgrade the protocol.

+
\ No newline at end of file diff --git a/awc/http/header/constant.UPGRADE_INSECURE_REQUESTS.html b/awc/http/header/constant.UPGRADE_INSECURE_REQUESTS.html new file mode 100644 index 000000000..69830e0bf --- /dev/null +++ b/awc/http/header/constant.UPGRADE_INSECURE_REQUESTS.html @@ -0,0 +1,3 @@ +UPGRADE_INSECURE_REQUESTS in awc::http::header - Rust

Constant awc::http::header::UPGRADE_INSECURE_REQUESTS

source ·
pub const UPGRADE_INSECURE_REQUESTS: HeaderName;
Expand description

Sends a signal to the server expressing the client’s preference for an +encrypted and authenticated response.

+
\ No newline at end of file diff --git a/awc/http/header/constant.USER_AGENT.html b/awc/http/header/constant.USER_AGENT.html new file mode 100644 index 000000000..bdaebb869 --- /dev/null +++ b/awc/http/header/constant.USER_AGENT.html @@ -0,0 +1,3 @@ +USER_AGENT in awc::http::header - Rust

Constant awc::http::header::USER_AGENT

source ·
pub const USER_AGENT: HeaderName;
Expand description

Contains a string that allows identifying the requesting client’s +software.

+
\ No newline at end of file diff --git a/awc/http/header/constant.VARY.html b/awc/http/header/constant.VARY.html new file mode 100644 index 000000000..a175470ba --- /dev/null +++ b/awc/http/header/constant.VARY.html @@ -0,0 +1,9 @@ +VARY in awc::http::header - Rust

Constant awc::http::header::VARY

source ·
pub const VARY: HeaderName;
Expand description

Determines how to match future requests with cached responses.

+

The vary HTTP response header determines how to match future request +headers to decide whether a cached response can be used rather than +requesting a fresh one from the origin server. It is used by the server +to indicate which headers it used when selecting a representation of a +resource in a content negotiation algorithm.

+

The vary header should be set on a 304 Not Modified response exactly +like it would have been set on an equivalent 200 OK response.

+
\ No newline at end of file diff --git a/awc/http/header/constant.VIA.html b/awc/http/header/constant.VIA.html new file mode 100644 index 000000000..8dda731a8 --- /dev/null +++ b/awc/http/header/constant.VIA.html @@ -0,0 +1,7 @@ +VIA in awc::http::header - Rust

Constant awc::http::header::VIA

source ·
pub const VIA: HeaderName;
Expand description

Added by proxies to track routing.

+

The via general header is added by proxies, both forward and reverse +proxies, and can appear in the request headers and the response headers. +It is used for tracking message forwards, avoiding request loops, and +identifying the protocol capabilities of senders along the +request/response chain.

+
\ No newline at end of file diff --git a/awc/http/header/constant.WARNING.html b/awc/http/header/constant.WARNING.html new file mode 100644 index 000000000..61a995942 --- /dev/null +++ b/awc/http/header/constant.WARNING.html @@ -0,0 +1,6 @@ +WARNING in awc::http::header - Rust

Constant awc::http::header::WARNING

source ·
pub const WARNING: HeaderName;
Expand description

General HTTP header contains information about possible problems with +the status of the message.

+

More than one warning header may appear in a response. Warning header +fields can in general be applied to any message, however some warn-codes +are specific to caches and can only be applied to response messages.

+
\ No newline at end of file diff --git a/awc/http/header/constant.WWW_AUTHENTICATE.html b/awc/http/header/constant.WWW_AUTHENTICATE.html new file mode 100644 index 000000000..9c77ac93c --- /dev/null +++ b/awc/http/header/constant.WWW_AUTHENTICATE.html @@ -0,0 +1,3 @@ +WWW_AUTHENTICATE in awc::http::header - Rust

Constant awc::http::header::WWW_AUTHENTICATE

source ·
pub const WWW_AUTHENTICATE: HeaderName;
Expand description

Defines the authentication method that should be used to gain access to +a resource.

+
\ No newline at end of file diff --git a/awc/http/header/constant.X_CONTENT_TYPE_OPTIONS.html b/awc/http/header/constant.X_CONTENT_TYPE_OPTIONS.html new file mode 100644 index 000000000..c0fafa49a --- /dev/null +++ b/awc/http/header/constant.X_CONTENT_TYPE_OPTIONS.html @@ -0,0 +1,11 @@ +X_CONTENT_TYPE_OPTIONS in awc::http::header - Rust

Constant awc::http::header::X_CONTENT_TYPE_OPTIONS

source ·
pub const X_CONTENT_TYPE_OPTIONS: HeaderName;
Expand description

Marker used by the server to indicate that the MIME types advertised in +the content-type headers should not be changed and be followed.

+

This allows to opt-out of MIME type sniffing, or, in other words, it is +a way to say that the webmasters knew what they were doing.

+

This header was introduced by Microsoft in IE 8 as a way for webmasters +to block content sniffing that was happening and could transform +non-executable MIME types into executable MIME types. Since then, other +browsers have introduced it, even if their MIME sniffing algorithms were +less aggressive.

+

Site security testers usually expect this header to be set.

+
\ No newline at end of file diff --git a/awc/http/header/constant.X_DNS_PREFETCH_CONTROL.html b/awc/http/header/constant.X_DNS_PREFETCH_CONTROL.html new file mode 100644 index 000000000..fceedc6df --- /dev/null +++ b/awc/http/header/constant.X_DNS_PREFETCH_CONTROL.html @@ -0,0 +1,10 @@ +X_DNS_PREFETCH_CONTROL in awc::http::header - Rust

Constant awc::http::header::X_DNS_PREFETCH_CONTROL

source ·
pub const X_DNS_PREFETCH_CONTROL: HeaderName;
Expand description

Controls DNS prefetching.

+

The x-dns-prefetch-control HTTP response header controls DNS +prefetching, a feature by which browsers proactively perform domain name +resolution on both links that the user may choose to follow as well as +URLs for items referenced by the document, including images, CSS, +JavaScript, and so forth.

+

This prefetching is performed in the background, so that the DNS is +likely to have been resolved by the time the referenced items are +needed. This reduces latency when the user clicks a link.

+
\ No newline at end of file diff --git a/awc/http/header/constant.X_FORWARDED_FOR.html b/awc/http/header/constant.X_FORWARDED_FOR.html new file mode 100644 index 000000000..252d5152e --- /dev/null +++ b/awc/http/header/constant.X_FORWARDED_FOR.html @@ -0,0 +1,3 @@ +X_FORWARDED_FOR in awc::http::header - Rust

Constant awc::http::header::X_FORWARDED_FOR

pub const X_FORWARDED_FOR: HeaderName;
Expand description

Request header (de-facto standard) for identifying the originating IP address of a client +connecting to a web server through a proxy server.

+
\ No newline at end of file diff --git a/awc/http/header/constant.X_FORWARDED_HOST.html b/awc/http/header/constant.X_FORWARDED_HOST.html new file mode 100644 index 000000000..6174cffcf --- /dev/null +++ b/awc/http/header/constant.X_FORWARDED_HOST.html @@ -0,0 +1,3 @@ +X_FORWARDED_HOST in awc::http::header - Rust

Constant awc::http::header::X_FORWARDED_HOST

pub const X_FORWARDED_HOST: HeaderName;
Expand description

Request header (de-facto standard) for identifying the original host requested by the client in +the Host HTTP request header.

+
\ No newline at end of file diff --git a/awc/http/header/constant.X_FORWARDED_PROTO.html b/awc/http/header/constant.X_FORWARDED_PROTO.html new file mode 100644 index 000000000..18e57fd67 --- /dev/null +++ b/awc/http/header/constant.X_FORWARDED_PROTO.html @@ -0,0 +1,3 @@ +X_FORWARDED_PROTO in awc::http::header - Rust

Constant awc::http::header::X_FORWARDED_PROTO

pub const X_FORWARDED_PROTO: HeaderName;
Expand description

Request header (de-facto standard) for identifying the protocol that a client used to connect to +your proxy or load balancer.

+
\ No newline at end of file diff --git a/awc/http/header/constant.X_FRAME_OPTIONS.html b/awc/http/header/constant.X_FRAME_OPTIONS.html new file mode 100644 index 000000000..10cf8fae9 --- /dev/null +++ b/awc/http/header/constant.X_FRAME_OPTIONS.html @@ -0,0 +1,7 @@ +X_FRAME_OPTIONS in awc::http::header - Rust

Constant awc::http::header::X_FRAME_OPTIONS

source ·
pub const X_FRAME_OPTIONS: HeaderName;
Expand description

Indicates whether or not a browser should be allowed to render a page in +a frame.

+

Sites can use this to avoid clickjacking attacks, by ensuring that their +content is not embedded into other sites.

+

The added security is only provided if the user accessing the document +is using a browser supporting x-frame-options.

+
\ No newline at end of file diff --git a/awc/http/header/constant.X_XSS_PROTECTION.html b/awc/http/header/constant.X_XSS_PROTECTION.html new file mode 100644 index 000000000..b3c04bacb --- /dev/null +++ b/awc/http/header/constant.X_XSS_PROTECTION.html @@ -0,0 +1,9 @@ +X_XSS_PROTECTION in awc::http::header - Rust

Constant awc::http::header::X_XSS_PROTECTION

source ·
pub const X_XSS_PROTECTION: HeaderName;
Expand description

Stop pages from loading when an XSS attack is detected.

+

The HTTP X-XSS-Protection response header is a feature of Internet +Explorer, Chrome and Safari that stops pages from loading when they +detect reflected cross-site scripting (XSS) attacks. Although these +protections are largely unnecessary in modern browsers when sites +implement a strong Content-Security-Policy that disables the use of +inline JavaScript (‘unsafe-inline’), they can still provide protections +for users of older web browsers that don’t yet support CSP.

+
\ No newline at end of file diff --git a/awc/http/header/enum.Charset.html b/awc/http/header/enum.Charset.html new file mode 100644 index 000000000..fcacc9168 --- /dev/null +++ b/awc/http/header/enum.Charset.html @@ -0,0 +1,79 @@ +Charset in awc::http::header - Rust

Enum awc::http::header::Charset

pub enum Charset {
+
Show 25 variants Us_Ascii, + Iso_8859_1, + Iso_8859_2, + Iso_8859_3, + Iso_8859_4, + Iso_8859_5, + Iso_8859_6, + Iso_8859_7, + Iso_8859_8, + Iso_8859_9, + Iso_8859_10, + Shift_Jis, + Euc_Jp, + Iso_2022_Kr, + Euc_Kr, + Iso_2022_Jp, + Iso_2022_Jp_2, + Iso_8859_6_E, + Iso_8859_6_I, + Iso_8859_8_E, + Iso_8859_8_I, + Gb2312, + Big5, + Koi8_R, + Ext(String), +
}
Expand description

A MIME character set.

+

The string representation is normalized to upper case.

+

See http://www.iana.org/assignments/character-sets/character-sets.xhtml.

+

Variants§

§

Us_Ascii

US ASCII

+
§

Iso_8859_1

ISO-8859-1

+
§

Iso_8859_2

ISO-8859-2

+
§

Iso_8859_3

ISO-8859-3

+
§

Iso_8859_4

ISO-8859-4

+
§

Iso_8859_5

ISO-8859-5

+
§

Iso_8859_6

ISO-8859-6

+
§

Iso_8859_7

ISO-8859-7

+
§

Iso_8859_8

ISO-8859-8

+
§

Iso_8859_9

ISO-8859-9

+
§

Iso_8859_10

ISO-8859-10

+
§

Shift_Jis

Shift_JIS

+
§

Euc_Jp

EUC-JP

+
§

Iso_2022_Kr

ISO-2022-KR

+
§

Euc_Kr

EUC-KR

+
§

Iso_2022_Jp

ISO-2022-JP

+
§

Iso_2022_Jp_2

ISO-2022-JP-2

+
§

Iso_8859_6_E

ISO-8859-6-E

+
§

Iso_8859_6_I

ISO-8859-6-I

+
§

Iso_8859_8_E

ISO-8859-8-E

+
§

Iso_8859_8_I

ISO-8859-8-I

+
§

Gb2312

GB2312

+
§

Big5

Big5

+
§

Koi8_R

KOI8-R

+
§

Ext(String)

An arbitrary charset specified as a string

+

Trait Implementations§

§

impl Clone for Charset

§

fn clone(&self) -> Charset

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Charset

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for Charset

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl FromStr for Charset

§

type Err = Error

The associated error which can be returned from parsing.
§

fn from_str(s: &str) -> Result<Charset, Error>

Parses a string s to return a value of this type. Read more
§

impl PartialEq for Charset

§

fn eq(&self, other: &Charset) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Eq for Charset

§

impl StructuralPartialEq for Charset

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/enum.ContentEncoding.html b/awc/http/header/enum.ContentEncoding.html new file mode 100644 index 000000000..da0c4176e --- /dev/null +++ b/awc/http/header/enum.ContentEncoding.html @@ -0,0 +1,54 @@ +ContentEncoding in awc::http::header - Rust

Enum awc::http::header::ContentEncoding

#[non_exhaustive]
pub enum ContentEncoding { + Identity, + Brotli, + Deflate, + Gzip, + Zstd, +}
Expand description

Represents a supported content encoding.

+

Includes a commonly-used subset of media types appropriate for use as HTTP content encodings. +See IANA HTTP Content Coding Registry.

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

Identity

Indicates the no-op identity encoding.

+

I.e., no compression or modification.

+
§

Brotli

A format using the Brotli algorithm.

+
§

Deflate

A format using the zlib structure with deflate algorithm.

+
§

Gzip

Gzip algorithm.

+
§

Zstd

Zstd algorithm.

+

Implementations§

§

impl ContentEncoding

pub const fn as_str(self) -> &'static str

Convert content encoding to string.

+

pub const fn to_header_value(self) -> HeaderValue

Convert content encoding to header value.

+

Trait Implementations§

§

impl Clone for ContentEncoding

§

fn clone(&self) -> ContentEncoding

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for ContentEncoding

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for ContentEncoding

§

fn default() -> ContentEncoding

Returns the “default value” for a type. Read more
§

impl FromStr for ContentEncoding

§

type Err = ContentEncodingParseError

The associated error which can be returned from parsing.
§

fn from_str( + enc: &str +) -> Result<ContentEncoding, <ContentEncoding as FromStr>::Err>

Parses a string s to return a value of this type. Read more
§

impl Hash for ContentEncoding

§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl Header for ContentEncoding

§

fn name() -> HeaderName

Returns the name of the header field.
§

fn parse<T>(msg: &T) -> Result<ContentEncoding, ParseError>
where + T: HttpMessage,

Parse the header from a HTTP message.
§

impl PartialEq for ContentEncoding

§

fn eq(&self, other: &ContentEncoding) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl TryFrom<&str> for ContentEncoding

§

type Error = ContentEncodingParseError

The type returned in the event of a conversion error.
§

fn try_from( + val: &str +) -> Result<ContentEncoding, <ContentEncoding as TryFrom<&str>>::Error>

Performs the conversion.
§

impl TryIntoHeaderValue for ContentEncoding

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
§

fn try_into_value( + self +) -> Result<HeaderValue, <ContentEncoding as TryIntoHeaderValue>::Error>

Try to convert value to a HeaderValue.
§

impl Copy for ContentEncoding

§

impl Eq for ContentEncoding

§

impl StructuralPartialEq for ContentEncoding

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> TryIntoHeaderPair for T
where + T: Header,

§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/fn.fmt_comma_delimited.html b/awc/http/header/fn.fmt_comma_delimited.html new file mode 100644 index 000000000..871d5818f --- /dev/null +++ b/awc/http/header/fn.fmt_comma_delimited.html @@ -0,0 +1,6 @@ +fmt_comma_delimited in awc::http::header - Rust

Function awc::http::header::fmt_comma_delimited

pub fn fmt_comma_delimited<T>(
+    f: &mut Formatter<'_>,
+    parts: &[T]
+) -> Result<(), Error>
where + T: Display,
Expand description

Format an array into a comma-delimited string.

+
\ No newline at end of file diff --git a/awc/http/header/fn.from_comma_delimited.html b/awc/http/header/fn.from_comma_delimited.html new file mode 100644 index 000000000..992e94ce4 --- /dev/null +++ b/awc/http/header/fn.from_comma_delimited.html @@ -0,0 +1,4 @@ +from_comma_delimited in awc::http::header - Rust

Function awc::http::header::from_comma_delimited

pub fn from_comma_delimited<'a, I, T>(all: I) -> Result<Vec<T>, ParseError>
where + I: Iterator<Item = &'a HeaderValue> + 'a, + T: FromStr,
Expand description

Reads a comma-delimited raw header into a Vec.

+
\ No newline at end of file diff --git a/awc/http/header/fn.from_one_raw_str.html b/awc/http/header/fn.from_one_raw_str.html new file mode 100644 index 000000000..a7dc2449c --- /dev/null +++ b/awc/http/header/fn.from_one_raw_str.html @@ -0,0 +1,3 @@ +from_one_raw_str in awc::http::header - Rust

Function awc::http::header::from_one_raw_str

pub fn from_one_raw_str<T>(val: Option<&HeaderValue>) -> Result<T, ParseError>
where + T: FromStr,
Expand description

Reads a single string when parsing a header.

+
\ No newline at end of file diff --git a/awc/http/header/fn.http_percent_encode.html b/awc/http/header/fn.http_percent_encode.html new file mode 100644 index 000000000..3dbfe1b6d --- /dev/null +++ b/awc/http/header/fn.http_percent_encode.html @@ -0,0 +1,5 @@ +http_percent_encode in awc::http::header - Rust

Function awc::http::header::http_percent_encode

pub fn http_percent_encode(
+    f: &mut Formatter<'_>,
+    bytes: &[u8]
+) -> Result<(), Error>
Expand description

Percent encode a sequence of bytes with a character set defined in RFC 5987 §3.2.

+
\ No newline at end of file diff --git a/awc/http/header/fn.parse_extended_value.html b/awc/http/header/fn.parse_extended_value.html new file mode 100644 index 000000000..6b37543ea --- /dev/null +++ b/awc/http/header/fn.parse_extended_value.html @@ -0,0 +1,30 @@ +parse_extended_value in awc::http::header - Rust

Function awc::http::header::parse_extended_value

pub fn parse_extended_value(val: &str) -> Result<ExtendedValue, ParseError>
Expand description

Parses extended header parameter values (ext-value), as defined +in RFC 5987 §3.2.

+

Extended values are denoted by parameter names that end with *.

+

§ABNF

ext-value     = charset  "'" [ language ] "'" value-chars
+              ; like RFC 2231's <extended-initial-value>
+              ; (see [RFC 2231 §7])
+
+charset       = "UTF-8" / "ISO-8859-1" / mime-charset
+
+mime-charset  = 1*mime-charsetc
+mime-charsetc = ALPHA / DIGIT
+              / "!" / "#" / "$" / "%" / "&"
+              / "+" / "-" / "^" / "_" / "`"
+              / "{" / "}" / "~"
+              ; as <mime-charset> in [RFC 2978 §2.3]
+              ; except that the single quote is not included
+              ; SHOULD be registered in the IANA charset registry
+
+language      = <Language-Tag, defined in [RFC 5646 §2.1]>
+
+value-chars   = *( pct-encoded / attr-char )
+
+pct-encoded   = "%" HEXDIG HEXDIG
+              ; see [RFC 3986 §2.1]
+
+attr-char     = ALPHA / DIGIT
+              / "!" / "#" / "$" / "&" / "+" / "-" / "."
+              / "^" / "_" / "`" / "|" / "~"
+              ; token except ( "*" / "'" / "%" )
+
\ No newline at end of file diff --git a/awc/http/header/fn.q.html b/awc/http/header/fn.q.html new file mode 100644 index 000000000..dea65cc40 --- /dev/null +++ b/awc/http/header/fn.q.html @@ -0,0 +1,21 @@ +q in awc::http::header - Rust

Function awc::http::header::q

pub fn q<T>(quality: T) -> Quality
where + T: TryInto<Quality>, + <T as TryInto<Quality>>::Error: Debug,
Expand description

Convenience function to create a Quality from an f32 (0.0–1.0).

+

Not recommended for use with user input. Rely on the TryFrom impls where possible.

+

§Panics

+

Panics if value is out of range.

+

§Examples

+
let q1 = q(1.0);
+assert_eq!(q1, Quality::MAX);
+
+let q2 = q(0.001);
+assert_eq!(q2, Quality::MIN);
+
+let q3 = q(0.0);
+assert_eq!(q3, Quality::ZERO);
+
+let q4 = q(0.42);
+

An out-of-range f32 quality will panic.

+ +
let _q2 = q(1.42);
+
\ No newline at end of file diff --git a/awc/http/header/index.html b/awc/http/header/index.html new file mode 100644 index 000000000..bb375fea9 --- /dev/null +++ b/awc/http/header/index.html @@ -0,0 +1,69 @@ +awc::http::header - Rust

Module awc::http::header

Expand description

Pre-defined HeaderNames, traits for parsing and conversion, and other header utility methods.

+

Modules§

Structs§

Enums§

Constants§

  • Advertises which content types the client is able to understand.
  • Advertises which character set the client is able to understand.
  • Advertises which content encoding the client is able to understand.
  • Advertises which languages the client is able to understand.
  • Marker used by the server to advertise partial request support.
  • Preflight response indicating if the response to the request can be +exposed to the page.
  • Preflight response indicating permitted HTTP headers.
  • Preflight header response indicating permitted access methods.
  • Indicates whether the response can be shared with resources with the +given origin.
  • Indicates which headers can be exposed as part of the response by +listing their names.
  • Indicates how long the results of a preflight request can be cached.
  • Informs the server which HTTP headers will be used when an actual +request is made.
  • Informs the server know which HTTP method will be used when the actual +request is made.
  • Indicates the time in seconds the object has been in a proxy cache.
  • Lists the set of methods support by a resource.
  • Advertises the availability of alternate services to clients.
  • Contains the credentials to authenticate a user agent with a server.
  • Specifies directives for caching mechanisms in both requests and +responses.
  • Response header field that indicates how caches have handled that response and its corresponding +request.
  • Response header field that allows origin servers to control the behavior of CDN caches +interposed between them and clients separately from other caches that might handle the response.
  • Controls whether or not the network connection stays open after the +current transaction finishes.
  • Indicates if the content is expected to be displayed inline.
  • Used to compress the media-type.
  • Used to describe the languages intended for the audience.
  • Indicates the size of the entity-body.
  • Indicates an alternate location for the returned data.
  • Indicates where in a full body message a partial message belongs.
  • Allows controlling resources the user agent is allowed to load for a +given page.
  • Allows experimenting with policies by monitoring their effects.
  • Used to indicate the media type of the resource.
  • Contains stored HTTP cookies previously sent by the server with the +Set-Cookie header.
  • Response header that prevents a document from loading any cross-origin resources that don’t +explicitly grant the document permission (using CORP or CORS).
  • Response header that allows you to ensure a top-level document does not share a browsing context +group with cross-origin documents.
  • Response header that conveys a desire that the browser blocks no-cors cross-origin/cross-site +requests to the given resource.
  • Contains the date and time at which the message was originated.
  • Indicates the client’s tracking preference.
  • Identifier for a specific version of a resource.
  • Indicates expectations that need to be fulfilled by the server in order +to properly handle the request.
  • Contains the date/time after which the response is considered stale.
  • Contains information from the client-facing side of proxy servers that +is altered or lost when a proxy is involved in the path of the request.
  • Contains an Internet email address for a human user who controls the +requesting user agent.
  • Specifies the domain name of the server and (optionally) the TCP port +number on which the server is listening.
  • Makes a request conditional based on the E-Tag.
  • Makes a request conditional based on the modification date.
  • Makes a request conditional based on the E-Tag.
  • Makes a request conditional based on range.
  • Makes the request conditional based on the last modification date.
  • Content-Types that are acceptable for the response.
  • Allows the server to point an interested client to another resource +containing metadata about the requested resource.
  • Indicates the URL to redirect a page to.
  • Indicates the max number of intermediaries the request should be sent +through.
  • Indicates where a fetch originates from.
  • Response header that provides a mechanism to allow and deny the use of browser features in a +document or within any <iframe> elements in the document.
  • HTTP/1.0 header usually used for backwards compatibility.
  • Defines the authentication method that should be used to gain access to +a proxy.
  • Contains the credentials to authenticate a user agent to a proxy server.
  • Associates a specific cryptographic public key with a certain server.
  • Sends reports of pinning violation to the report-uri specified in the +header.
  • Indicates the part of a document that the server should return.
  • Contains the address of the previous web page from which a link to the +currently requested page was followed.
  • Governs which referrer information should be included with requests +made.
  • Informs the web browser that the current page or frame should be +refreshed.
  • The Retry-After response HTTP header indicates how long the user agent +should wait before making a follow-up request. There are two main cases +this header is used:
  • The |Sec-WebSocket-Accept| header field is used in the WebSocket +opening handshake. It is sent from the server to the client to +confirm that the server is willing to initiate the WebSocket +connection.
  • The |Sec-WebSocket-Extensions| header field is used in the WebSocket +opening handshake. It is initially sent from the client to the +server, and then subsequently sent from the server to the client, to +agree on a set of protocol-level extensions to use for the duration +of the connection.
  • The |Sec-WebSocket-Key| header field is used in the WebSocket opening +handshake. It is sent from the client to the server to provide part +of the information used by the server to prove that it received a +valid WebSocket opening handshake. This helps ensure that the server +does not accept connections from non-WebSocket clients (e.g., HTTP +clients) that are being abused to send data to unsuspecting WebSocket +servers.
  • The |Sec-WebSocket-Protocol| header field is used in the WebSocket +opening handshake. It is sent from the client to the server and back +from the server to the client to confirm the subprotocol of the +connection. This enables scripts to both select a subprotocol and be +sure that the server agreed to serve that subprotocol.
  • The |Sec-WebSocket-Version| header field is used in the WebSocket +opening handshake. It is sent from the client to the server to +indicate the protocol version of the connection. This enables +servers to correctly interpret the opening handshake and subsequent +data being sent from the data, and close the connection if the server +cannot interpret that data in a safe manner.
  • Contains information about the software used by the origin server to +handle the request.
  • Used to send cookies from the server to the user agent.
  • Tells the client to communicate with HTTPS instead of using HTTP.
  • Informs the server of transfer encodings willing to be accepted as part +of the response.
  • Allows the sender to include additional fields at the end of chunked +messages.
  • Specifies the form of encoding used to safely transfer the entity to the +client.
  • Used as part of the exchange to upgrade the protocol.
  • Sends a signal to the server expressing the client’s preference for an +encrypted and authenticated response.
  • Contains a string that allows identifying the requesting client’s +software.
  • Determines how to match future requests with cached responses.
  • Added by proxies to track routing.
  • General HTTP header contains information about possible problems with +the status of the message.
  • Defines the authentication method that should be used to gain access to +a resource.
  • Marker used by the server to indicate that the MIME types advertised in +the content-type headers should not be changed and be followed.
  • Controls DNS prefetching.
  • Request header (de-facto standard) for identifying the originating IP address of a client +connecting to a web server through a proxy server.
  • Request header (de-facto standard) for identifying the original host requested by the client in +the Host HTTP request header.
  • Request header (de-facto standard) for identifying the protocol that a client used to connect to +your proxy or load balancer.
  • Indicates whether or not a browser should be allowed to render a page in +a frame.
  • Stop pages from loading when an XSS attack is detected.

Traits§

Functions§

\ No newline at end of file diff --git a/awc/http/header/map/index.html b/awc/http/header/map/index.html new file mode 100644 index 000000000..b70da9a24 --- /dev/null +++ b/awc/http/header/map/index.html @@ -0,0 +1,2 @@ +awc::http::header::map - Rust

Module awc::http::header::map

Expand description

A multi-value HeaderMap and its iterators.

+

Structs§

  • Iterator over drained name-value pairs.
  • A multi-map of HTTP headers.
  • Iterator over owned name-value pairs.
  • Iterator over borrowed name-value pairs.
  • Iterator over all names in the map.
  • Iterator over removed, owned values with the same associated name.
\ No newline at end of file diff --git a/awc/http/header/map/sidebar-items.js b/awc/http/header/map/sidebar-items.js new file mode 100644 index 000000000..d8f41164a --- /dev/null +++ b/awc/http/header/map/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Drain","HeaderMap","IntoIter","Iter","Keys","Removed"]}; \ No newline at end of file diff --git a/awc/http/header/map/struct.Drain.html b/awc/http/header/map/struct.Drain.html new file mode 100644 index 000000000..25efbc449 --- /dev/null +++ b/awc/http/header/map/struct.Drain.html @@ -0,0 +1,203 @@ +Drain in awc::http::header::map - Rust

Struct awc::http::header::map::Drain

pub struct Drain<'a> { /* private fields */ }
Expand description

Iterator over drained name-value pairs.

+

Iterator items are (Option<HeaderName>, HeaderValue) to avoid cloning.

+

Trait Implementations§

§

impl<'a> Debug for Drain<'a>

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl ExactSizeIterator for Drain<'_>

1.0.0 · source§

fn len(&self) -> usize

Returns the exact remaining length of the iterator. Read more
source§

fn is_empty(&self) -> bool

🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
§

impl<'a> Iterator for Drain<'a>

§

type Item = (Option<HeaderName>, HeaderValue)

The type of the elements being iterated over.
§

fn next(&mut self) -> Option<<Drain<'a> as Iterator>::Item>

Advances the iterator and returns the next value. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usize
where + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>
where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
§

impl FusedIterator for Drain<'_>

Auto Trait Implementations§

§

impl<'a> !Freeze for Drain<'a>

§

impl<'a> RefUnwindSafe for Drain<'a>

§

impl<'a> Send for Drain<'a>

§

impl<'a> Sync for Drain<'a>

§

impl<'a> Unpin for Drain<'a>

§

impl<'a> UnwindSafe for Drain<'a>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for I
where + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<I> IteratorRandom for I
where + I: Iterator,

source§

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where + R: Rng + ?Sized,

Collects values at random from the iterator into a supplied buffer +until that buffer is filled. Read more
source§

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where + R: Rng + ?Sized,

Available on crate feature alloc only.
Collects amount values at random from the iterator into a vector. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/map/struct.HeaderMap.html b/awc/http/header/map/struct.HeaderMap.html new file mode 100644 index 000000000..9fa944dc4 --- /dev/null +++ b/awc/http/header/map/struct.HeaderMap.html @@ -0,0 +1,330 @@ +HeaderMap in awc::http::header::map - Rust

Struct awc::http::header::map::HeaderMap

pub struct HeaderMap { /* private fields */ }
Expand description

A multi-map of HTTP headers.

+

HeaderMap is a “multi-map” of HeaderName to one or more HeaderValues.

+

§Examples

+
use actix_http::header::{self, HeaderMap, HeaderValue};
+
+let mut map = HeaderMap::new();
+
+map.insert(header::CONTENT_TYPE, HeaderValue::from_static("text/plain"));
+map.insert(header::ORIGIN, HeaderValue::from_static("example.com"));
+
+assert!(map.contains_key(header::CONTENT_TYPE));
+assert!(map.contains_key(header::ORIGIN));
+
+let mut removed = map.remove(header::ORIGIN);
+assert_eq!(removed.next().unwrap(), "example.com");
+
+assert!(!map.contains_key(header::ORIGIN));
+

Implementations§

§

impl HeaderMap

pub fn new() -> HeaderMap

Create an empty HeaderMap.

+

The map will be created without any capacity; this function will not allocate.

+
§Examples
+
let map = HeaderMap::new();
+
+assert!(map.is_empty());
+assert_eq!(0, map.capacity());
+

pub fn with_capacity(capacity: usize) -> HeaderMap

Create an empty HeaderMap with the specified capacity.

+

The map will be able to hold at least capacity elements without needing to reallocate. +If capacity is 0, the map will be created without allocating.

+
§Examples
+
let map = HeaderMap::with_capacity(16);
+
+assert!(map.is_empty());
+assert!(map.capacity() >= 16);
+

pub fn len(&self) -> usize

Returns the number of values stored in the map.

+

See also: len_keys.

+
§Examples
+
let mut map = HeaderMap::new();
+assert_eq!(map.len(), 0);
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+assert_eq!(map.len(), 2);
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+assert_eq!(map.len(), 3);
+

pub fn len_keys(&self) -> usize

Returns the number of keys stored in the map.

+

The number of values stored will be at least this number. See also: Self::len.

+
§Examples
+
let mut map = HeaderMap::new();
+assert_eq!(map.len_keys(), 0);
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+assert_eq!(map.len_keys(), 2);
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+assert_eq!(map.len_keys(), 2);
+

pub fn is_empty(&self) -> bool

Returns true if the map contains no elements.

+
§Examples
+
let mut map = HeaderMap::new();
+assert!(map.is_empty());
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(!map.is_empty());
+

pub fn clear(&mut self)

Clears the map, removing all name-value pairs.

+

Keeps the allocated memory for reuse.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+assert_eq!(map.len(), 2);
+
+map.clear();
+assert!(map.is_empty());
+

pub fn get(&self, key: impl AsHeaderName) -> Option<&HeaderValue>

Returns a reference to the first value associated with a header name.

+

Returns None if there is no value associated with the key.

+

Even when multiple values are associated with the key, the “first” one is returned but is +not guaranteed to be chosen with any particular order; though, the returned item will be +consistent for each call to get if the map has not changed.

+

See also: get_all.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+
+let cookie = map.get(header::SET_COOKIE).unwrap();
+assert_eq!(cookie, "one=1");
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+assert_eq!(map.get(header::SET_COOKIE).unwrap(), "one=1");
+
+assert_eq!(map.get(header::SET_COOKIE), map.get("set-cookie"));
+assert_eq!(map.get(header::SET_COOKIE), map.get("Set-Cookie"));
+
+assert!(map.get(header::HOST).is_none());
+assert!(map.get("INVALID HEADER NAME").is_none());
+

pub fn get_mut(&mut self, key: impl AsHeaderName) -> Option<&mut HeaderValue>

Returns a mutable reference to the first value associated a header name.

+

Returns None if there is no value associated with the key.

+

Even when multiple values are associated with the key, the “first” one is returned but is +not guaranteed to be chosen with any particular order; though, the returned item will be +consistent for each call to get_mut if the map has not changed.

+

See also: get_all.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+
+let mut cookie = map.get_mut(header::SET_COOKIE).unwrap();
+assert_eq!(cookie, "one=1");
+
+*cookie = HeaderValue::from_static("three=3");
+assert_eq!(map.get(header::SET_COOKIE).unwrap(), "three=3");
+
+assert!(map.get(header::HOST).is_none());
+assert!(map.get("INVALID HEADER NAME").is_none());
+

pub fn get_all(&self, key: impl AsHeaderName) -> Iter<'_, HeaderValue>

Returns an iterator over all values associated with a header name.

+

The returned iterator does not incur any allocations and will yield no items if there are no +values associated with the key. Iteration order is guaranteed to be the same as +insertion order.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut none_iter = map.get_all(header::ORIGIN);
+assert!(none_iter.next().is_none());
+
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let mut set_cookies_iter = map.get_all(header::SET_COOKIE);
+assert_eq!(set_cookies_iter.next().unwrap(), "one=1");
+assert_eq!(set_cookies_iter.next().unwrap(), "two=2");
+assert!(set_cookies_iter.next().is_none());
+

pub fn contains_key(&self, key: impl AsHeaderName) -> bool

Returns true if the map contains a value for the specified key.

+

Invalid header names will simply return false.

+
§Examples
+
let mut map = HeaderMap::new();
+assert!(!map.contains_key(header::ACCEPT));
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(map.contains_key(header::ACCEPT));
+

pub fn insert(&mut self, key: HeaderName, val: HeaderValue) -> Removed

Inserts (overrides) a name-value pair in the map.

+

If the map already contained this key, the new value is associated with the key and all +previous values are removed and returned as a Removed iterator. The key is not updated; +this matters for types that can be == without being identical.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(map.contains_key(header::ACCEPT));
+assert_eq!(map.len(), 1);
+
+let mut removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/csv"));
+assert_eq!(removed.next().unwrap(), "text/plain");
+assert!(removed.next().is_none());
+
+assert_eq!(map.len(), 1);
+

A convenience method is provided on the returned iterator to check if the insertion replaced +any values.

+ +
let mut map = HeaderMap::new();
+
+let removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(removed.is_empty());
+
+let removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/html"));
+assert!(!removed.is_empty());
+

pub fn append(&mut self, key: HeaderName, value: HeaderValue)

Appends a name-value pair to the map.

+

If the map already contained this key, the new value is added to the list of values +currently associated with the key. The key is not updated; this matters for types that can +be == without being identical.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.append(header::HOST, HeaderValue::from_static("example.com"));
+assert_eq!(map.len(), 1);
+
+map.append(header::ACCEPT, HeaderValue::from_static("text/csv"));
+assert_eq!(map.len(), 2);
+
+map.append(header::ACCEPT, HeaderValue::from_static("text/html"));
+assert_eq!(map.len(), 3);
+

pub fn remove(&mut self, key: impl AsHeaderName) -> Removed

Removes all headers for a particular header name from the map.

+

Providing an invalid header names (as a string argument) will have no effect and return +without error.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=2"));
+
+assert_eq!(map.len(), 2);
+
+let mut removed = map.remove(header::SET_COOKIE);
+assert_eq!(removed.next().unwrap(), "one=1");
+assert_eq!(removed.next().unwrap(), "one=2");
+assert!(removed.next().is_none());
+
+assert!(map.is_empty());
+

A convenience method is provided on the returned iterator to check if the remove call +actually removed any values.

+ +
let mut map = HeaderMap::new();
+
+let removed = map.remove("accept");
+assert!(removed.is_empty());
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/html"));
+let removed = map.remove("accept");
+assert!(!removed.is_empty());
+

pub fn capacity(&self) -> usize

Returns the number of single-value headers the map can hold without needing to reallocate.

+

Since this is a multi-value map, the actual capacity is much larger when considering +each header name can be associated with an arbitrary number of values. The effect is that +the size of len may be greater than capacity since it counts all the values. +Conversely, len_keys will never be larger than capacity.

+
§Examples
+
let map = HeaderMap::with_capacity(16);
+
+assert!(map.is_empty());
+assert!(map.capacity() >= 16);
+

pub fn reserve(&mut self, additional: usize)

Reserves capacity for at least additional more headers to be inserted in the map.

+

The header map may reserve more space to avoid frequent reallocations. Additional capacity +only considers single-value headers.

+
§Panics
+

Panics if the new allocation size overflows usize.

+
§Examples
+
let mut map = HeaderMap::with_capacity(2);
+assert!(map.capacity() >= 2);
+
+map.reserve(100);
+assert!(map.capacity() >= 102);
+
+assert!(map.is_empty());
+

pub fn iter(&self) -> Iter<'_>

An iterator over all name-value pairs.

+

Names will be yielded for each associated value. So, if a key has 3 associated values, it +will be yielded 3 times. The iteration order should be considered arbitrary.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut iter = map.iter();
+assert!(iter.next().is_none());
+
+map.append(header::HOST, HeaderValue::from_static("duck.com"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let mut iter = map.iter();
+assert!(iter.next().is_some());
+assert!(iter.next().is_some());
+assert!(iter.next().is_some());
+assert!(iter.next().is_none());
+
+let pairs = map.iter().collect::<Vec<_>>();
+assert!(pairs.contains(&(&header::HOST, &HeaderValue::from_static("duck.com"))));
+assert!(pairs.contains(&(&header::SET_COOKIE, &HeaderValue::from_static("one=1"))));
+assert!(pairs.contains(&(&header::SET_COOKIE, &HeaderValue::from_static("two=2"))));
+

pub fn keys(&self) -> Keys<'_>

An iterator over all contained header names.

+

Each name will only be yielded once even if it has multiple associated values. The iteration +order should be considered arbitrary.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut iter = map.keys();
+assert!(iter.next().is_none());
+
+map.append(header::HOST, HeaderValue::from_static("duck.com"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let keys = map.keys().cloned().collect::<Vec<_>>();
+assert_eq!(keys.len(), 2);
+assert!(keys.contains(&header::HOST));
+assert!(keys.contains(&header::SET_COOKIE));
+

pub fn retain<F>(&mut self, retain_fn: F)
where + F: FnMut(&HeaderName, &mut HeaderValue) -> bool,

Retains only the headers specified by the predicate.

+

In other words, removes all headers (name, val) for which retain_fn(&name, &mut val) +returns false.

+

The order in which headers are visited should be considered arbitrary.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.append(header::HOST, HeaderValue::from_static("duck.com"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+map.retain(|name, val| val.as_bytes().starts_with(b"one"));
+
+assert_eq!(map.len(), 1);
+assert!(map.contains_key(&header::SET_COOKIE));
+

pub fn drain(&mut self) -> Drain<'_>

Clears the map, returning all name-value sets as an iterator.

+

Header names will only be yielded for the first value in each set. All items that are +yielded without a name and after an item with a name are associated with that same name. +The first item will always contain a name.

+

Keeps the allocated memory for reuse.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut iter = map.drain();
+assert!(iter.next().is_none());
+drop(iter);
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let mut iter = map.drain();
+assert_eq!(iter.next().unwrap(), (Some(header::SET_COOKIE), HeaderValue::from_static("one=1")));
+assert_eq!(iter.next().unwrap(), (None, HeaderValue::from_static("two=2")));
+drop(iter);
+
+assert!(map.is_empty());
+

Trait Implementations§

§

impl Clone for HeaderMap

§

fn clone(&self) -> HeaderMap

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for HeaderMap

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for HeaderMap

§

fn default() -> HeaderMap

Returns the “default value” for a type. Read more
§

impl From<HeaderMap> for HeaderMap

Convert a http::HeaderMap to our HeaderMap.

+
§

fn from(map: HeaderMap) -> HeaderMap

Converts to this type from the input type.
§

impl<'a> IntoIterator for &'a HeaderMap

§

type Item = (&'a HeaderName, &'a HeaderValue)

The type of the elements being iterated over.
§

type IntoIter = Iter<'a>

Which kind of iterator are we turning this into?
§

fn into_iter(self) -> <&'a HeaderMap as IntoIterator>::IntoIter

Creates an iterator from a value. Read more
§

impl IntoIterator for HeaderMap

Note that this implementation will clone a HeaderName for each value. Consider using +drain to control header name cloning.

+
§

type Item = (HeaderName, HeaderValue)

The type of the elements being iterated over.
§

type IntoIter = IntoIter

Which kind of iterator are we turning this into?
§

fn into_iter(self) -> <HeaderMap as IntoIterator>::IntoIter

Creates an iterator from a value. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/map/struct.IntoIter.html b/awc/http/header/map/struct.IntoIter.html new file mode 100644 index 000000000..5800db0e0 --- /dev/null +++ b/awc/http/header/map/struct.IntoIter.html @@ -0,0 +1,206 @@ +IntoIter in awc::http::header::map - Rust

Struct awc::http::header::map::IntoIter

pub struct IntoIter { /* private fields */ }
Expand description

Iterator over owned name-value pairs.

+

Implementation necessarily clones header names for each value.

+

Trait Implementations§

§

impl Debug for IntoIter

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl ExactSizeIterator for IntoIter

1.0.0 · source§

fn len(&self) -> usize

Returns the exact remaining length of the iterator. Read more
source§

fn is_empty(&self) -> bool

🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
§

impl Iterator for IntoIter

§

type Item = (HeaderName, HeaderValue)

The type of the elements being iterated over.
§

fn next(&mut self) -> Option<<IntoIter as Iterator>::Item>

Advances the iterator and returns the next value. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usize
where + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>
where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
where + Self: Sized, + Self::Item: Clone,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places a copy of separator between adjacent +items of the original iterator. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
§

impl FusedIterator for IntoIter

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for I
where + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<I> IteratorRandom for I
where + I: Iterator,

source§

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where + R: Rng + ?Sized,

Collects values at random from the iterator into a supplied buffer +until that buffer is filled. Read more
source§

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where + R: Rng + ?Sized,

Available on crate feature alloc only.
Collects amount values at random from the iterator into a vector. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/map/struct.Iter.html b/awc/http/header/map/struct.Iter.html new file mode 100644 index 000000000..9a6651d57 --- /dev/null +++ b/awc/http/header/map/struct.Iter.html @@ -0,0 +1,202 @@ +Iter in awc::http::header::map - Rust

Struct awc::http::header::map::Iter

pub struct Iter<'a> { /* private fields */ }
Expand description

Iterator over borrowed name-value pairs.

+

Trait Implementations§

§

impl<'a> Debug for Iter<'a>

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl ExactSizeIterator for Iter<'_>

1.0.0 · source§

fn len(&self) -> usize

Returns the exact remaining length of the iterator. Read more
source§

fn is_empty(&self) -> bool

🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
§

impl<'a> Iterator for Iter<'a>

§

type Item = (&'a HeaderName, &'a HeaderValue)

The type of the elements being iterated over.
§

fn next(&mut self) -> Option<<Iter<'a> as Iterator>::Item>

Advances the iterator and returns the next value. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usize
where + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>
where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
§

impl FusedIterator for Iter<'_>

Auto Trait Implementations§

§

impl<'a> Freeze for Iter<'a>

§

impl<'a> RefUnwindSafe for Iter<'a>

§

impl<'a> Send for Iter<'a>

§

impl<'a> Sync for Iter<'a>

§

impl<'a> Unpin for Iter<'a>

§

impl<'a> UnwindSafe for Iter<'a>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for I
where + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<I> IteratorRandom for I
where + I: Iterator,

source§

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where + R: Rng + ?Sized,

Collects values at random from the iterator into a supplied buffer +until that buffer is filled. Read more
source§

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where + R: Rng + ?Sized,

Available on crate feature alloc only.
Collects amount values at random from the iterator into a vector. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/map/struct.Keys.html b/awc/http/header/map/struct.Keys.html new file mode 100644 index 000000000..399073a13 --- /dev/null +++ b/awc/http/header/map/struct.Keys.html @@ -0,0 +1,202 @@ +Keys in awc::http::header::map - Rust

Struct awc::http::header::map::Keys

pub struct Keys<'a>(/* private fields */);
Expand description

Iterator over all names in the map.

+

Trait Implementations§

§

impl<'a> Debug for Keys<'a>

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl ExactSizeIterator for Keys<'_>

1.0.0 · source§

fn len(&self) -> usize

Returns the exact remaining length of the iterator. Read more
source§

fn is_empty(&self) -> bool

🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
§

impl<'a> Iterator for Keys<'a>

§

type Item = &'a HeaderName

The type of the elements being iterated over.
§

fn next(&mut self) -> Option<<Keys<'a> as Iterator>::Item>

Advances the iterator and returns the next value. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usize
where + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>
where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
§

impl FusedIterator for Keys<'_>

Auto Trait Implementations§

§

impl<'a> Freeze for Keys<'a>

§

impl<'a> RefUnwindSafe for Keys<'a>

§

impl<'a> Send for Keys<'a>

§

impl<'a> Sync for Keys<'a>

§

impl<'a> Unpin for Keys<'a>

§

impl<'a> UnwindSafe for Keys<'a>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for I
where + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<I> IteratorRandom for I
where + I: Iterator,

source§

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where + R: Rng + ?Sized,

Collects values at random from the iterator into a supplied buffer +until that buffer is filled. Read more
source§

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where + R: Rng + ?Sized,

Available on crate feature alloc only.
Collects amount values at random from the iterator into a vector. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/map/struct.Removed.html b/awc/http/header/map/struct.Removed.html new file mode 100644 index 000000000..509e49630 --- /dev/null +++ b/awc/http/header/map/struct.Removed.html @@ -0,0 +1,220 @@ +Removed in awc::http::header::map - Rust

Struct awc::http::header::map::Removed

pub struct Removed { /* private fields */ }
Expand description

Iterator over removed, owned values with the same associated name.

+

Returned from methods that remove or replace items. See HeaderMap::insert +and HeaderMap::remove.

+

Implementations§

§

impl Removed

pub fn is_empty(&self) -> bool

Returns true if iterator contains no elements, without consuming it.

+

If called immediately after HeaderMap::insert or HeaderMap::remove, it will indicate +whether any items were actually replaced or removed, respectively.

+

Trait Implementations§

§

impl Debug for Removed

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl ExactSizeIterator for Removed

1.0.0 · source§

fn len(&self) -> usize

Returns the exact remaining length of the iterator. Read more
source§

fn is_empty(&self) -> bool

🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
§

impl Iterator for Removed

§

type Item = HeaderValue

The type of the elements being iterated over.
§

fn next(&mut self) -> Option<<Removed as Iterator>::Item>

Advances the iterator and returns the next value. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn next_chunk<const N: usize>( + &mut self +) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usize
where + Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
1.0.0 · source§

fn last(self) -> Option<Self::Item>
where + Self: Sized,

Consumes the iterator, returning the last element. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.0.0 · source§

fn nth(&mut self, n: usize) -> Option<Self::Item>

Returns the nth element of the iterator. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where + Self: Sized,

Creates an iterator starting at the same point, but stepping by +the given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where + Self: Sized, + U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse(self, separator: Self::Item) -> Intersperse<Self>
where + Self: Sized, + Self::Item: Clone,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places a copy of separator between adjacent +items of the original iterator. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where + Self: Sized, + G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator +between adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each +element. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where + Self: Sized, + F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element +should be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates an iterator which gives the current iteration count as well as +the next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates an iterator which can use the peek and peek_mut methods +to look at the next element of the iterator without consuming it. See +their documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where + Self: Sized, + P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates an iterator that yields the first n elements, or fewer +if the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but +unlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + Self: Sized, + U: IntoIterator, + F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where + Self: Sized, + F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over +self and returns an iterator over the outputs of f. Like slice::windows(), +the windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + Self: Sized, + F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where + Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where + B: FromIterator<Self::Item>, + Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where + E: Extend<Self::Item>, + Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where + Self: Sized, + B: Default + Extend<Self::Item>, + F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate, +such that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where + Self: Sized, + F: FnMut(B, Self::Item) -> R, + R: Try<Output = B>,

An iterator method that applies a function as long as it returns +successfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where + Self: Sized, + F: FnMut(Self::Item) -> R, + R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the +iterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where + Self: Sized, + F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation, +returning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing +operation. Read more
source§

fn try_reduce<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where + Self: Sized, + F: FnMut(Self::Item, Self::Item) -> R, + R: Try<Output = Self::Item>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the +closure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where + Self: Sized, + P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where + Self: Sized, + F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns +the first non-none result. Read more
source§

fn try_find<F, R>( + &mut self, + f: F +) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where + Self: Sized, + F: FnMut(&Self::Item) -> R, + R: Try<Output = bool>, + <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns +the first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where + Self: Sized, + P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.0.0 · source§

fn max(self) -> Option<Self::Item>
where + Self: Sized, + Self::Item: Ord,

Returns the maximum element of an iterator. Read more
1.0.0 · source§

fn min(self) -> Option<Self::Item>
where + Self: Sized, + Self::Item: Ord,

Returns the minimum element of an iterator. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the +specified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the +specified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where + B: Ord, + Self: Sized, + F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the +specified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the +specified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where + T: 'a + Copy, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where + T: 'a + Clone, + Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where + Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where + Self: Sized, + S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where + Self: Sized, + P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
1.5.0 · source§

fn cmp<I>(self, other: I) -> Ordering
where + I: IntoIterator<Item = Self::Item>, + Self::Item: Ord, + Self: Sized,

Lexicographically compares the elements of this Iterator with those +of another. Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Lexicographically compares the PartialOrd elements of +this Iterator with those of another. The comparison works like short-circuit +evaluation, returning a result without comparing the remaining elements. +As soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those +of another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are equal to those of +another. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where + Self: Sized, + I: IntoIterator, + F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of +another with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialEq<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are not equal to those of +another. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +less or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where + I: IntoIterator, + Self::Item: PartialOrd<<I as IntoIterator>::Item>, + Self: Sized,

Determines if the elements of this Iterator are lexicographically +greater than or equal to those of another. Read more
source§

fn is_sorted(self) -> bool
where + Self: Sized, + Self::Item: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where + Self: Sized, + F: FnMut(Self::Item) -> K, + K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction +function. Read more
§

impl FusedIterator for Removed

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<I> IntoIterator for I
where + I: Iterator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
§

type IntoIter = I

Which kind of iterator are we turning this into?
const: unstable · source§

fn into_iter(self) -> I

Creates an iterator from a value. Read more
source§

impl<I> IteratorRandom for I
where + I: Iterator,

source§

fn choose<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_stable<R>(self, rng: &mut R) -> Option<Self::Item>
where + R: Rng + ?Sized,

Choose one element at random from the iterator. Read more
source§

fn choose_multiple_fill<R>(self, rng: &mut R, buf: &mut [Self::Item]) -> usize
where + R: Rng + ?Sized,

Collects values at random from the iterator into a supplied buffer +until that buffer is filled. Read more
source§

fn choose_multiple<R>(self, rng: &mut R, amount: usize) -> Vec<Self::Item>
where + R: Rng + ?Sized,

Available on crate feature alloc only.
Collects amount values at random from the iterator into a vector. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/sidebar-items.js b/awc/http/header/sidebar-items.js new file mode 100644 index 000000000..d9f2e6ee8 --- /dev/null +++ b/awc/http/header/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"constant":["ACCEPT","ACCEPT_CHARSET","ACCEPT_ENCODING","ACCEPT_LANGUAGE","ACCEPT_RANGES","ACCESS_CONTROL_ALLOW_CREDENTIALS","ACCESS_CONTROL_ALLOW_HEADERS","ACCESS_CONTROL_ALLOW_METHODS","ACCESS_CONTROL_ALLOW_ORIGIN","ACCESS_CONTROL_EXPOSE_HEADERS","ACCESS_CONTROL_MAX_AGE","ACCESS_CONTROL_REQUEST_HEADERS","ACCESS_CONTROL_REQUEST_METHOD","AGE","ALLOW","ALT_SVC","AUTHORIZATION","CACHE_CONTROL","CACHE_STATUS","CDN_CACHE_CONTROL","CONNECTION","CONTENT_DISPOSITION","CONTENT_ENCODING","CONTENT_LANGUAGE","CONTENT_LENGTH","CONTENT_LOCATION","CONTENT_RANGE","CONTENT_SECURITY_POLICY","CONTENT_SECURITY_POLICY_REPORT_ONLY","CONTENT_TYPE","COOKIE","CROSS_ORIGIN_EMBEDDER_POLICY","CROSS_ORIGIN_OPENER_POLICY","CROSS_ORIGIN_RESOURCE_POLICY","DATE","DNT","ETAG","EXPECT","EXPIRES","FORWARDED","FROM","HOST","IF_MATCH","IF_MODIFIED_SINCE","IF_NONE_MATCH","IF_RANGE","IF_UNMODIFIED_SINCE","LAST_MODIFIED","LINK","LOCATION","MAX_FORWARDS","ORIGIN","PERMISSIONS_POLICY","PRAGMA","PROXY_AUTHENTICATE","PROXY_AUTHORIZATION","PUBLIC_KEY_PINS","PUBLIC_KEY_PINS_REPORT_ONLY","RANGE","REFERER","REFERRER_POLICY","REFRESH","RETRY_AFTER","SEC_WEBSOCKET_ACCEPT","SEC_WEBSOCKET_EXTENSIONS","SEC_WEBSOCKET_KEY","SEC_WEBSOCKET_PROTOCOL","SEC_WEBSOCKET_VERSION","SERVER","SET_COOKIE","STRICT_TRANSPORT_SECURITY","TE","TRAILER","TRANSFER_ENCODING","UPGRADE","UPGRADE_INSECURE_REQUESTS","USER_AGENT","VARY","VIA","WARNING","WWW_AUTHENTICATE","X_CONTENT_TYPE_OPTIONS","X_DNS_PREFETCH_CONTROL","X_FORWARDED_FOR","X_FORWARDED_HOST","X_FORWARDED_PROTO","X_FRAME_OPTIONS","X_XSS_PROTECTION"],"enum":["Charset","ContentEncoding"],"fn":["fmt_comma_delimited","from_comma_delimited","from_one_raw_str","http_percent_encode","parse_extended_value","q"],"mod":["map"],"struct":["ExtendedValue","HeaderMap","HeaderName","HeaderValue","HttpDate","InvalidHeaderName","InvalidHeaderValue","LanguageTag","Quality","QualityItem","ToStrError"],"trait":["AsHeaderName","Header","TryIntoHeaderPair","TryIntoHeaderValue"]}; \ No newline at end of file diff --git a/awc/http/header/struct.ExtendedValue.html b/awc/http/header/struct.ExtendedValue.html new file mode 100644 index 000000000..97d5972ca --- /dev/null +++ b/awc/http/header/struct.ExtendedValue.html @@ -0,0 +1,39 @@ +ExtendedValue in awc::http::header - Rust

Struct awc::http::header::ExtendedValue

pub struct ExtendedValue {
+    pub charset: Charset,
+    pub language_tag: Option<LanguageTag>,
+    pub value: Vec<u8>,
+}
Expand description

The value part of an extended parameter consisting of three parts:

+
    +
  • The REQUIRED character set name (charset).
  • +
  • The OPTIONAL language information (language_tag).
  • +
  • A character sequence representing the actual value (value), separated by single quotes.
  • +
+

It is defined in RFC 5987 §3.2.

+

Fields§

§charset: Charset

The character set that is used to encode the value to a string.

+
§language_tag: Option<LanguageTag>

The human language details of the value, if available.

+
§value: Vec<u8>

The parameter value, as expressed in octets.

+

Trait Implementations§

§

impl Clone for ExtendedValue

§

fn clone(&self) -> ExtendedValue

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for ExtendedValue

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for ExtendedValue

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl PartialEq for ExtendedValue

§

fn eq(&self, other: &ExtendedValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Eq for ExtendedValue

§

impl StructuralPartialEq for ExtendedValue

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/struct.HeaderMap.html b/awc/http/header/struct.HeaderMap.html new file mode 100644 index 000000000..fd5105569 --- /dev/null +++ b/awc/http/header/struct.HeaderMap.html @@ -0,0 +1,330 @@ +HeaderMap in awc::http::header - Rust

Struct awc::http::header::HeaderMap

pub struct HeaderMap { /* private fields */ }
Expand description

A multi-map of HTTP headers.

+

HeaderMap is a “multi-map” of HeaderName to one or more HeaderValues.

+

§Examples

+
use actix_http::header::{self, HeaderMap, HeaderValue};
+
+let mut map = HeaderMap::new();
+
+map.insert(header::CONTENT_TYPE, HeaderValue::from_static("text/plain"));
+map.insert(header::ORIGIN, HeaderValue::from_static("example.com"));
+
+assert!(map.contains_key(header::CONTENT_TYPE));
+assert!(map.contains_key(header::ORIGIN));
+
+let mut removed = map.remove(header::ORIGIN);
+assert_eq!(removed.next().unwrap(), "example.com");
+
+assert!(!map.contains_key(header::ORIGIN));
+

Implementations§

§

impl HeaderMap

pub fn new() -> HeaderMap

Create an empty HeaderMap.

+

The map will be created without any capacity; this function will not allocate.

+
§Examples
+
let map = HeaderMap::new();
+
+assert!(map.is_empty());
+assert_eq!(0, map.capacity());
+

pub fn with_capacity(capacity: usize) -> HeaderMap

Create an empty HeaderMap with the specified capacity.

+

The map will be able to hold at least capacity elements without needing to reallocate. +If capacity is 0, the map will be created without allocating.

+
§Examples
+
let map = HeaderMap::with_capacity(16);
+
+assert!(map.is_empty());
+assert!(map.capacity() >= 16);
+

pub fn len(&self) -> usize

Returns the number of values stored in the map.

+

See also: len_keys.

+
§Examples
+
let mut map = HeaderMap::new();
+assert_eq!(map.len(), 0);
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+assert_eq!(map.len(), 2);
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+assert_eq!(map.len(), 3);
+

pub fn len_keys(&self) -> usize

Returns the number of keys stored in the map.

+

The number of values stored will be at least this number. See also: Self::len.

+
§Examples
+
let mut map = HeaderMap::new();
+assert_eq!(map.len_keys(), 0);
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+assert_eq!(map.len_keys(), 2);
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+assert_eq!(map.len_keys(), 2);
+

pub fn is_empty(&self) -> bool

Returns true if the map contains no elements.

+
§Examples
+
let mut map = HeaderMap::new();
+assert!(map.is_empty());
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(!map.is_empty());
+

pub fn clear(&mut self)

Clears the map, removing all name-value pairs.

+

Keeps the allocated memory for reuse.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+assert_eq!(map.len(), 2);
+
+map.clear();
+assert!(map.is_empty());
+

pub fn get(&self, key: impl AsHeaderName) -> Option<&HeaderValue>

Returns a reference to the first value associated with a header name.

+

Returns None if there is no value associated with the key.

+

Even when multiple values are associated with the key, the “first” one is returned but is +not guaranteed to be chosen with any particular order; though, the returned item will be +consistent for each call to get if the map has not changed.

+

See also: get_all.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+
+let cookie = map.get(header::SET_COOKIE).unwrap();
+assert_eq!(cookie, "one=1");
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+assert_eq!(map.get(header::SET_COOKIE).unwrap(), "one=1");
+
+assert_eq!(map.get(header::SET_COOKIE), map.get("set-cookie"));
+assert_eq!(map.get(header::SET_COOKIE), map.get("Set-Cookie"));
+
+assert!(map.get(header::HOST).is_none());
+assert!(map.get("INVALID HEADER NAME").is_none());
+

pub fn get_mut(&mut self, key: impl AsHeaderName) -> Option<&mut HeaderValue>

Returns a mutable reference to the first value associated a header name.

+

Returns None if there is no value associated with the key.

+

Even when multiple values are associated with the key, the “first” one is returned but is +not guaranteed to be chosen with any particular order; though, the returned item will be +consistent for each call to get_mut if the map has not changed.

+

See also: get_all.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+
+let mut cookie = map.get_mut(header::SET_COOKIE).unwrap();
+assert_eq!(cookie, "one=1");
+
+*cookie = HeaderValue::from_static("three=3");
+assert_eq!(map.get(header::SET_COOKIE).unwrap(), "three=3");
+
+assert!(map.get(header::HOST).is_none());
+assert!(map.get("INVALID HEADER NAME").is_none());
+

pub fn get_all(&self, key: impl AsHeaderName) -> Iter<'_, HeaderValue>

Returns an iterator over all values associated with a header name.

+

The returned iterator does not incur any allocations and will yield no items if there are no +values associated with the key. Iteration order is guaranteed to be the same as +insertion order.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut none_iter = map.get_all(header::ORIGIN);
+assert!(none_iter.next().is_none());
+
+map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let mut set_cookies_iter = map.get_all(header::SET_COOKIE);
+assert_eq!(set_cookies_iter.next().unwrap(), "one=1");
+assert_eq!(set_cookies_iter.next().unwrap(), "two=2");
+assert!(set_cookies_iter.next().is_none());
+

pub fn contains_key(&self, key: impl AsHeaderName) -> bool

Returns true if the map contains a value for the specified key.

+

Invalid header names will simply return false.

+
§Examples
+
let mut map = HeaderMap::new();
+assert!(!map.contains_key(header::ACCEPT));
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(map.contains_key(header::ACCEPT));
+

pub fn insert(&mut self, key: HeaderName, val: HeaderValue) -> Removed

Inserts (overrides) a name-value pair in the map.

+

If the map already contained this key, the new value is associated with the key and all +previous values are removed and returned as a Removed iterator. The key is not updated; +this matters for types that can be == without being identical.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(map.contains_key(header::ACCEPT));
+assert_eq!(map.len(), 1);
+
+let mut removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/csv"));
+assert_eq!(removed.next().unwrap(), "text/plain");
+assert!(removed.next().is_none());
+
+assert_eq!(map.len(), 1);
+

A convenience method is provided on the returned iterator to check if the insertion replaced +any values.

+ +
let mut map = HeaderMap::new();
+
+let removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+assert!(removed.is_empty());
+
+let removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/html"));
+assert!(!removed.is_empty());
+

pub fn append(&mut self, key: HeaderName, value: HeaderValue)

Appends a name-value pair to the map.

+

If the map already contained this key, the new value is added to the list of values +currently associated with the key. The key is not updated; this matters for types that can +be == without being identical.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.append(header::HOST, HeaderValue::from_static("example.com"));
+assert_eq!(map.len(), 1);
+
+map.append(header::ACCEPT, HeaderValue::from_static("text/csv"));
+assert_eq!(map.len(), 2);
+
+map.append(header::ACCEPT, HeaderValue::from_static("text/html"));
+assert_eq!(map.len(), 3);
+

pub fn remove(&mut self, key: impl AsHeaderName) -> Removed

Removes all headers for a particular header name from the map.

+

Providing an invalid header names (as a string argument) will have no effect and return +without error.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=2"));
+
+assert_eq!(map.len(), 2);
+
+let mut removed = map.remove(header::SET_COOKIE);
+assert_eq!(removed.next().unwrap(), "one=1");
+assert_eq!(removed.next().unwrap(), "one=2");
+assert!(removed.next().is_none());
+
+assert!(map.is_empty());
+

A convenience method is provided on the returned iterator to check if the remove call +actually removed any values.

+ +
let mut map = HeaderMap::new();
+
+let removed = map.remove("accept");
+assert!(removed.is_empty());
+
+map.insert(header::ACCEPT, HeaderValue::from_static("text/html"));
+let removed = map.remove("accept");
+assert!(!removed.is_empty());
+

pub fn capacity(&self) -> usize

Returns the number of single-value headers the map can hold without needing to reallocate.

+

Since this is a multi-value map, the actual capacity is much larger when considering +each header name can be associated with an arbitrary number of values. The effect is that +the size of len may be greater than capacity since it counts all the values. +Conversely, len_keys will never be larger than capacity.

+
§Examples
+
let map = HeaderMap::with_capacity(16);
+
+assert!(map.is_empty());
+assert!(map.capacity() >= 16);
+

pub fn reserve(&mut self, additional: usize)

Reserves capacity for at least additional more headers to be inserted in the map.

+

The header map may reserve more space to avoid frequent reallocations. Additional capacity +only considers single-value headers.

+
§Panics
+

Panics if the new allocation size overflows usize.

+
§Examples
+
let mut map = HeaderMap::with_capacity(2);
+assert!(map.capacity() >= 2);
+
+map.reserve(100);
+assert!(map.capacity() >= 102);
+
+assert!(map.is_empty());
+

pub fn iter(&self) -> Iter<'_>

An iterator over all name-value pairs.

+

Names will be yielded for each associated value. So, if a key has 3 associated values, it +will be yielded 3 times. The iteration order should be considered arbitrary.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut iter = map.iter();
+assert!(iter.next().is_none());
+
+map.append(header::HOST, HeaderValue::from_static("duck.com"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let mut iter = map.iter();
+assert!(iter.next().is_some());
+assert!(iter.next().is_some());
+assert!(iter.next().is_some());
+assert!(iter.next().is_none());
+
+let pairs = map.iter().collect::<Vec<_>>();
+assert!(pairs.contains(&(&header::HOST, &HeaderValue::from_static("duck.com"))));
+assert!(pairs.contains(&(&header::SET_COOKIE, &HeaderValue::from_static("one=1"))));
+assert!(pairs.contains(&(&header::SET_COOKIE, &HeaderValue::from_static("two=2"))));
+

pub fn keys(&self) -> Keys<'_>

An iterator over all contained header names.

+

Each name will only be yielded once even if it has multiple associated values. The iteration +order should be considered arbitrary.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut iter = map.keys();
+assert!(iter.next().is_none());
+
+map.append(header::HOST, HeaderValue::from_static("duck.com"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let keys = map.keys().cloned().collect::<Vec<_>>();
+assert_eq!(keys.len(), 2);
+assert!(keys.contains(&header::HOST));
+assert!(keys.contains(&header::SET_COOKIE));
+

pub fn retain<F>(&mut self, retain_fn: F)
where + F: FnMut(&HeaderName, &mut HeaderValue) -> bool,

Retains only the headers specified by the predicate.

+

In other words, removes all headers (name, val) for which retain_fn(&name, &mut val) +returns false.

+

The order in which headers are visited should be considered arbitrary.

+
§Examples
+
let mut map = HeaderMap::new();
+
+map.append(header::HOST, HeaderValue::from_static("duck.com"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+map.retain(|name, val| val.as_bytes().starts_with(b"one"));
+
+assert_eq!(map.len(), 1);
+assert!(map.contains_key(&header::SET_COOKIE));
+

pub fn drain(&mut self) -> Drain<'_>

Clears the map, returning all name-value sets as an iterator.

+

Header names will only be yielded for the first value in each set. All items that are +yielded without a name and after an item with a name are associated with that same name. +The first item will always contain a name.

+

Keeps the allocated memory for reuse.

+
§Examples
+
let mut map = HeaderMap::new();
+
+let mut iter = map.drain();
+assert!(iter.next().is_none());
+drop(iter);
+
+map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+
+let mut iter = map.drain();
+assert_eq!(iter.next().unwrap(), (Some(header::SET_COOKIE), HeaderValue::from_static("one=1")));
+assert_eq!(iter.next().unwrap(), (None, HeaderValue::from_static("two=2")));
+drop(iter);
+
+assert!(map.is_empty());
+

Trait Implementations§

§

impl Clone for HeaderMap

§

fn clone(&self) -> HeaderMap

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for HeaderMap

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for HeaderMap

§

fn default() -> HeaderMap

Returns the “default value” for a type. Read more
§

impl From<HeaderMap> for HeaderMap

Convert a http::HeaderMap to our HeaderMap.

+
§

fn from(map: HeaderMap) -> HeaderMap

Converts to this type from the input type.
§

impl<'a> IntoIterator for &'a HeaderMap

§

type Item = (&'a HeaderName, &'a HeaderValue)

The type of the elements being iterated over.
§

type IntoIter = Iter<'a>

Which kind of iterator are we turning this into?
§

fn into_iter(self) -> <&'a HeaderMap as IntoIterator>::IntoIter

Creates an iterator from a value. Read more
§

impl IntoIterator for HeaderMap

Note that this implementation will clone a HeaderName for each value. Consider using +drain to control header name cloning.

+
§

type Item = (HeaderName, HeaderValue)

The type of the elements being iterated over.
§

type IntoIter = IntoIter

Which kind of iterator are we turning this into?
§

fn into_iter(self) -> <HeaderMap as IntoIterator>::IntoIter

Creates an iterator from a value. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/struct.HeaderName.html b/awc/http/header/struct.HeaderName.html new file mode 100644 index 000000000..c0c39bb25 --- /dev/null +++ b/awc/http/header/struct.HeaderName.html @@ -0,0 +1,136 @@ +HeaderName in awc::http::header - Rust

Struct awc::http::header::HeaderName

source ·
pub struct HeaderName { /* private fields */ }
Expand description

Represents an HTTP header field name

+

Header field names identify the header. Header sets may include multiple +headers with the same name. The HTTP specification defines a number of +standard headers, but HTTP messages may include non-standard header names as +well as long as they adhere to the specification.

+

HeaderName is used as the HeaderMap key. Constants are available for +all standard header names in the header module.

+

§Representation

+

HeaderName represents standard header names using an enum, as such they +will not require an allocation for storage. All custom header names are +lower cased upon conversion to a HeaderName value. This avoids the +overhead of dynamically doing lower case conversion during the hash code +computation and the comparison operation.

+

Implementations§

source§

impl HeaderName

source

pub fn from_bytes(src: &[u8]) -> Result<HeaderName, InvalidHeaderName>

Converts a slice of bytes to an HTTP header name.

+

This function normalizes the input.

+
source

pub fn from_lowercase(src: &[u8]) -> Result<HeaderName, InvalidHeaderName>

Converts a slice of bytes to an HTTP header name.

+

This function expects the input to only contain lowercase characters. +This is useful when decoding HTTP/2.0 or HTTP/3.0 headers. Both +require that all headers be represented in lower case.

+
§Examples
+

+// Parsing a lower case header
+let hdr = HeaderName::from_lowercase(b"content-length").unwrap();
+assert_eq!(CONTENT_LENGTH, hdr);
+
+// Parsing a header that contains uppercase characters
+assert!(HeaderName::from_lowercase(b"Content-Length").is_err());
+
source

pub const fn from_static(src: &'static str) -> HeaderName

Converts a static string to a HTTP header name.

+

This function requires the static string to only contain lowercase +characters, numerals and symbols, as per the HTTP/2.0 specification +and header names internal representation within this library.

+
§Panics
+

This function panics when the static string is a invalid header.

+

Until Allow panicking in constants +makes its way into stable, the panic message at compile-time is +going to look cryptic, but should at least point at your header value:

+
error: any use of this value will cause an error
+    --> http/src/header/name.rs:1241:13
+     |
+1241 |             ([] as [u8; 0])[0]; // Invalid header name
+     |             ^^^^^^^^^^^^^^^^^^
+     |             |
+     |             index out of bounds: the length is 0 but the index is 0
+     |             inside `http::HeaderName::from_static` at http/src/header/name.rs:1241:13
+     |             inside `INVALID_NAME` at src/main.rs:3:34
+     |
+    ::: src/main.rs:3:1
+     |
+3    | const INVALID_NAME: HeaderName = HeaderName::from_static("Capitalized");
+     | ------------------------------------------------------------------------
+
§Examples
+
// Parsing a standard header
+let hdr = HeaderName::from_static("content-length");
+assert_eq!(CONTENT_LENGTH, hdr);
+
+// Parsing a custom header
+let CUSTOM_HEADER: &'static str = "custom-header";
+
+let a = HeaderName::from_lowercase(b"custom-header").unwrap();
+let b = HeaderName::from_static(CUSTOM_HEADER);
+assert_eq!(a, b);
+ +
// Parsing a header that contains invalid symbols(s):
+HeaderName::from_static("content{}{}length"); // This line panics!
+
+// Parsing a header that contains invalid uppercase characters.
+let a = HeaderName::from_static("foobar");
+let b = HeaderName::from_static("FOOBAR"); // This line panics!
+
source

pub fn as_str(&self) -> &str

Returns a str representation of the header.

+

The returned string will always be lower case.

+

Trait Implementations§

source§

impl AsRef<[u8]> for HeaderName

source§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl AsRef<str> for HeaderName

source§

fn as_ref(&self) -> &str

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Borrow<str> for HeaderName

source§

fn borrow(&self) -> &str

Immutably borrows from an owned value. Read more
source§

impl Clone for HeaderName

source§

fn clone(&self) -> HeaderName

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for HeaderName

source§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for HeaderName

source§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a HeaderName> for HeaderName

source§

fn from(src: &'a HeaderName) -> HeaderName

Converts to this type from the input type.
source§

impl From<HeaderName> for HeaderValue

source§

fn from(h: HeaderName) -> HeaderValue

Converts to this type from the input type.
source§

impl FromStr for HeaderName

§

type Err = InvalidHeaderName

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<HeaderName, InvalidHeaderName>

Parses a string s to return a value of this type. Read more
source§

impl Hash for HeaderName

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<'a> PartialEq<&'a HeaderName> for HeaderName

source§

fn eq(&self, other: &&'a HeaderName) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<&'a str> for HeaderName

source§

fn eq(&self, other: &&'a str) -> bool

Performs a case-insensitive comparison of the string against the header +name

+
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<HeaderName> for &'a HeaderName

source§

fn eq(&self, other: &HeaderName) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<HeaderName> for &'a str

source§

fn eq(&self, other: &HeaderName) -> bool

Performs a case-insensitive comparison of the string against the header +name

+
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<HeaderName> for str

source§

fn eq(&self, other: &HeaderName) -> bool

Performs a case-insensitive comparison of the string against the header +name

+
§Examples
+
use http::header::CONTENT_LENGTH;
+
+assert_eq!(CONTENT_LENGTH, "content-length");
+assert_eq!(CONTENT_LENGTH, "Content-Length");
+assert_ne!(CONTENT_LENGTH, "content length");
+
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for HeaderName

source§

fn eq(&self, other: &str) -> bool

Performs a case-insensitive comparison of the string against the header +name

+
§Examples
+
use http::header::CONTENT_LENGTH;
+
+assert_eq!(CONTENT_LENGTH, "content-length");
+assert_eq!(CONTENT_LENGTH, "Content-Length");
+assert_ne!(CONTENT_LENGTH, "content length");
+
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for HeaderName

source§

fn eq(&self, other: &HeaderName) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> TryFrom<&'a [u8]> for HeaderName

§

type Error = InvalidHeaderName

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a [u8] +) -> Result<HeaderName, <HeaderName as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a String> for HeaderName

§

type Error = InvalidHeaderName

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a String +) -> Result<HeaderName, <HeaderName as TryFrom<&'a String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for HeaderName

§

type Error = InvalidHeaderName

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a str +) -> Result<HeaderName, <HeaderName as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for HeaderName

§

type Error = InvalidHeaderName

The type returned in the event of a conversion error.
source§

fn try_from( + s: String +) -> Result<HeaderName, <HeaderName as TryFrom<String>>::Error>

Performs the conversion.
source§

impl TryFrom<Vec<u8>> for HeaderName

§

type Error = InvalidHeaderName

The type returned in the event of a conversion error.
source§

fn try_from( + vec: Vec<u8> +) -> Result<HeaderName, <HeaderName as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
§

impl AsHeaderName for &HeaderName

source§

impl<'a> AsHeaderName for &'a HeaderName

§

impl AsHeaderName for HeaderName

source§

impl AsHeaderName for HeaderName

source§

impl Eq for HeaderName

source§

impl<'a> IntoHeaderName for &'a HeaderName

source§

impl IntoHeaderName for HeaderName

source§

impl StructuralPartialEq for HeaderName

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/struct.HeaderValue.html b/awc/http/header/struct.HeaderValue.html new file mode 100644 index 000000000..4a411b446 --- /dev/null +++ b/awc/http/header/struct.HeaderValue.html @@ -0,0 +1,208 @@ +HeaderValue in awc::http::header - Rust

Struct awc::http::header::HeaderValue

source ·
pub struct HeaderValue { /* private fields */ }
Expand description

Represents an HTTP header field value.

+

In practice, HTTP header field values are usually valid ASCII. However, the +HTTP spec allows for a header value to contain opaque bytes as well. In this +case, the header field value is not able to be represented as a string.

+

To handle this, the HeaderValue is useable as a type and can be compared +with strings and implements Debug. A to_str fn is provided that returns +an Err if the header value contains non visible ascii characters.

+

Implementations§

source§

impl HeaderValue

source

pub const fn from_static(src: &'static str) -> HeaderValue

Convert a static string to a HeaderValue.

+

This function will not perform any copying, however the string is +checked to ensure that no invalid characters are present. Only visible +ASCII characters (32-127) are permitted.

+
§Panics
+

This function panics if the argument contains invalid header value +characters.

+

Until Allow panicking in constants +makes its way into stable, the panic message at compile-time is +going to look cryptic, but should at least point at your header value:

+
error: any use of this value will cause an error
+  --> http/src/header/value.rs:67:17
+   |
+67 |                 ([] as [u8; 0])[0]; // Invalid header value
+   |                 ^^^^^^^^^^^^^^^^^^
+   |                 |
+   |                 index out of bounds: the length is 0 but the index is 0
+   |                 inside `HeaderValue::from_static` at http/src/header/value.rs:67:17
+   |                 inside `INVALID_HEADER` at src/main.rs:73:33
+   |
+  ::: src/main.rs:73:1
+   |
+73 | const INVALID_HEADER: HeaderValue = HeaderValue::from_static("жsome value");
+   | ----------------------------------------------------------------------------
+
§Examples
+
let val = HeaderValue::from_static("hello");
+assert_eq!(val, "hello");
+
source

pub fn from_str(src: &str) -> Result<HeaderValue, InvalidHeaderValue>

Attempt to convert a string to a HeaderValue.

+

If the argument contains invalid header value characters, an error is +returned. Only visible ASCII characters (32-127) are permitted. Use +from_bytes to create a HeaderValue that includes opaque octets +(128-255).

+

This function is intended to be replaced in the future by a TryFrom +implementation once the trait is stabilized in std.

+
§Examples
+
let val = HeaderValue::from_str("hello").unwrap();
+assert_eq!(val, "hello");
+

An invalid value

+ +
let val = HeaderValue::from_str("\n");
+assert!(val.is_err());
+
source

pub fn from_name(name: HeaderName) -> HeaderValue

Converts a HeaderName into a HeaderValue

+

Since every valid HeaderName is a valid HeaderValue this is done infallibly.

+
§Examples
+
let val = HeaderValue::from_name(ACCEPT);
+assert_eq!(val, HeaderValue::from_bytes(b"accept").unwrap());
+
source

pub fn from_bytes(src: &[u8]) -> Result<HeaderValue, InvalidHeaderValue>

Attempt to convert a byte slice to a HeaderValue.

+

If the argument contains invalid header value bytes, an error is +returned. Only byte values between 32 and 255 (inclusive) are permitted, +excluding byte 127 (DEL).

+

This function is intended to be replaced in the future by a TryFrom +implementation once the trait is stabilized in std.

+
§Examples
+
let val = HeaderValue::from_bytes(b"hello\xfa").unwrap();
+assert_eq!(val, &b"hello\xfa"[..]);
+

An invalid value

+ +
let val = HeaderValue::from_bytes(b"\n");
+assert!(val.is_err());
+
source

pub fn from_maybe_shared<T>(src: T) -> Result<HeaderValue, InvalidHeaderValue>
where + T: AsRef<[u8]> + 'static,

Attempt to convert a Bytes buffer to a HeaderValue.

+

This will try to prevent a copy if the type passed is the type used +internally, and will copy the data if it is not.

+
source

pub unsafe fn from_maybe_shared_unchecked<T>(src: T) -> HeaderValue
where + T: AsRef<[u8]> + 'static,

Convert a Bytes directly into a HeaderValue without validating.

+

This function does NOT validate that illegal bytes are not contained +within the buffer.

+
source

pub fn to_str(&self) -> Result<&str, ToStrError>

Yields a &str slice if the HeaderValue only contains visible ASCII +chars.

+

This function will perform a scan of the header value, checking all the +characters.

+
§Examples
+
let val = HeaderValue::from_static("hello");
+assert_eq!(val.to_str().unwrap(), "hello");
+
source

pub fn len(&self) -> usize

Returns the length of self.

+

This length is in bytes.

+
§Examples
+
let val = HeaderValue::from_static("hello");
+assert_eq!(val.len(), 5);
+
source

pub fn is_empty(&self) -> bool

Returns true if the HeaderValue has a length of zero bytes.

+
§Examples
+
let val = HeaderValue::from_static("");
+assert!(val.is_empty());
+
+let val = HeaderValue::from_static("hello");
+assert!(!val.is_empty());
+
source

pub fn as_bytes(&self) -> &[u8]

Converts a HeaderValue to a byte slice.

+
§Examples
+
let val = HeaderValue::from_static("hello");
+assert_eq!(val.as_bytes(), b"hello");
+
source

pub fn set_sensitive(&mut self, val: bool)

Mark that the header value represents sensitive information.

+
§Examples
+
let mut val = HeaderValue::from_static("my secret");
+
+val.set_sensitive(true);
+assert!(val.is_sensitive());
+
+val.set_sensitive(false);
+assert!(!val.is_sensitive());
+
source

pub fn is_sensitive(&self) -> bool

Returns true if the value represents sensitive data.

+

Sensitive data could represent passwords or other data that should not +be stored on disk or in memory. By marking header values as sensitive, +components using this crate can be instructed to treat them with special +care for security reasons. For example, caches can avoid storing +sensitive values, and HPACK encoders used by HTTP/2.0 implementations +can choose not to compress them.

+

Additionally, sensitive values will be masked by the Debug +implementation of HeaderValue.

+

Note that sensitivity is not factored into equality or ordering.

+
§Examples
+
let mut val = HeaderValue::from_static("my secret");
+
+val.set_sensitive(true);
+assert!(val.is_sensitive());
+
+val.set_sensitive(false);
+assert!(!val.is_sensitive());
+

Trait Implementations§

source§

impl AsRef<[u8]> for HeaderValue

source§

fn as_ref(&self) -> &[u8]

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for HeaderValue

source§

fn clone(&self) -> HeaderValue

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for HeaderValue

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a HeaderValue> for HeaderValue

source§

fn from(t: &'a HeaderValue) -> HeaderValue

Converts to this type from the input type.
source§

impl From<HeaderName> for HeaderValue

source§

fn from(h: HeaderName) -> HeaderValue

Converts to this type from the input type.
source§

impl From<HeaderValue> for WsClientError

source§

fn from(original: HeaderValue) -> WsClientError

Converts to this type from the input type.
source§

impl From<i16> for HeaderValue

source§

fn from(num: i16) -> HeaderValue

Converts to this type from the input type.
source§

impl From<i32> for HeaderValue

source§

fn from(num: i32) -> HeaderValue

Converts to this type from the input type.
source§

impl From<i64> for HeaderValue

source§

fn from(num: i64) -> HeaderValue

Converts to this type from the input type.
source§

impl From<isize> for HeaderValue

source§

fn from(num: isize) -> HeaderValue

Converts to this type from the input type.
source§

impl From<u16> for HeaderValue

source§

fn from(num: u16) -> HeaderValue

Converts to this type from the input type.
source§

impl From<u32> for HeaderValue

source§

fn from(num: u32) -> HeaderValue

Converts to this type from the input type.
source§

impl From<u64> for HeaderValue

source§

fn from(num: u64) -> HeaderValue

Converts to this type from the input type.
source§

impl From<usize> for HeaderValue

source§

fn from(num: usize) -> HeaderValue

Converts to this type from the input type.
source§

impl FromStr for HeaderValue

§

type Err = InvalidHeaderValue

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<HeaderValue, <HeaderValue as FromStr>::Err>

Parses a string s to return a value of this type. Read more
source§

impl Hash for HeaderValue

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for HeaderValue

source§

fn cmp(&self, other: &HeaderValue) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl<'a, T> PartialEq<&'a T> for HeaderValue
where + HeaderValue: PartialEq<T>, + T: ?Sized,

source§

fn eq(&self, other: &&'a T) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<[u8]> for HeaderValue

source§

fn eq(&self, other: &[u8]) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<HeaderValue> for &'a HeaderValue

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<HeaderValue> for &'a str

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<HeaderValue> for [u8]

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<HeaderValue> for str

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<String> for HeaderValue

source§

fn eq(&self, other: &String) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for HeaderValue

source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for HeaderValue

source§

fn eq(&self, other: &HeaderValue) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a, T> PartialOrd<&'a T> for HeaderValue
where + HeaderValue: PartialOrd<T>, + T: ?Sized,

source§

fn partial_cmp(&self, other: &&'a T) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<[u8]> for HeaderValue

source§

fn partial_cmp(&self, other: &[u8]) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> PartialOrd<HeaderValue> for &'a HeaderValue

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> PartialOrd<HeaderValue> for &'a str

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<HeaderValue> for [u8]

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<HeaderValue> for str

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<String> for HeaderValue

source§

fn partial_cmp(&self, other: &String) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<str> for HeaderValue

source§

fn partial_cmp(&self, other: &str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for HeaderValue

source§

fn partial_cmp(&self, other: &HeaderValue) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> TryFrom<&'a [u8]> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + t: &'a [u8] +) -> Result<HeaderValue, <HeaderValue as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a String> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a String +) -> Result<HeaderValue, <HeaderValue as TryFrom<&'a String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + t: &'a str +) -> Result<HeaderValue, <HeaderValue as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + t: String +) -> Result<HeaderValue, <HeaderValue as TryFrom<String>>::Error>

Performs the conversion.
source§

impl TryFrom<Vec<u8>> for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
source§

fn try_from( + vec: Vec<u8> +) -> Result<HeaderValue, <HeaderValue as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
§

impl TryIntoHeaderValue for &HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
§

fn try_into_value( + self +) -> Result<HeaderValue, <&HeaderValue as TryIntoHeaderValue>::Error>

Try to convert value to a HeaderValue.
§

impl TryIntoHeaderValue for HeaderValue

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
§

fn try_into_value( + self +) -> Result<HeaderValue, <HeaderValue as TryIntoHeaderValue>::Error>

Try to convert value to a HeaderValue.
source§

impl Eq for HeaderValue

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/struct.HttpDate.html b/awc/http/header/struct.HttpDate.html new file mode 100644 index 000000000..5586bd6aa --- /dev/null +++ b/awc/http/header/struct.HttpDate.html @@ -0,0 +1,35 @@ +HttpDate in awc::http::header - Rust

Struct awc::http::header::HttpDate

pub struct HttpDate(/* private fields */);
Expand description

A timestamp with HTTP-style formatting and parsing.

+

Trait Implementations§

§

impl Clone for HttpDate

§

fn clone(&self) -> HttpDate

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for HttpDate

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for HttpDate

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl From<SystemTime> for HttpDate

§

fn from(sys_time: SystemTime) -> HttpDate

Converts to this type from the input type.
§

impl FromStr for HttpDate

§

type Err = ParseError

The associated error which can be returned from parsing.
§

fn from_str(s: &str) -> Result<HttpDate, ParseError>

Parses a string s to return a value of this type. Read more
§

impl Ord for HttpDate

§

fn cmp(&self, other: &HttpDate) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
§

impl PartialEq for HttpDate

§

fn eq(&self, other: &HttpDate) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialOrd for HttpDate

§

fn partial_cmp(&self, other: &HttpDate) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl TryIntoHeaderValue for HttpDate

§

type Error = InvalidHeaderValue

The type returned in the event of a conversion error.
§

fn try_into_value( + self +) -> Result<HeaderValue, <HttpDate as TryIntoHeaderValue>::Error>

Try to convert value to a HeaderValue.
§

impl Copy for HttpDate

§

impl Eq for HttpDate

§

impl StructuralPartialEq for HttpDate

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/struct.InvalidHeaderName.html b/awc/http/header/struct.InvalidHeaderName.html new file mode 100644 index 000000000..2f782ce80 --- /dev/null +++ b/awc/http/header/struct.InvalidHeaderName.html @@ -0,0 +1,19 @@ +InvalidHeaderName in awc::http::header - Rust

Struct awc::http::header::InvalidHeaderName

source ·
pub struct InvalidHeaderName { /* private fields */ }
Expand description

A possible error when converting a HeaderName from another type.

+

Trait Implementations§

source§

impl Debug for InvalidHeaderName

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for InvalidHeaderName

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for InvalidHeaderName

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<InvalidHeaderName> for Error

source§

fn from(err: InvalidHeaderName) -> Error

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/struct.InvalidHeaderValue.html b/awc/http/header/struct.InvalidHeaderValue.html new file mode 100644 index 000000000..51e77c704 --- /dev/null +++ b/awc/http/header/struct.InvalidHeaderValue.html @@ -0,0 +1,20 @@ +InvalidHeaderValue in awc::http::header - Rust

Struct awc::http::header::InvalidHeaderValue

source ·
pub struct InvalidHeaderValue { /* private fields */ }
Expand description

A possible error when converting a HeaderValue from a string or byte +slice.

+

Trait Implementations§

source§

impl Debug for InvalidHeaderValue

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for InvalidHeaderValue

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for InvalidHeaderValue

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<InvalidHeaderValue> for Error

source§

fn from(err: InvalidHeaderValue) -> Error

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/struct.LanguageTag.html b/awc/http/header/struct.LanguageTag.html new file mode 100644 index 000000000..4e7926068 --- /dev/null +++ b/awc/http/header/struct.LanguageTag.html @@ -0,0 +1,177 @@ +LanguageTag in awc::http::header - Rust

Struct awc::http::header::LanguageTag

pub struct LanguageTag { /* private fields */ }
Expand description

A language tag as described in RFC 5646.

+

Language tags are used to help identify languages, whether spoken, +written, signed, or otherwise signaled, for the purpose of +communication. This includes constructed and artificial languages +but excludes languages not intended primarily for human +communication, such as programming languages.

+

Implementations§

§

impl LanguageTag

pub fn as_str(&self) -> &str

Return the serialization of this language tag.

+

This is fast since that serialization is already stored in the LanguageTag struct.

+

pub fn into_string(self) -> String

Return the serialization of this language tag.

+

This consumes the LanguageTag and takes ownership of the String stored in it.

+

pub fn primary_language(&self) -> &str

Return the primary language subtag.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.primary_language(), "zh");
+

pub fn extended_language(&self) -> Option<&str>

Return the extended language subtags.

+

Valid language tags have at most one extended language.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.extended_language(), Some("cmn"));
+

pub fn extended_language_subtags(&self) -> impl Iterator<Item = &str>

Iterate on the extended language subtags.

+

Valid language tags have at most one extended language.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.extended_language_subtags().collect::<Vec<_>>(), vec!["cmn"]);
+

pub fn full_language(&self) -> &str

Return the primary language subtag +and its extended language subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.full_language(), "zh-cmn");
+

pub fn script(&self) -> Option<&str>

Return the script subtag.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.script(), Some("Hans"));
+

pub fn region(&self) -> Option<&str>

Return the region subtag.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-cmn-Hans-CN").unwrap();
+assert_eq!(language_tag.region(), Some("CN"));
+

pub fn variant(&self) -> Option<&str>

Return the variant subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-Latn-TW-pinyin").unwrap();
+assert_eq!(language_tag.variant(), Some("pinyin"));
+

pub fn variant_subtags(&self) -> impl Iterator<Item = &str>

Iterate on the variant subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("zh-Latn-TW-pinyin").unwrap();
+assert_eq!(language_tag.variant_subtags().collect::<Vec<_>>(), vec!["pinyin"]);
+

pub fn extension(&self) -> Option<&str>

Return the extension subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("de-DE-u-co-phonebk").unwrap();
+assert_eq!(language_tag.extension(), Some("u-co-phonebk"));
+

pub fn extension_subtags(&self) -> impl Iterator<Item = (char, &str)>

Iterate on the extension subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("de-DE-u-co-phonebk").unwrap();
+assert_eq!(language_tag.extension_subtags().collect::<Vec<_>>(), vec![('u', "co-phonebk")]);
+

pub fn private_use(&self) -> Option<&str>

Return the private use subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("de-x-foo-bar").unwrap();
+assert_eq!(language_tag.private_use(), Some("x-foo-bar"));
+

pub fn private_use_subtags(&self) -> impl Iterator<Item = &str>

Iterate on the private use subtags.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("de-x-foo-bar").unwrap();
+assert_eq!(language_tag.private_use_subtags().collect::<Vec<_>>(), vec!["foo", "bar"]);
+

pub fn parse(input: &str) -> Result<LanguageTag, ParseError>

Create a LanguageTag from its serialization.

+

This parser accepts the language tags that are “well-formed” according to +RFC 5646. +Full validation could be done with the validate method.

+ +
use language_tags::LanguageTag;
+
+let language_tag = LanguageTag::parse("en-us").unwrap();
+assert_eq!(language_tag.into_string(), "en-US")
+
§Errors
+

If the language tag is not “well-formed” a ParseError variant will be returned.

+

pub fn validate(&self) -> Result<(), ValidationError>

Check if the language tag is “valid” according to +RFC 5646.

+

It applies the following steps:

+
    +
  • grandfathereds and private use tags are valid
  • +
  • There should be no more than one extended language subtag +(c.f. errata 5457).
  • +
  • Primary language, extended language, script, region and variants should appear +in the IANA Language Subtag Registry.
  • +
  • Extended language and variants should have a correct prefix as set +in the IANA Language Subtag Registry.
  • +
  • There should be no duplicate variant and singleton (extension) subtags.
  • +
+
§Errors
+

If the language tag is not “valid” a ValidationError variant will be returned.

+

pub fn is_valid(&self) -> bool

Check if the language tag is valid according to +RFC 5646.

+

pub fn canonicalize(&self) -> Result<LanguageTag, ValidationError>

Returns the canonical version of the language tag following +RFC 5646 4.5.

+

It currently applies the following steps:

+
    +
  • Grandfathered tags are replaced with the canonical version if possible.
  • +
  • Redundant tags are replaced with the canonical version if possible.
  • +
  • Extension languages are promoted to primary language.
  • +
  • Deprecated languages, scripts, regions and variants are replaced with modern equivalents.
  • +
  • Suppress-Script is applied to remove default script for a language (e.g. “en-Latn” is canonicalized as “en”).
  • +
  • Variants are deduplicated
  • +
+
§Errors
+

If there is not a unique way to canonicalize the language tag +a ValidationError variant will be returned.

+

pub fn matches(&self, other: &LanguageTag) -> bool

Matches language tags. The first language acts as a language range, the second one is used +as a normal language tag. None fields in the language range are ignored. If the language +tag has more extlangs than the range these extlangs are ignored. Matches are +case-insensitive.

+

For example the range en-GB matches only en-GB and en-Arab-GB but not en. +The range en matches all language tags starting with en including en, en-GB, +en-Arab and en-Arab-GB.

+
§Panics
+

If the language range has extensions or private use tags.

+
§Examples
+
use language_tags::LanguageTag;
+
+let range_italian = LanguageTag::parse("it").unwrap();
+let tag_german = LanguageTag::parse("de").unwrap();
+let tag_italian_switzerland = LanguageTag::parse("it-CH").unwrap();
+assert!(!range_italian.matches(&tag_german));
+assert!(range_italian.matches(&tag_italian_switzerland));
+
+let range_spanish_brazil = LanguageTag::parse("es-BR").unwrap();
+let tag_spanish = LanguageTag::parse("es").unwrap();
+assert!(!range_spanish_brazil.matches(&tag_spanish));
+

pub fn is_language_range(&self) -> bool

Checks if it is a language range, meaning that there are no extension and privateuse tags.

+

Trait Implementations§

§

impl Clone for LanguageTag

§

fn clone(&self) -> LanguageTag

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for LanguageTag

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for LanguageTag

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl FromStr for LanguageTag

§

type Err = ParseError

The associated error which can be returned from parsing.
§

fn from_str(input: &str) -> Result<LanguageTag, ParseError>

Parses a string s to return a value of this type. Read more
§

impl Hash for LanguageTag

§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl PartialEq for LanguageTag

§

fn eq(&self, other: &LanguageTag) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Eq for LanguageTag

§

impl StructuralPartialEq for LanguageTag

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/struct.Quality.html b/awc/http/header/struct.Quality.html new file mode 100644 index 000000000..826b0f27b --- /dev/null +++ b/awc/http/header/struct.Quality.html @@ -0,0 +1,52 @@ +Quality in awc::http::header - Rust

Struct awc::http::header::Quality

pub struct Quality(/* private fields */);
Expand description

Represents a quality used in q-factor values.

+

The default value is equivalent to q=1.0 (the max value).

+

§Implementation notes

+

The quality value is defined as a number between 0.0 and 1.0 with three decimal places. +This means there are 1001 possible values. Since floating point numbers are not exact and the +smallest floating point data type (f32) consumes four bytes, we use an u16 value to store +the quality internally.

+

RFC 7231 §5.3.1 gives more information on quality values in HTTP header fields.

+

§Examples

+
use actix_http::header::{Quality, q};
+assert_eq!(q(1.0), Quality::MAX);
+
+assert_eq!(q(0.42).to_string(), "0.42");
+assert_eq!(q(1.0).to_string(), "1");
+assert_eq!(Quality::MIN.to_string(), "0.001");
+assert_eq!(Quality::ZERO.to_string(), "0");
+

Implementations§

§

impl Quality

pub const MAX: Quality = _

The maximum quality value, equivalent to q=1.0.

+

pub const MIN: Quality = _

The minimum, non-zero quality value, equivalent to q=0.001.

+

pub const ZERO: Quality = _

The zero quality value, equivalent to q=0.0.

+

Trait Implementations§

§

impl Clone for Quality

§

fn clone(&self) -> Quality

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Quality

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Default for Quality

The default value is Quality::MAX.

+
§

fn default() -> Quality

Returns the “default value” for a type. Read more
§

impl Display for Quality

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Ord for Quality

§

fn cmp(&self, other: &Quality) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
§

impl PartialEq for Quality

§

fn eq(&self, other: &Quality) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl PartialOrd for Quality

§

fn partial_cmp(&self, other: &Quality) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl TryFrom<f32> for Quality

§

type Error = QualityOutOfBounds

The type returned in the event of a conversion error.
§

fn try_from(value: f32) -> Result<Quality, <Quality as TryFrom<f32>>::Error>

Performs the conversion.
§

impl Copy for Quality

§

impl Eq for Quality

§

impl StructuralPartialEq for Quality

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/struct.QualityItem.html b/awc/http/header/struct.QualityItem.html new file mode 100644 index 000000000..4cdc9dbee --- /dev/null +++ b/awc/http/header/struct.QualityItem.html @@ -0,0 +1,74 @@ +QualityItem in awc::http::header - Rust

Struct awc::http::header::QualityItem

pub struct QualityItem<T> {
+    pub item: T,
+    pub quality: Quality,
+}
Expand description

Represents an item with a quality value as defined +in RFC 7231 §5.3.1.

+

§Parsing and Formatting

+

This wrapper be used to parse header value items that have a q-factor annotation as well as +serialize items with a their q-factor.

+

§Ordering

+

Since this context of use for this type is header value items, ordering is defined for +QualityItems but only considers the item’s quality. Order of appearance should be used as +the secondary sorting parameter; i.e., a stable sort over the quality values will produce a +correctly sorted sequence.

+

§Examples

+
let q_item: QualityItem<String> = "hello;q=0.3".parse().unwrap();
+assert_eq!(&q_item.item, "hello");
+assert_eq!(q_item.quality, q(0.3));
+
+// note that format is normalized compared to parsed item
+assert_eq!(q_item.to_string(), "hello; q=0.3");
+
+// item with q=0.3 is greater than item with q=0.1
+let q_item_fallback: QualityItem<String> = "abc;q=0.1".parse().unwrap();
+assert!(q_item > q_item_fallback);
+

Fields§

§item: T

The wrapped contents of the field.

+
§quality: Quality

The quality (client or server preference) for the value.

+

Implementations§

§

impl<T> QualityItem<T>

pub fn new(item: T, quality: Quality) -> QualityItem<T>

Constructs a new QualityItem from an item and a quality value.

+

The item can be of any type. The quality should be a value in the range [0, 1].

+

pub fn max(item: T) -> QualityItem<T>

Constructs a new QualityItem from an item, using the maximum q-value.

+

pub fn min(item: T) -> QualityItem<T>

Constructs a new QualityItem from an item, using the minimum, non-zero q-value.

+

pub fn zero(item: T) -> QualityItem<T>

Constructs a new QualityItem from an item, using zero q-value of zero.

+

Trait Implementations§

§

impl<T> Clone for QualityItem<T>
where + T: Clone,

§

fn clone(&self) -> QualityItem<T>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl<T> Debug for QualityItem<T>
where + T: Debug,

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<T> Display for QualityItem<T>
where + T: Display,

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<T> FromStr for QualityItem<T>
where + T: FromStr,

§

type Err = ParseError

The associated error which can be returned from parsing.
§

fn from_str( + q_item_str: &str +) -> Result<QualityItem<T>, <QualityItem<T> as FromStr>::Err>

Parses a string s to return a value of this type. Read more
§

impl<T> PartialEq for QualityItem<T>
where + T: PartialEq,

§

fn eq(&self, other: &QualityItem<T>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl<T> PartialOrd for QualityItem<T>
where + T: PartialEq,

§

fn partial_cmp(&self, other: &QualityItem<T>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
§

impl<T> Copy for QualityItem<T>
where + T: Copy,

§

impl<T> Eq for QualityItem<T>
where + T: Eq,

§

impl<T> StructuralPartialEq for QualityItem<T>

Auto Trait Implementations§

§

impl<T> Freeze for QualityItem<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for QualityItem<T>
where + T: RefUnwindSafe,

§

impl<T> Send for QualityItem<T>
where + T: Send,

§

impl<T> Sync for QualityItem<T>
where + T: Sync,

§

impl<T> Unpin for QualityItem<T>
where + T: Unpin,

§

impl<T> UnwindSafe for QualityItem<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/struct.ToStrError.html b/awc/http/header/struct.ToStrError.html new file mode 100644 index 000000000..70bc7c107 --- /dev/null +++ b/awc/http/header/struct.ToStrError.html @@ -0,0 +1,21 @@ +ToStrError in awc::http::header - Rust

Struct awc::http::header::ToStrError

source ·
pub struct ToStrError { /* private fields */ }
Expand description

A possible error when converting a HeaderValue to a string representation.

+

Header field values may contain opaque bytes, in which case it is not +possible to represent the value as a string.

+

Trait Implementations§

source§

impl Debug for ToStrError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for ToStrError

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for ToStrError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/header/trait.AsHeaderName.html b/awc/http/header/trait.AsHeaderName.html new file mode 100644 index 000000000..a87916186 --- /dev/null +++ b/awc/http/header/trait.AsHeaderName.html @@ -0,0 +1,2 @@ +AsHeaderName in awc::http::header - Rust

Trait awc::http::header::AsHeaderName

pub trait AsHeaderName: Sealed { }
Expand description

Sealed trait implemented for types that can be effectively borrowed as a HeaderValue.

+

Implementations on Foreign Types§

§

impl AsHeaderName for &str

§

impl AsHeaderName for &String

§

impl AsHeaderName for String

Implementors§

\ No newline at end of file diff --git a/awc/http/header/trait.Header.html b/awc/http/header/trait.Header.html new file mode 100644 index 000000000..9b9cc5194 --- /dev/null +++ b/awc/http/header/trait.Header.html @@ -0,0 +1,10 @@ +Header in awc::http::header - Rust

Trait awc::http::header::Header

pub trait Header: TryIntoHeaderValue {
+    // Required methods
+    fn name() -> HeaderName;
+    fn parse<M>(msg: &M) -> Result<Self, ParseError>
+       where M: HttpMessage;
+}
Expand description

An interface for types that already represent a valid header.

+

Required Methods§

fn name() -> HeaderName

Returns the name of the header field.

+

fn parse<M>(msg: &M) -> Result<Self, ParseError>
where + M: HttpMessage,

Parse the header from a HTTP message.

+

Object Safety§

This trait is not object safe.

Implementors§

\ No newline at end of file diff --git a/awc/http/header/trait.TryIntoHeaderPair.html b/awc/http/header/trait.TryIntoHeaderPair.html new file mode 100644 index 000000000..072250113 --- /dev/null +++ b/awc/http/header/trait.TryIntoHeaderPair.html @@ -0,0 +1,29 @@ +TryIntoHeaderPair in awc::http::header - Rust

Trait awc::http::header::TryIntoHeaderPair

pub trait TryIntoHeaderPair: Sized {
+    type Error: Into<Error>;
+
+    // Required method
+    fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error>;
+}
Expand description

An interface for types that can be converted into a HeaderName + HeaderValue pair for +insertion into a HeaderMap.

+

Required Associated Types§

Required Methods§

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

§

impl<V> TryIntoHeaderPair for (&str, V)

§

type Error = InvalidHeaderPart

§

fn try_into_pair( + self +) -> Result<(HeaderName, HeaderValue), <(&str, V) as TryIntoHeaderPair>::Error>

§

impl<V> TryIntoHeaderPair for (&HeaderName, V)

§

type Error = InvalidHeaderPart

§

fn try_into_pair( + self +) -> Result<(HeaderName, HeaderValue), <(&HeaderName, V) as TryIntoHeaderPair>::Error>

§

impl<V> TryIntoHeaderPair for (&[u8], V)

§

type Error = InvalidHeaderPart

§

fn try_into_pair( + self +) -> Result<(HeaderName, HeaderValue), <(&[u8], V) as TryIntoHeaderPair>::Error>

§

impl<V> TryIntoHeaderPair for (String, V)

§

type Error = InvalidHeaderPart

§

fn try_into_pair( + self +) -> Result<(HeaderName, HeaderValue), <(String, V) as TryIntoHeaderPair>::Error>

§

impl<V> TryIntoHeaderPair for (HeaderName, V)

§

type Error = InvalidHeaderPart

§

fn try_into_pair( + self +) -> Result<(HeaderName, HeaderValue), <(HeaderName, V) as TryIntoHeaderPair>::Error>

Implementors§

§

impl<T> TryIntoHeaderPair for T
where + T: Header,

\ No newline at end of file diff --git a/awc/http/header/trait.TryIntoHeaderValue.html b/awc/http/header/trait.TryIntoHeaderValue.html new file mode 100644 index 000000000..77cde5fce --- /dev/null +++ b/awc/http/header/trait.TryIntoHeaderValue.html @@ -0,0 +1,31 @@ +TryIntoHeaderValue in awc::http::header - Rust

Trait awc::http::header::TryIntoHeaderValue

pub trait TryIntoHeaderValue: Sized {
+    type Error: Into<Error>;
+
+    // Required method
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error>;
+}
Expand description

An interface for types that can be converted into a HeaderValue.

+

Required Associated Types§

type Error: Into<Error>

The type returned in the event of a conversion error.

+

Required Methods§

fn try_into_value(self) -> Result<HeaderValue, Self::Error>

Try to convert value to a HeaderValue.

+

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

§

impl TryIntoHeaderValue for &str

§

impl TryIntoHeaderValue for &[u8]

§

impl TryIntoHeaderValue for i32

§

impl TryIntoHeaderValue for i64

§

impl TryIntoHeaderValue for u32

§

impl TryIntoHeaderValue for u64

§

impl TryIntoHeaderValue for usize

§

impl TryIntoHeaderValue for String

§

impl TryIntoHeaderValue for Vec<u8>

§

impl TryIntoHeaderValue for Mime

§

impl TryIntoHeaderValue for Bytes

Implementors§

\ No newline at end of file diff --git a/awc/http/index.html b/awc/http/index.html new file mode 100644 index 000000000..778493a1c --- /dev/null +++ b/awc/http/index.html @@ -0,0 +1,2 @@ +awc::http - Rust

Module awc::http

source ·
Expand description

Various HTTP related types.

+

Modules§

  • Pre-defined HeaderNames, traits for parsing and conversion, and other header utility methods.
  • URI component of request and response lines

Structs§

  • The Request Method (VERB)
  • An HTTP status code (status-code in RFC 7230 et al.).
  • The URI component of a request.
  • Represents a version of the HTTP spec.

Enums§

\ No newline at end of file diff --git a/awc/http/sidebar-items.js b/awc/http/sidebar-items.js new file mode 100644 index 000000000..566f95a54 --- /dev/null +++ b/awc/http/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["ConnectionType"],"mod":["header","uri"],"struct":["Error","Method","StatusCode","Uri","Version"]}; \ No newline at end of file diff --git a/awc/http/struct.Error.html b/awc/http/struct.Error.html new file mode 100644 index 000000000..3fce01eff --- /dev/null +++ b/awc/http/struct.Error.html @@ -0,0 +1,18 @@ +Error in awc::http - Rust

Struct awc::http::Error

pub struct Error { /* private fields */ }

Trait Implementations§

§

impl Debug for Error

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Display for Error

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Error for Error

§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
§

impl From<EncoderError> for Error

§

fn from(err: EncoderError) -> Error

Converts to this type from the input type.
§

impl From<Error> for Error

§

fn from(err: Error) -> Error

Converts to this type from the input type.
§

impl From<HandshakeError> for Error

Available on crate feature ws only.
§

fn from(err: HandshakeError) -> Error

Converts to this type from the input type.
§

impl From<Infallible> for Error

§

fn from(err: Infallible) -> Error

Converts to this type from the input type.
§

impl From<ParseError> for Error

§

fn from(err: ParseError) -> Error

Converts to this type from the input type.
§

impl From<PayloadError> for Error

§

fn from(err: PayloadError) -> Error

Converts to this type from the input type.
§

impl From<ProtocolError> for Error

Available on crate feature ws only.
§

fn from(err: ProtocolError) -> Error

Converts to this type from the input type.

Auto Trait Implementations§

§

impl Freeze for Error

§

impl !RefUnwindSafe for Error

§

impl !Send for Error

§

impl !Sync for Error

§

impl Unpin for Error

§

impl !UnwindSafe for Error

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/struct.Method.html b/awc/http/struct.Method.html new file mode 100644 index 000000000..ded4745f0 --- /dev/null +++ b/awc/http/struct.Method.html @@ -0,0 +1,71 @@ +Method in awc::http - Rust

Struct awc::http::Method

source ·
pub struct Method(/* private fields */);
Expand description

The Request Method (VERB)

+

This type also contains constants for a number of common HTTP methods such +as GET, POST, etc.

+

Currently includes 8 variants representing the 8 methods defined in +RFC 7230, plus PATCH, +and an Extension variant for all extensions.

+

§Examples

+
use http::Method;
+
+assert_eq!(Method::GET, Method::from_bytes(b"GET").unwrap());
+assert!(Method::GET.is_idempotent());
+assert_eq!(Method::POST.as_str(), "POST");
+

Implementations§

source§

impl Method

source

pub const GET: Method = _

GET

+
source

pub const POST: Method = _

POST

+
source

pub const PUT: Method = _

PUT

+
source

pub const DELETE: Method = _

DELETE

+
source

pub const HEAD: Method = _

HEAD

+
source

pub const OPTIONS: Method = _

OPTIONS

+
source

pub const CONNECT: Method = _

CONNECT

+
source

pub const PATCH: Method = _

PATCH

+
source

pub const TRACE: Method = _

TRACE

+
source

pub fn from_bytes(src: &[u8]) -> Result<Method, InvalidMethod>

Converts a slice of bytes to an HTTP method.

+
source

pub fn is_safe(&self) -> bool

Whether a method is considered “safe”, meaning the request is +essentially read-only.

+

See the spec +for more words.

+
source

pub fn is_idempotent(&self) -> bool

Whether a method is considered “idempotent”, meaning the request has +the same result if executed multiple times.

+

See the spec for +more words.

+
source

pub fn as_str(&self) -> &str

Return a &str representation of the HTTP method

+

Trait Implementations§

source§

impl AsRef<str> for Method

source§

fn as_ref(&self) -> &str

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for Method

source§

fn clone(&self) -> Method

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Method

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Method

source§

fn default() -> Method

Returns the “default value” for a type. Read more
source§

impl Display for Method

source§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a Method> for Method

source§

fn from(t: &'a Method) -> Method

Converts to this type from the input type.
source§

impl FromStr for Method

§

type Err = InvalidMethod

The associated error which can be returned from parsing.
source§

fn from_str(t: &str) -> Result<Method, <Method as FromStr>::Err>

Parses a string s to return a value of this type. Read more
source§

impl Hash for Method

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<'a> PartialEq<&'a Method> for Method

source§

fn eq(&self, other: &&'a Method) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<&'a str> for Method

source§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<Method> for &'a Method

source§

fn eq(&self, other: &Method) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<Method> for &'a str

source§

fn eq(&self, other: &Method) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Method> for str

source§

fn eq(&self, other: &Method) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for Method

source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Method

source§

fn eq(&self, other: &Method) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> TryFrom<&'a [u8]> for Method

§

type Error = InvalidMethod

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a [u8]) -> Result<Method, <Method as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for Method

§

type Error = InvalidMethod

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a str) -> Result<Method, <Method as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl Eq for Method

source§

impl StructuralPartialEq for Method

Auto Trait Implementations§

§

impl Freeze for Method

§

impl RefUnwindSafe for Method

§

impl Send for Method

§

impl Sync for Method

§

impl Unpin for Method

§

impl UnwindSafe for Method

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/struct.StatusCode.html b/awc/http/struct.StatusCode.html new file mode 100644 index 000000000..c74e4b0eb --- /dev/null +++ b/awc/http/struct.StatusCode.html @@ -0,0 +1,221 @@ +StatusCode in awc::http - Rust

Struct awc::http::StatusCode

source ·
pub struct StatusCode(/* private fields */);
Expand description

An HTTP status code (status-code in RFC 7230 et al.).

+

Constants are provided for known status codes, including those in the IANA +HTTP Status Code Registry.

+

Status code values in the range 100-999 (inclusive) are supported by this +type. Values in the range 100-599 are semantically classified by the most +significant digit. See StatusCode::is_success, etc. Values above 599 +are unclassified but allowed for legacy compatibility, though their use is +discouraged. Applications may interpret such values as protocol errors.

+

§Examples

+
use http::StatusCode;
+
+assert_eq!(StatusCode::from_u16(200).unwrap(), StatusCode::OK);
+assert_eq!(StatusCode::NOT_FOUND.as_u16(), 404);
+assert!(StatusCode::OK.is_success());
+

Implementations§

source§

impl StatusCode

source

pub fn from_u16(src: u16) -> Result<StatusCode, InvalidStatusCode>

Converts a u16 to a status code.

+

The function validates the correctness of the supplied u16. It must be +greater or equal to 100 and less than 1000.

+
§Example
+
use http::StatusCode;
+
+let ok = StatusCode::from_u16(200).unwrap();
+assert_eq!(ok, StatusCode::OK);
+
+let err = StatusCode::from_u16(99);
+assert!(err.is_err());
+
source

pub fn from_bytes(src: &[u8]) -> Result<StatusCode, InvalidStatusCode>

Converts a &u8 to a status code

+
source

pub fn as_u16(&self) -> u16

Returns the u16 corresponding to this StatusCode.

+
§Note
+

This is the same as the From<StatusCode> implementation, but +included as an inherent method because that implementation doesn’t +appear in rustdocs, as well as a way to force the type instead of +relying on inference.

+
§Example
+
let status = http::StatusCode::OK;
+assert_eq!(status.as_u16(), 200);
+
source

pub fn as_str(&self) -> &str

Returns a &str representation of the StatusCode

+

The return value only includes a numerical representation of the +status code. The canonical reason is not included.

+
§Example
+
let status = http::StatusCode::OK;
+assert_eq!(status.as_str(), "200");
+
source

pub fn canonical_reason(&self) -> Option<&'static str>

Get the standardised reason-phrase for this status code.

+

This is mostly here for servers writing responses, but could potentially have application +at other times.

+

The reason phrase is defined as being exclusively for human readers. You should avoid +deriving any meaning from it at all costs.

+

Bear in mind also that in HTTP/2.0 and HTTP/3.0 the reason phrase is abolished from +transmission, and so this canonical reason phrase really is the only reason phrase you’ll +find.

+
§Example
+
let status = http::StatusCode::OK;
+assert_eq!(status.canonical_reason(), Some("OK"));
+
source

pub fn is_informational(&self) -> bool

Check if status is within 100-199.

+
source

pub fn is_success(&self) -> bool

Check if status is within 200-299.

+
source

pub fn is_redirection(&self) -> bool

Check if status is within 300-399.

+
source

pub fn is_client_error(&self) -> bool

Check if status is within 400-499.

+
source

pub fn is_server_error(&self) -> bool

Check if status is within 500-599.

+
source§

impl StatusCode

source

pub const CONTINUE: StatusCode = _

100 Continue +[RFC7231, Section 6.2.1]

+
source

pub const SWITCHING_PROTOCOLS: StatusCode = _

101 Switching Protocols +[RFC7231, Section 6.2.2]

+
source

pub const PROCESSING: StatusCode = _

102 Processing +[RFC2518]

+
source

pub const OK: StatusCode = _

source

pub const CREATED: StatusCode = _

201 Created +[RFC7231, Section 6.3.2]

+
source

pub const ACCEPTED: StatusCode = _

202 Accepted +[RFC7231, Section 6.3.3]

+
source

pub const NON_AUTHORITATIVE_INFORMATION: StatusCode = _

203 Non-Authoritative Information +[RFC7231, Section 6.3.4]

+
source

pub const NO_CONTENT: StatusCode = _

204 No Content +[RFC7231, Section 6.3.5]

+
source

pub const RESET_CONTENT: StatusCode = _

205 Reset Content +[RFC7231, Section 6.3.6]

+
source

pub const PARTIAL_CONTENT: StatusCode = _

206 Partial Content +[RFC7233, Section 4.1]

+
source

pub const MULTI_STATUS: StatusCode = _

207 Multi-Status +[RFC4918]

+
source

pub const ALREADY_REPORTED: StatusCode = _

208 Already Reported +[RFC5842]

+
source

pub const IM_USED: StatusCode = _

226 IM Used +[RFC3229]

+
source

pub const MULTIPLE_CHOICES: StatusCode = _

300 Multiple Choices +[RFC7231, Section 6.4.1]

+
source

pub const MOVED_PERMANENTLY: StatusCode = _

301 Moved Permanently +[RFC7231, Section 6.4.2]

+
source

pub const FOUND: StatusCode = _

302 Found +[RFC7231, Section 6.4.3]

+
source

pub const SEE_OTHER: StatusCode = _

303 See Other +[RFC7231, Section 6.4.4]

+
source

pub const NOT_MODIFIED: StatusCode = _

304 Not Modified +[RFC7232, Section 4.1]

+
source

pub const USE_PROXY: StatusCode = _

305 Use Proxy +[RFC7231, Section 6.4.5]

+
source

pub const TEMPORARY_REDIRECT: StatusCode = _

307 Temporary Redirect +[RFC7231, Section 6.4.7]

+
source

pub const PERMANENT_REDIRECT: StatusCode = _

308 Permanent Redirect +[RFC7238]

+
source

pub const BAD_REQUEST: StatusCode = _

400 Bad Request +[RFC7231, Section 6.5.1]

+
source

pub const UNAUTHORIZED: StatusCode = _

401 Unauthorized +[RFC7235, Section 3.1]

+
source

pub const PAYMENT_REQUIRED: StatusCode = _

402 Payment Required +[RFC7231, Section 6.5.2]

+
source

pub const FORBIDDEN: StatusCode = _

403 Forbidden +[RFC7231, Section 6.5.3]

+
source

pub const NOT_FOUND: StatusCode = _

404 Not Found +[RFC7231, Section 6.5.4]

+
source

pub const METHOD_NOT_ALLOWED: StatusCode = _

405 Method Not Allowed +[RFC7231, Section 6.5.5]

+
source

pub const NOT_ACCEPTABLE: StatusCode = _

406 Not Acceptable +[RFC7231, Section 6.5.6]

+
source

pub const PROXY_AUTHENTICATION_REQUIRED: StatusCode = _

407 Proxy Authentication Required +[RFC7235, Section 3.2]

+
source

pub const REQUEST_TIMEOUT: StatusCode = _

408 Request Timeout +[RFC7231, Section 6.5.7]

+
source

pub const CONFLICT: StatusCode = _

409 Conflict +[RFC7231, Section 6.5.8]

+
source

pub const GONE: StatusCode = _

source

pub const LENGTH_REQUIRED: StatusCode = _

411 Length Required +[RFC7231, Section 6.5.10]

+
source

pub const PRECONDITION_FAILED: StatusCode = _

412 Precondition Failed +[RFC7232, Section 4.2]

+
source

pub const PAYLOAD_TOO_LARGE: StatusCode = _

413 Payload Too Large +[RFC7231, Section 6.5.11]

+
source

pub const URI_TOO_LONG: StatusCode = _

414 URI Too Long +[RFC7231, Section 6.5.12]

+
source

pub const UNSUPPORTED_MEDIA_TYPE: StatusCode = _

415 Unsupported Media Type +[RFC7231, Section 6.5.13]

+
source

pub const RANGE_NOT_SATISFIABLE: StatusCode = _

416 Range Not Satisfiable +[RFC7233, Section 4.4]

+
source

pub const EXPECTATION_FAILED: StatusCode = _

417 Expectation Failed +[RFC7231, Section 6.5.14]

+
source

pub const IM_A_TEAPOT: StatusCode = _

418 I’m a teapot +[curiously not registered by IANA but RFC2324]

+
source

pub const MISDIRECTED_REQUEST: StatusCode = _

421 Misdirected Request +RFC7540, Section 9.1.2

+
source

pub const UNPROCESSABLE_ENTITY: StatusCode = _

422 Unprocessable Entity +[RFC4918]

+
source

pub const LOCKED: StatusCode = _

423 Locked +[RFC4918]

+
source

pub const FAILED_DEPENDENCY: StatusCode = _

424 Failed Dependency +[RFC4918]

+
source

pub const UPGRADE_REQUIRED: StatusCode = _

426 Upgrade Required +[RFC7231, Section 6.5.15]

+
source

pub const PRECONDITION_REQUIRED: StatusCode = _

428 Precondition Required +[RFC6585]

+
source

pub const TOO_MANY_REQUESTS: StatusCode = _

429 Too Many Requests +[RFC6585]

+
source

pub const REQUEST_HEADER_FIELDS_TOO_LARGE: StatusCode = _

431 Request Header Fields Too Large +[RFC6585]

+

451 Unavailable For Legal Reasons +[RFC7725]

+
source

pub const INTERNAL_SERVER_ERROR: StatusCode = _

500 Internal Server Error +[RFC7231, Section 6.6.1]

+
source

pub const NOT_IMPLEMENTED: StatusCode = _

501 Not Implemented +[RFC7231, Section 6.6.2]

+
source

pub const BAD_GATEWAY: StatusCode = _

502 Bad Gateway +[RFC7231, Section 6.6.3]

+
source

pub const SERVICE_UNAVAILABLE: StatusCode = _

503 Service Unavailable +[RFC7231, Section 6.6.4]

+
source

pub const GATEWAY_TIMEOUT: StatusCode = _

504 Gateway Timeout +[RFC7231, Section 6.6.5]

+
source

pub const HTTP_VERSION_NOT_SUPPORTED: StatusCode = _

505 HTTP Version Not Supported +[RFC7231, Section 6.6.6]

+
source

pub const VARIANT_ALSO_NEGOTIATES: StatusCode = _

506 Variant Also Negotiates +[RFC2295]

+
source

pub const INSUFFICIENT_STORAGE: StatusCode = _

507 Insufficient Storage +[RFC4918]

+
source

pub const LOOP_DETECTED: StatusCode = _

508 Loop Detected +[RFC5842]

+
source

pub const NOT_EXTENDED: StatusCode = _

510 Not Extended +[RFC2774]

+
source

pub const NETWORK_AUTHENTICATION_REQUIRED: StatusCode = _

511 Network Authentication Required +[RFC6585]

+

Trait Implementations§

source§

impl Clone for StatusCode

source§

fn clone(&self) -> StatusCode

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for StatusCode

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for StatusCode

source§

fn default() -> StatusCode

Returns the “default value” for a type. Read more
source§

impl Display for StatusCode

Formats the status code, including the canonical reason.

+

§Example

+
assert_eq!(format!("{}", StatusCode::OK), "200 OK");
+
source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<'a> From<&'a StatusCode> for StatusCode

source§

fn from(t: &'a StatusCode) -> StatusCode

Converts to this type from the input type.
source§

impl From<StatusCode> for WsClientError

source§

fn from(original: StatusCode) -> WsClientError

Converts to this type from the input type.
source§

impl FromStr for StatusCode

§

type Err = InvalidStatusCode

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<StatusCode, InvalidStatusCode>

Parses a string s to return a value of this type. Read more
source§

impl Hash for StatusCode

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for StatusCode

source§

fn cmp(&self, other: &StatusCode) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq<u16> for StatusCode

source§

fn eq(&self, other: &u16) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for StatusCode

source§

fn eq(&self, other: &StatusCode) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for StatusCode

source§

fn partial_cmp(&self, other: &StatusCode) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> TryFrom<&'a [u8]> for StatusCode

§

type Error = InvalidStatusCode

The type returned in the event of a conversion error.
source§

fn try_from( + t: &'a [u8] +) -> Result<StatusCode, <StatusCode as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for StatusCode

§

type Error = InvalidStatusCode

The type returned in the event of a conversion error.
source§

fn try_from( + t: &'a str +) -> Result<StatusCode, <StatusCode as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<u16> for StatusCode

§

type Error = InvalidStatusCode

The type returned in the event of a conversion error.
source§

fn try_from(t: u16) -> Result<StatusCode, <StatusCode as TryFrom<u16>>::Error>

Performs the conversion.
source§

impl Copy for StatusCode

source§

impl Eq for StatusCode

source§

impl StructuralPartialEq for StatusCode

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/struct.Uri.html b/awc/http/struct.Uri.html new file mode 100644 index 000000000..756a20cf8 --- /dev/null +++ b/awc/http/struct.Uri.html @@ -0,0 +1,284 @@ +Uri in awc::http - Rust

Struct awc::http::Uri

source ·
pub struct Uri { /* private fields */ }
Expand description

The URI component of a request.

+

For HTTP 1, this is included as part of the request line. From Section 5.3, +Request Target:

+
+

Once an inbound connection is obtained, the client sends an HTTP +request message (Section 3) with a request-target derived from the +target URI. There are four distinct formats for the request-target, +depending on both the method being requested and whether the request +is to a proxy.

+
request-target = origin-form
+               / absolute-form
+               / authority-form
+               / asterisk-form
+
+

The URI is structured as follows:

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+|-|   |-------------------------------||--------| |-------------------| |-----|
+ |                  |                       |               |              |
+scheme          authority                 path            query         fragment
+
+

For HTTP 2.0, the URI is encoded using pseudoheaders.

+

§Examples

+
use http::Uri;
+
+let uri = "/foo/bar?baz".parse::<Uri>().unwrap();
+assert_eq!(uri.path(), "/foo/bar");
+assert_eq!(uri.query(), Some("baz"));
+assert_eq!(uri.host(), None);
+
+let uri = "https://www.rust-lang.org/install.html".parse::<Uri>().unwrap();
+assert_eq!(uri.scheme_str(), Some("https"));
+assert_eq!(uri.host(), Some("www.rust-lang.org"));
+assert_eq!(uri.path(), "/install.html");
+

Implementations§

source§

impl Uri

source

pub fn builder() -> Builder

Creates a new builder-style object to manufacture a Uri.

+

This method returns an instance of Builder which can be usd to +create a Uri.

+
§Examples
+
use http::Uri;
+
+let uri = Uri::builder()
+    .scheme("https")
+    .authority("hyper.rs")
+    .path_and_query("/")
+    .build()
+    .unwrap();
+
source

pub fn from_parts(src: Parts) -> Result<Uri, InvalidUriParts>

Attempt to convert a Parts into a Uri.

+
§Examples
+

Relative URI

+ +
let mut parts = Parts::default();
+parts.path_and_query = Some("/foo".parse().unwrap());
+
+let uri = Uri::from_parts(parts).unwrap();
+
+assert_eq!(uri.path(), "/foo");
+
+assert!(uri.scheme().is_none());
+assert!(uri.authority().is_none());
+

Absolute URI

+ +
let mut parts = Parts::default();
+parts.scheme = Some("http".parse().unwrap());
+parts.authority = Some("foo.com".parse().unwrap());
+parts.path_and_query = Some("/foo".parse().unwrap());
+
+let uri = Uri::from_parts(parts).unwrap();
+
+assert_eq!(uri.scheme().unwrap().as_str(), "http");
+assert_eq!(uri.authority().unwrap(), "foo.com");
+assert_eq!(uri.path(), "/foo");
+
source

pub fn from_maybe_shared<T>(src: T) -> Result<Uri, InvalidUri>
where + T: AsRef<[u8]> + 'static,

Attempt to convert a Bytes buffer to a Uri.

+

This will try to prevent a copy if the type passed is the type used +internally, and will copy the data if it is not.

+
source

pub fn from_static(src: &'static str) -> Uri

Convert a Uri from a static string.

+

This function will not perform any copying, however the string is +checked to ensure that it is valid.

+
§Panics
+

This function panics if the argument is an invalid URI.

+
§Examples
+
let uri = Uri::from_static("http://example.com/foo");
+
+assert_eq!(uri.host().unwrap(), "example.com");
+assert_eq!(uri.path(), "/foo");
+
source

pub fn into_parts(self) -> Parts

Convert a Uri into Parts.

+
§Note
+

This is just an inherent method providing the same functionality as +let parts: Parts = uri.into()

+
§Examples
+
let uri: Uri = "/foo".parse().unwrap();
+
+let parts = uri.into_parts();
+
+assert_eq!(parts.path_and_query.unwrap(), "/foo");
+
+assert!(parts.scheme.is_none());
+assert!(parts.authority.is_none());
+
source

pub fn path_and_query(&self) -> Option<&PathAndQuery>

Returns the path & query components of the Uri

+
source

pub fn path(&self) -> &str

Get the path of this Uri.

+

Both relative and absolute URIs contain a path component, though it +might be the empty string. The path component is case sensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                       |--------|
+                                            |
+                                          path
+
+

If the URI is * then the path component is equal to *.

+
§Examples
+

A relative URI

+ +

+let uri: Uri = "/hello/world".parse().unwrap();
+
+assert_eq!(uri.path(), "/hello/world");
+

An absolute URI

+ +
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.path(), "/hello/world");
+
source

pub fn scheme(&self) -> Option<&Scheme>

Get the scheme of this Uri.

+

The URI scheme refers to a specification for assigning identifiers +within that scheme. Only absolute URIs contain a scheme component, but +not all absolute URIs will contain a scheme component. Although scheme +names are case-insensitive, the canonical form is lowercase.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+|-|
+ |
+scheme
+
§Examples
+

Absolute URI

+ +
use http::uri::{Scheme, Uri};
+
+let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.scheme(), Some(&Scheme::HTTP));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.scheme().is_none());
+
source

pub fn scheme_str(&self) -> Option<&str>

Get the scheme of this Uri as a &str.

+
§Example
+
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.scheme_str(), Some("http"));
+
source

pub fn authority(&self) -> Option<&Authority>

Get the authority of this Uri.

+

The authority is a hierarchical element for naming authority such that +the remainder of the URI is delegated to that authority. For HTTP, the +authority consists of the host and port. The host portion of the +authority is case-insensitive.

+

The authority also includes a username:password component, however +the use of this is deprecated and should be avoided.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+      |-------------------------------|
+                    |
+                authority
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.authority().map(|a| a.as_str()), Some("example.org:80"));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.authority().is_none());
+
source

pub fn host(&self) -> Option<&str>

Get the host of this Uri.

+

The host subcomponent of authority is identified by an IP literal +encapsulated within square brackets, an IPv4 address in dotted- decimal +form, or a registered name. The host subcomponent is case-insensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                        |---------|
+                             |
+                            host
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.host(), Some("example.org"));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.host().is_none());
+
source

pub fn port(&self) -> Option<Port<&str>>

Get the port part of this Uri.

+

The port subcomponent of authority is designated by an optional port +number following the host and delimited from it by a single colon (“:”) +character. It can be turned into a decimal port number with the as_u16 +method or as a str with the as_str method.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                    |-|
+                                     |
+                                    port
+
§Examples
+

Absolute URI with port

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+let port = uri.port().unwrap();
+assert_eq!(port.as_u16(), 80);
+

Absolute URI without port

+ +
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert!(uri.port().is_none());
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.port().is_none());
+
source

pub fn port_u16(&self) -> Option<u16>

Get the port of this Uri as a u16.

+
§Example
+
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.port_u16(), Some(80));
+
source

pub fn query(&self) -> Option<&str>

Get the query string of this Uri, starting after the ?.

+

The query component contains non-hierarchical data that, along with data +in the path component, serves to identify a resource within the scope of +the URI’s scheme and naming authority (if any). The query component is +indicated by the first question mark (“?”) character and terminated by a +number sign (“#”) character or by the end of the URI.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                                  |-------------------|
+                                                            |
+                                                          query
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org/hello/world?key=value".parse().unwrap();
+
+assert_eq!(uri.query(), Some("key=value"));
+

Relative URI with a query string component

+ +
let uri: Uri = "/hello/world?key=value&foo=bar".parse().unwrap();
+
+assert_eq!(uri.query(), Some("key=value&foo=bar"));
+

Relative URI without a query string component

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.query().is_none());
+

Trait Implementations§

source§

impl Clone for Uri

source§

fn clone(&self) -> Uri

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Uri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Uri

Returns a Uri representing /

+
source§

fn default() -> Uri

Returns the “default value” for a type. Read more
source§

impl Display for Uri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl From<Authority> for Uri

Convert an Authority into a Uri.

+
source§

fn from(authority: Authority) -> Uri

Converts to this type from the input type.
source§

impl From<PathAndQuery> for Uri

Convert a PathAndQuery into a Uri.

+
source§

fn from(path_and_query: PathAndQuery) -> Uri

Converts to this type from the input type.
source§

impl From<Uri> for Parts

Convert a Uri into Parts

+
source§

fn from(src: Uri) -> Parts

Converts to this type from the input type.
source§

impl FromStr for Uri

§

type Err = InvalidUri

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Uri, InvalidUri>

Parses a string s to return a value of this type. Read more
source§

impl Hash for Uri

source§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl Host for Uri

§

fn hostname(&self) -> &str

Extract hostname.
§

fn port(&self) -> Option<u16>

Extract optional port.
source§

impl<'a> PartialEq<&'a str> for Uri

source§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<Uri> for &'a str

source§

fn eq(&self, uri: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Uri> for str

source§

fn eq(&self, uri: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for Uri

source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Uri

source§

fn eq(&self, other: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> TryFrom<&'a [u8]> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a [u8]) -> Result<Uri, <Uri as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a String> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a String) -> Result<Uri, <Uri as TryFrom<&'a String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a Uri> for Uri

§

type Error = Error

The type returned in the event of a conversion error.
source§

fn try_from(src: &'a Uri) -> Result<Uri, <Uri as TryFrom<&'a Uri>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a str) -> Result<Uri, <Uri as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<Parts> for Uri

§

type Error = InvalidUriParts

The type returned in the event of a conversion error.
source§

fn try_from(src: Parts) -> Result<Uri, <Uri as TryFrom<Parts>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: String) -> Result<Uri, <Uri as TryFrom<String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<Vec<u8>> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(vec: Vec<u8>) -> Result<Uri, <Uri as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
source§

impl Eq for Uri

Auto Trait Implementations§

§

impl !Freeze for Uri

§

impl RefUnwindSafe for Uri

§

impl Send for Uri

§

impl Sync for Uri

§

impl Unpin for Uri

§

impl UnwindSafe for Uri

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/struct.Version.html b/awc/http/struct.Version.html new file mode 100644 index 000000000..fcc6a4ea8 --- /dev/null +++ b/awc/http/struct.Version.html @@ -0,0 +1,40 @@ +Version in awc::http - Rust

Struct awc::http::Version

source ·
pub struct Version(/* private fields */);
Expand description

Represents a version of the HTTP spec.

+

Implementations§

source§

impl Version

source

pub const HTTP_09: Version = _

HTTP/0.9

+
source

pub const HTTP_10: Version = _

HTTP/1.0

+
source

pub const HTTP_11: Version = _

HTTP/1.1

+
source

pub const HTTP_2: Version = _

HTTP/2.0

+
source

pub const HTTP_3: Version = _

HTTP/3.0

+

Trait Implementations§

source§

impl Clone for Version

source§

fn clone(&self) -> Version

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Version

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Version

source§

fn default() -> Version

Returns the “default value” for a type. Read more
source§

impl Hash for Version

source§

fn hash<__H>(&self, state: &mut __H)
where + __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for Version

source§

fn cmp(&self, other: &Version) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq for Version

source§

fn eq(&self, other: &Version) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for Version

source§

fn partial_cmp(&self, other: &Version) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl Copy for Version

source§

impl Eq for Version

source§

impl StructuralPartialEq for Version

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Comparable<K> for Q
where + Q: Ord + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn compare(&self, key: &K) -> Ordering

Compare self to key and return their ordering.
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/uri/index.html b/awc/http/uri/index.html new file mode 100644 index 000000000..5471b7672 --- /dev/null +++ b/awc/http/uri/index.html @@ -0,0 +1,19 @@ +awc::http::uri - Rust

Module awc::http::uri

source ·
Expand description

URI component of request and response lines

+

This module primarily contains the Uri type which is a component of all +HTTP requests and also reexports this type at the root of the crate. A URI +is not always a “full URL” in the sense of something you’d type into a web +browser, but HTTP requests may only have paths on servers but may have full +schemes and hostnames on clients.

+

§Examples

+
use http::Uri;
+
+let uri = "/foo/bar?baz".parse::<Uri>().unwrap();
+assert_eq!(uri.path(), "/foo/bar");
+assert_eq!(uri.query(), Some("baz"));
+assert_eq!(uri.host(), None);
+
+let uri = "https://www.rust-lang.org/install.html".parse::<Uri>().unwrap();
+assert_eq!(uri.scheme_str(), Some("https"));
+assert_eq!(uri.host(), Some("www.rust-lang.org"));
+assert_eq!(uri.path(), "/install.html");
+

Structs§

  • Represents the authority component of a URI.
  • A builder for Uris.
  • An error resulting from a failed attempt to construct a URI.
  • An error resulting from a failed attempt to construct a URI.
  • The various parts of a URI.
  • Represents the path component of a URI
  • The port component of a URI.
  • Represents the scheme component of a URI
  • The URI component of a request.
\ No newline at end of file diff --git a/awc/http/uri/sidebar-items.js b/awc/http/uri/sidebar-items.js new file mode 100644 index 000000000..0b4e597bc --- /dev/null +++ b/awc/http/uri/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Authority","Builder","InvalidUri","InvalidUriParts","Parts","PathAndQuery","Port","Scheme","Uri"]}; \ No newline at end of file diff --git a/awc/http/uri/struct.Authority.html b/awc/http/uri/struct.Authority.html new file mode 100644 index 000000000..191b54827 --- /dev/null +++ b/awc/http/uri/struct.Authority.html @@ -0,0 +1,138 @@ +Authority in awc::http::uri - Rust

Struct awc::http::uri::Authority

source ·
pub struct Authority { /* private fields */ }
Expand description

Represents the authority component of a URI.

+

Implementations§

source§

impl Authority

source

pub fn from_static(src: &'static str) -> Authority

Attempt to convert an Authority from a static string.

+

This function will not perform any copying, and the string will be +checked if it is empty or contains an invalid character.

+
§Panics
+

This function panics if the argument contains invalid characters or +is empty.

+
§Examples
+
let authority = Authority::from_static("example.com");
+assert_eq!(authority.host(), "example.com");
+
source

pub fn from_maybe_shared<T>(src: T) -> Result<Authority, InvalidUri>
where + T: AsRef<[u8]> + 'static,

Attempt to convert a Bytes buffer to a Authority.

+

This will try to prevent a copy if the type passed is the type used +internally, and will copy the data if it is not.

+
source

pub fn host(&self) -> &str

Get the host of this Authority.

+

The host subcomponent of authority is identified by an IP literal +encapsulated within square brackets, an IPv4 address in dotted- decimal +form, or a registered name. The host subcomponent is case-insensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                        |---------|
+                             |
+                            host
+
§Examples
+
let authority: Authority = "example.org:80".parse().unwrap();
+
+assert_eq!(authority.host(), "example.org");
+
source

pub fn port(&self) -> Option<Port<&str>>

Get the port part of this Authority.

+

The port subcomponent of authority is designated by an optional port +number following the host and delimited from it by a single colon (“:”) +character. It can be turned into a decimal port number with the as_u16 +method or as a str with the as_str method.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                    |-|
+                                     |
+                                    port
+
§Examples
+

Authority with port

+ +
let authority: Authority = "example.org:80".parse().unwrap();
+
+let port = authority.port().unwrap();
+assert_eq!(port.as_u16(), 80);
+assert_eq!(port.as_str(), "80");
+

Authority without port

+ +
let authority: Authority = "example.org".parse().unwrap();
+
+assert!(authority.port().is_none());
+
source

pub fn port_u16(&self) -> Option<u16>

Get the port of this Authority as a u16.

+
§Example
+
let authority: Authority = "example.org:80".parse().unwrap();
+
+assert_eq!(authority.port_u16(), Some(80));
+
source

pub fn as_str(&self) -> &str

Return a str representation of the authority

+

Trait Implementations§

source§

impl AsRef<str> for Authority

source§

fn as_ref(&self) -> &str

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for Authority

source§

fn clone(&self) -> Authority

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Authority

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for Authority

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl From<Authority> for Uri

Convert an Authority into a Uri.

+
source§

fn from(authority: Authority) -> Uri

Converts to this type from the input type.
source§

impl FromStr for Authority

§

type Err = InvalidUri

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Authority, InvalidUri>

Parses a string s to return a value of this type. Read more
source§

impl Hash for Authority

Case-insensitive hashing

+

§Examples

+

+let a: Authority = "HELLO.com".parse().unwrap();
+let b: Authority = "hello.coM".parse().unwrap();
+
+let mut s = DefaultHasher::new();
+a.hash(&mut s);
+let a = s.finish();
+
+let mut s = DefaultHasher::new();
+b.hash(&mut s);
+let b = s.finish();
+
+assert_eq!(a, b);
+
source§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<'a> PartialEq<&'a str> for Authority

source§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<Authority> for &'a str

source§

fn eq(&self, other: &Authority) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Authority> for str

source§

fn eq(&self, other: &Authority) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<String> for Authority

source§

fn eq(&self, other: &String) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for Authority

Case-insensitive equality

+

§Examples

+
let authority: Authority = "HELLO.com".parse().unwrap();
+assert_eq!(authority, "hello.coM");
+assert_eq!("hello.com", authority);
+
source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Authority

source§

fn eq(&self, other: &Authority) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialOrd<&'a str> for Authority

source§

fn partial_cmp(&self, other: &&'a str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> PartialOrd<Authority> for &'a str

source§

fn partial_cmp(&self, other: &Authority) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<Authority> for str

source§

fn partial_cmp(&self, other: &Authority) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<String> for Authority

source§

fn partial_cmp(&self, other: &String) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<str> for Authority

source§

fn partial_cmp(&self, other: &str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for Authority

Case-insensitive ordering

+

§Examples

+
let authority: Authority = "DEF.com".parse().unwrap();
+assert!(authority < "ghi.com");
+assert!(authority > "abc.com");
+
source§

fn partial_cmp(&self, other: &Authority) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> TryFrom<&'a [u8]> for Authority

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a [u8] +) -> Result<Authority, <Authority as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for Authority

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a str +) -> Result<Authority, <Authority as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for Authority

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + t: String +) -> Result<Authority, <Authority as TryFrom<String>>::Error>

Performs the conversion.
source§

impl TryFrom<Vec<u8>> for Authority

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + vec: Vec<u8> +) -> Result<Authority, <Authority as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
source§

impl Eq for Authority

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/uri/struct.Builder.html b/awc/http/uri/struct.Builder.html new file mode 100644 index 000000000..753705afa --- /dev/null +++ b/awc/http/uri/struct.Builder.html @@ -0,0 +1,70 @@ +Builder in awc::http::uri - Rust

Struct awc::http::uri::Builder

source ·
pub struct Builder { /* private fields */ }
Expand description

A builder for Uris.

+

This type can be used to construct an instance of Uri +through a builder pattern.

+

Implementations§

source§

impl Builder

source

pub fn new() -> Builder

Creates a new default instance of Builder to construct a Uri.

+
§Examples
+

+let uri = uri::Builder::new()
+    .scheme("https")
+    .authority("hyper.rs")
+    .path_and_query("/")
+    .build()
+    .unwrap();
+
source

pub fn scheme<T>(self, scheme: T) -> Builder
where + Scheme: TryFrom<T>, + <Scheme as TryFrom<T>>::Error: Into<Error>,

Set the Scheme for this URI.

+
§Examples
+

+let mut builder = uri::Builder::new();
+builder.scheme("https");
+
source

pub fn authority<T>(self, auth: T) -> Builder
where + Authority: TryFrom<T>, + <Authority as TryFrom<T>>::Error: Into<Error>,

Set the Authority for this URI.

+
§Examples
+

+let uri = uri::Builder::new()
+    .authority("tokio.rs")
+    .build()
+    .unwrap();
+
source

pub fn path_and_query<T>(self, p_and_q: T) -> Builder

Set the PathAndQuery for this URI.

+
§Examples
+

+let uri = uri::Builder::new()
+    .path_and_query("/hello?foo=bar")
+    .build()
+    .unwrap();
+
source

pub fn build(self) -> Result<Uri, Error>

Consumes this builder, and tries to construct a valid Uri from +the configured pieces.

+
§Errors
+

This function may return an error if any previously configured argument +failed to parse or get converted to the internal representation. For +example if an invalid scheme was specified via scheme("!@#%/^") +the error will be returned when this function is called rather than +when scheme was called.

+

Additionally, the various forms of URI require certain combinations of +parts to be set to be valid. If the parts don’t fit into any of the +valid forms of URI, a new error is returned.

+
§Examples
+

+let uri = Uri::builder()
+    .build()
+    .unwrap();
+

Trait Implementations§

source§

impl Debug for Builder

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Builder

source§

fn default() -> Builder

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/uri/struct.InvalidUri.html b/awc/http/uri/struct.InvalidUri.html new file mode 100644 index 000000000..b4cb0f7b8 --- /dev/null +++ b/awc/http/uri/struct.InvalidUri.html @@ -0,0 +1,19 @@ +InvalidUri in awc::http::uri - Rust

Struct awc::http::uri::InvalidUri

source ·
pub struct InvalidUri(/* private fields */);
Expand description

An error resulting from a failed attempt to construct a URI.

+

Trait Implementations§

source§

impl Debug for InvalidUri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for InvalidUri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for InvalidUri

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<ErrorKind> for InvalidUri

source§

fn from(src: ErrorKind) -> InvalidUri

Converts to this type from the input type.
source§

impl From<InvalidUri> for Error

source§

fn from(err: InvalidUri) -> Error

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/uri/struct.InvalidUriParts.html b/awc/http/uri/struct.InvalidUriParts.html new file mode 100644 index 000000000..0c921d9f9 --- /dev/null +++ b/awc/http/uri/struct.InvalidUriParts.html @@ -0,0 +1,19 @@ +InvalidUriParts in awc::http::uri - Rust

Struct awc::http::uri::InvalidUriParts

source ·
pub struct InvalidUriParts(/* private fields */);
Expand description

An error resulting from a failed attempt to construct a URI.

+

Trait Implementations§

source§

impl Debug for InvalidUriParts

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for InvalidUriParts

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Error for InvalidUriParts

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<ErrorKind> for InvalidUriParts

source§

fn from(src: ErrorKind) -> InvalidUriParts

Converts to this type from the input type.
source§

impl From<InvalidUriParts> for Error

source§

fn from(err: InvalidUriParts) -> Error

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/uri/struct.Parts.html b/awc/http/uri/struct.Parts.html new file mode 100644 index 000000000..4332c710a --- /dev/null +++ b/awc/http/uri/struct.Parts.html @@ -0,0 +1,28 @@ +Parts in awc::http::uri - Rust

Struct awc::http::uri::Parts

source ·
pub struct Parts {
+    pub scheme: Option<Scheme>,
+    pub authority: Option<Authority>,
+    pub path_and_query: Option<PathAndQuery>,
+    /* private fields */
+}
Expand description

The various parts of a URI.

+

This struct is used to provide to and retrieve from a URI.

+

Fields§

§scheme: Option<Scheme>

The scheme component of a URI

+
§authority: Option<Authority>

The authority component of a URI

+
§path_and_query: Option<PathAndQuery>

The origin-form component of a URI

+

Trait Implementations§

source§

impl Debug for Parts

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Parts

source§

fn default() -> Parts

Returns the “default value” for a type. Read more
source§

impl From<Uri> for Parts

Convert a Uri into Parts

+
source§

fn from(src: Uri) -> Parts

Converts to this type from the input type.
source§

impl TryFrom<Parts> for Uri

§

type Error = InvalidUriParts

The type returned in the event of a conversion error.
source§

fn try_from(src: Parts) -> Result<Uri, <Uri as TryFrom<Parts>>::Error>

Performs the conversion.

Auto Trait Implementations§

§

impl !Freeze for Parts

§

impl RefUnwindSafe for Parts

§

impl Send for Parts

§

impl Sync for Parts

§

impl Unpin for Parts

§

impl UnwindSafe for Parts

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/uri/struct.PathAndQuery.html b/awc/http/uri/struct.PathAndQuery.html new file mode 100644 index 000000000..f29e657fa --- /dev/null +++ b/awc/http/uri/struct.PathAndQuery.html @@ -0,0 +1,122 @@ +PathAndQuery in awc::http::uri - Rust

Struct awc::http::uri::PathAndQuery

source ·
pub struct PathAndQuery { /* private fields */ }
Expand description

Represents the path component of a URI

+

Implementations§

source§

impl PathAndQuery

source

pub fn from_static(src: &'static str) -> PathAndQuery

Convert a PathAndQuery from a static string.

+

This function will not perform any copying, however the string is +checked to ensure that it is valid.

+
§Panics
+

This function panics if the argument is an invalid path and query.

+
§Examples
+
let v = PathAndQuery::from_static("/hello?world");
+
+assert_eq!(v.path(), "/hello");
+assert_eq!(v.query(), Some("world"));
+
source

pub fn from_maybe_shared<T>(src: T) -> Result<PathAndQuery, InvalidUri>
where + T: AsRef<[u8]> + 'static,

Attempt to convert a Bytes buffer to a PathAndQuery.

+

This will try to prevent a copy if the type passed is the type used +internally, and will copy the data if it is not.

+
source

pub fn path(&self) -> &str

Returns the path component

+

The path component is case sensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                       |--------|
+                                            |
+                                          path
+
+

If the URI is * then the path component is equal to *.

+
§Examples
+

+let path_and_query: PathAndQuery = "/hello/world".parse().unwrap();
+
+assert_eq!(path_and_query.path(), "/hello/world");
+
source

pub fn query(&self) -> Option<&str>

Returns the query string component

+

The query component contains non-hierarchical data that, along with data +in the path component, serves to identify a resource within the scope of +the URI’s scheme and naming authority (if any). The query component is +indicated by the first question mark (“?”) character and terminated by a +number sign (“#”) character or by the end of the URI.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                                  |-------------------|
+                                                            |
+                                                          query
+
§Examples
+

With a query string component

+ +
let path_and_query: PathAndQuery = "/hello/world?key=value&foo=bar".parse().unwrap();
+
+assert_eq!(path_and_query.query(), Some("key=value&foo=bar"));
+

Without a query string component

+ +
let path_and_query: PathAndQuery = "/hello/world".parse().unwrap();
+
+assert!(path_and_query.query().is_none());
+
source

pub fn as_str(&self) -> &str

Returns the path and query as a string component.

+
§Examples
+

With a query string component

+ +
let path_and_query: PathAndQuery = "/hello/world?key=value&foo=bar".parse().unwrap();
+
+assert_eq!(path_and_query.as_str(), "/hello/world?key=value&foo=bar");
+

Without a query string component

+ +
let path_and_query: PathAndQuery = "/hello/world".parse().unwrap();
+
+assert_eq!(path_and_query.as_str(), "/hello/world");
+

Trait Implementations§

source§

impl Clone for PathAndQuery

source§

fn clone(&self) -> PathAndQuery

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for PathAndQuery

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for PathAndQuery

source§

fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl From<PathAndQuery> for Uri

Convert a PathAndQuery into a Uri.

+
source§

fn from(path_and_query: PathAndQuery) -> Uri

Converts to this type from the input type.
source§

impl FromStr for PathAndQuery

§

type Err = InvalidUri

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<PathAndQuery, InvalidUri>

Parses a string s to return a value of this type. Read more
source§

impl Hash for PathAndQuery

source§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<'a> PartialEq<&'a str> for PathAndQuery

source§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<PathAndQuery> for &'a str

source§

fn eq(&self, other: &PathAndQuery) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<PathAndQuery> for str

source§

fn eq(&self, other: &PathAndQuery) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<String> for PathAndQuery

source§

fn eq(&self, other: &String) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for PathAndQuery

source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for PathAndQuery

source§

fn eq(&self, other: &PathAndQuery) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialOrd<&'a str> for PathAndQuery

source§

fn partial_cmp(&self, other: &&'a str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> PartialOrd<PathAndQuery> for &'a str

source§

fn partial_cmp(&self, other: &PathAndQuery) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<PathAndQuery> for str

source§

fn partial_cmp(&self, other: &PathAndQuery) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<String> for PathAndQuery

source§

fn partial_cmp(&self, other: &String) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd<str> for PathAndQuery

source§

fn partial_cmp(&self, other: &str) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl PartialOrd for PathAndQuery

source§

fn partial_cmp(&self, other: &PathAndQuery) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl<'a> TryFrom<&'a [u8]> for PathAndQuery

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a [u8] +) -> Result<PathAndQuery, <PathAndQuery as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl TryFrom<&String> for PathAndQuery

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: &String +) -> Result<PathAndQuery, <PathAndQuery as TryFrom<&String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for PathAndQuery

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: &'a str +) -> Result<PathAndQuery, <PathAndQuery as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for PathAndQuery

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + s: String +) -> Result<PathAndQuery, <PathAndQuery as TryFrom<String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<Vec<u8>> for PathAndQuery

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from( + vec: Vec<u8> +) -> Result<PathAndQuery, <PathAndQuery as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
source§

impl Eq for PathAndQuery

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/uri/struct.Port.html b/awc/http/uri/struct.Port.html new file mode 100644 index 000000000..f705368ec --- /dev/null +++ b/awc/http/uri/struct.Port.html @@ -0,0 +1,48 @@ +Port in awc::http::uri - Rust

Struct awc::http::uri::Port

source ·
pub struct Port<T> { /* private fields */ }
Expand description

The port component of a URI.

+

Implementations§

source§

impl<T> Port<T>

source

pub fn as_u16(&self) -> u16

Returns the port number as a u16.

+
§Examples
+

Port as u16.

+ +
let authority: Authority = "example.org:80".parse().unwrap();
+
+let port = authority.port().unwrap();
+assert_eq!(port.as_u16(), 80);
+
source§

impl<T> Port<T>
where + T: AsRef<str>,

source

pub fn as_str(&self) -> &str

Returns the port number as a str.

+
§Examples
+

Port as str.

+ +
let authority: Authority = "example.org:80".parse().unwrap();
+
+let port = authority.port().unwrap();
+assert_eq!(port.as_str(), "80");
+

Trait Implementations§

source§

impl<T> AsRef<str> for Port<T>
where + T: AsRef<str>,

source§

fn as_ref(&self) -> &str

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl<T> Debug for Port<T>
where + T: Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<T> Display for Port<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl<T, U> PartialEq<Port<U>> for Port<T>

source§

fn eq(&self, other: &Port<U>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<T> PartialEq<u16> for Port<T>

source§

fn eq(&self, other: &u16) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

§

impl<T> Freeze for Port<T>
where + T: Freeze,

§

impl<T> RefUnwindSafe for Port<T>
where + T: RefUnwindSafe,

§

impl<T> Send for Port<T>
where + T: Send,

§

impl<T> Sync for Port<T>
where + T: Sync,

§

impl<T> Unpin for Port<T>
where + T: Unpin,

§

impl<T> UnwindSafe for Port<T>
where + T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/uri/struct.Scheme.html b/awc/http/uri/struct.Scheme.html new file mode 100644 index 000000000..e7dd86519 --- /dev/null +++ b/awc/http/uri/struct.Scheme.html @@ -0,0 +1,45 @@ +Scheme in awc::http::uri - Rust

Struct awc::http::uri::Scheme

source ·
pub struct Scheme { /* private fields */ }
Expand description

Represents the scheme component of a URI

+

Implementations§

source§

impl Scheme

source

pub const HTTP: Scheme = _

HTTP protocol scheme

+
source

pub const HTTPS: Scheme = _

HTTP protocol over TLS.

+
source

pub fn as_str(&self) -> &str

Return a str representation of the scheme

+
§Examples
+
let scheme: Scheme = "http".parse().unwrap();
+assert_eq!(scheme.as_str(), "http");
+

Trait Implementations§

source§

impl AsRef<str> for Scheme

source§

fn as_ref(&self) -> &str

Converts this type into a shared reference of the (usually inferred) input type.
source§

impl Clone for Scheme

source§

fn clone(&self) -> Scheme

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Scheme

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Display for Scheme

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl FromStr for Scheme

§

type Err = InvalidUri

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Scheme, <Scheme as FromStr>::Err>

Parses a string s to return a value of this type. Read more
source§

impl Hash for Scheme

Case-insensitive hashing

+
source§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq<Scheme> for str

Case-insensitive equality

+
source§

fn eq(&self, other: &Scheme) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for Scheme

Case-insensitive equality

+

§Examples

+
let scheme: Scheme = "HTTP".parse().unwrap();
+assert_eq!(scheme, *"http");
+
source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Scheme

source§

fn eq(&self, other: &Scheme) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> TryFrom<&'a [u8]> for Scheme

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(s: &'a [u8]) -> Result<Scheme, <Scheme as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for Scheme

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(s: &'a str) -> Result<Scheme, <Scheme as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl Eq for Scheme

Auto Trait Implementations§

§

impl Freeze for Scheme

§

impl RefUnwindSafe for Scheme

§

impl Send for Scheme

§

impl Sync for Scheme

§

impl Unpin for Scheme

§

impl UnwindSafe for Scheme

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/http/uri/struct.Uri.html b/awc/http/uri/struct.Uri.html new file mode 100644 index 000000000..41b33f90e --- /dev/null +++ b/awc/http/uri/struct.Uri.html @@ -0,0 +1,284 @@ +Uri in awc::http::uri - Rust

Struct awc::http::uri::Uri

source ·
pub struct Uri { /* private fields */ }
Expand description

The URI component of a request.

+

For HTTP 1, this is included as part of the request line. From Section 5.3, +Request Target:

+
+

Once an inbound connection is obtained, the client sends an HTTP +request message (Section 3) with a request-target derived from the +target URI. There are four distinct formats for the request-target, +depending on both the method being requested and whether the request +is to a proxy.

+
request-target = origin-form
+               / absolute-form
+               / authority-form
+               / asterisk-form
+
+

The URI is structured as follows:

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+|-|   |-------------------------------||--------| |-------------------| |-----|
+ |                  |                       |               |              |
+scheme          authority                 path            query         fragment
+
+

For HTTP 2.0, the URI is encoded using pseudoheaders.

+

§Examples

+
use http::Uri;
+
+let uri = "/foo/bar?baz".parse::<Uri>().unwrap();
+assert_eq!(uri.path(), "/foo/bar");
+assert_eq!(uri.query(), Some("baz"));
+assert_eq!(uri.host(), None);
+
+let uri = "https://www.rust-lang.org/install.html".parse::<Uri>().unwrap();
+assert_eq!(uri.scheme_str(), Some("https"));
+assert_eq!(uri.host(), Some("www.rust-lang.org"));
+assert_eq!(uri.path(), "/install.html");
+

Implementations§

source§

impl Uri

source

pub fn builder() -> Builder

Creates a new builder-style object to manufacture a Uri.

+

This method returns an instance of Builder which can be usd to +create a Uri.

+
§Examples
+
use http::Uri;
+
+let uri = Uri::builder()
+    .scheme("https")
+    .authority("hyper.rs")
+    .path_and_query("/")
+    .build()
+    .unwrap();
+
source

pub fn from_parts(src: Parts) -> Result<Uri, InvalidUriParts>

Attempt to convert a Parts into a Uri.

+
§Examples
+

Relative URI

+ +
let mut parts = Parts::default();
+parts.path_and_query = Some("/foo".parse().unwrap());
+
+let uri = Uri::from_parts(parts).unwrap();
+
+assert_eq!(uri.path(), "/foo");
+
+assert!(uri.scheme().is_none());
+assert!(uri.authority().is_none());
+

Absolute URI

+ +
let mut parts = Parts::default();
+parts.scheme = Some("http".parse().unwrap());
+parts.authority = Some("foo.com".parse().unwrap());
+parts.path_and_query = Some("/foo".parse().unwrap());
+
+let uri = Uri::from_parts(parts).unwrap();
+
+assert_eq!(uri.scheme().unwrap().as_str(), "http");
+assert_eq!(uri.authority().unwrap(), "foo.com");
+assert_eq!(uri.path(), "/foo");
+
source

pub fn from_maybe_shared<T>(src: T) -> Result<Uri, InvalidUri>
where + T: AsRef<[u8]> + 'static,

Attempt to convert a Bytes buffer to a Uri.

+

This will try to prevent a copy if the type passed is the type used +internally, and will copy the data if it is not.

+
source

pub fn from_static(src: &'static str) -> Uri

Convert a Uri from a static string.

+

This function will not perform any copying, however the string is +checked to ensure that it is valid.

+
§Panics
+

This function panics if the argument is an invalid URI.

+
§Examples
+
let uri = Uri::from_static("http://example.com/foo");
+
+assert_eq!(uri.host().unwrap(), "example.com");
+assert_eq!(uri.path(), "/foo");
+
source

pub fn into_parts(self) -> Parts

Convert a Uri into Parts.

+
§Note
+

This is just an inherent method providing the same functionality as +let parts: Parts = uri.into()

+
§Examples
+
let uri: Uri = "/foo".parse().unwrap();
+
+let parts = uri.into_parts();
+
+assert_eq!(parts.path_and_query.unwrap(), "/foo");
+
+assert!(parts.scheme.is_none());
+assert!(parts.authority.is_none());
+
source

pub fn path_and_query(&self) -> Option<&PathAndQuery>

Returns the path & query components of the Uri

+
source

pub fn path(&self) -> &str

Get the path of this Uri.

+

Both relative and absolute URIs contain a path component, though it +might be the empty string. The path component is case sensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                       |--------|
+                                            |
+                                          path
+
+

If the URI is * then the path component is equal to *.

+
§Examples
+

A relative URI

+ +

+let uri: Uri = "/hello/world".parse().unwrap();
+
+assert_eq!(uri.path(), "/hello/world");
+

An absolute URI

+ +
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.path(), "/hello/world");
+
source

pub fn scheme(&self) -> Option<&Scheme>

Get the scheme of this Uri.

+

The URI scheme refers to a specification for assigning identifiers +within that scheme. Only absolute URIs contain a scheme component, but +not all absolute URIs will contain a scheme component. Although scheme +names are case-insensitive, the canonical form is lowercase.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+|-|
+ |
+scheme
+
§Examples
+

Absolute URI

+ +
use http::uri::{Scheme, Uri};
+
+let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.scheme(), Some(&Scheme::HTTP));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.scheme().is_none());
+
source

pub fn scheme_str(&self) -> Option<&str>

Get the scheme of this Uri as a &str.

+
§Example
+
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert_eq!(uri.scheme_str(), Some("http"));
+
source

pub fn authority(&self) -> Option<&Authority>

Get the authority of this Uri.

+

The authority is a hierarchical element for naming authority such that +the remainder of the URI is delegated to that authority. For HTTP, the +authority consists of the host and port. The host portion of the +authority is case-insensitive.

+

The authority also includes a username:password component, however +the use of this is deprecated and should be avoided.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+      |-------------------------------|
+                    |
+                authority
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.authority().map(|a| a.as_str()), Some("example.org:80"));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.authority().is_none());
+
source

pub fn host(&self) -> Option<&str>

Get the host of this Uri.

+

The host subcomponent of authority is identified by an IP literal +encapsulated within square brackets, an IPv4 address in dotted- decimal +form, or a registered name. The host subcomponent is case-insensitive.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                        |---------|
+                             |
+                            host
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.host(), Some("example.org"));
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.host().is_none());
+
source

pub fn port(&self) -> Option<Port<&str>>

Get the port part of this Uri.

+

The port subcomponent of authority is designated by an optional port +number following the host and delimited from it by a single colon (“:”) +character. It can be turned into a decimal port number with the as_u16 +method or as a str with the as_str method.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                    |-|
+                                     |
+                                    port
+
§Examples
+

Absolute URI with port

+ +
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+let port = uri.port().unwrap();
+assert_eq!(port.as_u16(), 80);
+

Absolute URI without port

+ +
let uri: Uri = "http://example.org/hello/world".parse().unwrap();
+
+assert!(uri.port().is_none());
+

Relative URI

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.port().is_none());
+
source

pub fn port_u16(&self) -> Option<u16>

Get the port of this Uri as a u16.

+
§Example
+
let uri: Uri = "http://example.org:80/hello/world".parse().unwrap();
+
+assert_eq!(uri.port_u16(), Some(80));
+
source

pub fn query(&self) -> Option<&str>

Get the query string of this Uri, starting after the ?.

+

The query component contains non-hierarchical data that, along with data +in the path component, serves to identify a resource within the scope of +the URI’s scheme and naming authority (if any). The query component is +indicated by the first question mark (“?”) character and terminated by a +number sign (“#”) character or by the end of the URI.

+
abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1
+                                                  |-------------------|
+                                                            |
+                                                          query
+
§Examples
+

Absolute URI

+ +
let uri: Uri = "http://example.org/hello/world?key=value".parse().unwrap();
+
+assert_eq!(uri.query(), Some("key=value"));
+

Relative URI with a query string component

+ +
let uri: Uri = "/hello/world?key=value&foo=bar".parse().unwrap();
+
+assert_eq!(uri.query(), Some("key=value&foo=bar"));
+

Relative URI without a query string component

+ +
let uri: Uri = "/hello/world".parse().unwrap();
+
+assert!(uri.query().is_none());
+

Trait Implementations§

source§

impl Clone for Uri

source§

fn clone(&self) -> Uri

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Uri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl Default for Uri

Returns a Uri representing /

+
source§

fn default() -> Uri

Returns the “default value” for a type. Read more
source§

impl Display for Uri

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl From<Authority> for Uri

Convert an Authority into a Uri.

+
source§

fn from(authority: Authority) -> Uri

Converts to this type from the input type.
source§

impl From<PathAndQuery> for Uri

Convert a PathAndQuery into a Uri.

+
source§

fn from(path_and_query: PathAndQuery) -> Uri

Converts to this type from the input type.
source§

impl From<Uri> for Parts

Convert a Uri into Parts

+
source§

fn from(src: Uri) -> Parts

Converts to this type from the input type.
source§

impl FromStr for Uri

§

type Err = InvalidUri

The associated error which can be returned from parsing.
source§

fn from_str(s: &str) -> Result<Uri, InvalidUri>

Parses a string s to return a value of this type. Read more
source§

impl Hash for Uri

source§

fn hash<H>(&self, state: &mut H)
where + H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
§

impl Host for Uri

§

fn hostname(&self) -> &str

Extract hostname.
§

fn port(&self) -> Option<u16>

Extract optional port.
source§

impl<'a> PartialEq<&'a str> for Uri

source§

fn eq(&self, other: &&'a str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> PartialEq<Uri> for &'a str

source§

fn eq(&self, uri: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<Uri> for str

source§

fn eq(&self, uri: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq<str> for Uri

source§

fn eq(&self, other: &str) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialEq for Uri

source§

fn eq(&self, other: &Uri) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> TryFrom<&'a [u8]> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a [u8]) -> Result<Uri, <Uri as TryFrom<&'a [u8]>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a String> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a String) -> Result<Uri, <Uri as TryFrom<&'a String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a Uri> for Uri

§

type Error = Error

The type returned in the event of a conversion error.
source§

fn try_from(src: &'a Uri) -> Result<Uri, <Uri as TryFrom<&'a Uri>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<&'a str> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: &'a str) -> Result<Uri, <Uri as TryFrom<&'a str>>::Error>

Performs the conversion.
source§

impl TryFrom<Parts> for Uri

§

type Error = InvalidUriParts

The type returned in the event of a conversion error.
source§

fn try_from(src: Parts) -> Result<Uri, <Uri as TryFrom<Parts>>::Error>

Performs the conversion.
source§

impl TryFrom<String> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(t: String) -> Result<Uri, <Uri as TryFrom<String>>::Error>

Performs the conversion.
source§

impl<'a> TryFrom<Vec<u8>> for Uri

§

type Error = InvalidUri

The type returned in the event of a conversion error.
source§

fn try_from(vec: Vec<u8>) -> Result<Uri, <Uri as TryFrom<Vec<u8>>>::Error>

Performs the conversion.
source§

impl Eq for Uri

Auto Trait Implementations§

§

impl !Freeze for Uri

§

impl RefUnwindSafe for Uri

§

impl Send for Uri

§

impl Sync for Uri

§

impl Unpin for Uri

§

impl UnwindSafe for Uri

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/index.html b/awc/index.html new file mode 100644 index 000000000..cb3f20f2d --- /dev/null +++ b/awc/index.html @@ -0,0 +1,60 @@ +awc - Rust

Crate awc

source ·
Expand description

awc is an asynchronous HTTP and WebSocket client library.

+

§GET Requests

+
// create client
+let mut client = awc::Client::default();
+
+// construct request
+let req = client.get("http://www.rust-lang.org")
+    .insert_header(("User-Agent", "awc/3.0"));
+
+// send request and await response
+let res = req.send().await?;
+println!("Response: {:?}", res);
+

§POST Requests

§Raw Body

+
let mut client = awc::Client::default();
+let response = client.post("http://httpbin.org/post")
+    .send_body("Raw body contents")
+    .await?;
+

§JSON

+
let request = serde_json::json!({
+    "lang": "rust",
+    "body": "json"
+});
+
+let mut client = awc::Client::default();
+let response = client.post("http://httpbin.org/post")
+    .send_json(&request)
+    .await?;
+

§URL Encoded Form

+
let params = [("foo", "bar"), ("baz", "quux")];
+
+let mut client = awc::Client::default();
+let response = client.post("http://httpbin.org/post")
+    .send_form(&params)
+    .await?;
+

§Response Compression

+

All official and common content encoding codecs are supported, optionally.

+

The Accept-Encoding header will automatically be populated with enabled codecs and added to +outgoing requests, allowing servers to select their Content-Encoding accordingly.

+

Feature flags enable these codecs according to the table below. By default, all compress-* +features are enabled.

+
+ + + +
FeatureCodecs
compress-brotlibrotli
compress-gzipgzip, deflate
compress-zstdzstd
+

§WebSockets

+
use futures_util::{SinkExt as _, StreamExt as _};
+
+let (_resp, mut connection) = awc::Client::new()
+    .ws("ws://echo.websocket.org")
+    .connect()
+    .await?;
+
+connection
+    .send(awc::ws::Message::Text("Echo".into()))
+    .await?;
+
+let response = connection.next().await.unwrap()?;
+assert_eq!(response, awc::ws::Frame::Text("Echo".into()));
+

Re-exports§

Modules§

  • Traits and structures to aid consuming and writing HTTP payloads.
  • HTTP client errors
  • Various HTTP related types.
  • Test helpers for actix http client to use during testing.
  • Websockets client

Structs§

Enums§

  • Combined HTTP and WebSocket request type received by connection service.
  • Combined HTTP response & WebSocket tunnel type returned from connection service.
  • Future that sends request’s payload and resolves to a server response.

Type Aliases§

\ No newline at end of file diff --git a/awc/middleware/index.html b/awc/middleware/index.html new file mode 100644 index 000000000..2e048d523 --- /dev/null +++ b/awc/middleware/index.html @@ -0,0 +1,2 @@ +awc::middleware - Rust

Module awc::middleware

source ·

Structs§

Traits§

  • Trait for transform a type to another one. +Both the input and output type should impl [actix_service::Service] trait.
\ No newline at end of file diff --git a/awc/middleware/redirect/struct.Redirect.html b/awc/middleware/redirect/struct.Redirect.html new file mode 100644 index 000000000..463fb1d5d --- /dev/null +++ b/awc/middleware/redirect/struct.Redirect.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../awc/middleware/struct.Redirect.html...

+ + + \ No newline at end of file diff --git a/awc/middleware/sidebar-items.js b/awc/middleware/sidebar-items.js new file mode 100644 index 000000000..ebea532f6 --- /dev/null +++ b/awc/middleware/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Redirect"],"trait":["Transform"]}; \ No newline at end of file diff --git a/awc/middleware/struct.Redirect.html b/awc/middleware/struct.Redirect.html new file mode 100644 index 000000000..30741df1f --- /dev/null +++ b/awc/middleware/struct.Redirect.html @@ -0,0 +1,18 @@ +Redirect in awc::middleware - Rust

Struct awc::middleware::Redirect

source ·
pub struct Redirect { /* private fields */ }

Implementations§

source§

impl Redirect

source

pub fn new() -> Self

source

pub fn max_redirect_times(self, times: u8) -> Self

Trait Implementations§

source§

impl Default for Redirect

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<S> Transform<S, ConnectRequest> for Redirect
where + S: Service<ConnectRequest, Response = ConnectResponse, Error = SendRequestError> + 'static,

§

type Transform = RedirectService<S>

source§

fn new_transform(self, service: S) -> Self::Transform

Creates and returns a new Transform component.

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/middleware/trait.Transform.html b/awc/middleware/trait.Transform.html new file mode 100644 index 000000000..3cfb8cea5 --- /dev/null +++ b/awc/middleware/trait.Transform.html @@ -0,0 +1,12 @@ +Transform in awc::middleware - Rust

Trait awc::middleware::Transform

source ·
pub trait Transform<S, Req> {
+    type Transform: Service<Req>;
+
+    // Required method
+    fn new_transform(self, service: S) -> Self::Transform;
+}
Expand description

Trait for transform a type to another one. +Both the input and output type should impl [actix_service::Service] trait.

+

Required Associated Types§

source

type Transform: Service<Req>

Required Methods§

source

fn new_transform(self, service: S) -> Self::Transform

Creates and returns a new Transform component.

+

Implementations on Foreign Types§

source§

impl<S, Req> Transform<S, Req> for ()
where + S: Service<Req>,

Dummy impl for kick start NestTransform type in ClientBuilder type

+
§

type Transform = S

source§

fn new_transform(self, service: S) -> Self::Transform

Implementors§

source§

impl<S> Transform<S, ConnectRequest> for Redirect
where + S: Service<ConnectRequest, Response = ConnectResponse, Error = SendRequestError> + 'static,

§

type Transform = RedirectService<S>

\ No newline at end of file diff --git a/awc/request/struct.ClientRequest.html b/awc/request/struct.ClientRequest.html new file mode 100644 index 000000000..db74e162e --- /dev/null +++ b/awc/request/struct.ClientRequest.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../awc/struct.ClientRequest.html...

+ + + \ No newline at end of file diff --git a/awc/responses/json_body/struct.JsonBody.html b/awc/responses/json_body/struct.JsonBody.html new file mode 100644 index 000000000..14d84f6ac --- /dev/null +++ b/awc/responses/json_body/struct.JsonBody.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../awc/struct.JsonBody.html...

+ + + \ No newline at end of file diff --git a/awc/responses/response/struct.ClientResponse.html b/awc/responses/response/struct.ClientResponse.html new file mode 100644 index 000000000..64def9288 --- /dev/null +++ b/awc/responses/response/struct.ClientResponse.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../awc/struct.ClientResponse.html...

+ + + \ No newline at end of file diff --git a/awc/responses/response_body/struct.ResponseBody.html b/awc/responses/response_body/struct.ResponseBody.html new file mode 100644 index 000000000..c229b52ec --- /dev/null +++ b/awc/responses/response_body/struct.ResponseBody.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../awc/struct.ResponseBody.html...

+ + + \ No newline at end of file diff --git a/awc/responses/response_body/type.MessageBody.html b/awc/responses/response_body/type.MessageBody.html new file mode 100644 index 000000000..2fce9882a --- /dev/null +++ b/awc/responses/response_body/type.MessageBody.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../awc/type.MessageBody.html...

+ + + \ No newline at end of file diff --git a/awc/sender/enum.SendClientRequest.html b/awc/sender/enum.SendClientRequest.html new file mode 100644 index 000000000..a262f1ce3 --- /dev/null +++ b/awc/sender/enum.SendClientRequest.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../awc/enum.SendClientRequest.html...

+ + + \ No newline at end of file diff --git a/awc/sidebar-items.js b/awc/sidebar-items.js new file mode 100644 index 000000000..2d4965c96 --- /dev/null +++ b/awc/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["ConnectRequest","ConnectResponse","SendClientRequest"],"mod":["body","error","http","middleware","test","ws"],"struct":["Client","ClientBuilder","ClientRequest","ClientResponse","Connect","Connector","FrozenClientRequest","FrozenSendBuilder","JsonBody","ResponseBody"],"type":["BoxConnectorService","BoxedSocket","MessageBody"]}; \ No newline at end of file diff --git a/awc/struct.Client.html b/awc/struct.Client.html new file mode 100644 index 000000000..2858d7921 --- /dev/null +++ b/awc/struct.Client.html @@ -0,0 +1,75 @@ +Client in awc - Rust

Struct awc::Client

source ·
pub struct Client(/* private fields */);
Expand description

An asynchronous HTTP and WebSocket client.

+

You should take care to create, at most, one Client per thread. Otherwise, expect higher CPU +and memory usage.

+

§Examples

+
use awc::Client;
+
+#[actix_rt::main]
+async fn main() {
+    let mut client = Client::default();
+
+    let res = client.get("http://www.rust-lang.org")
+        .insert_header(("User-Agent", "my-app/1.2"))
+        .send()
+        .await;
+
+     println!("Response: {:?}", res);
+}
+

Implementations§

source§

impl Client

source

pub fn new() -> Client

Constructs new client instance with default settings.

+
source

pub fn builder( +) -> ClientBuilder<impl Service<ConnectInfo<Uri>, Response = TcpConnection<Uri, TcpStream>, Error = TcpConnectError> + Clone>

Constructs new Client builder.

+

This function is equivalent of ClientBuilder::new().

+
source

pub fn request<U>(&self, method: Method, url: U) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<HttpError>,

Construct HTTP request.

+
source

pub fn request_from<U>(&self, url: U, head: &RequestHead) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<HttpError>,

Create ClientRequest from RequestHead

+

It is useful for proxy requests. This implementation +copies all headers and the method.

+
source

pub fn get<U>(&self, url: U) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<HttpError>,

Construct HTTP GET request.

+
source

pub fn head<U>(&self, url: U) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<HttpError>,

Construct HTTP HEAD request.

+
source

pub fn put<U>(&self, url: U) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<HttpError>,

Construct HTTP PUT request.

+
source

pub fn post<U>(&self, url: U) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<HttpError>,

Construct HTTP POST request.

+
source

pub fn patch<U>(&self, url: U) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<HttpError>,

Construct HTTP PATCH request.

+
source

pub fn delete<U>(&self, url: U) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<HttpError>,

Construct HTTP DELETE request.

+
source

pub fn options<U>(&self, url: U) -> ClientRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<HttpError>,

Construct HTTP OPTIONS request.

+
source

pub fn ws<U>(&self, url: U) -> WebsocketsRequest
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<HttpError>,

Initialize a WebSocket connection. +Returns a WebSocket connection builder.

+
source

pub fn headers(&mut self) -> Option<&mut HeaderMap>

Get default HeaderMap of Client.

+

Returns Some(&mut HeaderMap) when Client object is unique +(No other clone of client exists at the same time).

+

Trait Implementations§

source§

impl Clone for Client

source§

fn clone(&self) -> Client

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Default for Client

source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl Freeze for Client

§

impl !RefUnwindSafe for Client

§

impl !Send for Client

§

impl !Sync for Client

§

impl Unpin for Client

§

impl !UnwindSafe for Client

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/struct.ClientBuilder.html b/awc/struct.ClientBuilder.html new file mode 100644 index 000000000..91b1cfb7d --- /dev/null +++ b/awc/struct.ClientBuilder.html @@ -0,0 +1,80 @@ +ClientBuilder in awc - Rust

Struct awc::ClientBuilder

source ·
pub struct ClientBuilder<S = (), M = ()> { /* private fields */ }
Expand description

An HTTP Client builder

+

This type can be used to construct an instance of Client through a +builder-like pattern.

+

Implementations§

source§

impl ClientBuilder

source

pub fn new( +) -> ClientBuilder<impl Service<ConnectInfo<Uri>, Response = TcpConnection<Uri, TcpStream>, Error = TcpConnectError> + Clone, ()>

Create a new ClientBuilder with default settings

+

Note: If the rustls-0_23 feature is enabled and neither rustls-0_23-native-roots nor +rustls-0_23-webpki-roots are enabled, this ClientBuilder will build without TLS. In order +to enable TLS in this scenario, a custom Connector must be added to the builder before +finishing construction.

+
source§

impl<S, Io, M> ClientBuilder<S, M>
where + S: Service<ConnectInfo<Uri>, Response = TcpConnection<Uri, Io>, Error = TcpConnectError> + Clone + 'static, + Io: ActixStream + Debug + 'static,

source

pub fn connector<S1, Io1>( + self, + connector: Connector<S1> +) -> ClientBuilder<S1, M>
where + S1: Service<ConnectInfo<Uri>, Response = TcpConnection<Uri, Io1>, Error = TcpConnectError> + Clone + 'static, + Io1: ActixStream + Debug + 'static,

Use custom connector service.

+
source

pub fn timeout(self, timeout: Duration) -> Self

Set request timeout

+

Request timeout is the total time before a response must be received. +Default value is 5 seconds.

+
source

pub fn disable_timeout(self) -> Self

Disable request timeout.

+
source

pub fn local_address(self, addr: IpAddr) -> Self

Set local IP Address the connector would use for establishing connection.

+
source

pub fn max_http_version(self, val: Version) -> Self

Maximum supported HTTP major version.

+

Supported versions are HTTP/1.1 and HTTP/2.

+
source

pub fn disable_redirects(self) -> Self

Do not follow redirects.

+

Redirects are allowed by default.

+
source

pub fn max_redirects(self, num: u8) -> Self

Set max number of redirects.

+

Max redirects is set to 10 by default.

+
source

pub fn initial_window_size(self, size: u32) -> Self

Indicates the initial window size (in octets) for +HTTP2 stream-level flow control for received data.

+

The default value is 65,535 and is good for APIs, but not for big objects.

+
source

pub fn initial_connection_window_size(self, size: u32) -> Self

Indicates the initial window size (in octets) for +HTTP2 connection-level flow control for received data.

+

The default value is 65,535 and is good for APIs, but not for big objects.

+
source

pub fn no_default_headers(self) -> Self

Do not add fundamental default request headers.

+

By default Date and User-Agent headers are set.

+
source

pub fn add_default_header(self, header: impl TryIntoHeaderPair) -> Self

Add default header.

+

Headers added by this method get added to every request unless overridden by other methods.

+
§Panics
+

Panics if header name or value is invalid.

+
source

pub fn basic_auth<N>(self, username: N, password: Option<&str>) -> Self
where + N: Display,

Set client wide HTTP basic authorization header

+
source

pub fn bearer_auth<T>(self, token: T) -> Self
where + T: Display,

Set client wide HTTP bearer authentication header

+
source

pub fn wrap<S1, M1>( + self, + mw: M1 +) -> ClientBuilder<S, NestTransform<M, M1, S1, ConnectRequest>>

Registers middleware, in the form of a middleware component (type), that runs during inbound +and/or outbound processing in the request life-cycle (request -> response), +modifying request/response as necessary, across all requests managed by the Client.

+
source

pub fn finish(self) -> Client
where + M: Transform<DefaultConnector<ConnectorServicePriv<TcpConnectorService<TcpConnectorInnerService<S>>, Rc<dyn Service<Connect, Response = (Box<dyn ConnectionIo>, Protocol), Error = ConnectError, Future = LocalBoxFuture<'static, Result<(Box<dyn ConnectionIo>, Protocol), ConnectError>>>>, Io, Box<dyn ConnectionIo>>>, ConnectRequest> + 'static, + M::Transform: Service<ConnectRequest, Response = ConnectResponse, Error = SendRequestError>,

Finish build process and create Client instance.

+

Auto Trait Implementations§

§

impl<S, M> Freeze for ClientBuilder<S, M>
where + M: Freeze, + S: Freeze,

§

impl<S = (), M = ()> !RefUnwindSafe for ClientBuilder<S, M>

§

impl<S, M> Send for ClientBuilder<S, M>
where + M: Send, + S: Send,

§

impl<S, M> Sync for ClientBuilder<S, M>
where + M: Sync, + S: Sync,

§

impl<S, M> Unpin for ClientBuilder<S, M>
where + M: Unpin, + S: Unpin,

§

impl<S = (), M = ()> !UnwindSafe for ClientBuilder<S, M>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/struct.ClientRequest.html b/awc/struct.ClientRequest.html new file mode 100644 index 000000000..6c4fad3df --- /dev/null +++ b/awc/struct.ClientRequest.html @@ -0,0 +1,90 @@ +ClientRequest in awc - Rust

Struct awc::ClientRequest

source ·
pub struct ClientRequest { /* private fields */ }
Expand description

An HTTP Client request builder

+

This type can be used to construct an instance of ClientRequest through a +builder-like pattern.

+ +
let response = awc::Client::new()
+     .get("http://www.rust-lang.org") // <- Create request builder
+     .insert_header(("User-Agent", "Actix-web"))
+     .send()                          // <- Send HTTP request
+     .await;
+
+response.and_then(|response| {   // <- server HTTP response
+     println!("Response: {:?}", response);
+     Ok(())
+});
+

Implementations§

source§

impl ClientRequest

source

pub fn uri<U>(self, uri: U) -> Self
where + Uri: TryFrom<U>, + <Uri as TryFrom<U>>::Error: Into<HttpError>,

Set HTTP URI of request.

+
source

pub fn get_uri(&self) -> &Uri

Get HTTP URI of request.

+
source

pub fn address(self, addr: SocketAddr) -> Self

Set socket address of the server.

+

This address is used for connection. If address is not +provided url’s host name get resolved.

+
source

pub fn method(self, method: Method) -> Self

Set HTTP method of this request.

+
source

pub fn get_method(&self) -> &Method

Get HTTP method of this request

+
source

pub fn get_version(&self) -> &Version

Get HTTP version of this request.

+
source

pub fn get_peer_addr(&self) -> &Option<SocketAddr>

Get peer address of this request.

+
source

pub fn headers(&self) -> &HeaderMap

Returns request’s headers.

+
source

pub fn headers_mut(&mut self) -> &mut HeaderMap

Returns request’s mutable headers.

+
source

pub fn insert_header(self, header: impl TryIntoHeaderPair) -> Self

Insert a header, replacing any that were set with an equivalent field name.

+
source

pub fn insert_header_if_none(self, header: impl TryIntoHeaderPair) -> Self

Insert a header only if it is not yet set.

+
source

pub fn append_header(self, header: impl TryIntoHeaderPair) -> Self

Append a header, keeping any that were set with an equivalent field name.

+ +
use awc::{http::header, Client};
+
+Client::new()
+    .get("http://www.rust-lang.org")
+    .insert_header(("X-TEST", "value"))
+    .insert_header((header::CONTENT_TYPE, mime::APPLICATION_JSON));
+
source

pub fn camel_case(self) -> Self

Send headers in Camel-Case form.

+
source

pub fn force_close(self) -> Self

Force close connection instead of returning it back to connections pool. +This setting affect only HTTP/1 connections.

+
source

pub fn content_type<V>(self, value: V) -> Self

Set request’s content type

+
source

pub fn content_length(self, len: u64) -> Self

Set content length

+
source

pub fn basic_auth(self, username: impl Display, password: impl Display) -> Self

Set HTTP basic authorization header.

+

If no password is needed, just provide an empty string.

+
source

pub fn bearer_auth(self, token: impl Display) -> Self

Set HTTP bearer authentication header

+
source

pub fn cookie(self, cookie: Cookie<'_>) -> Self

Available on crate feature cookies only.

Set a cookie

+ +
use awc::{cookie::Cookie, Client};
+
+let res = Client::new().get("https://httpbin.org/cookies")
+    .cookie(Cookie::new("name", "value"))
+    .send()
+    .await;
+
+println!("Response: {:?}", res);
+
source

pub fn no_decompress(self) -> Self

Disable automatic decompress of response’s body

+
source

pub fn timeout(self, timeout: Duration) -> Self

Set request timeout. Overrides client wide timeout setting.

+

Request timeout is the total time before a response must be received. +Default value is 5 seconds.

+
source

pub fn query<T: Serialize>(self, query: &T) -> Result<Self, Error>

Sets the query part of the request

+
source

pub fn freeze(self) -> Result<FrozenClientRequest, FreezeRequestError>

Freeze request builder and construct FrozenClientRequest, +which could be used for sending same request multiple times.

+
source

pub fn send_body<B>(self, body: B) -> SendClientRequest
where + B: MessageBody + 'static,

Complete request construction and send body.

+
source

pub fn send_json<T: Serialize>(self, value: &T) -> SendClientRequest

Set a JSON body and generate ClientRequest

+
source

pub fn send_form<T: Serialize>(self, value: &T) -> SendClientRequest

Set a urlencoded body and generate ClientRequest

+

ClientRequestBuilder can not be used after this call.

+
source

pub fn send_stream<S, E>(self, stream: S) -> SendClientRequest
where + S: Stream<Item = Result<Bytes, E>> + 'static, + E: Into<Box<dyn Error>> + 'static,

Set an streaming body and generate ClientRequest.

+
source

pub fn send(self) -> SendClientRequest

Set an empty body and generate ClientRequest.

+

Trait Implementations§

source§

impl Debug for ClientRequest

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/struct.ClientResponse.html b/awc/struct.ClientResponse.html new file mode 100644 index 000000000..69e8be25b --- /dev/null +++ b/awc/struct.ClientResponse.html @@ -0,0 +1,292 @@ +ClientResponse in awc - Rust

Struct awc::ClientResponse

source ·
pub struct ClientResponse<S = BoxedPayloadStream> { /* private fields */ }
Expand description

Client Response

+

Implementations§

source§

impl<S> ClientResponse<S>

source

pub fn version(&self) -> Version

Read the Request Version.

+
source

pub fn status(&self) -> StatusCode

Get the status from the server.

+
source

pub fn headers(&self) -> &HeaderMap

Returns request’s headers.

+
source

pub fn map_body<F, U>(self, f: F) -> ClientResponse<U>
where + F: FnOnce(&mut ResponseHead, Payload<S>) -> Payload<U>,

Map the current body type to another using a closure. Returns a new response.

+

Closure receives the response head and the current body type.

+
source

pub fn timeout(self, dur: Duration) -> Self

Set a timeout duration for ClientResponse.

+

This duration covers the duration of processing the response body stream +and would end it as timeout error when deadline met.

+

Disabled by default.

+
source

pub fn cookies(&self) -> Result<Ref<'_, Vec<Cookie<'static>>>, CookieParseError>

Available on crate feature cookies only.

Load request cookies.

+
source

pub fn cookie(&self, name: &str) -> Option<Cookie<'static>>

Available on crate feature cookies only.

Return request cookie.

+
source§

impl<S> ClientResponse<S>
where + S: Stream<Item = Result<Bytes, PayloadError>>,

source

pub fn body(&mut self) -> ResponseBody<S>

Returns a Future that consumes the body stream and resolves to [Bytes].

+
§Errors
+

Future implementation returns error if:

+
    +
  • content length is greater than limit (default: 2 MiB)
  • +
+
§Examples
+
let client = Client::default();
+let mut res = client.get("https://httpbin.org/robots.txt").send().await?;
+let body: Bytes = res.body().await?;
+
source

pub fn json<T: DeserializeOwned>(&mut self) -> JsonBody<S, T>

Returns a Future consumes the body stream, parses JSON, and resolves to a deserialized +T value.

+
§Errors
+

Future returns error if:

+
    +
  • content type is not application/json;
  • +
  • content length is greater than limit (default: 2 MiB).
  • +
+
§Examples
+
let client = Client::default();
+let mut res = client.get("https://httpbin.org/json").send().await?;
+let val = res.json::<serde_json::Value>().await?;
+assert!(val.is_object());
+

Trait Implementations§

source§

impl<S> Debug for ClientResponse<S>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<S> HttpMessage for ClientResponse<S>

§

type Stream = S

Type of message payload stream
source§

fn headers(&self) -> &HeaderMap

Read the message headers.
source§

fn take_payload(&mut self) -> Payload<S>

Message payload stream
source§

fn extensions(&self) -> Ref<'_, Extensions>

Returns a reference to the request-local data/extensions container.
source§

fn extensions_mut(&self) -> RefMut<'_, Extensions>

Returns a mutable reference to the request-local data/extensions container.
§

fn content_type(&self) -> &str

Read the request content type. If request did not contain a Content-Type header, an empty +string is returned.
§

fn encoding(&self) -> Result<&'static Encoding, ContentTypeError>

Get content type encoding. Read more
§

fn mime_type(&self) -> Result<Option<Mime>, ContentTypeError>

Convert the request content type to a known mime type.
§

fn chunked(&self) -> Result<bool, ParseError>

Check if request has chunked transfer encoding.
source§

impl<S> Stream for ClientResponse<S>
where + S: Stream<Item = Result<Bytes, PayloadError>> + Unpin,

§

type Item = Result<Bytes, PayloadError>

Values yielded by the stream.
source§

fn poll_next( + self: Pin<&mut Self>, + cx: &mut Context<'_> +) -> Poll<Option<Self::Item>>

Attempt to pull out the next value of this stream, registering the +current task for wakeup if the value is not yet available, and returning +None if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more
source§

impl<'__pin, S> Unpin for ClientResponse<S>
where + __Origin<'__pin, S>: Unpin,

Auto Trait Implementations§

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Freeze for ClientResponse<S>

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !RefUnwindSafe for ClientResponse<S>

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Send for ClientResponse<S>

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Sync for ClientResponse<S>

§

impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !UnwindSafe for ClientResponse<S>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
§

impl<T> StreamExt for T
where + T: Stream + ?Sized,

§

fn next(&mut self) -> Next<'_, Self>
where + Self: Unpin,

Creates a future that resolves to the next item in the stream. Read more
§

fn into_future(self) -> StreamFuture<Self>
where + Self: Sized + Unpin,

Converts this stream into a future of (next_item, tail_of_stream). +If the stream terminates, then the next item is None. Read more
§

fn map<T, F>(self, f: F) -> Map<Self, F>
where + F: FnMut(Self::Item) -> T, + Self: Sized,

Maps this stream’s items to a different type, returning a new stream of +the resulting type. Read more
§

fn enumerate(self) -> Enumerate<Self>
where + Self: Sized,

Creates a stream which gives the current iteration count as well as +the next value. Read more
§

fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Filters the values produced by this stream according to the provided +asynchronous predicate. Read more
§

fn filter_map<Fut, T, F>(self, f: F) -> FilterMap<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = Option<T>>, + Self: Sized,

Filters the values produced by this stream while simultaneously mapping +them to a different type according to the provided asynchronous closure. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future, + Self: Sized,

Computes from this stream’s items new items of a different type using +an asynchronous closure. Read more
§

fn collect<C>(self) -> Collect<Self, C>
where + C: Default + Extend<Self::Item>, + Self: Sized,

Transforms a stream into a collection, returning a +future representing the result of that computation. Read more
§

fn unzip<A, B, FromA, FromB>(self) -> Unzip<Self, FromA, FromB>
where + FromA: Default + Extend<A>, + FromB: Default + Extend<B>, + Self: Sized + Stream<Item = (A, B)>,

Converts a stream of pairs into a future, which +resolves to pair of containers. Read more
§

fn concat(self) -> Concat<Self>
where + Self: Sized, + Self::Item: Extend<<Self::Item as IntoIterator>::Item> + IntoIterator + Default,

Concatenate all items of a stream into a single extendable +destination, returning a future representing the end result. Read more
§

fn count(self) -> Count<Self>
where + Self: Sized,

Drives the stream to completion, counting the number of items. Read more
§

fn cycle(self) -> Cycle<Self>
where + Self: Sized + Clone,

Repeats a stream endlessly. Read more
§

fn fold<T, Fut, F>(self, init: T, f: F) -> Fold<Self, Fut, T, F>
where + F: FnMut(T, Self::Item) -> Fut, + Fut: Future<Output = T>, + Self: Sized,

Execute an accumulating asynchronous computation over a stream, +collecting all the values into one final result. Read more
§

fn any<Fut, F>(self, f: F) -> Any<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if any element in stream satisfied a predicate. Read more
§

fn all<Fut, F>(self, f: F) -> All<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Execute predicate over asynchronous stream, and return true if all element in stream satisfied a predicate. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Item: Stream, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> FlattenUnorderedWithFlowController<Self, ()>
where + Self::Item: Stream + Unpin, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Polls +inner streams produced by the base stream concurrently. Read more
§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where + F: FnMut(Self::Item) -> U, + U: Stream, + Self: Sized,

Maps a stream like [StreamExt::map] but flattens nested Streams. Read more
§

fn flat_map_unordered<U, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> FlatMapUnordered<Self, U, F>
where + U: Stream + Unpin, + F: FnMut(Self::Item) -> U, + Self: Sized,

Available on crate feature alloc only.
Maps a stream like [StreamExt::map] but flattens nested Streams +and polls them concurrently, yielding items in any order, as they made +available. Read more
§

fn scan<S, B, Fut, F>(self, initial_state: S, f: F) -> Scan<Self, S, Fut, F>
where + F: FnMut(&mut S, Self::Item) -> Fut, + Fut: Future<Output = Option<B>>, + Self: Sized,

Combinator similar to [StreamExt::fold] that holds internal state +and produces a new stream. Read more
§

fn skip_while<Fut, F>(self, f: F) -> SkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_while<Fut, F>(self, f: F) -> TakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Item) -> Fut, + Fut: Future<Output = bool>, + Self: Sized,

Take elements from this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn take_until<Fut>(self, fut: Fut) -> TakeUntil<Self, Fut>
where + Fut: Future, + Self: Sized,

Take elements from this stream until the provided future resolves. Read more
§

fn for_each<Fut, F>(self, f: F) -> ForEach<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream. Read more
§

fn for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> ForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Item) -> Fut, + Fut: Future<Output = ()>, + Self: Sized,

Available on crate feature alloc only.
Runs this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available. Read more
§

fn take(self, n: usize) -> Take<Self>
where + Self: Sized,

Creates a new stream of at most n items of the underlying stream. Read more
§

fn skip(self, n: usize) -> Skip<Self>
where + Self: Sized,

Creates a new stream which skips n items of the underlying stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a stream such that poll_next will never +again be called once it has finished. This method can be used to turn +any Stream into a FusedStream. Read more
§

fn by_ref(&mut self) -> &mut Self

Borrows a stream, rather than consuming it. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the stream. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Stream<Item = Self::Item> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the stream in a Box, pinning it. Read more
§

fn buffered(self, n: usize) -> Buffered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures. Read more
§

fn buffer_unordered(self, n: usize) -> BufferUnordered<Self>
where + Self::Item: Future, + Self: Sized,

Available on crate feature alloc only.
An adaptor for creating a buffered list of pending futures (unordered). Read more
§

fn zip<St>(self, other: St) -> Zip<Self, St>
where + St: Stream, + Self: Sized,

An adapter for zipping two streams together. Read more
§

fn chain<St>(self, other: St) -> Chain<Self, St>
where + St: Stream<Item = Self::Item>, + Self: Sized,

Adapter for chaining two streams. Read more
§

fn peekable(self) -> Peekable<Self>
where + Self: Sized,

Creates a new stream which exposes a peek method. Read more
§

fn chunks(self, capacity: usize) -> Chunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up items of the stream inside a vector. Read more
§

fn ready_chunks(self, capacity: usize) -> ReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up ready items of the stream inside a vector. Read more
§

fn forward<S>(self, sink: S) -> Forward<Self, S>
where + S: Sink<Self::Ok, Error = Self::Error>, + Self: Sized + TryStream,

Available on crate feature sink only.
A future that completes after the given stream has been fully processed +into the sink and the sink has been flushed and closed. Read more
§

fn split<Item>(self) -> (SplitSink<Self, Item>, SplitStream<Self>)
where + Self: Sized + Sink<Item>,

Available on crate features sink and alloc only.
Splits this Stream + Sink object into separate Sink and Stream +objects. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnMut(&Self::Item), + Self: Sized,

Do something with each item of this stream, afterwards passing it on. Read more
§

fn left_stream<B>(self) -> Either<Self, B>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the left-hand variant +of that Either. Read more
§

fn right_stream<B>(self) -> Either<B, Self>
where + B: Stream<Item = Self::Item>, + Self: Sized,

Wrap this stream in an Either stream, making it the right-hand variant +of that Either. Read more
§

fn poll_next_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>
where + Self: Unpin,

A convenience method for calling [Stream::poll_next] on Unpin +stream types.
§

fn select_next_some(&mut self) -> SelectNextSome<'_, Self>
where + Self: Unpin + FusedStream,

Returns a Future that resolves when the next item in this stream is +ready. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<S, T, E> TryStream for S
where + S: Stream<Item = 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
§

fn try_poll_next( + self: Pin<&mut S>, + cx: &mut Context<'_> +) -> Poll<Option<Result<<S as TryStream>::Ok, <S as TryStream>::Error>>>

Poll this TryStream as if it were a Stream. Read more
§

impl<S> TryStreamExt for S
where + S: TryStream + ?Sized,

§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Wraps the current stream in a new stream which converts the error type +into the one provided. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> T,

Wraps the current stream in a new stream which maps the success value +using the provided closure. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + Self: Sized, + F: FnMut(Self::Error) -> E,

Wraps the current stream in a new stream which maps the error value +using the provided closure. Read more
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Chain on a computation for when a value is ready, passing the successful +results to the provided closure f. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnMut(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Chain on a computation for when an error happens, passing the +erroneous result to the provided closure f. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnMut(&Self::Ok), + Self: Sized,

Do something with the success value of this stream, afterwards passing +it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnMut(&Self::Error), + Self: Sized,

Do something with the error value of this stream, afterwards passing it on. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Wraps a [TryStream] into a type that implements +Stream Read more
§

fn try_next(&mut self) -> TryNext<'_, Self>
where + Self: Unpin,

Creates a future that attempts to resolve the next item in the stream. +If an error is encountered before the next item, the error is returned +instead. Read more
§

fn try_for_each<Fut, F>(self, f: F) -> TryForEach<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: TryFuture<Ok = (), Error = Self::Error>, + Self: Sized,

Attempts to run this stream to completion, executing the provided +asynchronous closure for each element on the stream. Read more
§

fn try_skip_while<Fut, F>(self, f: F) -> TrySkipWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Skip elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_take_while<Fut, F>(self, f: F) -> TryTakeWhile<Self, Fut, F>
where + F: FnMut(&Self::Ok) -> Fut, + Fut: TryFuture<Ok = bool, Error = Self::Error>, + Self: Sized,

Take elements on this stream while the provided asynchronous predicate +resolves to true. Read more
§

fn try_for_each_concurrent<Fut, F>( + self, + limit: impl Into<Option<usize>>, + f: F +) -> TryForEachConcurrent<Self, Fut, F>
where + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = Result<(), Self::Error>>, + Self: Sized,

Available on crate feature alloc only.
Attempts to run this stream to completion, executing the provided asynchronous +closure for each element on the stream concurrently as elements become +available, exiting as soon as an error occurs. Read more
§

fn try_collect<C>(self) -> TryCollect<Self, C>
where + C: Default + Extend<Self::Ok>, + Self: Sized,

Attempt to transform a stream into a collection, +returning a future representing the result of that computation. Read more
§

fn try_chunks(self, capacity: usize) -> TryChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful items of the stream inside a vector. Read more
§

fn try_ready_chunks(self, capacity: usize) -> TryReadyChunks<Self>
where + Self: Sized,

Available on crate feature alloc only.
An adaptor for chunking up successful, ready items of the stream inside a vector. Read more
§

fn try_filter<Fut, F>(self, f: F) -> TryFilter<Self, Fut, F>
where + Fut: Future<Output = bool>, + F: FnMut(&Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream according to the +provided asynchronous closure. Read more
§

fn try_filter_map<Fut, F, T>(self, f: F) -> TryFilterMap<Self, Fut, F>
where + Fut: TryFuture<Ok = Option<T>, Error = Self::Error>, + F: FnMut(Self::Ok) -> Fut, + Self: Sized,

Attempt to filter the values produced by this stream while +simultaneously mapping them to a different type according to the +provided asynchronous closure. Read more
§

fn try_flatten_unordered( + self, + limit: impl Into<Option<usize>> +) -> TryFlattenUnordered<Self>
where + Self::Ok: TryStream + Unpin, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Flattens a stream of streams into just one continuous stream. Produced streams +will be polled concurrently and any errors will be passed through without looking at them. +If the underlying base stream returns an error, it will be immediately propagated. Read more
§

fn try_flatten(self) -> TryFlatten<Self>
where + Self::Ok: TryStream, + <Self::Ok as TryStream>::Error: From<Self::Error>, + Self: Sized,

Flattens a stream of streams into just one continuous stream. Read more
§

fn try_fold<T, Fut, F>(self, init: T, f: F) -> TryFold<Self, Fut, T, F>
where + F: FnMut(T, Self::Ok) -> Fut, + Fut: TryFuture<Ok = T, Error = Self::Error>, + Self: Sized,

Attempt to execute an accumulating asynchronous computation over a +stream, collecting all the values into one final result. Read more
§

fn try_concat(self) -> TryConcat<Self>
where + Self: Sized, + Self::Ok: Extend<<Self::Ok as IntoIterator>::Item> + IntoIterator + Default,

Attempt to concatenate all items of a stream into a single +extendable destination, returning a future representing the end result. Read more
§

fn try_buffer_unordered(self, n: usize) -> TryBufferUnordered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently (unordered). Read more
§

fn try_buffered(self, n: usize) -> TryBuffered<Self>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Available on crate feature alloc only.
Attempt to execute several futures from a stream concurrently. Read more
§

fn try_poll_next_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Option<Result<Self::Ok, Self::Error>>>
where + Self: Unpin,

A convenience method for calling [TryStream::try_poll_next] on Unpin +stream types.
§

fn try_all<Fut, F>(self, f: F) -> TryAll<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if all items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that does not satisfy the predicate. Read more
§

fn try_any<Fut, F>(self, f: F) -> TryAny<Self, Fut, F>
where + Self: Sized, + F: FnMut(Self::Ok) -> Fut, + Fut: Future<Output = bool>,

Attempt to execute a predicate over an asynchronous stream and evaluate if any items +satisfy the predicate. Exits early if an Err is encountered or if an Ok item is found +that satisfies the predicate. Read more
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/struct.Connect.html b/awc/struct.Connect.html new file mode 100644 index 000000000..623bb69ab --- /dev/null +++ b/awc/struct.Connect.html @@ -0,0 +1,21 @@ +Connect in awc - Rust

Struct awc::Connect

source ·
pub struct Connect {
+    pub uri: Uri,
+    pub addr: Option<SocketAddr>,
+}

Fields§

§uri: Uri§addr: Option<SocketAddr>

Trait Implementations§

source§

impl Clone for Connect

source§

fn clone(&self) -> Connect

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/struct.Connector.html b/awc/struct.Connector.html new file mode 100644 index 000000000..0fe8df4e8 --- /dev/null +++ b/awc/struct.Connector.html @@ -0,0 +1,90 @@ +Connector in awc - Rust

Struct awc::Connector

source ·
pub struct Connector<T> { /* private fields */ }
Expand description

Manages HTTP client network connectivity.

+

The Connector type uses a builder-like combinator pattern for service construction that +finishes by calling the .finish() method.

+ +
use std::time::Duration;
+
+let connector = awc::Connector::new()
+     .timeout(Duration::from_secs(5))
+     .finish();
+

Implementations§

source§

impl Connector<()>

source

pub fn new( +) -> Connector<impl Service<ConnectInfo<Uri>, Response = TcpConnection<Uri, TcpStream>, Error = ConnectError> + Clone>

Create a new connector with default TLS settings

+
§Panics
+
    +
  • When the rustls-0_23-webpki-roots or rustls-0_23-native-roots features are enabled +and no default crypto provider has been loaded, this method will panic.
  • +
  • When the rustls-0_23-native-roots or rustls-0_22-native-roots features are enabled +and the runtime system has no native root certificates, this method will panic.
  • +
+
source§

impl<S> Connector<S>

source

pub fn connector<S1, Io1>(self, connector: S1) -> Connector<S1>
where + Io1: ActixStream + Debug + 'static, + S1: Service<ConnectInfo<Uri>, Response = TcpConnection<Uri, Io1>, Error = TcpConnectError> + Clone,

Sets custom connector.

+
source§

impl<S, IO> Connector<S>
where + IO: ActixStream + Debug + 'static, + S: Service<ConnectInfo<Uri>, Response = Connection<Uri, IO>, Error = ConnectError> + Clone + 'static,

source

pub fn timeout(self, timeout: Duration) -> Self

Sets TCP connection timeout.

+

This is the max time allowed to connect to remote host, including DNS name resolution.

+

By default, the timeout is 5 seconds.

+
source

pub fn handshake_timeout(self, timeout: Duration) -> Self

Sets TLS handshake timeout.

+

This is the max time allowed to perform the TLS handshake with remote host after TCP +connection is established.

+

By default, the timeout is 5 seconds.

+
source

pub fn openssl(self, connector: SslConnector) -> Self

Available on crate feature openssl only.

Sets custom OpenSSL SslConnector instance.

+
source

pub fn rustls(self, connector: Arc<ClientConfig>) -> Self

Available on crate feature rustls-0_20 only.

Sets custom Rustls v0.20 ClientConfig instance.

+
source

pub fn rustls_021(self, connector: Arc<ClientConfig>) -> Self

Available on crate feature rustls-0_21 only.

Sets custom Rustls v0.21 ClientConfig instance.

+
source

pub fn rustls_0_22(self, connector: Arc<ClientConfig>) -> Self

Available on crate features rustls-0_22-webpki-roots or rustls-0_22-native-roots only.

Sets custom Rustls v0.22 ClientConfig instance.

+
source

pub fn rustls_0_23(self, connector: Arc<ClientConfig>) -> Self

Available on crate feature rustls-0_23 only.

Sets custom Rustls v0.23 ClientConfig instance.

+

In order to enable ALPN, set the .alpn_protocols field on the ClientConfig to the +following:

+ +
vec![b"h2".to_vec(), b"http/1.1".to_vec()]
+
source

pub fn max_http_version(self, val: Version) -> Self

Sets maximum supported HTTP major version.

+

Supported versions are HTTP/1.1 and HTTP/2.

+
source

pub fn initial_window_size(self, size: u32) -> Self

Sets the initial window size (in bytes) for HTTP/2 stream-level flow control for received +data.

+

The default value is 65,535 and is good for APIs, but not for big objects.

+
source

pub fn initial_connection_window_size(self, size: u32) -> Self

Sets the initial window size (in bytes) for HTTP/2 connection-level flow control for +received data.

+

The default value is 65,535 and is good for APIs, but not for big objects.

+
source

pub fn limit(self, limit: usize) -> Self

Set total number of simultaneous connections per type of scheme.

+

If limit is 0, the connector has no limit.

+

The default limit size is 100.

+
source

pub fn conn_keep_alive(self, dur: Duration) -> Self

Set keep-alive period for opened connection.

+

Keep-alive period is the period between connection usage. If +the delay between repeated usages of the same connection +exceeds this period, the connection is closed. +Default keep-alive period is 15 seconds.

+
source

pub fn conn_lifetime(self, dur: Duration) -> Self

Set max lifetime period for connection.

+

Connection lifetime is max lifetime of any opened connection +until it is closed regardless of keep-alive period. +Default lifetime period is 75 seconds.

+
source

pub fn disconnect_timeout(self, dur: Duration) -> Self

Set server connection disconnect timeout in milliseconds.

+

Defines a timeout for disconnect connection. If a disconnect procedure does not complete +within this time, the socket get dropped. This timeout affects only secure connections.

+

To disable timeout set value to 0.

+

By default disconnect timeout is set to 3000 milliseconds.

+
source

pub fn local_address(self, addr: IpAddr) -> Self

Set local IP Address the connector would use for establishing connection.

+
source

pub fn finish( + self +) -> ConnectorServicePriv<TcpConnectorService<TcpConnectorInnerService<S>>, Rc<dyn Service<Connect, Response = (Box<dyn ConnectionIo>, Protocol), Error = ConnectError, Future = LocalBoxFuture<'static, Result<(Box<dyn ConnectionIo>, Protocol), ConnectError>>>>, IO, Box<dyn ConnectionIo>>

Finish configuration process and create connector service.

+

The Connector builder always concludes by calling finish() last in its combinator chain.

+

Auto Trait Implementations§

§

impl<T> Freeze for Connector<T>
where + T: Freeze,

§

impl<T> !RefUnwindSafe for Connector<T>

§

impl<T> Send for Connector<T>
where + T: Send,

§

impl<T> Sync for Connector<T>
where + T: Sync,

§

impl<T> Unpin for Connector<T>
where + T: Unpin,

§

impl<T> !UnwindSafe for Connector<T>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/struct.FrozenClientRequest.html b/awc/struct.FrozenClientRequest.html new file mode 100644 index 000000000..113d6954c --- /dev/null +++ b/awc/struct.FrozenClientRequest.html @@ -0,0 +1,33 @@ +FrozenClientRequest in awc - Rust

Struct awc::FrozenClientRequest

source ·
pub struct FrozenClientRequest { /* private fields */ }
Expand description

FrozenClientRequest struct represents cloneable client request.

+

It could be used to send same request multiple times.

+

Implementations§

source§

impl FrozenClientRequest

source

pub fn get_uri(&self) -> &Uri

Get HTTP URI of request

+
source

pub fn get_method(&self) -> &Method

Get HTTP method of this request

+
source

pub fn headers(&self) -> &HeaderMap

Returns request’s headers.

+
source

pub fn send_body<B>(&self, body: B) -> SendClientRequest
where + B: MessageBody + 'static,

Send a body.

+
source

pub fn send_json<T: Serialize>(&self, value: &T) -> SendClientRequest

Send a json body.

+
source

pub fn send_form<T: Serialize>(&self, value: &T) -> SendClientRequest

Send an urlencoded body.

+
source

pub fn send_stream<S, E>(&self, stream: S) -> SendClientRequest
where + S: Stream<Item = Result<Bytes, E>> + 'static, + E: Into<Box<dyn Error>> + 'static,

Send a streaming body.

+
source

pub fn send(&self) -> SendClientRequest

Send an empty body.

+
source

pub fn extra_headers(&self, extra_headers: HeaderMap) -> FrozenSendBuilder

Clones this FrozenClientRequest, returning a new one with extra headers added.

+
source

pub fn extra_header(&self, header: impl TryIntoHeaderPair) -> FrozenSendBuilder

Clones this FrozenClientRequest, returning a new one with the extra header added.

+

Trait Implementations§

source§

impl Clone for FrozenClientRequest

source§

fn clone(&self) -> FrozenClientRequest

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/struct.FrozenSendBuilder.html b/awc/struct.FrozenSendBuilder.html new file mode 100644 index 000000000..d2011b890 --- /dev/null +++ b/awc/struct.FrozenSendBuilder.html @@ -0,0 +1,26 @@ +FrozenSendBuilder in awc - Rust

Struct awc::FrozenSendBuilder

source ·
pub struct FrozenSendBuilder { /* private fields */ }
Expand description

Builder that allows to modify extra headers.

+

Implementations§

source§

impl FrozenSendBuilder

source

pub fn extra_header(self, header: impl TryIntoHeaderPair) -> Self

Insert a header, it overrides existing header in FrozenClientRequest.

+
source

pub fn send_body(self, body: impl MessageBody + 'static) -> SendClientRequest

Complete request construction and send a body.

+
source

pub fn send_json(self, value: impl Serialize) -> SendClientRequest

Complete request construction and send a json body.

+
source

pub fn send_form(self, value: impl Serialize) -> SendClientRequest

Complete request construction and send an urlencoded body.

+
source

pub fn send_stream<S, E>(self, stream: S) -> SendClientRequest
where + S: Stream<Item = Result<Bytes, E>> + 'static, + E: Into<Box<dyn Error>> + 'static,

Complete request construction and send a streaming body.

+
source

pub fn send(self) -> SendClientRequest

Complete request construction and send an empty body.

+

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/struct.JsonBody.html b/awc/struct.JsonBody.html new file mode 100644 index 000000000..7823b6e07 --- /dev/null +++ b/awc/struct.JsonBody.html @@ -0,0 +1,125 @@ +JsonBody in awc - Rust

Struct awc::JsonBody

source ·
pub struct JsonBody<S, T> { /* private fields */ }
Expand description

A Future that reads a body stream, parses JSON, resolving to a deserialized T.

+

§Errors

+

Future implementation returns error if:

+
    +
  • content type is not application/json;
  • +
  • content length is greater than limit (default: 2 MiB).
  • +
+

Implementations§

source§

impl<S, T> JsonBody<S, T>
where + S: Stream<Item = Result<Bytes, PayloadError>>, + T: DeserializeOwned,

source

pub fn new(res: &mut ClientResponse<S>) -> Self

Creates a JSON body stream reader from a response by taking its payload.

+
source

pub fn limit(self, limit: usize) -> Self

Change max size of payload. Default limit is 2 MiB.

+

Trait Implementations§

source§

impl<S, T> Future for JsonBody<S, T>
where + S: Stream<Item = Result<Bytes, PayloadError>>, + T: DeserializeOwned,

§

type Output = Result<T, JsonPayloadError>

The type of value produced on completion.
source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
source§

impl<'__pin, S, T> Unpin for JsonBody<S, T>
where + __Origin<'__pin, S, T>: Unpin,

Auto Trait Implementations§

§

impl<S, T> !Freeze for JsonBody<S, T>

§

impl<S, T> !RefUnwindSafe for JsonBody<S, T>

§

impl<S, T> !Send for JsonBody<S, T>

§

impl<S, T> !Sync for JsonBody<S, T>

§

impl<S, T> !UnwindSafe for JsonBody<S, T>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> FutureExt for T
where + T: Future + ?Sized,

§

fn map<U, F>(self, f: F) -> Map<Self, F>
where + F: FnOnce(Self::Output) -> U, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn map_into<U>(self) -> MapInto<Self, U>
where + Self::Output: Into<U>, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnOnce(Self::Output) -> Fut, + Fut: Future, + Self: Sized,

Chain on a computation for when a future finished, passing the result of +the future to the provided closure f. Read more
§

fn left_future<B>(self) -> Either<Self, B>
where + B: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the left-hand variant +of that Either. Read more
§

fn right_future<A>(self) -> Either<A, Self>
where + A: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the right-hand variant +of that Either. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Convert this future into a single element stream. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Output: Future, + Self: Sized,

Flatten the execution of this future when the output of this +future is itself another future. Read more
§

fn flatten_stream(self) -> FlattenStream<Self>
where + Self::Output: Stream, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a future such that poll will never again be called once it has +completed. This method can be used to turn any Future into a +FusedFuture. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnOnce(&Self::Output), + Self: Sized,

Do something with the output of a future before passing it on. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the future. Read more
§

fn shared(self) -> Shared<Self>
where + Self: Sized, + Self::Output: Clone,

Available on crate feature std only.
Create a cloneable handle to this future where all handles will resolve +to the same result. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn unit_error(self) -> UnitError<Self>
where + Self: Sized,

§

fn never_error(self) -> NeverError<Self>
where + Self: Sized,

§

fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where + Self: Unpin,

A convenience for calling Future::poll on Unpin future types.
§

fn now_or_never(self) -> Option<Self::Output>
where + Self: Sized,

Evaluates and consumes the future, returning the resulting output if +the future is ready after the first call to Future::poll. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<F> IntoFuture for F
where + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

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
§

fn try_poll( + self: Pin<&mut F>, + cx: &mut Context<'_> +) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
§

impl<Fut> TryFutureExt for Fut
where + Fut: TryFuture + ?Sized,

§

fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>
where + Self::Ok: Sink<Item, Error = Self::Error>, + Self: Sized,

Available on crate feature sink only.
Flattens the execution of this future when the successful result of this +future is a [Sink]. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + F: FnOnce(Self::Ok) -> T, + Self: Sized,

Maps this future’s success value to a different value. Read more
§

fn map_ok_or_else<T, E, F>(self, e: E, f: F) -> MapOkOrElse<Self, F, E>
where + F: FnOnce(Self::Ok) -> T, + E: FnOnce(Self::Error) -> T, + Self: Sized,

Maps this future’s success value to a different value, and permits for error handling resulting in the same type. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + F: FnOnce(Self::Error) -> E, + Self: Sized,

Maps this future’s error value to a different value. Read more
§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Maps this future’s Error to a new error type +using the Into trait. Read more
§

fn ok_into<U>(self) -> OkInto<Self, U>
where + Self: Sized, + Self::Ok: Into<U>,

Maps this future’s Ok to a new type +using the Into trait.
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnOnce(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Executes another future after this one resolves successfully. The +success value is passed to a closure to create this subsequent future. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnOnce(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Executes another future if this one resolves to an error. The +error value is passed to a closure to create this subsequent future. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnOnce(&Self::Ok), + Self: Sized,

Do something with the success value of a future before passing it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnOnce(&Self::Error), + Self: Sized,

Do something with the error value of a future before passing it on. Read more
§

fn try_flatten(self) -> TryFlatten<Self, Self::Ok>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is another future. Read more
§

fn try_flatten_stream(self) -> TryFlattenStream<Self>
where + Self::Ok: TryStream<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F>
where + Self: Sized, + F: FnOnce(Self::Error) -> Self::Ok,

Unwraps this future’s output, producing a future with this future’s +Ok type as its +Output type. Read more
§

fn into_future(self) -> IntoFuture<Self>
where + Self: Sized,

Wraps a [TryFuture] into a type that implements +Future. Read more
§

fn try_poll_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Result<Self::Ok, Self::Error>>
where + Self: Unpin,

A convenience method for calling [TryFuture::try_poll] on Unpin +future types.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/struct.ResponseBody.html b/awc/struct.ResponseBody.html new file mode 100644 index 000000000..364eed574 --- /dev/null +++ b/awc/struct.ResponseBody.html @@ -0,0 +1,124 @@ +ResponseBody in awc - Rust

Struct awc::ResponseBody

source ·
pub struct ResponseBody<S> { /* private fields */ }
Expand description

A Future that reads a body stream, resolving as [Bytes].

+

§Errors

+

Future implementation returns error if:

+
    +
  • content type is not application/json;
  • +
  • content length is greater than limit (default: 2 MiB).
  • +
+

Implementations§

source§

impl<S> ResponseBody<S>
where + S: Stream<Item = Result<Bytes, PayloadError>>,

source

pub fn new(res: &mut ClientResponse<S>) -> ResponseBody<S>

Creates a body stream reader from a response by taking its payload.

+
source

pub fn limit(self, limit: usize) -> Self

Change max size limit of payload.

+

The default limit is 2 MiB.

+

Trait Implementations§

source§

impl<S> Future for ResponseBody<S>
where + S: Stream<Item = Result<Bytes, PayloadError>>,

§

type Output = Result<Bytes, PayloadError>

The type of value produced on completion.
source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempt to resolve the future to a final value, registering +the current task for wakeup if the value is not yet available. Read more
source§

impl<'__pin, S> Unpin for ResponseBody<S>
where + __Origin<'__pin, S>: Unpin,

Auto Trait Implementations§

§

impl<S> !Freeze for ResponseBody<S>

§

impl<S> !RefUnwindSafe for ResponseBody<S>

§

impl<S> !Send for ResponseBody<S>

§

impl<S> !Sync for ResponseBody<S>

§

impl<S> !UnwindSafe for ResponseBody<S>

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> FutureExt for T
where + T: Future + ?Sized,

§

fn map<U, F>(self, f: F) -> Map<Self, F>
where + F: FnOnce(Self::Output) -> U, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn map_into<U>(self) -> MapInto<Self, U>
where + Self::Output: Into<U>, + Self: Sized,

Map this future’s output to a different type, returning a new future of +the resulting type. Read more
§

fn then<Fut, F>(self, f: F) -> Then<Self, Fut, F>
where + F: FnOnce(Self::Output) -> Fut, + Fut: Future, + Self: Sized,

Chain on a computation for when a future finished, passing the result of +the future to the provided closure f. Read more
§

fn left_future<B>(self) -> Either<Self, B>
where + B: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the left-hand variant +of that Either. Read more
§

fn right_future<A>(self) -> Either<A, Self>
where + A: Future<Output = Self::Output>, + Self: Sized,

Wrap this future in an Either future, making it the right-hand variant +of that Either. Read more
§

fn into_stream(self) -> IntoStream<Self>
where + Self: Sized,

Convert this future into a single element stream. Read more
§

fn flatten(self) -> Flatten<Self>
where + Self::Output: Future, + Self: Sized,

Flatten the execution of this future when the output of this +future is itself another future. Read more
§

fn flatten_stream(self) -> FlattenStream<Self>
where + Self::Output: Stream, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn fuse(self) -> Fuse<Self>
where + Self: Sized,

Fuse a future such that poll will never again be called once it has +completed. This method can be used to turn any Future into a +FusedFuture. Read more
§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where + F: FnOnce(&Self::Output), + Self: Sized,

Do something with the output of a future before passing it on. Read more
§

fn catch_unwind(self) -> CatchUnwind<Self>
where + Self: Sized + UnwindSafe,

Available on crate feature std only.
Catches unwinding panics while polling the future. Read more
§

fn shared(self) -> Shared<Self>
where + Self: Sized, + Self::Output: Clone,

Available on crate feature std only.
Create a cloneable handle to this future where all handles will resolve +to the same result. Read more
§

fn boxed<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>>
where + Self: Sized + Send + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn boxed_local<'a>(self) -> Pin<Box<dyn Future<Output = Self::Output> + 'a>>
where + Self: Sized + 'a,

Available on crate feature alloc only.
Wrap the future in a Box, pinning it. Read more
§

fn unit_error(self) -> UnitError<Self>
where + Self: Sized,

§

fn never_error(self) -> NeverError<Self>
where + Self: Sized,

§

fn poll_unpin(&mut self, cx: &mut Context<'_>) -> Poll<Self::Output>
where + Self: Unpin,

A convenience for calling Future::poll on Unpin future types.
§

fn now_or_never(self) -> Option<Self::Output>
where + Self: Sized,

Evaluates and consumes the future, returning the resulting output if +the future is ready after the first call to Future::poll. Read more
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<F> IntoFuture for F
where + F: Future,

§

type Output = <F as Future>::Output

The output that the future will produce on completion.
§

type IntoFuture = F

Which kind of future are we turning this into?
source§

fn into_future(self) -> <F as IntoFuture>::IntoFuture

Creates a future from a value. Read more
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

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
§

fn try_poll( + self: Pin<&mut F>, + cx: &mut Context<'_> +) -> Poll<<F as Future>::Output>

Poll this TryFuture as if it were a Future. Read more
§

impl<Fut> TryFutureExt for Fut
where + Fut: TryFuture + ?Sized,

§

fn flatten_sink<Item>(self) -> FlattenSink<Self, Self::Ok>
where + Self::Ok: Sink<Item, Error = Self::Error>, + Self: Sized,

Available on crate feature sink only.
Flattens the execution of this future when the successful result of this +future is a [Sink]. Read more
§

fn map_ok<T, F>(self, f: F) -> MapOk<Self, F>
where + F: FnOnce(Self::Ok) -> T, + Self: Sized,

Maps this future’s success value to a different value. Read more
§

fn map_ok_or_else<T, E, F>(self, e: E, f: F) -> MapOkOrElse<Self, F, E>
where + F: FnOnce(Self::Ok) -> T, + E: FnOnce(Self::Error) -> T, + Self: Sized,

Maps this future’s success value to a different value, and permits for error handling resulting in the same type. Read more
§

fn map_err<E, F>(self, f: F) -> MapErr<Self, F>
where + F: FnOnce(Self::Error) -> E, + Self: Sized,

Maps this future’s error value to a different value. Read more
§

fn err_into<E>(self) -> ErrInto<Self, E>
where + Self: Sized, + Self::Error: Into<E>,

Maps this future’s Error to a new error type +using the Into trait. Read more
§

fn ok_into<U>(self) -> OkInto<Self, U>
where + Self: Sized, + Self::Ok: Into<U>,

Maps this future’s Ok to a new type +using the Into trait.
§

fn and_then<Fut, F>(self, f: F) -> AndThen<Self, Fut, F>
where + F: FnOnce(Self::Ok) -> Fut, + Fut: TryFuture<Error = Self::Error>, + Self: Sized,

Executes another future after this one resolves successfully. The +success value is passed to a closure to create this subsequent future. Read more
§

fn or_else<Fut, F>(self, f: F) -> OrElse<Self, Fut, F>
where + F: FnOnce(Self::Error) -> Fut, + Fut: TryFuture<Ok = Self::Ok>, + Self: Sized,

Executes another future if this one resolves to an error. The +error value is passed to a closure to create this subsequent future. Read more
§

fn inspect_ok<F>(self, f: F) -> InspectOk<Self, F>
where + F: FnOnce(&Self::Ok), + Self: Sized,

Do something with the success value of a future before passing it on. Read more
§

fn inspect_err<F>(self, f: F) -> InspectErr<Self, F>
where + F: FnOnce(&Self::Error), + Self: Sized,

Do something with the error value of a future before passing it on. Read more
§

fn try_flatten(self) -> TryFlatten<Self, Self::Ok>
where + Self::Ok: TryFuture<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is another future. Read more
§

fn try_flatten_stream(self) -> TryFlattenStream<Self>
where + Self::Ok: TryStream<Error = Self::Error>, + Self: Sized,

Flatten the execution of this future when the successful result of this +future is a stream. Read more
§

fn unwrap_or_else<F>(self, f: F) -> UnwrapOrElse<Self, F>
where + Self: Sized, + F: FnOnce(Self::Error) -> Self::Ok,

Unwraps this future’s output, producing a future with this future’s +Ok type as its +Output type. Read more
§

fn into_future(self) -> IntoFuture<Self>
where + Self: Sized,

Wraps a [TryFuture] into a type that implements +Future. Read more
§

fn try_poll_unpin( + &mut self, + cx: &mut Context<'_> +) -> Poll<Result<Self::Ok, Self::Error>>
where + Self: Unpin,

A convenience method for calling [TryFuture::try_poll] on Unpin +future types.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/test/index.html b/awc/test/index.html new file mode 100644 index 000000000..27c12f5fd --- /dev/null +++ b/awc/test/index.html @@ -0,0 +1,2 @@ +awc::test - Rust

Module awc::test

source ·
Expand description

Test helpers for actix http client to use during testing.

+

Structs§

\ No newline at end of file diff --git a/awc/test/sidebar-items.js b/awc/test/sidebar-items.js new file mode 100644 index 000000000..1d5fadadb --- /dev/null +++ b/awc/test/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["TestResponse"]}; \ No newline at end of file diff --git a/awc/test/struct.TestResponse.html b/awc/test/struct.TestResponse.html new file mode 100644 index 000000000..fef475c40 --- /dev/null +++ b/awc/test/struct.TestResponse.html @@ -0,0 +1,25 @@ +TestResponse in awc::test - Rust

Struct awc::test::TestResponse

source ·
pub struct TestResponse { /* private fields */ }
Expand description

Test ClientResponse builder

+

Implementations§

source§

impl TestResponse

source

pub fn with_header(header: impl TryIntoHeaderPair) -> Self

Create TestResponse and set header

+
source

pub fn version(self, ver: Version) -> Self

Set HTTP version of this response

+
source

pub fn insert_header(self, header: impl TryIntoHeaderPair) -> Self

Insert a header

+
source

pub fn append_header(self, header: impl TryIntoHeaderPair) -> Self

Append a header

+
source

pub fn cookie(self, cookie: Cookie<'_>) -> Self

Available on crate feature cookies only.

Set cookie for this response

+
source

pub fn set_payload<B: Into<Bytes>>(self, data: B) -> Self

Set response’s payload

+
source

pub fn finish(self) -> ClientResponse

Complete response creation and generate ClientResponse instance

+

Trait Implementations§

source§

impl Default for TestResponse

source§

fn default() -> TestResponse

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/type.BoxConnectorService.html b/awc/type.BoxConnectorService.html new file mode 100644 index 000000000..bb51063a4 --- /dev/null +++ b/awc/type.BoxConnectorService.html @@ -0,0 +1 @@ +BoxConnectorService in awc - Rust

Type Alias awc::BoxConnectorService

source ·
pub type BoxConnectorService = Rc<dyn Service<ConnectRequest, Response = ConnectResponse, Error = SendRequestError, Future = LocalBoxFuture<'static, Result<ConnectResponse, SendRequestError>>>>;

Aliased Type§

struct BoxConnectorService { /* private fields */ }
\ No newline at end of file diff --git a/awc/type.BoxedSocket.html b/awc/type.BoxedSocket.html new file mode 100644 index 000000000..d9bb82cf5 --- /dev/null +++ b/awc/type.BoxedSocket.html @@ -0,0 +1 @@ +BoxedSocket in awc - Rust

Type Alias awc::BoxedSocket

source ·
pub type BoxedSocket = Box<dyn ConnectionIo>;

Aliased Type§

struct BoxedSocket(/* private fields */);
\ No newline at end of file diff --git a/awc/type.MessageBody.html b/awc/type.MessageBody.html new file mode 100644 index 000000000..1c4969aaf --- /dev/null +++ b/awc/type.MessageBody.html @@ -0,0 +1 @@ +MessageBody in awc - Rust

Type Alias awc::MessageBody

source ·
pub type MessageBody<B> = ResponseBody<B>;
👎Deprecated since 3.0.0: Renamed to ResponseBody.

Aliased Type§

struct MessageBody<B> { /* private fields */ }
\ No newline at end of file diff --git a/awc/ws/enum.CloseCode.html b/awc/ws/enum.CloseCode.html new file mode 100644 index 000000000..2e069e052 --- /dev/null +++ b/awc/ws/enum.CloseCode.html @@ -0,0 +1,72 @@ +CloseCode in awc::ws - Rust

Enum awc::ws::CloseCode

pub enum CloseCode {
+    Normal,
+    Away,
+    Protocol,
+    Unsupported,
+    Abnormal,
+    Invalid,
+    Policy,
+    Size,
+    Extension,
+    Error,
+    Restart,
+    Again,
+    // some variants omitted
+}
Expand description

Status code used to indicate why an endpoint is closing the WebSocket connection.

+

Variants§

§

Normal

Indicates a normal closure, meaning that the purpose for which the connection was +established has been fulfilled.

+
§

Away

Indicates that an endpoint is “going away”, such as a server going down or a browser having +navigated away from a page.

+
§

Protocol

Indicates that an endpoint is terminating the connection due to a protocol error.

+
§

Unsupported

Indicates that an endpoint is terminating the connection because it has received a type of +data it cannot accept (e.g., an endpoint that understands only text data MAY send this if it +receives a binary message).

+
§

Abnormal

Indicates an abnormal closure. If the abnormal closure was due to an error, this close code +will not be used. Instead, the on_error method of the handler will be called with +the error. However, if the connection is simply dropped, without an error, this close code +will be sent to the handler.

+
§

Invalid

Indicates that an endpoint is terminating the connection because it has received data within +a message that was not consistent with the type of the message (e.g., non-UTF-8 [RFC 3629] +data within a text message).

+
§

Policy

Indicates that an endpoint is terminating the connection because it has received a message +that violates its policy. This is a generic status code that can be returned when there is +no other more suitable status code (e.g., Unsupported or Size) or if there is a need to hide +specific details about the policy.

+
§

Size

Indicates that an endpoint is terminating the connection because it has received a message +that is too big for it to process.

+
§

Extension

Indicates that an endpoint (client) is terminating the connection because it has expected +the server to negotiate one or more extension, but the server didn’t return them in the +response message of the WebSocket handshake. The list of extensions that are needed should +be given as the reason for closing. Note that this status code is not used by the server, +because it can fail the WebSocket handshake instead.

+
§

Error

Indicates that a server is terminating the connection because it encountered an unexpected +condition that prevented it from fulfilling the request.

+
§

Restart

Indicates that the server is restarting. A client may choose to reconnect, and if it does, +it should use a randomized delay of 5-30 seconds between attempts.

+
§

Again

Indicates that the server is overloaded and the client should either connect to a different +IP (when multiple targets exist), or reconnect to the same IP when a user has performed +an action.

+

Trait Implementations§

§

impl Clone for CloseCode

§

fn clone(&self) -> CloseCode

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for CloseCode

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl From<CloseCode> for CloseReason

§

fn from(code: CloseCode) -> CloseReason

Converts to this type from the input type.
§

impl From<u16> for CloseCode

§

fn from(code: u16) -> CloseCode

Converts to this type from the input type.
§

impl PartialEq for CloseCode

§

fn eq(&self, other: &CloseCode) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Copy for CloseCode

§

impl Eq for CloseCode

§

impl StructuralPartialEq for CloseCode

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/ws/enum.Frame.html b/awc/ws/enum.Frame.html new file mode 100644 index 000000000..ca89fad0e --- /dev/null +++ b/awc/ws/enum.Frame.html @@ -0,0 +1,37 @@ +Frame in awc::ws - Rust

Enum awc::ws::Frame

pub enum Frame {
+    Text(Bytes),
+    Binary(Bytes),
+    Continuation(Item),
+    Ping(Bytes),
+    Pong(Bytes),
+    Close(Option<CloseReason>),
+}
Expand description

A WebSocket frame.

+

Variants§

§

Text(Bytes)

Text frame. Note that the codec does not validate UTF-8 encoding.

+
§

Binary(Bytes)

Binary frame.

+
§

Continuation(Item)

Continuation.

+
§

Ping(Bytes)

Ping message.

+
§

Pong(Bytes)

Pong message.

+
§

Close(Option<CloseReason>)

Close message with optional reason.

+

Trait Implementations§

§

impl Debug for Frame

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl PartialEq for Frame

§

fn eq(&self, other: &Frame) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Eq for Frame

§

impl StructuralPartialEq for Frame

Auto Trait Implementations§

§

impl !Freeze for Frame

§

impl RefUnwindSafe for Frame

§

impl Send for Frame

§

impl Sync for Frame

§

impl Unpin for Frame

§

impl UnwindSafe for Frame

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/ws/enum.Message.html b/awc/ws/enum.Message.html new file mode 100644 index 000000000..eb372441d --- /dev/null +++ b/awc/ws/enum.Message.html @@ -0,0 +1,43 @@ +Message in awc::ws - Rust

Enum awc::ws::Message

pub enum Message {
+    Text(ByteString),
+    Binary(Bytes),
+    Continuation(Item),
+    Ping(Bytes),
+    Pong(Bytes),
+    Close(Option<CloseReason>),
+    Nop,
+}
Expand description

A WebSocket message.

+

Variants§

§

Text(ByteString)

Text message.

+
§

Binary(Bytes)

Binary message.

+
§

Continuation(Item)

Continuation.

+
§

Ping(Bytes)

Ping message.

+
§

Pong(Bytes)

Pong message.

+
§

Close(Option<CloseReason>)

Close message with optional reason.

+
§

Nop

No-op. Useful for low-level services.

+

Trait Implementations§

§

impl Debug for Message

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Encoder<Message> for Codec

§

type Error = ProtocolError

The type of encoding errors. Read more
§

fn encode( + &mut self, + item: Message, + dst: &mut BytesMut +) -> Result<(), <Codec as Encoder<Message>>::Error>

Encodes a frame into the buffer provided. Read more
§

impl PartialEq for Message

§

fn eq(&self, other: &Message) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Eq for Message

§

impl StructuralPartialEq for Message

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/ws/index.html b/awc/ws/index.html new file mode 100644 index 000000000..eefa78580 --- /dev/null +++ b/awc/ws/index.html @@ -0,0 +1,23 @@ +awc::ws - Rust

Module awc::ws

source ·
Expand description

Websockets client

+

Type definitions required to use awc::Client as a WebSocket client.

+

§Examples

+
use awc::{Client, ws};
+use futures_util::{SinkExt as _, StreamExt as _};
+
+#[actix_rt::main]
+async fn main() {
+    let (_resp, mut connection) = Client::new()
+        .ws("ws://echo.websocket.org")
+        .connect()
+        .await
+        .unwrap();
+
+    connection
+        .send(ws::Message::Text("Echo".into()))
+        .await
+        .unwrap();
+    let response = connection.next().await.unwrap().unwrap();
+
+    assert_eq!(response, ws::Frame::Text("Echo".as_bytes().into()));
+}
+

Structs§

Enums§

  • Status code used to indicate why an endpoint is closing the WebSocket connection.
  • A WebSocket frame.
  • A WebSocket message.
\ No newline at end of file diff --git a/awc/ws/sidebar-items.js b/awc/ws/sidebar-items.js new file mode 100644 index 000000000..b1d76a386 --- /dev/null +++ b/awc/ws/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["CloseCode","Frame","Message"],"struct":["CloseReason","Codec","WebsocketsRequest"]}; \ No newline at end of file diff --git a/awc/ws/struct.CloseReason.html b/awc/ws/struct.CloseReason.html new file mode 100644 index 000000000..4ad06cab7 --- /dev/null +++ b/awc/ws/struct.CloseReason.html @@ -0,0 +1,31 @@ +CloseReason in awc::ws - Rust

Struct awc::ws::CloseReason

pub struct CloseReason {
+    pub code: CloseCode,
+    pub description: Option<String>,
+}
Expand description

Reason for closing the connection

+

Fields§

§code: CloseCode

Exit code

+
§description: Option<String>

Optional description of the exit code

+

Trait Implementations§

§

impl Clone for CloseReason

§

fn clone(&self) -> CloseReason

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for CloseReason

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl<T> From<(CloseCode, T)> for CloseReason
where + T: Into<String>,

§

fn from(info: (CloseCode, T)) -> CloseReason

Converts to this type from the input type.
§

impl From<CloseCode> for CloseReason

§

fn from(code: CloseCode) -> CloseReason

Converts to this type from the input type.
§

impl PartialEq for CloseReason

§

fn eq(&self, other: &CloseReason) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
§

impl Eq for CloseReason

§

impl StructuralPartialEq for CloseReason

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
§

impl<Q, K> Equivalent<K> for Q
where + Q: Eq + ?Sized, + K: Borrow<Q> + ?Sized,

§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/ws/struct.Codec.html b/awc/ws/struct.Codec.html new file mode 100644 index 000000000..ab8bd4525 --- /dev/null +++ b/awc/ws/struct.Codec.html @@ -0,0 +1,38 @@ +Codec in awc::ws - Rust

Struct awc::ws::Codec

pub struct Codec { /* private fields */ }
Expand description

WebSocket protocol codec.

+

Implementations§

§

impl Codec

pub const fn new() -> Codec

Create new WebSocket frames decoder.

+

pub fn max_size(self, size: usize) -> Codec

Set max frame size.

+

By default max size is set to 64KiB.

+

pub fn client_mode(self) -> Codec

Set decoder to client mode.

+

By default decoder works in server mode.

+

Trait Implementations§

§

impl Clone for Codec

§

fn clone(&self) -> Codec

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
§

impl Debug for Codec

§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
§

impl Decoder for Codec

§

type Item = Frame

The type of decoded frames.
§

type Error = ProtocolError

The type of unrecoverable frame decoding errors. Read more
§

fn decode( + &mut self, + src: &mut BytesMut +) -> Result<Option<<Codec as Decoder>::Item>, <Codec as Decoder>::Error>

Attempts to decode a frame from the provided buffer of bytes. Read more
§

fn decode_eof( + &mut self, + buf: &mut BytesMut +) -> Result<Option<Self::Item>, Self::Error>

A default method available to be called when there are no more bytes +available to be read from the underlying I/O. Read more
§

fn framed<T>(self, io: T) -> Framed<T, Self>
where + T: AsyncRead + AsyncWrite, + Self: Sized,

Provides a Stream and Sink interface for reading and writing to this +Io object, using Decode and Encode to read and write the raw data. Read more
§

impl Default for Codec

§

fn default() -> Codec

Returns the “default value” for a type. Read more
§

impl Encoder<Message> for Codec

§

type Error = ProtocolError

The type of encoding errors. Read more
§

fn encode( + &mut self, + item: Message, + dst: &mut BytesMut +) -> Result<(), <Codec as Encoder<Message>>::Error>

Encodes a frame into the buffer provided. Read more

Auto Trait Implementations§

§

impl Freeze for Codec

§

impl RefUnwindSafe for Codec

§

impl Send for Codec

§

impl Sync for Codec

§

impl Unpin for Codec

§

impl UnwindSafe for Codec

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for T
where + T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/awc/ws/struct.WebsocketsRequest.html b/awc/ws/struct.WebsocketsRequest.html new file mode 100644 index 000000000..c26fa251c --- /dev/null +++ b/awc/ws/struct.WebsocketsRequest.html @@ -0,0 +1,52 @@ +WebsocketsRequest in awc::ws - Rust

Struct awc::ws::WebsocketsRequest

source ·
pub struct WebsocketsRequest { /* private fields */ }
Expand description

WebSocket connection.

+

Implementations§

source§

impl WebsocketsRequest

source

pub fn address(self, addr: SocketAddr) -> Self

Set socket address of the server.

+

This address is used for connection. If address is not +provided url’s host name get resolved.

+
source

pub fn protocols<U, V>(self, protos: U) -> Self
where + U: IntoIterator<Item = V>, + V: AsRef<str>,

Set supported WebSocket protocols

+
source

pub fn cookie(self, cookie: Cookie<'_>) -> Self

Available on crate feature cookies only.

Set a cookie

+
source

pub fn origin<V, E>(self, origin: V) -> Self
where + HeaderValue: TryFrom<V, Error = E>, + HttpError: From<E>,

Set request Origin

+
source

pub fn max_frame_size(self, size: usize) -> Self

Set max frame size

+

By default max size is set to 64kB

+
source

pub fn server_mode(self) -> Self

Disable payload masking. By default ws client masks frame payload.

+
source

pub fn header<K, V>(self, key: K, value: V) -> Self

Append a header.

+

Header gets appended to existing header. +To override header use set_header() method.

+
source

pub fn set_header<K, V>(self, key: K, value: V) -> Self

Insert a header, replaces existing header.

+
source

pub fn set_header_if_none<K, V>(self, key: K, value: V) -> Self

Insert a header only if it is not yet set.

+
source

pub fn basic_auth<U>(self, username: U, password: Option<&str>) -> Self
where + U: Display,

Set HTTP basic authorization header

+
source

pub fn bearer_auth<T>(self, token: T) -> Self
where + T: Display,

Set HTTP bearer authentication header

+
source

pub async fn connect( + self +) -> Result<(ClientResponse, Framed<BoxedSocket, Codec>), WsClientError>

Complete request construction and connect to a WebSocket server.

+

Trait Implementations§

source§

impl Debug for WebsocketsRequest

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where + T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where + T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

+
§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an +Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an +Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where + U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

+

That is, this conversion is whatever the implementation of +From<T> for U chooses to do.

+
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where + U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where + U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where + S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a +[WithDispatch] wrapper. Read more
\ No newline at end of file diff --git a/crates.js b/crates.js new file mode 100644 index 000000000..d7c1ce550 --- /dev/null +++ b/crates.js @@ -0,0 +1 @@ +window.ALL_CRATES = ["actix_files","actix_http","actix_http_test","actix_multipart","actix_multipart_derive","actix_router","actix_test","actix_web","actix_web_actors","actix_web_codegen","awc"]; \ No newline at end of file diff --git a/help.html b/help.html new file mode 100644 index 000000000..443c66bd7 --- /dev/null +++ b/help.html @@ -0,0 +1 @@ +Help

Rustdoc help

Back
\ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 000000000..b116fea46 --- /dev/null +++ b/index.html @@ -0,0 +1 @@ + diff --git a/search-index.js b/search-index.js new file mode 100644 index 000000000..7d45f8997 --- /dev/null +++ b/search-index.js @@ -0,0 +1,15 @@ +var searchIndex = new Map(JSON.parse('[\ +["actix_files",{"t":"EFFFFFONNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNONNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNN","n":["ChunkedReadFile","Directory","Files","FilesService","HttpRange","NamedFile","base","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","call","clone","clone","clone","clone_into","clone_into","clone_into","content_disposition","content_encoding","content_type","default_handler","deref","deref","deref_mut","disable_content_disposition","disable_content_disposition","file","file_extension_to_mime","files_listing_renderer","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from_file","guard","index_file","into","into","into","into","into","into_factory","into_factory","into_response","into_service","is_visible","length","metadata","method_guard","mime_override","modified","new","new","new_service","new_service","open_async","parse","path","path","path_filter","poll_ready","prefer_utf8","prefer_utf8","redirect_to_slash_directory","register","register","respond_to","set_content_disposition","set_content_encoding","set_content_type","set_status_code","show_files_listing","start","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","use_etag","use_etag","use_hidden_files","use_last_modified","use_last_modified","vzip","vzip","vzip","vzip","vzip"],"q":[[0,"actix_files"],[114,"actix_files::service"],[115,"actix_web::service"],[116,"actix_files::files"],[117,"actix_files::range"],[118,"actix_files::named"],[119,"actix_web::http::header::content_disposition"],[120,"actix_http::header::shared::content_encoding"],[121,"core::option"],[122,"mime"],[123,"actix_web::error::error"],[124,"actix_service"],[125,"tokio_uring::fs::file"],[126,"actix_files::directory"],[127,"actix_web::request"],[128,"std::io::error"],[129,"core::result"],[130,"core::ops::function"],[131,"core::fmt"],[132,"std::path"],[133,"core::convert"],[134,"actix_web::guard"],[135,"alloc::string"],[136,"actix_http::body::boxed"],[137,"actix_web::response::response"],[138,"std::fs"],[139,"std::time"],[140,"alloc::vec"],[141,"actix_http::requests::head"],[142,"core::task::wake"],[143,"core::task::poll"],[144,"actix_web::config"],[145,"http::status"],[146,"core::any"],[147,"actix_files::chunked"]],"i":[0,0,0,0,0,0,22,5,22,8,6,3,5,22,8,6,3,3,5,6,3,5,6,3,8,8,8,5,8,3,8,5,8,8,0,5,5,22,8,6,3,5,22,8,6,3,8,5,5,5,22,8,6,3,5,8,8,3,22,6,8,5,5,8,5,22,5,8,8,6,8,22,5,3,5,8,5,5,8,8,8,8,8,8,5,6,5,6,3,5,22,8,6,3,5,22,8,6,3,5,22,8,6,3,5,8,5,5,8,5,22,8,6,3],"f":"```````{{{b{c}}}{{b{e}}}{}{}}0000{{{b{dc}}}{{b{de}}}{}{}}0000{{{b{f}}h}c{}}{{{b{j}}}j}{{{b{l}}}l}{{{b{f}}}f}{{{b{c}}{b{de}}}n{}{}}00{{{b{A`}}}{{b{Ab}}}}{{{b{A`}}}{{Af{Ad}}}}{{{b{A`}}}{{b{Ah}}}}{{je}j{{Bd{h}{{Aj{n}}{Al{An}}{B`{Bb}}}}}{{Bf{ch}}}}{{{b{A`}}}{{b{c}}}{}}{{{b{f}}}{{b{c}}}{}}{{{b{dA`}}}{{b{dc}}}{}}{jj}{A`A`}{{{b{A`}}}{{b{Bh}}}}{{{b{Bj}}}Ah}{{jc}j{{Cf{{b{Bl}}{b{Bn}}}{{C`{{Cd{AnCb}}}}}}}}{{{b{j}}{b{dCh}}}Cj}{{{b{Bl}}{b{dCh}}}Cj}{{{b{A`}}{b{dCh}}}Cj}{{{b{l}}{b{dCh}}}Cj}{{{b{f}}{b{dCh}}}Cj}{cc{}}0000{{Bhc}{{Cl{A`}}}{{D`{Cn}}}}{{jc}jDb}{{jc}j{{Df{Dd}}}}{ce{}{}}000000{{A`{b{Bn}}}{{Dj{Dh}}}}1{{{b{Bl}}{b{{Cl{Dl}}}}}Dn}`{{{b{A`}}}{{b{E`}}}}5{{jc}j{{Cf{{b{Eb}}}{{C`{Ed}}}}}}{{{b{A`}}}{{Af{Ef}}}}{{{b{Bj}}c}j{{Df{Eh}}}}{{EhEh}Bl}{{{b{j}}n}c{}}{{{b{A`}}n}c{}}{c{{Cl{A`}}}{{D`{Cn}}}}{{{b{Bj}}Ej}{{Cd{{El{l}}`}}}}{{{b{A`}}}{{b{Cn}}}}`{{jc}j{{Cf{{b{Cn}}{b{En}}}{{C`{Dn}}}}}}{{{b{f}}{b{dF`}}}{{Fb{{Cd{nc}}}}}{}}{{jDn}j}{{A`Dn}A`}{jj}{{j{b{dFd}}}n}{{A`{b{dFd}}}n}{{A`{b{Bn}}}{{Dj{c}}}{}}{{A`Ab}A`}{{A`Ad}A`}{{A`Ah}A`}{{A`Ff}A`}7`{{{b{c}}}e{}{}}00{c{{Cd{e}}}{}{}}000000000{{{b{c}}}Fh{}}0000<;:<;{ce{}{}}0000","D":"Gb","p":[[1,"reference"],[0,"mut"],[5,"FilesService",0,114],[5,"ServiceRequest",115],[5,"Files",0,116],[5,"HttpRange",0,117],[1,"unit"],[5,"NamedFile",0,118],[5,"ContentDisposition",119],[6,"ContentEncoding",120],[6,"Option",121],[5,"Mime",122],[17,"Config"],[17,"Response"],[5,"ServiceResponse",115],[17,"Error"],[5,"Error",123],[10,"ServiceFactory",124],[10,"IntoServiceFactory",124],[5,"File",125],[1,"str"],[5,"Directory",0,126],[5,"HttpRequest",127],[17,"Output"],[5,"Error",128],[6,"Result",129],[10,"Fn",130],[5,"Formatter",131],[8,"Result",131],[8,"Result",128],[5,"Path",132],[10,"AsRef",133],[10,"Guard",134],[5,"String",135],[10,"Into",133],[5,"BoxBody",136],[5,"HttpResponse",137],[5,"DirEntry",138],[1,"bool"],[5,"Metadata",138],[5,"Name",122],[6,"DispositionType",119],[5,"SystemTime",139],[5,"PathBuf",132],[1,"u64"],[5,"Vec",140],[5,"RequestHead",141],[5,"Context",142],[6,"Poll",143],[5,"AppService",144],[5,"StatusCode",145],[5,"TypeId",146]],"r":[[0,147],[1,126],[2,116],[3,114],[4,117],[5,118]],"b":[],"c":"OjAAAAEAAAAAAAAAEAAAAFQA","e":"OzAAAAEAADkACwABAAAACAAQAB0AAgAlAAQANwABADoAAABDAAEASgAAAE4AAgBXABEAbgAEAA=="}],\ +["actix_http",{"t":"TTTTITTTTPGETPTEFTTTTTTPPTTTTTTTPPPKFFTTTTGPTTTTTTTTFFTTTTTTTTPTTPPTTTTTTTTTTTGEGTTTTPFFGFFFTTTFFPRTTTPFTTTTTTTPFTFNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNMNNMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNCNNNNNNNNNNCMNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNONNNNNNNNNNNNNNNNNNNNNONNNNMNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNONNOONNNNNNNNNNNNNNNNNNNNNNCOOOFGFFGRPKFPPPFPTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNMNNNNNHHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOFFNNNNNNNNNNNNNNNNNNNNNNNNPGPGPFPPPPFPPPPPPPPPGPGPPPPPPPPPPPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNPFFFFFFIPGGPFPFPFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNFFFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNSSSSSSSSSSSSSSSSSKPPSSSSSSSSSSSSSSSSSGGSSPSSSRRPPPFSSPPSKEFFFSSSSSPFFPPPPPPPPPPPPPPPPPPSSSFTSTSSSSSSSFFSSSSSSSSSSSSSPSSSFKKSSSPSSSSSSSSSSSTPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNNHNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNOONCNNNMNNMNNHNNNNNNNNNNNNHONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNMNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNFFFFFFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNFFFFNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNOFFTTFFFFFFFNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNPPPPPPPPPPPPGFFPPPPPPPFPPPPGPGPPPPGPPGPPPPPGPFPPPPPPPPGPPPPPPPPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHHHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNN","n":["ACCEPTED","ALREADY_REPORTED","BAD_GATEWAY","BAD_REQUEST","BoxedPayloadStream","CONFLICT","CONNECT","CONTINUE","CREATED","Close","ConnectionType","ContentEncoding","DELETE","Disabled","EXPECTATION_FAILED","Error","Extensions","FAILED_DEPENDENCY","FORBIDDEN","FOUND","GATEWAY_TIMEOUT","GET","GONE","H1","H2","HEAD","HTTP_09","HTTP_10","HTTP_11","HTTP_2","HTTP_3","HTTP_VERSION_NOT_SUPPORTED","Http1","Http2","Http3","HttpMessage","HttpService","HttpServiceBuilder","IM_A_TEAPOT","IM_USED","INSUFFICIENT_STORAGE","INTERNAL_SERVER_ERROR","KeepAlive","KeepAlive","LENGTH_REQUIRED","LOCKED","LOOP_DETECTED","METHOD_NOT_ALLOWED","MISDIRECTED_REQUEST","MOVED_PERMANENTLY","MULTIPLE_CHOICES","MULTI_STATUS","Message","Method","NETWORK_AUTHENTICATION_REQUIRED","NON_AUTHORITATIVE_INFORMATION","NOT_ACCEPTABLE","NOT_EXTENDED","NOT_FOUND","NOT_IMPLEMENTED","NOT_MODIFIED","NO_CONTENT","None","OK","OPTIONS","Os","Owned","PARTIAL_CONTENT","PATCH","PAYLOAD_TOO_LARGE","PAYMENT_REQUIRED","PERMANENT_REDIRECT","POST","PRECONDITION_FAILED","PRECONDITION_REQUIRED","PROCESSING","PROXY_AUTHENTICATION_REQUIRED","PUT","Payload","PayloadStream","Protocol","RANGE_NOT_SATISFIABLE","REQUEST_HEADER_FIELDS_TOO_LARGE","REQUEST_TIMEOUT","RESET_CONTENT","Rc","Request","RequestHead","RequestHeadType","Response","ResponseBuilder","ResponseHead","SEE_OTHER","SERVICE_UNAVAILABLE","SWITCHING_PROTOCOLS","ServiceConfig","StatusCode","Stream","Stream","TEMPORARY_REDIRECT","TOO_MANY_REQUESTS","TRACE","Timeout","TlsAcceptorConfig","UNAUTHORIZED","UNAVAILABLE_FOR_LEGAL_REASONS","UNPROCESSABLE_ENTITY","UNSUPPORTED_MEDIA_TYPE","UPGRADE_REQUIRED","URI_TOO_LONG","USE_PROXY","Upgrade","Uri","VARIANT_ALSO_NEGOTIATES","Version","append_header","as_ref","as_ref","as_str","as_str","as_u16","authority","bad_request","body","body","body","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build","build","builder","camel_case_headers","canonical_reason","chunked","chunked","chunked","chunked","clear","client_disconnect_deadline","client_disconnect_timeout","client_request_deadline","client_request_timeout","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","compare","compare","conn_data","connection_type","connection_type","contains","content_type","content_type","content_type","default","default","default","default","default","default","default","default","default","default","default","default","deref","deref_mut","drop","drop_body","encoding","encoding","encoding","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","error","expect","expect","expect","extend","extensions","extensions","extensions","extensions_mut","extensions_mut","extensions_mut","extra_headers","finish","finish","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","force_close","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_bytes","from_bytes","from_maybe_shared","from_parts","from_static","from_str","from_str","from_str","from_u16","get","get_mut","h1","h1","h2","h2","handshake_timeout","hash","hash","hash","hash","hash","head","head","head_mut","header","headers","headers","headers","headers","headers","headers","headers","headers_mut","headers_mut","headers_mut","headers_mut","host","hostname","insert","insert_header","internal_server_error","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into_body","into_factory","into_parts","into_parts","into_parts","is_client_error","is_idempotent","is_informational","is_redirection","is_safe","is_server_error","is_success","keep_alive","keep_alive","keep_alive","keep_alive","keep_alive","keep_alive_deadline","local_addr","local_addr","map_body","map_into_boxed_body","message_body","method","method","mime_type","mime_type","new","new","new","new","new","new","new","new","new_service","no_chunking","no_chunking","no_chunking","not_found","ok","on_connect_ext","openssl","openssl_with_config","partial_cmp","partial_cmp","path","path","path_and_query","payload","peer_addr","peer_addr","poll_next","port","port","port_u16","query","reason","reason","reason","remove","replace_payload","rustls","rustls_021","rustls_021_with_config","rustls_0_22","rustls_0_22_with_config","rustls_0_23","rustls_0_23_with_config","rustls_with_config","scheme","scheme_str","secure","secure","set_body","set_camel_case_headers","set_camel_case_headers","set_connection_type","set_connection_type","status","status","status","status_mut","take","take","take_conn_data","take_payload","take_payload","take_payload","take_req_data","tcp","tcp_auto_h2c","test","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_poll_next","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","upgrade","upgrade","upgrade","upgrade","upgrade","upgrade","upgrade","uri","uri","uri","uri_mut","version","version","version","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","with_body","with_payload","ws","payload","payload","payload","BodyLimitExceeded","BodySize","BodyStream","BoxBody","EitherBody","Error","Left","MessageBody","None","None","Right","Sized","SizedStream","Stream","ZERO","as_pin_mut","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","boxed","boxed","boxed","boxed","clone","clone","clone","clone_into","clone_into","clone_into","default","eq","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","into","into","into","into","into","into","into","is_eof","left","new","new","new","new","new","poll_next","poll_next","poll_next","poll_next","poll_next","poll_next","right","size","size","size","size","size","size","to_bytes","to_bytes_limited","to_owned","to_owned","to_owned","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into_bytes","try_into_bytes","try_into_bytes","try_into_bytes","try_into_bytes","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","body","body","Decoder","Encoder","borrow","borrow","borrow_mut","borrow_mut","from","from","from_headers","into","into","new","poll_next","poll_next","response","size","try_from","try_from","try_into","try_into","try_into_bytes","try_poll_next","type_id","type_id","vzip","vzip","Body","ContentTypeError","DisconnectTimeout","DispatchError","EncodingCorrupted","Error","H2","HandlerDroppedPayload","Header","Http2Payload","HttpError","Incomplete","Incomplete","InternalError","Io","Io","Io","Method","Overflow","Parse","ParseError","ParseError","PayloadError","Service","SlowRequestTimeout","Status","Timeout","TooLarge","UnknownEncoding","UnknownLength","Upgrade","Uri","Utf8","Version","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","get_ref","into","into","into","into","into","into","is","source","source","source","source","source","to_string","to_string","to_string","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","Chunk","ClientCodec","ClientPayloadCodec","Codec","Dispatcher","ExpectHandler","H1Service","H1ServiceHandler","Item","Message","MessageType","None","Payload","Payload","SendResponse","Stream","UpgradeHandler","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","call","call","clone","clone_into","config","create","decode","decode","decode","default","default","encode","encode","eq","equivalent","equivalent","equivalent","expect","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","into","into","into","into","into","into","into","into","into","into","into","into_factory","into_factory","into_factory","into_future","into_future","into_message_codec","into_payload_codec","into_service","into_service","keep_alive","keep_alive","keep_alive","keep_alive_enabled","message_type","message_type","new","new","new","new_service","new_service","new_service","openssl","poll","poll","poll_next","poll_ready","poll_ready","rustls","rustls_021","rustls_0_22","rustls_0_23","tcp","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_poll","try_poll","try_poll_next","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","unread_data","upgrade","upgrade","upgrade","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","Dispatcher","H2Service","Payload","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","from","from","from","into","into","into","into_factory","into_future","new_service","openssl","poll","poll_next","rustls","rustls_021","rustls_0_22","rustls_0_23","tcp","try_from","try_from","try_from","try_into","try_into","try_into","try_poll","try_poll_next","type_id","type_id","type_id","vzip","vzip","vzip","ACCEPT","ACCEPT_CHARSET","ACCEPT_ENCODING","ACCEPT_LANGUAGE","ACCEPT_RANGES","ACCESS_CONTROL_ALLOW_CREDENTIALS","ACCESS_CONTROL_ALLOW_HEADERS","ACCESS_CONTROL_ALLOW_METHODS","ACCESS_CONTROL_ALLOW_ORIGIN","ACCESS_CONTROL_EXPOSE_HEADERS","ACCESS_CONTROL_MAX_AGE","ACCESS_CONTROL_REQUEST_HEADERS","ACCESS_CONTROL_REQUEST_METHOD","AGE","ALLOW","ALT_SVC","AUTHORIZATION","AsHeaderName","Big5","Brotli","CACHE_CONTROL","CACHE_STATUS","CDN_CACHE_CONTROL","CONNECTION","CONTENT_DISPOSITION","CONTENT_ENCODING","CONTENT_LANGUAGE","CONTENT_LENGTH","CONTENT_LOCATION","CONTENT_RANGE","CONTENT_SECURITY_POLICY","CONTENT_SECURITY_POLICY_REPORT_ONLY","CONTENT_TYPE","COOKIE","CROSS_ORIGIN_EMBEDDER_POLICY","CROSS_ORIGIN_OPENER_POLICY","CROSS_ORIGIN_RESOURCE_POLICY","Charset","ContentEncoding","DATE","DNT","Deflate","ETAG","EXPECT","EXPIRES","Error","Error","Euc_Jp","Euc_Kr","Ext","ExtendedValue","FORWARDED","FROM","Gb2312","Gzip","HOST","Header","HeaderMap","HeaderName","HeaderValue","HttpDate","IF_MATCH","IF_MODIFIED_SINCE","IF_NONE_MATCH","IF_RANGE","IF_UNMODIFIED_SINCE","Identity","InvalidHeaderName","InvalidHeaderValue","Iso_2022_Jp","Iso_2022_Jp_2","Iso_2022_Kr","Iso_8859_1","Iso_8859_10","Iso_8859_2","Iso_8859_3","Iso_8859_4","Iso_8859_5","Iso_8859_6","Iso_8859_6_E","Iso_8859_6_I","Iso_8859_7","Iso_8859_8","Iso_8859_8_E","Iso_8859_8_I","Iso_8859_9","Koi8_R","LAST_MODIFIED","LINK","LOCATION","LanguageTag","MAX","MAX_FORWARDS","MIN","ORIGIN","PERMISSIONS_POLICY","PRAGMA","PROXY_AUTHENTICATE","PROXY_AUTHORIZATION","PUBLIC_KEY_PINS","PUBLIC_KEY_PINS_REPORT_ONLY","Quality","QualityItem","RANGE","REFERER","REFERRER_POLICY","REFRESH","RETRY_AFTER","SEC_WEBSOCKET_ACCEPT","SEC_WEBSOCKET_EXTENSIONS","SEC_WEBSOCKET_KEY","SEC_WEBSOCKET_PROTOCOL","SEC_WEBSOCKET_VERSION","SERVER","SET_COOKIE","STRICT_TRANSPORT_SECURITY","Shift_Jis","TE","TRAILER","TRANSFER_ENCODING","ToStrError","TryIntoHeaderPair","TryIntoHeaderValue","UPGRADE","UPGRADE_INSECURE_REQUESTS","USER_AGENT","Us_Ascii","VARY","VIA","WARNING","WWW_AUTHENTICATE","X_CONTENT_TYPE_OPTIONS","X_DNS_PREFETCH_CONTROL","X_FORWARDED_FOR","X_FORWARDED_HOST","X_FORWARDED_PROTO","X_FRAME_OPTIONS","X_XSS_PROTECTION","ZERO","Zstd","as_bytes","as_ref","as_ref","as_ref","as_str","as_str","as_str","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","canonicalize","charset","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","compare","compare","compare","default","default","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","extended_language","extended_language_subtags","extension","extension_subtags","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt_comma_delimited","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_bytes","from_bytes","from_comma_delimited","from_lowercase","from_maybe_shared","from_maybe_shared_unchecked","from_name","from_one_raw_str","from_static","from_static","from_str","from_str","from_str","from_str","from_str","from_str","from_str","from_str","full_language","hash","hash","hash","hash","http_percent_encode","into","into","into","into","into","into","into","into","into","into","into","into","into_string","is_empty","is_language_range","is_sensitive","is_valid","item","language_tag","len","map","matches","max","min","name","name","new","parse","parse","parse","parse_extended_value","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","primary_language","private_use","private_use_subtags","q","quality","region","script","set_sensitive","to_header_value","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_str","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into_pair","try_into_pair","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","validate","value","variant","variant_subtags","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","zero","Drain","HeaderMap","IntoIter","Iter","Keys","Removed","append","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","capacity","clear","clone","clone_into","contains_key","default","drain","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","get","get_all","get_mut","insert","into","into","into","into","into","into","into_iter","into_iter","into_iter","into_iter","into_iter","into_iter","into_iter","is_empty","is_empty","iter","keys","len","len_keys","new","next","next","next","next","next","remove","reserve","retain","size_hint","size_hint","size_hint","size_hint","size_hint","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","with_capacity","TestBuffer","TestRequest","TestSeqBuffer","TestSeqInner","append_header","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone_into","default","empty","empty","err","err","extend_read_buf","extend_read_buf","finish","flush","flush","fmt","from","from","from","from","insert_header","into","into","into","into","method","new","new","poll_flush","poll_flush","poll_read","poll_read","poll_shutdown","poll_shutdown","poll_write","poll_write","read","read","read_buf","read_buf","set_payload","take","to_owned","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","uri","version","vzip","vzip","vzip","vzip","with_uri","write","write","write_buf","write_buf","Authority","Builder","HTTP","HTTPS","InvalidUri","InvalidUriParts","Parts","PathAndQuery","Port","Scheme","Uri","as_ref","as_ref","as_ref","as_str","as_str","as_str","as_str","as_u16","authority","authority","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build","clone","clone","clone","clone_into","clone_into","clone_into","default","default","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from_maybe_shared","from_maybe_shared","from_static","from_static","from_str","from_str","from_str","hash","hash","hash","host","into","into","into","into","into","into","into","into","new","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","path","path_and_query","path_and_query","port","port_u16","query","scheme","scheme","to_owned","to_owned","to_owned","to_string","to_string","to_string","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","Abnormal","Again","Away","Bad","BadOpCode","BadWebsocketKey","Binary","Binary","Binary","Close","Close","Close","CloseCode","CloseReason","Codec","Continuation","Continuation","ContinuationFragment","ContinuationNotStarted","ContinuationStarted","Continue","Continue","Dispatcher","Error","Extension","FirstBinary","FirstText","Frame","GetMethodRequired","HandshakeError","Invalid","InvalidLength","InvalidOpcode","Io","Item","Last","MaskedFrame","Message","NoConnectionUpgrade","NoVersionHeader","NoWebsocketUpgrade","Nop","Normal","OpCode","Overflow","Parser","Ping","Ping","Ping","Policy","Pong","Pong","Pong","Protocol","ProtocolError","Restart","Size","Text","Text","Text","UnmaskedFrame","Unsupported","UnsupportedVersion","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","client_mode","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","code","decode","default","description","encode","eq","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","handshake","handshake_response","hash_key","into","into","into","into","into","into","into","into","into","into","into","into_future","max_size","new","new","parse","parse_close_payload","poll","source","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_poll","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","verify_handshake","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","with","write_close","write_message"],"q":[[0,"actix_http"],[626,"actix_http::Payload"],[629,"actix_http::body"],[753,"actix_http::body::EitherBody"],[755,"actix_http::encoding"],[781,"actix_http::error"],[915,"actix_http::h1"],[1085,"actix_http::h2"],[1125,"actix_http::header"],[1586,"actix_http::header::map"],[1688,"actix_http::test"],[1764,"actix_http::uri"],[1944,"actix_http::ws"],[2184,"actix_http::responses::builder"],[2185,"actix_http::header::into_pair"],[2186,"http::method"],[2187,"actix_http::requests::head"],[2188,"http::status"],[2189,"http::uri"],[2190,"http::uri::authority"],[2191,"core::option"],[2192,"actix_http::body::boxed"],[2193,"actix_http::responses::response"],[2194,"actix_http::body::either"],[2195,"actix_http::body::message_body"],[2196,"actix_http::builder"],[2197,"actix_http::requests::request"],[2198,"actix_service"],[2199,"http::uri::builder"],[2200,"actix_http::http_message"],[2201,"core::result"],[2202,"actix_http::responses::head"],[2203,"actix_http::extensions"],[2204,"actix_http::config"],[2205,"std::time"],[2206,"core::time"],[2207,"actix_http::h1::codec"],[2208,"actix_codec::framed"],[2209,"http::version"],[2210,"actix_http::keep_alive"],[2211,"actix_http::message"],[2212,"core::cmp"],[2213,"actix_http::header::into_value"],[2214,"actix_http::h1::expect"],[2215,"actix_http::h1::upgrade"],[2216,"core::default"],[2217,"actix_http::service"],[2218,"encoding_rs"],[2219,"core::cell"],[2220,"core::fmt"],[2221,"actix_http::payload"],[2222,"http::uri::path"],[2223,"alloc::string"],[2224,"core::convert"],[2225,"alloc::vec"],[2226,"bytes::bytes"],[2227,"bytestring"],[2228,"bytes::bytes_mut"],[2229,"h2::share"],[2230,"actix_http::h1::payload"],[2231,"actix_http::h1::service"],[2232,"actix_http::h2::service"],[2233,"core::hash"],[2234,"core::net::socket_addr"],[2235,"core::ops::function"],[2236,"mime"],[2237,"tokio::io::async_read"],[2238,"tokio::io::async_write"],[2239,"core::marker"],[2240,"tokio::net::tcp::stream"],[2241,"actix_tls::accept::openssl"],[2242,"openssl::ssl::connector"],[2243,"openssl::ssl::error"],[2244,"actix_tls::accept"],[2245,"core::pin"],[2246,"core::task::wake"],[2247,"core::task::poll"],[2248,"futures_core::stream"],[2249,"http::uri::port"],[2250,"actix_tls::accept::rustls_0_20"],[2251,"rustls::server::server_conn"],[2252,"std::io::error"],[2253,"actix_tls::accept::rustls_0_21"],[2254,"actix_tls::accept::rustls_0_22"],[2255,"actix_tls::accept::rustls_0_23"],[2256,"http::uri::scheme"],[2257,"alloc::rc"],[2258,"core::any"],[2259,"core::error"],[2260,"alloc::boxed"],[2261,"core::clone"],[2262,"actix_http::body::none"],[2263,"actix_http::body::size"],[2264,"actix_http::body::utils"],[2265,"actix_http::body::body_stream"],[2266,"actix_http::body::sized_stream"],[2267,"actix_http::encoding::decoder"],[2268,"actix_http::header::shared::content_encoding"],[2269,"actix_http::encoding::encoder"],[2270,"http::header::name"],[2271,"http::header::value"],[2272,"http::header::map"],[2273,"core::str::error"],[2274,"httparse"],[2275,"h2::error"],[2276,"actix_http::h1::client"],[2277,"actix_http::h1::utils"],[2278,"actix_http::h1::dispatcher"],[2279,"actix_http::h2::dispatcher"],[2280,"language_tags"],[2281,"actix_http::header::shared::charset"],[2282,"actix_http::header::shared::extended"],[2283,"actix_http::header::shared::http_date"],[2284,"actix_http::header::shared::quality"],[2285,"actix_http::header::shared::quality_item"],[2286,"core::iter::traits::iterator"],[2287,"core::str::traits"],[2288,"actix_http::header::as_name"],[2289,"core::slice::iter"],[2290,"tokio::io::read_buf"],[2291,"actix_http::ws::codec"],[2292,"actix_http::ws::proto"],[2293,"actix_http::ws::frame"],[2294,"actix_http::ws::dispatcher"],[2295,"http"],[2296,"actix_http::header::common"],[2297,"actix_http::header::utils"]],"i":[9,9,9,9,0,9,5,9,9,40,0,0,5,39,9,0,0,9,9,9,9,5,9,72,72,5,38,38,38,38,38,9,41,41,41,0,0,0,9,9,9,9,0,40,9,9,9,9,9,9,9,9,0,0,9,9,9,9,9,9,9,9,72,9,5,39,7,9,5,9,9,9,5,9,9,9,9,5,0,0,0,9,9,9,9,7,0,0,0,0,0,0,9,9,9,0,0,72,26,9,9,5,39,0,9,9,9,9,9,9,9,40,0,9,0,2,5,7,5,9,9,11,15,0,2,15,18,48,5,9,19,2,11,38,15,52,31,30,39,40,72,8,7,29,47,41,18,48,5,9,19,2,11,38,15,52,31,30,39,40,72,8,7,29,47,41,15,52,11,8,9,26,26,8,29,30,31,18,31,18,5,9,11,38,31,39,40,8,29,41,5,9,11,38,31,39,40,8,29,41,9,38,9,38,19,8,29,30,26,26,2,18,5,9,2,11,38,15,31,30,39,8,47,48,48,48,15,0,26,26,5,5,5,5,5,9,9,11,11,11,38,39,40,41,5,5,5,9,9,9,11,11,11,38,38,38,39,39,39,40,40,40,41,41,41,0,18,52,8,30,26,19,15,26,19,15,7,18,2,5,5,9,9,19,2,11,11,38,15,31,30,39,40,8,7,29,47,41,2,18,48,5,5,9,9,19,19,2,2,2,11,11,11,38,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,52,31,30,39,39,39,40,72,72,72,72,72,8,7,7,29,47,41,5,9,11,11,11,5,9,11,9,30,30,0,18,0,18,47,5,9,11,38,41,19,15,15,0,26,19,15,8,29,8,29,19,15,8,29,11,11,30,2,15,18,48,5,9,19,2,11,38,15,52,31,30,39,40,72,8,7,29,47,41,15,52,19,11,15,9,5,9,9,5,9,9,18,2,15,31,29,31,18,31,15,15,2,19,8,26,26,48,19,2,15,52,31,30,29,52,2,8,29,15,15,18,52,52,9,38,19,11,11,19,19,8,72,11,11,11,11,2,29,29,30,19,52,52,52,52,52,52,52,52,11,11,18,31,15,8,29,8,29,2,15,29,15,2,72,19,26,19,19,19,52,52,0,5,9,11,38,31,39,40,8,29,41,5,9,11,18,48,5,5,5,9,9,9,9,19,2,11,11,11,11,11,11,11,11,38,15,52,31,30,39,40,72,8,7,29,47,41,18,48,5,9,19,2,11,38,15,52,31,30,39,40,72,8,7,29,47,41,72,18,48,5,9,19,2,11,38,15,52,31,30,39,40,72,8,7,29,47,41,18,19,2,15,52,8,29,0,19,8,19,19,8,29,18,48,5,9,19,2,11,38,15,52,31,30,39,40,72,8,7,29,47,41,15,19,0,204,205,206,0,0,0,0,0,17,16,0,0,125,16,125,0,125,125,14,128,14,16,124,125,129,127,128,14,16,124,125,129,127,17,17,14,16,16,124,125,16,124,125,124,125,125,125,125,14,16,124,125,127,127,128,14,16,124,125,129,127,128,14,16,124,125,129,127,125,16,128,14,16,124,129,17,128,14,16,124,129,16,17,128,14,16,124,129,0,0,16,124,125,127,128,14,16,124,125,129,127,128,14,16,124,125,129,127,17,17,14,16,124,128,14,16,124,125,129,127,128,14,16,124,125,129,127,207,208,0,0,131,133,131,133,131,133,131,131,133,131,131,133,133,133,131,133,131,133,133,131,131,133,131,133,99,0,99,0,106,0,99,99,27,106,0,27,106,99,27,106,99,27,106,99,0,50,0,99,99,27,27,27,50,106,99,27,27,27,63,134,27,106,99,50,63,134,27,106,99,50,63,63,134,134,27,27,106,106,99,99,50,50,63,63,63,63,63,63,63,134,134,134,134,134,134,134,134,134,27,27,27,27,27,27,106,106,106,106,99,99,99,99,99,99,50,134,63,134,27,106,99,50,134,63,134,27,106,99,63,134,27,106,99,50,63,134,27,106,99,50,63,134,27,106,99,50,63,134,27,106,99,50,63,134,27,106,99,50,146,0,0,0,0,0,0,0,146,0,0,143,0,143,0,143,0,144,145,35,44,82,45,149,75,148,146,143,144,145,35,44,82,45,149,75,148,146,143,44,45,143,143,35,75,144,145,35,144,35,144,35,143,143,143,143,82,144,35,75,146,143,144,145,35,44,82,45,149,75,148,146,146,146,143,144,145,35,44,82,45,149,75,148,146,143,44,82,45,149,148,145,144,44,45,144,145,35,35,144,35,144,35,148,44,82,45,82,149,148,75,44,45,82,82,82,82,82,143,144,145,35,44,82,45,149,75,148,146,143,144,145,35,44,82,45,149,75,148,146,143,149,148,75,144,145,35,44,82,45,149,75,148,146,143,75,144,35,82,144,145,35,44,82,45,149,75,148,146,143,0,0,0,83,73,151,83,73,151,83,73,151,83,73,151,83,151,83,83,151,73,83,83,83,83,83,83,73,151,83,73,151,151,73,83,73,151,83,73,151,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,156,132,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,4,43,156,156,156,0,0,0,156,132,0,0,0,0,0,0,0,0,0,0,0,132,0,0,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,156,0,0,0,0,159,0,159,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,156,0,0,0,0,0,0,0,0,0,156,0,0,0,0,0,0,0,0,0,0,0,159,132,152,153,153,152,154,153,132,154,136,137,153,153,152,165,156,132,157,158,159,160,154,136,137,153,152,165,156,132,157,158,159,160,154,157,154,153,152,156,132,157,158,159,160,154,153,152,156,132,157,158,159,160,152,158,159,152,158,159,132,159,154,153,153,153,153,153,152,152,152,152,152,152,156,132,157,158,159,160,154,154,154,153,153,153,152,152,152,156,156,156,132,132,132,157,157,157,158,158,158,159,159,159,160,160,160,154,154,154,154,154,154,136,136,137,137,153,153,152,165,165,156,156,132,157,157,158,158,159,159,160,160,0,154,136,137,153,153,152,152,152,152,152,152,152,152,152,152,152,165,156,132,157,158,158,159,160,153,152,0,153,152,152,152,0,153,152,154,153,152,152,156,132,158,160,154,154,153,152,132,0,154,136,137,153,152,165,156,132,157,158,159,160,154,152,154,152,154,160,157,152,0,154,160,160,175,132,160,175,154,132,0,152,152,152,152,152,152,158,159,160,154,154,154,0,160,154,154,152,132,154,153,152,156,132,157,158,159,160,152,154,136,137,153,165,156,157,158,159,160,154,136,137,153,153,153,153,153,153,152,152,152,152,152,152,165,156,132,132,157,158,159,159,160,154,136,137,153,152,165,156,132,157,158,159,160,4,132,43,152,152,132,158,154,136,137,153,152,165,156,132,157,158,159,160,154,157,154,154,154,136,137,153,152,165,156,132,157,158,159,160,160,0,0,0,0,0,0,55,55,180,181,182,179,183,55,180,181,182,179,183,55,55,55,55,55,55,55,55,180,181,182,179,183,55,55,180,181,182,179,183,55,55,55,55,55,180,181,182,179,183,55,55,180,181,182,179,183,55,180,55,55,55,55,55,180,181,182,179,183,55,55,55,180,181,182,179,183,55,55,180,181,182,179,183,55,180,181,182,179,183,55,180,181,182,179,183,55,180,181,182,179,183,55,0,0,0,0,187,187,209,189,188,187,209,189,188,188,188,187,189,188,188,189,189,188,187,189,188,189,187,209,189,188,187,187,209,189,188,187,189,188,189,188,189,188,189,188,189,188,189,188,188,189,187,187,188,187,209,189,188,187,209,189,188,187,209,189,188,187,187,187,209,189,188,187,189,188,188,189,0,0,118,118,0,0,0,0,0,0,0,108,12,118,108,12,60,118,108,23,80,108,12,23,60,118,80,78,81,108,12,23,60,118,80,78,81,23,12,60,118,12,60,118,23,80,108,108,12,12,12,12,60,60,60,60,118,118,12,12,12,60,60,60,118,118,118,108,108,12,12,23,60,60,118,118,80,78,78,81,81,108,12,23,60,118,80,80,78,78,81,81,12,60,12,60,12,60,118,12,60,118,12,108,12,23,60,118,80,78,81,23,12,12,12,12,60,60,60,60,60,23,80,12,12,60,23,80,12,60,118,108,12,60,118,78,81,108,12,12,12,12,12,23,60,60,60,60,60,60,118,118,118,80,78,81,108,12,23,60,118,80,78,81,108,12,23,60,118,80,78,81,108,12,23,60,118,80,78,81,195,195,195,194,135,65,197,198,194,197,198,194,0,0,0,197,198,135,135,135,199,194,0,195,195,199,199,0,65,0,195,135,135,135,0,199,135,0,65,65,65,197,195,0,135,0,197,198,194,195,197,198,194,195,0,195,195,197,198,194,135,195,65,197,198,199,193,202,200,194,195,196,135,65,197,198,199,193,202,200,194,195,196,135,65,193,193,194,195,196,65,193,194,195,196,65,196,193,193,196,193,197,198,199,194,195,196,65,197,197,197,198,198,198,199,199,199,194,194,194,195,195,195,196,196,196,65,65,65,197,198,199,193,200,194,194,195,196,135,135,65,65,197,198,199,193,202,200,194,194,195,195,196,196,196,135,135,135,135,135,65,0,0,0,197,198,199,193,202,200,194,195,196,135,65,202,193,193,202,200,200,202,135,193,194,195,196,65,194,135,65,197,198,199,193,202,200,194,195,196,135,65,197,198,199,193,202,200,194,195,196,135,65,202,197,198,199,193,202,200,194,195,196,135,65,0,197,198,199,193,202,200,194,195,196,135,65,202,200,200],"f":"```````````````````````````````````````````````````````````````````````````````````````````````````````````````````{{{f{bd}}c}{{f{bd}}}h}{{{f{j}}}{{f{l}}}}{{{f{n}}}{{f{A`}}}}1{{{f{Ab}}}{{f{l}}}}{{{f{Ab}}}Ad}{{{f{Af}}}{{Aj{{f{Ah}}}}}}{{}{{An{Al}}}}`{{{f{bd}}c}{{An{{B`{c}}}}}Bb}{{{f{{An{c}}}}}{{f{c}}}{}}{{{f{c}}}{{f{e}}}{}{}}0000000000000000000{{{f{bc}}}{{f{be}}}{}{}}0000000000000000000{Abd}{{}{{Bd{ce}}}{}{{Bl{Bf}{{Bh{Bj}}}}}}{{}Bn}{{{f{A`}}}C`}{{{f{Ab}}}{{Aj{{f{l}}}}}}{{{f{{Cd{}{{Cb{c}}}}}}}{{Ch{C`Cf}}}{}}02{{{f{Cj}}}C`}{{{f{bCl}}}Bj}{{{f{Cn}}}{{Aj{D`}}}}{{{Bd{cegi}}Db}{{Bd{cegi}}}{}{{Bl{Bf}{{Bh{Bj}}}}}{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{cDf}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}10{{{f{j}}}j}{{{f{Ab}}}Ab}{{{f{Af}}}Af}{{{f{Dl}}}Dl}{{{f{Cn}}}Cn}{{{f{Dn}}}Dn}{{{f{E`}}}E`}{{{f{A`}}}A`}{{{f{Cj}}}Cj}{{{f{Eb}}}Eb}{{{f{c}}{f{be}}}Bj{}{}}000000000{{{f{Ab}}{f{Ab}}}Ed}{{{f{Dl}}{f{Dl}}}Ed}{{{f{c}}{f{e}}}Ed{}{}}0{{{f{{Bf{c}}}}}{{Aj{{f{e}}}}}{}{}}{{{f{A`}}}E`}{{{f{Cj}}}E`}{{{f{Cl}}}C`}{{{f{{Cd{}{{Cb{c}}}}}}}{{f{l}}}{}}0{{{f{bd}}c}{{f{bd}}}Ef}{{}{{Bd{ceEhEj}}}{}{{Bl{Bf}{{Bh{Bj}}}}}}{{}j}{{}Ab}{{}d}{{}Af}{{}Dl}{{}{{An{c}}}El}{{}Cn}{{}Cl}{{}Dn}{{}A`}{{}En}{{{f{{F`{c}}}}}{{f{e}}}`{}}{{{f{b{F`{c}}}}}{{f{be}}}`{}}{{{f{b{F`{c}}}}}Bj`}{{{An{c}}}{{An{Bj}}}{}}`{{{f{{Cd{}{{Cb{c}}}}}}}{{Ch{{f{Fb}}Fd}}}{}}0{{{f{{f{j}}}}{f{j}}}C`}{{{f{j}}{f{{f{j}}}}}C`}{{{f{j}}{f{{f{l}}}}}C`}{{{f{j}}{f{l}}}C`}{{{f{j}}{f{j}}}C`}{{{f{Ab}}{f{Ab}}}C`}{{{f{Ab}}{f{Ad}}}C`}{{{f{Af}}{f{l}}}C`}{{{f{Af}}{f{Af}}}C`}{{{f{Af}}{f{{f{l}}}}}C`}{{{f{Dl}}{f{Dl}}}C`}{{{f{Dn}}{f{Dn}}}C`}{{{f{E`}}{f{E`}}}C`}{{{f{Eb}}{f{Eb}}}C`}{{{f{c}}{f{e}}}C`{}{}}00000000000000000000`{{{Bd{cegi}}m}{{Bd{ceki}}}{}{{Bl{Bf}{{Bh{Bj}}}}}{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{cDf}}}}}{{Bh{Bj}}{Dd{Bj}}}}}{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Ff{kBf}}}}{{{Fh{cegik}}m}{{Fh{cegmk}}}{}{{Bl{Bf}{{Bh{Bj}}}}}Bb{}{}{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}}{{{f{A`}}}C`}{{{f{bCl}}Cl}Bj}{{{f{{Cd{}{{Cb{c}}}}}}}{{Fj{Cl}}}{}}{{{f{{Bf{c}}}}}{{Fj{Cl}}}{}}{{{f{{An{c}}}}}{{Fj{Cl}}}{}}{{{f{{Cd{}{{Cb{c}}}}}}}{{Fl{Cl}}}{}}{{{f{{Bf{c}}}}}{{Fl{Cl}}}{}}{{{f{b{An{c}}}}}{{Fl{Cl}}}{}}{{{f{n}}}{{Aj{{f{Fn}}}}}}{{{Bd{cegi}}k}{{Fh{cemgi}}}{}{{Bl{Bf}{{Bh{Bj}}}}}{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{cDf}}}}}{{Bh{Bj}}{Dd{Bj}}}}}{{Ff{eBf}}}Bb}{{{f{bd}}}{{An{{B`{Bj}}}}}}{{{f{j}}{f{bG`}}}{{Ch{BjGb}}}}0{{{f{Ab}}{f{bG`}}}{{Ch{BjGb}}}}0{{{f{{Bf{c}}}}{f{bG`}}}Gd{}}{{{f{d}}{f{bG`}}}Gd}{{{f{Af}}{f{bG`}}}{{Ch{BjGb}}}}0{{{f{Dl}}{f{bG`}}}{{Ch{BjGb}}}}{{{f{{An{c}}}}{f{bG`}}}GdBb}{{{f{Cn}}{f{bG`}}}Gd}{{{f{Cl}}{f{bG`}}}Gd}{{{f{Dn}}{f{bG`}}}Gd}{{{f{E`}}{f{bG`}}}Gd}{{{f{A`}}{f{bG`}}}Gd}{{{f{n}}{f{bG`}}}Gd}{{{f{Cj}}{f{bG`}}}Gd}{{{f{En}}{f{bG`}}}Gd}{{{f{Eb}}{f{bG`}}}Gd}{{{f{bd}}}{{f{bd}}}}{cc{}}00{{{f{j}}}j}1{{{f{Ab}}}Ab}{{{F`{A`}}}{{Bf{Gf}}}}33{{{An{c}}}d{}}{{{f{Cj}}}d}{GhAf}{AhAf}77{Gj{{An{Gj}}}}{{{Ch{ce}}}{{An{Al}}}{{Gl{{An{Al}}}}}{{Gl{Gn}}}}{H`{{An{Al}}}}{{{f{Gj}}}{{An{Gj}}}}{Hb{{An{Al}}}}{Gn{{An{Al}}}}{{{f{{Hf{Hd}}}}}{{An{{Hf{Hd}}}}}}{{{f{{Hh{Hd}}}}}{{An{{f{{Hh{Hd}}}}}}}}?{{{f{l}}}{{An{{f{l}}}}}}{{{f{Hb}}}{{An{Al}}}}{Hj{{An{Hj}}}}{d{{An{{B`{Bj}}}}}}{{{Hf{Hd}}}{{An{{Hf{Hd}}}}}}{Hl{{An{Hl}}}}{Cf{{An{Al}}}}{Hn{{An{Hn}}}}{cc{}}000{DbDn}{{{Aj{Db}}}Dn}2{GfI`}3{Ib{{I`{c}}}{}}{Id{{I`{c}}}{}}{If{{I`{c}}}{}}66{A`n}777{{{f{{Hh{Hd}}}}}{{Ch{jIh}}}}{{{f{{Hh{Hd}}}}}{{Ch{AbIj}}}}{c{{Ch{AfIl}}}{{In{{Hh{Hd}}}}}}{J`{{Ch{AfJb}}}}{{{f{l}}}Af}{{{f{l}}}{{Ch{j}}}}{{{f{l}}}{{Ch{AbIj}}}}{{{f{l}}}{{Ch{AfIl}}}}{Ad{{Ch{AbIj}}}}{{{f{Cl}}}{{Aj{{f{c}}}}}{}}{{{f{bCl}}}{{Aj{{f{bc}}}}}{}}`{{{Bd{cegi}}k}{{Jd{cemgi}}}{}{{Bl{Bf}{{Bh{Bj}}}}}{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{cDf}}}}}{{Bh{Bj}}{Dd{Bj}}}}}{{Ff{eBf}}}Bb}`{{{Bd{cegi}}k}{{Jf{cem}}}{}{{Bl{Bf}{{Bh{Bj}}}}}{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{cDf}}}}}{{Bh{Bj}}{Dd{Bj}}}}}{{Ff{eBf}}}Bb}{{EnDb}En}{{{f{j}}{f{bc}}}BjJh}{{{f{Ab}}{f{bc}}}BjJh}{{{f{Af}}{f{bc}}}BjJh}{{{f{Dl}}{f{bc}}}BjJh}{{{f{Eb}}{f{bc}}}BjJh}{{{f{{Bf{c}}}}}{{f{A`}}}{}}{{{f{{An{c}}}}}{{f{Cj}}}{}}{{{f{b{An{c}}}}}{{f{bCj}}}{}}`{{{f{{Cd{}{{Cb{c}}}}}}}{{f{Fn}}}{}}{{{f{{Bf{c}}}}}{{f{Fn}}}{}}{{{f{{An{c}}}}}{{f{Fn}}}{}}{{{f{A`}}}{{f{Fn}}}}{{{f{Cj}}}{{f{Fn}}}}``{{{f{b{Bf{c}}}}}{{f{bFn}}}{}}{{{f{b{An{c}}}}}{{f{bFn}}}{}}{{{f{bA`}}}{{f{bFn}}}}{{{f{bCj}}}{{f{bFn}}}}{{{f{Af}}}{{Aj{{f{l}}}}}}{{{f{Af}}}{{f{l}}}}{{{f{bCl}}c}{{Aj{c}}}{}}{{{f{bd}}c}{{f{bd}}}h}{{}{{An{Al}}}}{ce{}{}}0000000000000000000{{{An{c}}}c{}}1{{{Bf{c}}}{{Dj{{F`{A`}}{I`{c}}}}}{}}{AfJ`}{{{An{c}}}{{Dj{{An{Bj}}c}}}{}}{{{f{Ab}}}C`}{{{f{j}}}C`}11011{{{Bd{cegi}}k}{{Bd{cegi}}}{}{{Bl{Bf}{{Bh{Bj}}}}}{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{cDf}}}}}{{Bh{Bj}}{Dd{Bj}}}}}{{Gl{Dn}}}}{{{f{bd}}}{{f{bd}}}}{{{f{{An{c}}}}}C`{}}{{{f{Cn}}}Dn}{{{f{Cj}}}C`}{{{f{Cn}}}{{Aj{D`}}}}{{{Bd{cegi}}Jj}{{Bd{cegi}}}{}{{Bl{Bf}{{Bh{Bj}}}}}{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{cDf}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{f{Cn}}}{{Aj{Jj}}}}{{{An{c}}g}{{An{e}}}{}{}{{Jn{{f{bCj}}c}{{Jl{e}}}}}}{{{An{c}}}{{An{Al}}}Bb}{{{f{bd}}c}{{Ch{{An{c}}Gn}}}{}}{{{f{{Bf{c}}}}}{{f{j}}}{}}`{{{f{{Cd{}{{Cb{c}}}}}}}{{Ch{{Aj{K`}}Fd}}}{}}0{{}{{F`{c}}}`}{{}{{Bf{Gf}}}}{Abd}{Ab{{An{Al}}}}{e{{Fh{gci}}}{{Bl{Bf}{{Bh{Bj}}}}}{{Ff{cBf}}}{}Bb}{{DnDbDbC`{Aj{Jj}}}Cn}{{}Cl}{AbCj}{{{f{{Fh{cegik}}}}Bj}m{KbKdKf}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{cDf}}}}}{{Bh{Bj}}{Dd{Bj}}}}}{}}{{{f{bd}}Kh}{{f{bd}}}}{{{f{bA`}}C`}Bj}{{{f{bCj}}C`}Bj}{{}{{An{Al}}}}0{{{Bd{cegi}}k}{{Bd{cegi}}}{}{{Bl{Bf}{{Bh{Bj}}}}}{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{cDf}}}}}{{Bh{Bj}}{Dd{Bj}}}}}{{Kj{{f{c}}{f{bCl}}}}}}{{{Fh{{Kn{Kl}}cegi}}L`}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{LdLf}}}}{Lj{Bj}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{{Kn{Kl}}Df}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{Fh{{Kn{Kl}}cegi}}L`En}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{LdLf}}}}{Lj{Bj}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{{Kn{Kl}}Df}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{f{Ab}}{f{Ab}}}{{Aj{Ed}}}}{{{f{Dl}}{f{Dl}}}{{Aj{Ed}}}}{{{f{{Bf{c}}}}}{{f{l}}}{}}{{{f{Af}}}{{f{l}}}}{{{f{Af}}}{{Aj{{f{Gh}}}}}}{{{f{b{Bf{c}}}}}{{f{b{I`{c}}}}}{}}{{{f{{Bf{c}}}}}{{Aj{Jj}}}{}}`{{{Ll{{f{b{I`{c}}}}}}{f{bLn}}}{{M`{{Aj{e}}}}}{{Mf{}{{Mb{{Ch{HjMd}}}}}}}{}}{{{f{Af}}}{{Aj{{Mh{{f{l}}}}}}}}{{{f{Af}}}{{Aj{Ad}}}}0{{{f{Af}}}{{Aj{{f{l}}}}}}{{{f{bd}}{f{l}}}{{f{bd}}}}{{{f{Cj}}}{{f{l}}}}`{{{f{bCl}}}{{Aj{c}}}{}}{{{Bf{c}}{I`{e}}}{{Dj{{Bf{e}}{I`{c}}}}}{}{}}{{{Fh{{Mj{Kl}}cegi}}Ml}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{MnLf}}}}{Lj{Bj}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{{Mj{Kl}}Df}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{Fh{{N`{Kl}}cegi}}Nb}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{MnLf}}}}{Lj{Bj}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{{N`{Kl}}Df}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{Fh{{N`{Kl}}cegi}}NbEn}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{MnLf}}}}{Lj{Bj}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{{N`{Kl}}Df}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{Fh{{Nd{Kl}}cegi}}Nf}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{MnLf}}}}{Lj{Bj}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{{Nd{Kl}}Df}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{Fh{{Nd{Kl}}cegi}}NfEn}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{MnLf}}}}{Lj{Bj}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{{Nd{Kl}}Df}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{Fh{{Nh{Kl}}cegi}}Nj}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{MnLf}}}}{Lj{Bj}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{{Nh{Kl}}Df}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{Fh{{Nh{Kl}}cegi}}NjEn}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{MnLf}}}}{Lj{Bj}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{{Nh{Kl}}Df}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{Fh{{Mj{Kl}}cegi}}MlEn}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{MnLf}}}}{Lj{Bj}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{{Mj{Kl}}Df}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{f{Af}}}{{Aj{{f{Nl}}}}}}={{{Bd{cegi}}}{{Bd{cegi}}}{}{{Bl{Bf}{{Bh{Bj}}}}}{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{cDf}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{f{Cn}}}C`}{{{An{c}}e}{{An{e}}}{}{}}{{{f{bA`}}C`}Bj}{{{f{bCj}}C`}Bj}{{{f{bA`}}E`}Bj}{{{f{bCj}}E`}Bj}{{{f{bd}}Ab}{{f{bd}}}}{{{f{{An{c}}}}}Ab{}}`{{{f{b{An{c}}}}}{{f{bAb}}}{}}{{{f{bd}}}d}{{{f{b{I`{c}}}}}{{I`{c}}}{}}{{{f{b{Bf{c}}}}}{{Aj{{Nn{Cl}}}}}{}}{{{f{b{Cd{}{{Cb{c}}}}}}}{{I`{c}}}{}}{{{f{b{Bf{c}}}}}{{I`{c}}}{}}0{{{f{b{Bf{c}}}}}Cl{}}{{{Fh{Klcegi}}}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{Lf}}{Lj{Bj}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{KlDf}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}0`{{{f{c}}}e{}{}}000000000{{{f{c}}}Gj{}}00{c{{Ch{e}}}{}{}}00{{{f{l}}}{{Ch{j}}}}{{{f{{Hh{Hd}}}}}{{Ch{j}}}}{{{f{{Hh{Hd}}}}}{{Ch{Ab}}}}{{{f{l}}}{{Ch{Ab}}}}{Ad{{Ch{Ab}}}}555{{{f{Gj}}}{{Ch{Af}}}}6{{{f{{Hh{Hd}}}}}{{Ch{Af}}}}{{{f{Af}}}{{Ch{Af}}}}{J`{{Ch{Af}}}}{Gj{{Ch{Af}}}}{{{f{l}}}{{Ch{Af}}}}{{{Hf{Hd}}}{{Ch{Af}}}}<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<{{{Ll{{f{bc}}}}{f{bLn}}}{{M`{{Aj{Ch}}}}}{}}{{{f{c}}}O`{}}0000000000000000000{{{Bd{cegi}}m}{{Bd{cegk}}}{}{{Bl{Bf}{{Bh{Bj}}}}}{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{cDf}}}}}{{Bh{Bj}}{Dd{Bj}}}}}{{Bl{{Dj{Bf{Dh{cDf}}}}}{{Bh{Bj}}{Dd{Bj}}}}}{{Ff{k{Dj{Bf{Dh{cDf}}}}}}}}{{{f{{Bf{c}}}}}C`{}}{{{f{bd}}c}{{f{bd}}}Ef}{{{f{{An{c}}}}}C`{}}{{{Fh{cegik}}{Aj{m}}}{{Fh{cegim}}}{}{{Bl{Bf}{{Bh{Bj}}}}}Bb{}{}{{Bl{{Dj{Bf{Dh{cDf}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{f{A`}}}C`}{{{f{Cj}}}C`}`{{{f{{Bf{c}}}}}{{f{Af}}}{}}`{{{f{b{Bf{c}}}}}{{f{bAf}}}{}}{{{f{{Bf{c}}}}}Dl{}}``{ce{}{}}0000000000000000000{{Abc}{{An{c}}}{}}{{{I`{c}}}{{Bf{c}}}{}}```````````````````{{{f{bAl}}}{{Ll{{f{bAl}}}}}}{{{f{c}}}{{f{e}}}{}{}}000000{{{f{bc}}}{{f{be}}}{}{}}000000{{{Bb{}{{Lb{c}}}}}Al{{Gl{{Od{Ob}}}}}}0{AlAl}{{{B`{ce}}}AlBbBb}{{{f{{B`{ce}}}}}{{B`{ce}}}OfOf}{{{f{Oh}}}Oh}{{{f{Oj}}}Oj}{{{f{c}}{f{be}}}Bj{}{}}00{{}Oh}{{{f{Oj}}{f{Oj}}}C`}{{{f{c}}{f{e}}}C`{}{}}00{{{f{Al}}{f{bG`}}}Gd}{{{f{{B`{ce}}}}{f{bG`}}}GdOlOl}{{{f{Oh}}{f{bG`}}}Gd}{{{f{Oj}}{f{bG`}}}Gd}{{{f{On}}{f{bG`}}}Gd}0{cc{}}000000{ce{}{}}000000{{{f{Oj}}}C`}{c{{B`{ce}}}{}{}}{e{{A@`{e}}}{{Gl{{Od{Ob}}}}}{{Mf{}{{Mb{{Ch{Hjc}}}}}}}}{cAlBb}{c{{B`{cAl}}}{}}>{{Khe}{{A@b{e}}}{{Gl{{Od{Ob}}}}}{{Mf{}{{Mb{{Ch{Hjc}}}}}}}}{{{Ll{{f{b{Bb{}{{Lb{c}}}}}}}}{f{bLn}}}{{M`{{Aj{{Ch{Hjc}}}}}}}{{Gl{{Od{Ob}}}}}}{{{Ll{{f{b{A@`{e}}}}}}{f{bLn}}}{{M`{{Aj{{Ch{Hjg}}}}}}}{{Gl{Od}}}{{Mf{}{{Mb{{Ch{Hjc}}}}}}}{}}{{{Ll{{f{bAl}}}}{f{bLn}}}{{M`{{Aj{{Ch{Hjc}}}}}}}{}}{{{Ll{{f{b{B`{ce}}}}}}{f{bLn}}}{{M`{{Aj{{Ch{Hjg}}}}}}}BbBb{}}{{{Ll{{f{bOh}}}}{f{bLn}}}{{M`{{Aj{{Ch{Hjc}}}}}}}{}}{{{Ll{{f{b{A@b{e}}}}}}{f{bLn}}}{{M`{{Aj{{Ch{Hjg}}}}}}}{{Gl{Od}}}{{Mf{}{{Mb{{Ch{Hjc}}}}}}}{}}{c{{B`{ec}}}{}{}}{{{f{{Bb{}{{Lb{c}}}}}}}Oj{{Gl{{Od{Ob}}}}}}{{{f{{A@`{e}}}}}Oj{{Gl{{Od{Ob}}}}}{{Mf{}{{Mb{{Ch{Hjc}}}}}}}}{{{f{Al}}}Oj}{{{f{{B`{ce}}}}}OjBbBb}{{{f{Oh}}}Oj}{{{f{{A@b{e}}}}}Oj{{Gl{{Od{Ob}}}}}{{Mf{}{{Mb{{Ch{Hjc}}}}}}}}{c{{Ch{Hj}}}Bb}{{cA@d}{{Ch{{Ch{Hj}}On}}}Bb}{{{f{c}}}e{}{}}00{{{f{c}}}Gj{}}{c{{Ch{e}}}{}{}}0000000000000{{{Bb{}{{Lb{c}}}}}{{Ch{Hj{Bb{}{{Lb{c}}}}}}}{{Gl{{Od{Ob}}}}}}0{Al{{Ch{HjAl}}}}{{{B`{ce}}}{{Ch{Hj{B`{ce}}}}}BbBb}{Oh{{Ch{HjOh}}}}{{{f{c}}}O`{}}000000{ce{}{}}000000````{{{f{c}}}{{f{e}}}{}{}}0{{{f{bc}}}{{f{be}}}{}{}}0{cc{}}0{{c{f{Fn}}}{{A@f{c}}}{{Mf{}{{Mb{{Ch{HjMd}}}}}}}}44{{cA@h}{{A@f{c}}}{{Mf{}{{Mb{{Ch{HjMd}}}}}}}}{{{Ll{{f{b{A@f{c}}}}}}{f{bLn}}}{{M`{{Aj{e}}}}}{{Mf{}{{Mb{{Ch{HjMd}}}}}}}{}}{{{Ll{{f{b{A@j{c}}}}}}{f{bLn}}}{{M`{{Aj{{Ch{Hje}}}}}}}Bb{}}{{A@h{f{bCj}}c}{{A@j{c}}}Bb}{{{f{{A@j{c}}}}}OjBb}????{{{A@j{c}}}{{Ch{Hj{A@j{c}}}}}Bb}{{{Ll{{f{bc}}}}{f{bLn}}}{{M`{{Aj{Ch}}}}}{}}<<;;``````````````````````````````````::::::999999{{{f{Gn}}{f{bG`}}}Gd}0{{{f{A@l}}{f{bG`}}}{{Ch{BjGb}}}}0{{{f{Cf}}{f{bG`}}}Gd}0{{{f{Md}}{f{bG`}}}Gd}0{{{f{Lf}}{f{bG`}}}Gd}0{{{f{Fd}}{f{bG`}}}Gd}0{A@lGn}{H`Gn}{HbGn}{MdGn}{CfGn}{cc{}}{A@nGn}1{IjA@l}{AA`A@l}{IlA@l}{H`A@l}{AAbA@l}{JbA@l}{IhA@l}{AAdA@l}{AAfCf}{IlCf}{AAhCf}{MnCf}={AAjCf}{AAlMd}{{{Aj{Mn}}}Md}{cc{}}{MnMd}{CfLf}{{{An{Al}}}Lf}{{{Od{Ob}}}Lf}{AAlLf}5{MnLf}6{{{f{A@l}}}{{f{Ob}}}}{ce{}{}}00000{{{f{A@l}}}C`}{{{f{Gn}}}{{Aj{{f{Ob}}}}}}{{{f{A@l}}}{{Aj{{f{Ob}}}}}}{{{f{Cf}}}{{Aj{{f{Ob}}}}}}{{{f{Md}}}{{Aj{{f{Ob}}}}}}{{{f{Lf}}}{{Aj{{f{Ob}}}}}}{{{f{c}}}Gj{}}00000{c{{Ch{e}}}{}{}}00000000000{{{f{c}}}O`{}}00000999999`````````````````{{{f{c}}}{{f{e}}}{}{}}0000000000{{{f{bc}}}{{f{be}}}{}{}}0000000000{{{f{Eh}}Bf}c{}}{{{f{Ej}}{Dj{Bf{Dh{cDf}}}}}e{}{}}{{{f{AAn}}}AAn}{{{f{c}}{f{be}}}Bj{}{}}{{{f{Df}}}{{f{Cn}}}}{C`{{Dj{`If}}}}{{{f{bAB`}}{f{bHn}}}{{Ch{{Aj{c}}e}}}{}{}}{{{f{bABb}}{f{bHn}}}{{Ch{{Aj{c}}e}}}{}{}}{{{f{bDf}}{f{bHn}}}{{Ch{{Aj{c}}e}}}{}{}}{{}AB`}{{}Df}{{{f{bAB`}}{ABd{{Dj{nOj}}}}{f{bHn}}}{{Ch{Bjc}}}{}}{{{f{bDf}}{ABd{{Dj{{An{Bj}}Oj}}}}{f{bHn}}}{{Ch{Bjc}}}{}}{{{f{AAn}}{f{AAn}}}C`}{{{f{c}}{f{e}}}C`{}{}}00{{{Jd{cegik}}m}{{Jd{cegmk}}}{}{{Bl{Bf}{{Bh{Bj}}}}}Bb{}{}{{Bl{Bf}{{Dd{Bf}}}}}}{{{f{AB`}}{f{bG`}}}Gd}{{{f{Df}}{f{bG`}}}Gd}{{{f{If}}{f{bG`}}}Gd}{{{f{{ABd{c}}}}{f{bG`}}}GdOl}{{{f{AAn}}{f{bG`}}}Gd}{cc{}}00000000{c{{ABd{c}}}{}}{ABfc{}}22{ce{}{}}0000000000000{c{}{}}0{ABbAB`}{AB`ABb}33{{{f{AB`}}}C`}{{{f{ABb}}}C`}{{{f{Df}}}C`}0{{{f{AB`}}}AAn}{{{f{Df}}}AAn}{CnAB`}{CnDf}{{{Dh{cDf}}{An{e}}}{{ABh{ce}}}{}Bb}{{{f{Eh}}c}e{}{}}{{{f{{Jd{cegik}}}}Bj}m{KbKdKf}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{cDf}}}}}{{Bh{Bj}}{Dd{Bj}}}}}{}}{{{f{Ej}}Bj}c{}}{{{Jd{{Kn{Kl}}cegi}}L`}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{LdLf}}}}{Lj{Bj}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{{Kn{Kl}}Df}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{Ll{{f{b{ABj{cegik}}}}}}{f{bLn}}}{{M`{m}}}{KbKdKf}{{ABl{Bf}}}Bb{{ABl{Bf}{{Dd{Bf}}}}}{{ABl{{Dj{Bf{Dh{cDf}}}}}{{Dd{Bj}}}}}{}}{{{Ll{{f{b{ABh{ce}}}}}}{f{bLn}}}{{M`{g}}}{KbKdKf}Bb{}}{{{Ll{{f{bIf}}}}{f{bLn}}}{{M`{{Aj{{Ch{HjMd}}}}}}}}{{{f{Eh}}{f{bLn}}}{{M`{{Ch{Bjc}}}}}{}}{{{f{Ej}}{f{bLn}}}{{M`{{Ch{Bjc}}}}}{}}{{{Jd{{Mj{Kl}}cegi}}Ml}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{MnLf}}}}{Lj{Bj}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{{Mj{Kl}}Df}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{Jd{{N`{Kl}}cegi}}Nb}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{MnLf}}}}{Lj{Bj}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{{N`{Kl}}Df}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{Jd{{Nd{Kl}}cegi}}Nf}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{MnLf}}}}{Lj{Bj}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{{Nd{Kl}}Df}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{Jd{{Nh{Kl}}cegi}}Nj}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{MnLf}}}}{Lj{Bj}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{{Nh{Kl}}Df}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{Jd{Klcegi}}}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{Lf}}{Lj{Bj}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb{{Bl{Bf}{{Bh{Bj}}{Dd{Bf}}}}}{{Bl{{Dj{Bf{Dh{KlDf}}}}}{{Bh{Bj}}{Dd{Bj}}}}}}{{{f{c}}}e{}{}}{c{{Ch{e}}}{}{}}000000000000000000000{{{Ll{{f{bc}}}}{f{bLn}}}M`{}}0{{{Ll{{f{bc}}}}{f{bLn}}}{{M`{{Aj{Ch}}}}}{}}{{{f{c}}}O`{}}0000000000{{{f{bIf}}Hj}Bj}{{{f{AB`}}}C`}{{{f{Df}}}C`}{{{Jd{cegik}}{Aj{m}}}{{Jd{cegim}}}{}{{Bl{Bf}{{Bh{Bj}}}}}Bb{}{}{{Bl{{Dj{Bf{Dh{cDf}}}}}{{Dd{Bj}}}}}}{ce{}{}}0000000000```{{{f{c}}}{{f{e}}}{}{}}00{{{f{bc}}}{{f{be}}}{}{}}00{cc{}}003333{c{}{}}{{{f{{Jf{ceg}}}}Bj}i{KbKdKf}{{Bl{Bf}{{Bh{Bj}}}}}Bb{}}{{{Jf{{Kn{Kl}}ce}}L`}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{LdLf}}}}{Lj{}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb}{{{Ll{{f{b{ABn{cegik}}}}}}{f{bLn}}}{{M`{m}}}{KbKdKf}{{ABl{Bf}}}Bb{}{}{}}{{{Ll{{f{bIb}}}}{f{bLn}}}{{M`{{Aj{c}}}}}{}}{{{Jf{{Mj{Kl}}ce}}Ml}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{MnLf}}}}{Lj{}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb}{{{Jf{{N`{Kl}}ce}}Nb}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{MnLf}}}}{Lj{}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb}{{{Jf{{Nd{Kl}}ce}}Nf}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{MnLf}}}}{Lj{}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb}{{{Jf{{Nh{Kl}}ce}}Nj}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{{Lh{MnLf}}}}{Lj{}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb}{{{Jf{Klce}}}{{`{{Bl{Kl}{{Bh{Bj}}{Dd{Bj}}{Lb{Lf}}{Lj{}}}}}}}{{Bl{Bf}{{Bh{Bj}}}}}Bb}{c{{Ch{e}}}{}{}}00000{{{Ll{{f{bc}}}}{f{bLn}}}M`{}}{{{Ll{{f{bc}}}}{f{bLn}}}{{M`{{Aj{Ch}}}}}{}}{{{f{c}}}O`{}}00{ce{}{}}00````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````{{{f{AC`}}}{{f{{Hh{Hd}}}}}}{{{f{ACb}}}{{f{{Hh{Hd}}}}}}{{{f{ACb}}}{{f{l}}}}2{{{f{ACd}}}{{f{l}}}}1{A@h{{f{l}}}}{{{f{c}}}{{f{e}}}{}{}}000300000000{{{f{bc}}}{{f{be}}}{}{}}00000000000{{{f{ACd}}}{{Ch{ACdACf}}}}`{{{f{ACd}}}ACd}{{{f{ACb}}}ACb}{{{f{AC`}}}AC`}{{{f{ACh}}}ACh}{{{f{A@h}}}A@h}{{{f{ACj}}}ACj}{{{f{ACl}}}ACl}{{{f{ACn}}}ACn}{{{f{{AD`{c}}}}}{{AD`{c}}}Of}{{{f{c}}{f{be}}}Bj{}{}}00000000{{{f{AC`}}{f{AC`}}}Ed}{{{f{ACl}}{f{ACl}}}Ed}{{{f{ACn}}{f{ACn}}}Ed}{{{f{c}}{f{e}}}Ed{}{}}00{{}A@h}{{}ACn}{{{f{ACd}}{f{ACd}}}C`}{{{f{ACb}}{f{l}}}C`}{{{f{ACb}}{f{{f{l}}}}}C`}{{{f{{f{ACb}}}}{f{ACb}}}C`}{{{f{ACb}}{f{ACb}}}C`}{{{f{ACb}}{f{{f{ACb}}}}}C`}{{{f{AC`}}{f{{Hh{Hd}}}}}C`}{{{f{AC`}}{f{Gj}}}C`}{{{f{AC`}}{f{AC`}}}C`}{{{f{{f{AC`}}}}{f{AC`}}}C`}{{{f{AC`}}{f{l}}}C`}{{{f{AC`}}{f{{f{c}}}}}C`ADb}{{{f{ACh}}{f{ACh}}}C`}{{{f{A@h}}{f{A@h}}}C`}{{{f{ACj}}{f{ACj}}}C`}{{{f{ACl}}{f{ACl}}}C`}{{{f{ACn}}{f{ACn}}}C`}{{{f{{AD`{c}}}}{f{{AD`{c}}}}}C`ADd}{{{f{c}}{f{e}}}C`{}{}}00000000000000000000000000{{{f{ACd}}}{{Aj{{f{l}}}}}}{{{f{ACd}}}{{`{{ADf{}{{Mb{{f{l}}}}}}}}}}1{{{f{ACd}}}{{`{{ADf{}{{Mb{{Dj{ADh{f{l}}}}}}}}}}}}{{{f{ACd}}{f{bG`}}}{{Ch{BjGb}}}}0{{{f{AA`}}{f{bG`}}}{{Ch{BjGb}}}}0{{{f{AAb}}{f{bG`}}}{{Ch{BjGb}}}}0{{{f{ACb}}{f{bG`}}}{{Ch{BjGb}}}}0{{{f{AC`}}{f{bG`}}}{{Ch{BjGb}}}}{{{f{ADj}}{f{bG`}}}{{Ch{BjGb}}}}0{{{f{ACh}}{f{bG`}}}Gd}0{{{f{A@h}}{f{bG`}}}Gd}{{{f{ACj}}{f{bG`}}}Gd}0{{{f{ACl}}{f{bG`}}}Gd}0{{{f{ACn}}{f{bG`}}}Gd}0{{{f{{AD`{c}}}}{f{bG`}}}GdADl}{{{f{{AD`{c}}}}{f{bG`}}}GdOl}{{{f{bG`}}{f{{Hh{c}}}}}GdADl}{cc{}}00{{{f{ACb}}}ACb}1{A@dAC`}{ADnAC`}{AE`AC`}{AEbAC`}{AdAC`}{KhAC`}7{{{f{AC`}}}AC`}{AEdAC`}{AEfAC`}{ACbAC`};;;;;{AEhACl}<<{{{f{{Hh{Hd}}}}}{{Ch{ACbAA`}}}}{{{f{{Hh{Hd}}}}}{{Ch{AC`AAb}}}}{c{{Ch{{Hf{e}}Cf}}}{{ADf{}{{Mb{{f{AC`}}}}}}}AEj}2{c{{Ch{AC`AAb}}}{{In{{Hh{Hd}}}}}}{cAC`{{In{{Hh{Hd}}}}}}6{{{Aj{{f{AC`}}}}}{{Ch{cCf}}}AEj}{{{f{l}}}ACb}{{{f{l}}}AC`}{{{f{l}}}{{Ch{ACdAEl}}}}{{{f{l}}}{{Ch{ACbAA`}}}}{{{f{l}}}{{Ch{AC`}}}}{{{f{l}}}{{Ch{AC`AAb}}}}{{{f{l}}}{{Ch{AChGn}}}}{{{f{l}}}{{Ch{A@hc}}}{}}{{{f{l}}}{{Ch{AClCf}}}}{{{f{l}}}{{Ch{{AD`{c}}e}}}AEj{}}{{{f{ACd}}}{{f{l}}}}{{{f{ACd}}{f{bc}}}BjJh}{{{f{ACb}}{f{bc}}}BjJh}{{{f{AC`}}{f{bc}}}BjJh}{{{f{A@h}}{f{bc}}}BjJh}{{{f{bG`}}{f{{Hh{Hd}}}}}Gd}{ce{}{}}00000000000{ACdGj}{{{f{AC`}}}C`}{{{f{ACd}}}C`}10``{{{f{AC`}}}A@d}`{{{f{ACd}}{f{ACd}}}C`}{c{{AD`{c}}}{}}0{{}ACb}0{{cACn}{{AD`{c}}}{}}{{{f{c}}}{{Ch{AEnCf}}}Cd}{{{f{l}}}{{Ch{ACdAEl}}}}{{{f{c}}}{{Ch{A@hCf}}}Cd}{{{f{l}}}{{Ch{ACjCf}}}}{{{f{AC`}}{f{Gj}}}{{Aj{Ed}}}}{{{f{AC`}}{f{{Hh{Hd}}}}}{{Aj{Ed}}}}{{{f{AC`}}{f{AC`}}}{{Aj{Ed}}}}{{{f{AC`}}{f{l}}}{{Aj{Ed}}}}{{{f{{f{AC`}}}}{f{AC`}}}{{Aj{Ed}}}}{{{f{AC`}}{f{{f{c}}}}}{{Aj{Ed}}}ADb}{{{f{ACl}}{f{ACl}}}{{Aj{Ed}}}}{{{f{ACn}}{f{ACn}}}{{Aj{Ed}}}}{{{f{{AD`{c}}}}{f{{AD`{c}}}}}{{Aj{Ed}}}ADd}{{{f{ACd}}}{{f{l}}}}{{{f{ACd}}}{{Aj{{f{l}}}}}}{{{f{ACd}}}{{`{{ADf{}{{Mb{{f{l}}}}}}}}}}{cACn{{AF`{ACn}}}}`22{{{f{bAC`}}C`}Bj}{A@hAC`}{{{f{c}}}e{}{}}00000000{{{f{AC`}}}{{Ch{{f{l}}ADj}}}}{{{f{c}}}Gj{}}000000000{c{{Ch{e}}}{}{}}000{Gj{{Ch{ACb}}}}{{{f{{Hh{Hd}}}}}{{Ch{ACb}}}}{{{f{Gj}}}{{Ch{ACb}}}}{{{f{l}}}{{Ch{ACb}}}}{{{Hf{Hd}}}{{Ch{ACb}}}}{{{f{{Hh{Hd}}}}}{{Ch{AC`}}}}{{{f{Gj}}}{{Ch{AC`}}}}{{{Hf{Hd}}}{{Ch{AC`}}}}{{{f{l}}}{{Ch{AC`}}}}{Gj{{Ch{AC`}}}}::::{{{f{l}}}{{Ch{A@hc}}}{}};;;{AFb{{Ch{ACnc}}}{}}<<<<<<<<<<<<<{{{h{}{{Lb{c}}}}}{{Ch{{Dj{ACbAC`}}c}}}{{Gl{A@l}}}}{c{{Ch{{Dj{ACbAC`}}}}}{}}{{{Ef{}{{Lb{c}}}}}{{Ch{AC`c}}}{{Gl{A@l}}}}{{{f{AC`}}}{{Ch{AC`c}}}{}}{AC`{{Ch{AC`c}}}{}}{A@h{{Ch{AC`c}}}{}}{ACl{{Ch{AC`c}}}{}}{{{f{c}}}O`{}}00000000000{{{f{ACd}}}{{Ch{BjACf}}}}`{{{f{ACd}}}{{Aj{{f{l}}}}}}{{{f{ACd}}}{{`{{ADf{}{{Mb{{f{l}}}}}}}}}}{ce{}{}}00000000000{c{{AD`{c}}}{}}``````{{{f{bFn}}ACbAC`}Bj}{{{f{c}}}{{f{e}}}{}{}}00000{{{f{bc}}}{{f{be}}}{}{}}00000{{{f{Fn}}}A@d}{{{f{bFn}}}Bj}{{{f{Fn}}}Fn}{{{f{c}}{f{be}}}Bj{}{}}{{{f{Fn}}c}C`AFd}{{}Fn}{{{f{bFn}}}AFf}{{{f{Fn}}{f{bG`}}}Gd}{{{f{AFh}}{f{bG`}}}Gd}{{{f{AFj}}{f{bG`}}}Gd}{{{f{AFl}}{f{bG`}}}Gd}{{{f{AFf}}{f{bG`}}}Gd}{{{f{AFn}}{f{bG`}}}Gd}{AG`Fn}{cc{}}00000{{{f{Fn}}c}{{Aj{{f{AC`}}}}}AFd}{{{f{Fn}}c}{{AGb{AC`}}}AFd}{{{f{bFn}}c}{{Aj{{f{bAC`}}}}}AFd}{{{f{bFn}}ACbAC`}AFh}{ce{}{}}00000{{{f{Fn}}}c{}}{Fnc{}}22222{{{f{Fn}}}C`}{{{f{AFh}}}C`}{{{f{Fn}}}AFl}{{{f{Fn}}}AFj}{{{f{Fn}}}A@d}0{{}Fn}{{{f{bAFh}}}{{Aj{c}}}{}}{{{f{bAFj}}}{{Aj{c}}}{}}{{{f{bAFl}}}{{Aj{c}}}{}}{{{f{bAFf}}}{{Aj{c}}}{}}{{{f{bAFn}}}{{Aj{c}}}{}}{{{f{bFn}}c}AFhAFd}{{{f{bFn}}A@d}Bj}{{{f{bFn}}c}Bj{{AGd{{f{ACb}}{f{bAC`}}}{{Jl{C`}}}}}}{{{f{AFh}}}{{Dj{A@d{Aj{A@d}}}}}}{{{f{AFj}}}{{Dj{A@d{Aj{A@d}}}}}}{{{f{AFl}}}{{Dj{A@d{Aj{A@d}}}}}}{{{f{AFf}}}{{Dj{A@d{Aj{A@d}}}}}}{{{f{AFn}}}{{Dj{A@d{Aj{A@d}}}}}}{{{f{c}}}e{}{}}{c{{Ch{e}}}{}{}}00000000000{{{f{c}}}O`{}}00000{ce{}{}}00000{A@dFn}````{{{f{bAGf}}c}{{f{bAGf}}}h}{{{f{c}}}{{f{e}}}{}{}}000{{{f{bc}}}{{f{be}}}{}{}}000{{{f{AGh}}}AGh}{{{f{c}}{f{be}}}Bj{}{}}{{}AGf}{{}AGj}{{}AGh}{{{f{AGh}}}{{Fj{{Aj{Mn}}}}}}`{{{f{bAGj}}c}Bj{{In{{Hh{Hd}}}}}}{{{f{bAGh}}c}Bj{{In{{Hh{Hd}}}}}}{{{f{bAGf}}}Bf}{{{f{bAGj}}}{{AGl{Bj}}}}{{{f{bAGh}}}{{AGl{Bj}}}}{{{f{AGj}}{f{bG`}}}Gd}{cc{}}000?{ce{}{}}000{{{f{bAGf}}j}{{f{bAGf}}}}{cAGj{{Gl{Hn}}}}{cAGh{{Gl{Hn}}}}{{{Ll{{f{bAGj}}}}{f{bLn}}}{{M`{{AGl{Bj}}}}}}{{{Ll{{f{bAGh}}}}{f{bLn}}}{{M`{{AGl{Bj}}}}}}{{{Ll{{f{bAGj}}}}{f{bLn}}{f{bAGn}}}{{M`{{AGl{Bj}}}}}}{{{Ll{{f{bAGh}}}}{f{bLn}}{f{bAGn}}}{{M`{{AGl{Bj}}}}}}32{{{Ll{{f{bAGj}}}}{f{bLn}}{f{{Hh{Hd}}}}}{{M`{{AGl{A@d}}}}}}{{{Ll{{f{bAGh}}}}{f{bLn}}{f{{Hh{Hd}}}}}{{M`{{AGl{A@d}}}}}}{{{f{bAGj}}{f{b{Hh{Hd}}}}}{{Ch{A@dMn}}}}{{{f{bAGh}}{f{b{Hh{Hd}}}}}{{Ch{A@dMn}}}}{{{f{AGh}}}{{Fj{Hn}}}}`{{{f{bAGf}}c}{{f{bAGf}}}{{Gl{Hj}}}}{{{f{bAGf}}}AGf}{{{f{c}}}e{}{}}{c{{Ch{e}}}{}{}}0000000{{{f{c}}}O`{}}000{{{f{bAGf}}{f{l}}}{{f{bAGf}}}}{{{f{bAGf}}Dl}{{f{bAGf}}}}{ce{}{}}000{{{f{l}}}AGf}{{{f{bAGj}}{f{{Hh{Hd}}}}}{{AGl{A@d}}}}{{{f{bAGh}}{f{{Hh{Hd}}}}}{{AGl{A@d}}}};````````````{{{f{{Mh{c}}}}}{{f{l}}}{{In{l}}}}{{{f{Ah}}}{{f{l}}}}{{{f{Nl}}}{{f{l}}}}21{{{f{Gh}}}{{f{l}}}}1{{{f{{Mh{c}}}}}Ad{}}{{Bnc}Bn{}}`{{{f{c}}}{{f{e}}}{}{}}0000000{{{f{bc}}}{{f{be}}}{}{}}0000000{Bn{{Ch{AfA@l}}}}{{{f{Ah}}}Ah}{{{f{Gh}}}Gh}{{{f{Nl}}}Nl}{{{f{c}}{f{be}}}Bj{}{}}00{{}Bn}{{}J`}{{{f{{Mh{c}}}}{f{{Mh{e}}}}}C`{}{}}{{{f{{Mh{c}}}}{f{Ad}}}C`{}}{{{f{Ah}}{f{l}}}C`}{{{f{Ah}}{f{{f{l}}}}}C`}{{{f{Ah}}{f{Gj}}}C`}{{{f{Ah}}{f{Ah}}}C`}{{{f{Gh}}{f{Gh}}}C`}{{{f{Gh}}{f{Gj}}}C`}{{{f{Gh}}{f{l}}}C`}{{{f{Gh}}{f{{f{l}}}}}C`}{{{f{Nl}}{f{Nl}}}C`}{{{f{Nl}}{f{l}}}C`}{{{f{c}}{f{e}}}C`{}{}}00000000{{{f{{Mh{c}}}}{f{bG`}}}{{Ch{BjGb}}}{}}{{{f{{Mh{c}}}}{f{bG`}}}{{Ch{BjGb}}}Ol}{{{f{Ah}}{f{bG`}}}{{Ch{BjGb}}}}0{{{f{Bn}}{f{bG`}}}{{Ch{BjGb}}}}{{{f{Gh}}{f{bG`}}}{{Ch{BjGb}}}}0{{{f{Nl}}{f{bG`}}}{{Ch{BjGb}}}}0{{{f{J`}}{f{bG`}}}{{Ch{BjGb}}}}{{{f{Il}}{f{bG`}}}{{Ch{BjGb}}}}0{{{f{Jb}}{f{bG`}}}{{Ch{BjGb}}}}0{cc{}}0000{AfJ`}1{AH`Il}2{AH`Jb}3{c{{Ch{AhIl}}}{{In{{Hh{Hd}}}}}}{c{{Ch{GhIl}}}{{In{{Hh{Hd}}}}}}{{{f{l}}}Ah}{{{f{l}}}Gh}{{{f{l}}}{{Ch{AhIl}}}}{{{f{l}}}{{Ch{GhIl}}}}{{{f{l}}}{{Ch{Nl}}}}{{{f{Ah}}{f{bc}}}BjJh}{{{f{Gh}}{f{bc}}}BjJh}{{{f{Nl}}{f{bc}}}BjJh}{{{f{Ah}}}{{f{l}}}}{ce{}{}}0000000{{}Bn}{{{f{Ah}}{f{Ah}}}{{Aj{Ed}}}}{{{f{Ah}}{f{{f{l}}}}}{{Aj{Ed}}}}{{{f{Ah}}{f{Gj}}}{{Aj{Ed}}}}{{{f{Ah}}{f{l}}}{{Aj{Ed}}}}{{{f{Gh}}{f{l}}}{{Aj{Ed}}}}{{{f{Gh}}{f{{f{l}}}}}{{Aj{Ed}}}}{{{f{Gh}}{f{Gj}}}{{Aj{Ed}}}}{{{f{Gh}}{f{Gh}}}{{Aj{Ed}}}}{{{f{Gh}}}{{f{l}}}}{{Bnc}Bn{}}`{{{f{Ah}}}{{Aj{{Mh{{f{l}}}}}}}}{{{f{Ah}}}{{Aj{Ad}}}}{{{f{Gh}}}{{Aj{{f{l}}}}}}3`{{{f{c}}}e{}{}}00{{{f{c}}}Gj{}}00000{c{{Ch{e}}}{}{}}{Gj{{Ch{Ah}}}}{{{Hf{Hd}}}{{Ch{Ah}}}}{{{f{l}}}{{Ch{Ah}}}}{{{f{{Hh{Hd}}}}}{{Ch{Ah}}}}44{{{f{{Hh{Hd}}}}}{{Ch{Gh}}}}{Gj{{Ch{Gh}}}}{{{f{l}}}{{Ch{Gh}}}}7{{{Hf{Hd}}}{{Ch{Gh}}}}{{{f{Gj}}}{{Ch{Gh}}}}{{{f{l}}}{{Ch{Nl}}}}{{{f{{Hh{Hd}}}}}{{Ch{Nl}}}};;;;;;;;;;;;{{{f{c}}}O`{}}0000000{ce{}{}}0000000```````````````````````````````````````````````````````````````{{{f{c}}}{{f{e}}}{}{}}0000000000{{{f{bc}}}{{f{be}}}{}{}}0000000000{AHbAHb}{{{f{AHb}}}AHb}{{{f{AHd}}}AHd}{{{f{AHf}}}AHf}{{{f{AHh}}}AHh}{{{f{Hb}}}Hb}{{{f{c}}{f{be}}}Bj{}{}}0000`{{{f{bAHb}}{f{bHn}}}{{Ch{{Aj{c}}e}}}{}{}}{{}AHb}`{{{f{bAHb}}AHj{f{bHn}}}{{Ch{Bjc}}}{}}{{{f{AHj}}{f{AHj}}}C`}{{{f{AHl}}{f{AHl}}}C`}{{{f{AHn}}{f{AHn}}}C`}{{{f{AHd}}{f{AHd}}}C`}{{{f{AHf}}{f{AHf}}}C`}{{{f{AHh}}{f{AHh}}}C`}{{{f{Hb}}{f{Hb}}}C`}{{{f{c}}{f{e}}}C`{}{}}00000000000000000000{{{f{AHj}}{f{bG`}}}Gd}{{{f{AHl}}{f{bG`}}}Gd}{{{f{AHn}}{f{bG`}}}Gd}{{{f{AHb}}{f{bG`}}}Gd}{{{f{AI`}}{f{bG`}}}Gd}{{{f{AHd}}{f{bG`}}}Gd}0{{{f{AHf}}{f{bG`}}}Gd}{{{f{AHh}}{f{bG`}}}Gd}{{{f{A@n}}{f{bG`}}}Gd}0{{{f{Hb}}{f{bG`}}}Gd}0{cc{}}000000{HdAHd}1{AdAHf}{{{Dj{AHfc}}}AHh{{Gl{Gj}}}}3{AHfAHh}4{MnA@n}{HdA@n}{A@dA@n}{AHdA@n}8{{{f{A`}}}{{Ch{dHb}}}}{{{f{A`}}}d}{{{f{{Hh{Hd}}}}}{{AIb{Hd}}}}{ce{}{}}0000000000{c{}{}}{{AHbA@d}AHb}{{}AHb}{{cg}{{AId{ec}}}{KbKd}{{ABl{AHl}{{Dd{AHj}}}}}{{AIf{eAHl}}}}{{{f{bHn}}C`A@d}{{Ch{{Aj{{Dj{C`AHd{Aj{Hn}}}}}}A@n}}}}{{{f{{Hh{Hd}}}}}{{Aj{AHh}}}}{{{Ll{{f{b{AId{ce}}}}}}{f{bLn}}}{{M`{g}}}{{ABl{AHl}{{Dd{AHj}}}}}{KbKd}{}}{{{f{A@n}}}{{Aj{{f{Ob}}}}}}{{{f{c}}}e{}{}}0000{{{f{c}}}Gj{}}00{c{{Ch{e}}}{}{}}000000000000000000000{{{Ll{{f{bc}}}}{f{bLn}}}M`{}}{{{f{c}}}O`{}}0000000000{{{f{A`}}}{{Ch{BjHb}}}}>>>>>>>>>>>{{{Dh{cAHb}}g}{{AId{ec}}}{KbKd}{{ABl{AHl}{{Dd{AHj}}}}}{{AIf{eAHl}}}}{{{f{bHn}}{Aj{AHh}}C`}Bj}{{{f{bHn}}cAHdC`C`}Bj{{In{{Hh{Hd}}}}}}","D":"GA`","p":[[0,"mut"],[5,"ResponseBuilder",0,2184],[1,"reference"],[10,"TryIntoHeaderPair",1125,2185],[5,"Method",0,2186],[1,"str"],[6,"RequestHeadType",0,2187],[5,"RequestHead",0,2187],[5,"StatusCode",0,2188],[1,"u16"],[5,"Uri",0,2189],[5,"Authority",1764,2190],[6,"Option",2191],[5,"BoxBody",629,2192],[5,"Response",0,2193],[6,"EitherBody",629,2194],[10,"MessageBody",629,2195],[5,"HttpServiceBuilder",0,2196],[5,"Request",0,2197],[17,"Config"],[1,"unit"],[10,"ServiceFactory",2198],[5,"Builder",1764,2199],[1,"bool"],[17,"Stream"],[10,"HttpMessage",0,2200],[6,"ParseError",781],[6,"Result",2201],[5,"ResponseHead",0,2202],[5,"Extensions",0,2203],[5,"ServiceConfig",0,2204],[5,"Instant",2205],[5,"Duration",2206],[17,"Response"],[5,"Codec",915,2207],[5,"Framed",2208],[1,"tuple"],[5,"Version",0,2209],[6,"KeepAlive",0,2210],[6,"ConnectionType",0,2211],[6,"Protocol",0],[6,"Ordering",2212],[10,"TryIntoHeaderValue",1125,2213],[5,"ExpectHandler",915,2214],[5,"UpgradeHandler",915,2215],[10,"Default",2216],[5,"TlsAcceptorConfig",0,2217],[5,"Message",0,2211],[5,"Encoding",2218],[6,"ContentTypeError",781],[10,"IntoServiceFactory",2198],[5,"HttpService",0,2217],[5,"Ref",2219],[5,"RefMut",2219],[5,"HeaderMap",1586],[5,"Formatter",2220],[5,"Error",2220],[8,"Result",2220],[8,"BoxedPayloadStream",0,2221],[5,"PathAndQuery",1764,2222],[5,"String",2223],[10,"Into",2224],[5,"Error",781],[6,"Infallible",2224],[6,"HandshakeError",1944],[1,"u8"],[5,"Vec",2225],[1,"slice"],[5,"Bytes",2226],[5,"ByteString",2227],[5,"BytesMut",2228],[6,"Payload",0,2221],[5,"Payload",1085],[5,"RecvStream",2229],[5,"Payload",915,2230],[5,"InvalidMethod",2186],[5,"InvalidStatusCode",2188],[5,"InvalidUri",1764,2189],[10,"AsRef",2224],[5,"Parts",1764,2189],[5,"InvalidUriParts",1764,2189],[5,"H1Service",915,2231],[5,"H2Service",1085,2232],[10,"Hasher",2233],[6,"SocketAddr",2234],[17,"Output"],[10,"FnOnce",2235],[5,"Mime",2236],[10,"AsyncRead",2237],[10,"AsyncWrite",2238],[10,"Unpin",2239],[1,"u64"],[10,"Fn",2235],[5,"TcpStream",2240],[5,"TlsStream",2241],[5,"SslAcceptor",2242],[17,"Error"],[5,"Error",2243],[6,"DispatchError",781],[6,"TlsError",2244],[17,"InitError"],[5,"Pin",2245],[5,"Context",2246],[6,"Poll",2247],[17,"Item"],[6,"PayloadError",781],[10,"Stream",2248],[5,"Port",1764,2249],[5,"TlsStream",2250],[5,"ServerConfig",2251],[5,"Error",2252],[5,"TlsStream",2253],[5,"ServerConfig",2251],[5,"TlsStream",2254],[5,"ServerConfig",2251],[5,"TlsStream",2255],[5,"ServerConfig",2251],[5,"Scheme",1764,2256],[5,"Rc",2257],[5,"TypeId",2258],[10,"Error",2259],[5,"Box",2260],[10,"Clone",2261],[5,"None",629,2262],[6,"BodySize",629,2263],[10,"Debug",2220],[5,"BodyLimitExceeded",629,2264],[5,"BodyStream",629,2265],[5,"SizedStream",629,2266],[1,"usize"],[5,"Decoder",755,2267],[6,"ContentEncoding",1125,2268],[5,"Encoder",755,2269],[5,"HttpError",781],[6,"ProtocolError",1944],[5,"InvalidHeaderName",1125,2270],[5,"InvalidHeaderValue",1125,2271],[5,"MaxSizeReached",2272],[5,"FromUtf8Error",2223],[5,"Utf8Error",2273],[6,"Error",2274],[5,"Error",2275],[6,"MessageType",915],[5,"ClientCodec",915,2276],[5,"ClientPayloadCodec",915,2276],[6,"Message",915],[1,"never"],[5,"SendResponse",915,2277],[5,"Dispatcher",915,2278],[10,"Service",2198],[5,"Dispatcher",1085,2279],[5,"HeaderValue",1125,2271],[5,"HeaderName",1125,2270],[5,"LanguageTag",1125,2280],[6,"ValidationError",2280],[6,"Charset",1125,2281],[5,"ExtendedValue",1125,2282],[5,"HttpDate",1125,2283],[5,"Quality",1125,2284],[5,"QualityItem",1125,2285],[10,"Sized",2239],[10,"PartialEq",2212],[10,"Iterator",2286],[1,"char"],[5,"ToStrError",1125,2271],[10,"Display",2220],[1,"isize"],[1,"i64"],[1,"u32"],[1,"i32"],[1,"i16"],[5,"SystemTime",2205],[10,"FromStr",2287],[6,"ParseError",2280],[10,"Header",1125],[10,"TryInto",2224],[1,"f32"],[10,"AsHeaderName",1125,2288],[5,"Drain",1586],[5,"Removed",1586],[5,"Keys",1586],[5,"Iter",1586],[5,"IntoIter",1586],[5,"HeaderMap",2272],[5,"Iter",2289],[10,"FnMut",2235],[5,"TestRequest",1688],[5,"TestSeqBuffer",1688],[5,"TestBuffer",1688],[8,"Result",2252],[5,"ReadBuf",2290],[6,"ErrorKind",2189],[5,"Codec",1944,2291],[6,"OpCode",1944,2292],[6,"CloseCode",1944,2292],[5,"CloseReason",1944,2292],[6,"Message",1944,2291],[6,"Frame",1944,2291],[6,"Item",1944,2291],[5,"Parser",1944,2293],[1,"array"],[5,"Dispatcher",1944,2294],[10,"IntoService",2198],[15,"H1",626],[15,"H2",626],[15,"Stream",626],[15,"Left",753],[15,"Right",753],[5,"TestSeqInner",1688]],"r":[[4,2221],[10,2211],[11,2268],[15,781],[16,2203],[35,2200],[36,2217],[37,2196],[42,2210],[52,2211],[53,2186],[78,2221],[79,2221],[86,2197],[87,2187],[88,2187],[89,2193],[90,2184],[91,2202],[95,2204],[96,2188],[103,2217],[112,2189],[114,2209],[596,2295],[629,2264],[630,2263],[631,2265],[632,2192],[633,2194],[636,2195],[637,2262],[641,2266],[714,2264],[715,2264],[755,2267],[756,2269],[916,2276],[917,2276],[918,2207],[919,2278],[920,2214],[921,2231],[922,2231],[927,2230],[929,2277],[931,2215],[1085,2279],[1086,2232],[1125,2270],[1126,2270],[1127,2270],[1128,2270],[1129,2270],[1130,2270],[1131,2270],[1132,2270],[1133,2270],[1134,2270],[1135,2270],[1136,2270],[1137,2270],[1138,2270],[1139,2270],[1140,2270],[1141,2270],[1142,2288],[1145,2270],[1146,2296],[1147,2296],[1148,2270],[1149,2270],[1150,2270],[1151,2270],[1152,2270],[1153,2270],[1154,2270],[1155,2270],[1156,2270],[1157,2270],[1158,2270],[1159,2296],[1160,2296],[1161,2296],[1162,2281],[1163,2268],[1164,2270],[1165,2270],[1167,2270],[1168,2270],[1169,2270],[1175,2282],[1176,2270],[1177,2270],[1180,2270],[1182,1586],[1183,2270],[1184,2271],[1185,2283],[1186,2270],[1187,2270],[1188,2270],[1189,2270],[1190,2270],[1192,2270],[1193,2271],[1212,2270],[1213,2270],[1214,2270],[1215,2280],[1217,2270],[1219,2270],[1220,2296],[1221,2270],[1222,2270],[1223,2270],[1224,2270],[1225,2270],[1226,2284],[1227,2285],[1228,2270],[1229,2270],[1230,2270],[1231,2270],[1232,2270],[1233,2270],[1234,2270],[1235,2270],[1236,2270],[1237,2270],[1238,2270],[1239,2270],[1240,2270],[1242,2270],[1243,2270],[1244,2270],[1245,2271],[1246,2185],[1247,2213],[1248,2270],[1249,2270],[1250,2270],[1252,2270],[1253,2270],[1254,2270],[1255,2270],[1256,2270],[1257,2270],[1258,2296],[1259,2296],[1260,2296],[1261,2270],[1262,2270],[1396,2297],[1423,2297],[1428,2297],[1444,2297],[1475,2282],[1488,2284],[1764,2190],[1765,2199],[1768,2189],[1769,2189],[1770,2189],[1771,2222],[1772,2249],[1773,2256],[1774,2189],[1956,2292],[1957,2292],[1958,2291],[1966,2294],[1971,2291],[1978,2291],[1981,2291],[1987,2292],[1989,2293],[2107,2292]],"b":[[230,"impl-PartialEq%3CMethod%3E-for-%26Method"],[231,"impl-PartialEq%3C%26Method%3E-for-Method"],[232,"impl-PartialEq%3C%26str%3E-for-Method"],[233,"impl-PartialEq%3Cstr%3E-for-Method"],[234,"impl-PartialEq-for-Method"],[235,"impl-PartialEq-for-StatusCode"],[236,"impl-PartialEq%3Cu16%3E-for-StatusCode"],[237,"impl-PartialEq%3Cstr%3E-for-Uri"],[238,"impl-PartialEq-for-Uri"],[239,"impl-PartialEq%3C%26str%3E-for-Uri"],[279,"impl-Display-for-Method"],[280,"impl-Debug-for-Method"],[281,"impl-Display-for-StatusCode"],[282,"impl-Debug-for-StatusCode"],[285,"impl-Debug-for-Uri"],[286,"impl-Display-for-Uri"],[308,"impl-From%3CResponse%3CB%3E%3E-for-ResponseBuilder"],[309,"impl-From%3C%26ResponseHead%3E-for-ResponseBuilder"],[310,"impl-From%3CPathAndQuery%3E-for-Uri"],[311,"impl-From%3CAuthority%3E-for-Uri"],[314,"impl-From%3CString%3E-for-Response%3CString%3E"],[315,"impl-From%3CResult%3CI,+E%3E%3E-for-Response%3CBoxBody%3E"],[316,"impl-From%3CInfallible%3E-for-Response%3CBoxBody%3E"],[317,"impl-From%3C%26String%3E-for-Response%3CString%3E"],[318,"impl-From%3CHandshakeError%3E-for-Response%3CBoxBody%3E"],[319,"impl-From%3CError%3E-for-Response%3CBoxBody%3E"],[320,"impl-From%3C%26Vec%3Cu8%3E%3E-for-Response%3CVec%3Cu8%3E%3E"],[321,"impl-From%3C%26%5Bu8%5D%3E-for-Response%3C%26%5Bu8%5D%3E"],[323,"impl-From%3C%26str%3E-for-Response%3C%26str%3E"],[324,"impl-From%3C%26HandshakeError%3E-for-Response%3CBoxBody%3E"],[325,"impl-From%3CBytes%3E-for-Response%3CBytes%3E"],[326,"impl-From%3CResponseBuilder%3E-for-Response%3CEitherBody%3C()%3E%3E"],[327,"impl-From%3CVec%3Cu8%3E%3E-for-Response%3CVec%3Cu8%3E%3E"],[328,"impl-From%3CByteString%3E-for-Response%3CByteString%3E"],[329,"impl-From%3CParseError%3E-for-Response%3CBoxBody%3E"],[330,"impl-From%3CBytesMut%3E-for-Response%3CBytesMut%3E"],[335,"impl-From%3CDuration%3E-for-KeepAlive"],[336,"impl-From%3COption%3CDuration%3E%3E-for-KeepAlive"],[338,"impl-From%3CPin%3CBox%3Cdyn+Stream%3CItem+=+Result%3CBytes,+PayloadError%3E%3E%3E%3E%3E-for-Payload"],[340,"impl-From%3CPayload%3E-for-Payload%3CS%3E"],[341,"impl-From%3CRecvStream%3E-for-Payload%3CS%3E"],[342,"impl-From%3CPayload%3E-for-Payload%3CS%3E"],[463,"impl-Uri"],[464,"impl-Host-for-Uri"],[497,"impl-Request%3CP%3E"],[498,"impl-HttpMessage-for-Request%3CP%3E"],[519,"impl-TryFrom%3C%26str%3E-for-Method"],[520,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-Method"],[521,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-StatusCode"],[522,"impl-TryFrom%3C%26str%3E-for-StatusCode"],[523,"impl-TryFrom%3Cu16%3E-for-StatusCode"],[527,"impl-TryFrom%3C%26String%3E-for-Uri"],[529,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-Uri"],[530,"impl-TryFrom%3C%26Uri%3E-for-Uri"],[531,"impl-TryFrom%3CParts%3E-for-Uri"],[532,"impl-TryFrom%3CString%3E-for-Uri"],[533,"impl-TryFrom%3C%26str%3E-for-Uri"],[534,"impl-TryFrom%3CVec%3Cu8%3E%3E-for-Uri"],[678,"impl-Display-for-BodyLimitExceeded"],[679,"impl-Debug-for-BodyLimitExceeded"],[827,"impl-Display-for-Error"],[828,"impl-Debug-for-Error"],[829,"impl-Debug-for-Error"],[830,"impl-Display-for-Error"],[831,"impl-Display-for-ParseError"],[832,"impl-Debug-for-ParseError"],[833,"impl-Display-for-PayloadError"],[834,"impl-Debug-for-PayloadError"],[835,"impl-Debug-for-DispatchError"],[836,"impl-Display-for-DispatchError"],[837,"impl-Debug-for-ContentTypeError"],[838,"impl-Display-for-ContentTypeError"],[839,"impl-From%3CError%3E-for-Error"],[840,"impl-From%3CInfallible%3E-for-Error"],[841,"impl-From%3CHandshakeError%3E-for-Error"],[842,"impl-From%3CPayloadError%3E-for-Error"],[843,"impl-From%3CParseError%3E-for-Error"],[845,"impl-From%3CProtocolError%3E-for-Error"],[847,"impl-From%3CInvalidStatusCode%3E-for-Error"],[848,"impl-From%3CInvalidHeaderName%3E-for-Error"],[849,"impl-From%3CInvalidUri%3E-for-Error"],[850,"impl-From%3CInfallible%3E-for-Error"],[851,"impl-From%3CInvalidHeaderValue%3E-for-Error"],[852,"impl-From%3CInvalidUriParts%3E-for-Error"],[853,"impl-From%3CInvalidMethod%3E-for-Error"],[854,"impl-From%3CMaxSizeReached%3E-for-Error"],[855,"impl-From%3CFromUtf8Error%3E-for-ParseError"],[856,"impl-From%3CInvalidUri%3E-for-ParseError"],[857,"impl-From%3CUtf8Error%3E-for-ParseError"],[858,"impl-From%3CError%3E-for-ParseError"],[860,"impl-From%3CError%3E-for-ParseError"],[861,"impl-From%3CError%3E-for-PayloadError"],[862,"impl-From%3COption%3CError%3E%3E-for-PayloadError"],[864,"impl-From%3CError%3E-for-PayloadError"],[865,"impl-From%3CParseError%3E-for-DispatchError"],[866,"impl-From%3CResponse%3CBoxBody%3E%3E-for-DispatchError"],[867,"impl-From%3CBox%3Cdyn+Error%3E%3E-for-DispatchError"],[868,"impl-From%3CError%3E-for-DispatchError"],[870,"impl-From%3CError%3E-for-DispatchError"],[1266,"impl-AsRef%3C%5Bu8%5D%3E-for-HeaderName"],[1267,"impl-AsRef%3Cstr%3E-for-HeaderName"],[1326,"impl-PartialEq%3Cstr%3E-for-HeaderName"],[1327,"impl-PartialEq%3C%26str%3E-for-HeaderName"],[1328,"impl-PartialEq%3CHeaderName%3E-for-%26HeaderName"],[1329,"impl-PartialEq-for-HeaderName"],[1330,"impl-PartialEq%3C%26HeaderName%3E-for-HeaderName"],[1331,"impl-PartialEq%3C%5Bu8%5D%3E-for-HeaderValue"],[1332,"impl-PartialEq%3CString%3E-for-HeaderValue"],[1333,"impl-PartialEq-for-HeaderValue"],[1334,"impl-PartialEq%3CHeaderValue%3E-for-%26HeaderValue"],[1335,"impl-PartialEq%3Cstr%3E-for-HeaderValue"],[1336,"impl-PartialEq%3C%26T%3E-for-HeaderValue"],[1374,"impl-Display-for-LanguageTag"],[1375,"impl-Debug-for-LanguageTag"],[1376,"impl-Display-for-InvalidHeaderName"],[1377,"impl-Debug-for-InvalidHeaderName"],[1378,"impl-Debug-for-InvalidHeaderValue"],[1379,"impl-Display-for-InvalidHeaderValue"],[1380,"impl-Debug-for-HeaderName"],[1381,"impl-Display-for-HeaderName"],[1383,"impl-Display-for-ToStrError"],[1384,"impl-Debug-for-ToStrError"],[1385,"impl-Debug-for-Charset"],[1386,"impl-Display-for-Charset"],[1388,"impl-Display-for-ExtendedValue"],[1389,"impl-Debug-for-ExtendedValue"],[1390,"impl-Display-for-HttpDate"],[1391,"impl-Debug-for-HttpDate"],[1392,"impl-Debug-for-Quality"],[1393,"impl-Display-for-Quality"],[1394,"impl-Display-for-QualityItem%3CT%3E"],[1395,"impl-Debug-for-QualityItem%3CT%3E"],[1402,"impl-From%3Cusize%3E-for-HeaderValue"],[1403,"impl-From%3Cisize%3E-for-HeaderValue"],[1404,"impl-From%3Ci64%3E-for-HeaderValue"],[1405,"impl-From%3Cu32%3E-for-HeaderValue"],[1406,"impl-From%3Cu16%3E-for-HeaderValue"],[1407,"impl-From%3Cu64%3E-for-HeaderValue"],[1409,"impl-From%3C%26HeaderValue%3E-for-HeaderValue"],[1410,"impl-From%3Ci32%3E-for-HeaderValue"],[1411,"impl-From%3Ci16%3E-for-HeaderValue"],[1412,"impl-From%3CHeaderName%3E-for-HeaderValue"],[1433,"impl-FromStr-for-HeaderValue"],[1434,"impl-HeaderValue"],[1476,"impl-PartialOrd%3CString%3E-for-HeaderValue"],[1477,"impl-PartialOrd%3C%5Bu8%5D%3E-for-HeaderValue"],[1478,"impl-PartialOrd-for-HeaderValue"],[1479,"impl-PartialOrd%3Cstr%3E-for-HeaderValue"],[1480,"impl-PartialOrd%3CHeaderValue%3E-for-%26HeaderValue"],[1481,"impl-PartialOrd%3C%26T%3E-for-HeaderValue"],[1518,"impl-TryFrom%3CString%3E-for-HeaderName"],[1519,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-HeaderName"],[1520,"impl-TryFrom%3C%26String%3E-for-HeaderName"],[1521,"impl-TryFrom%3C%26str%3E-for-HeaderName"],[1522,"impl-TryFrom%3CVec%3Cu8%3E%3E-for-HeaderName"],[1523,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-HeaderValue"],[1524,"impl-TryFrom%3C%26String%3E-for-HeaderValue"],[1525,"impl-TryFrom%3CVec%3Cu8%3E%3E-for-HeaderValue"],[1526,"impl-TryFrom%3C%26str%3E-for-HeaderValue"],[1527,"impl-TryFrom%3CString%3E-for-HeaderValue"],[1553,"impl-TryIntoHeaderValue-for-%26HeaderValue"],[1554,"impl-TryIntoHeaderValue-for-HeaderValue"],[1635,"impl-IntoIterator-for-%26HeaderMap"],[1636,"impl-IntoIterator-for-HeaderMap"],[1810,"impl-PartialEq%3CPort%3CU%3E%3E-for-Port%3CT%3E"],[1811,"impl-PartialEq%3Cu16%3E-for-Port%3CT%3E"],[1812,"impl-PartialEq%3Cstr%3E-for-Authority"],[1813,"impl-PartialEq%3C%26str%3E-for-Authority"],[1814,"impl-PartialEq%3CString%3E-for-Authority"],[1815,"impl-PartialEq-for-Authority"],[1816,"impl-PartialEq-for-PathAndQuery"],[1817,"impl-PartialEq%3CString%3E-for-PathAndQuery"],[1818,"impl-PartialEq%3Cstr%3E-for-PathAndQuery"],[1819,"impl-PartialEq%3C%26str%3E-for-PathAndQuery"],[1820,"impl-PartialEq-for-Scheme"],[1821,"impl-PartialEq%3Cstr%3E-for-Scheme"],[1831,"impl-Display-for-Port%3CT%3E"],[1832,"impl-Debug-for-Port%3CT%3E"],[1833,"impl-Debug-for-Authority"],[1834,"impl-Display-for-Authority"],[1836,"impl-Display-for-PathAndQuery"],[1837,"impl-Debug-for-PathAndQuery"],[1838,"impl-Debug-for-Scheme"],[1839,"impl-Display-for-Scheme"],[1841,"impl-Display-for-InvalidUri"],[1842,"impl-Debug-for-InvalidUri"],[1843,"impl-Display-for-InvalidUriParts"],[1844,"impl-Debug-for-InvalidUriParts"],[1876,"impl-PartialOrd-for-Authority"],[1877,"impl-PartialOrd%3C%26str%3E-for-Authority"],[1878,"impl-PartialOrd%3CString%3E-for-Authority"],[1879,"impl-PartialOrd%3Cstr%3E-for-Authority"],[1880,"impl-PartialOrd%3Cstr%3E-for-PathAndQuery"],[1881,"impl-PartialOrd%3C%26str%3E-for-PathAndQuery"],[1882,"impl-PartialOrd%3CString%3E-for-PathAndQuery"],[1883,"impl-PartialOrd-for-PathAndQuery"],[1902,"impl-TryFrom%3CString%3E-for-Authority"],[1903,"impl-TryFrom%3CVec%3Cu8%3E%3E-for-Authority"],[1904,"impl-TryFrom%3C%26str%3E-for-Authority"],[1905,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-Authority"],[1908,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-PathAndQuery"],[1909,"impl-TryFrom%3CString%3E-for-PathAndQuery"],[1910,"impl-TryFrom%3C%26str%3E-for-PathAndQuery"],[1912,"impl-TryFrom%3CVec%3Cu8%3E%3E-for-PathAndQuery"],[1913,"impl-TryFrom%3C%26String%3E-for-PathAndQuery"],[1914,"impl-TryFrom%3C%26str%3E-for-Scheme"],[1915,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-Scheme"],[2078,"impl-Debug-for-OpCode"],[2079,"impl-Display-for-OpCode"],[2082,"impl-Display-for-ProtocolError"],[2083,"impl-Debug-for-ProtocolError"],[2084,"impl-Display-for-HandshakeError"],[2085,"impl-Debug-for-HandshakeError"],[2096,"impl-From%3C(CloseCode,+T)%3E-for-CloseReason"],[2098,"impl-From%3CCloseCode%3E-for-CloseReason"],[2100,"impl-From%3CError%3E-for-ProtocolError"],[2101,"impl-From%3Cu8%3E-for-ProtocolError"],[2102,"impl-From%3Cusize%3E-for-ProtocolError"],[2103,"impl-From%3COpCode%3E-for-ProtocolError"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAAAFkAAMAAAAEAAAABgAAQAhAAIANQAAAD8AAABDAAAAUAAAAFYAAABYAAEAXAAAAGIAAAB1AAEAfwAnALUAFwDPAAAA1AAOAOcAIgAQAQAAEwEAABUBAAAYARIALwEAADEBAQA1AQMAOwEHAEQBBwBQAQEAUwEAAFUBAgBaAQAAYwECAG4BBAB4AQAAfAEBAIMBAACcAQAAswEAAL4BAADAAQAAxwEBAM8BAADRAQAA1gEAAOwBAADzAQAA+AFVAFcCAABaAhUAcwICAIYCDQCWAhIAuQIAAL0CAADAAgIAxgIEAM0CEQDhAhgAAAMNABMDAAAwAxwATgMAAFADCwBdAwIAYQMEAGcDAABxAyIAmQMAAJ8DAAChAwAAowMcAMEDEADbAwEA6gMEAPEDAQD7AwMAAAQEAAoEJAAyBAsAQQQFAE0EAgBRBAEAWAQNAJMEAACfBAAA8wQCAPkEGAAUBRoAMQUpAF8FFQB5BQAAewUFAIIFAwCLBQAAmAUCAJwFAwChBQMAvwUAAMMFAADFBQgA1wUIAOEFLwASBg8AJgYLADoGCwBIBgEASwYAAE0GBgBkBgYAcgYEAHoGHQCcBgAAngYKAKsGAQCwBgIAvwYLAMwGDQDcBgMA4QYDAPAGAgD6Bg8ACwcqADsHAAA9BwAAPwcAAEUHBQBVBwcAZQczAK0HAACvBwAAsgcBALwHAADYBxUA7wcJAPoHAQD9BykALggAADAIAQAzCAAANQgDAEgIAABLCAAATggrAHsICwA="}],\ +["actix_http_test",{"t":"FNNNNNNNNNNNNNNNNNNNNNNNNNHHNNNHNNNN","n":["TestServer","addr","borrow","borrow_mut","client_headers","delete","drop","from","get","head","into","load_body","options","patch","post","put","request","sdelete","sget","shead","soptions","spatch","spost","sput","stop","surl","test_server","test_server_with_addr","try_from","try_into","type_id","unused_addr","url","vzip","ws","ws_at"],"q":[[0,"actix_http_test"],[36,"core::net::socket_addr"],[37,"actix_http::header::map"],[38,"core::option"],[39,"awc::request"],[40,"core::convert"],[41,"awc::responses::response"],[42,"bytes::bytes"],[43,"actix_http::error"],[44,"core::result"],[45,"futures_core::stream"],[46,"core::marker"],[47,"http::method"],[48,"alloc::string"],[49,"tokio::net::tcp::stream"],[50,"actix_server::service"],[51,"std::net::tcp"],[52,"core::any"],[53,"tokio::io::async_read"],[54,"tokio::io::async_write"],[55,"actix_http::ws::codec"],[56,"actix_codec::framed"],[57,"awc::error"]],"i":[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,1,1,1,1],"f":"`{{{d{b}}}f}{{{d{c}}}{{d{e}}}{}{}}{{{d{hc}}}{{d{he}}}{}{}}{{{d{hb}}}{{l{{d{hj}}}}}}{{{d{b}}c}n{{Ab{A`}}}}{{{d{hb}}}Ad}{cc{}}22{ce{}{}}{{{d{hb}}{Af{c}}}{{Al{AhAj}}}{{B`{}{{An{{Al{AhAj}}}}}}Bb}}4444{{{d{b}}Bdc}n{{Ab{A`}}}}55555554{{{d{b}}{d{A`}}}Bf}{cb{{Bj{Bh}}}}{{Blc}b{{Bj{Bh}}}}{c{{Al{e}}}{}{}}0{{{d{c}}}Bn{}}{{}f}58{{{d{hb}}}{{Al{{Cf{{`{C`Cb}}Cd}}Ch}}}}{{{d{hb}}{d{A`}}}{{Al{{Cf{{`{C`Cb}}Cd}}Ch}}}}","D":"Cj","p":[[5,"TestServer",0],[1,"reference"],[6,"SocketAddr",36],[0,"mut"],[5,"HeaderMap",37],[6,"Option",38],[5,"ClientRequest",39],[1,"str"],[10,"AsRef",40],[1,"unit"],[5,"ClientResponse",41],[5,"Bytes",42],[6,"PayloadError",43],[6,"Result",44],[17,"Item"],[10,"Stream",45],[10,"Unpin",46],[5,"Method",47],[5,"String",48],[5,"TcpStream",49],[10,"ServerServiceFactory",50],[5,"TcpListener",51],[5,"TypeId",52],[10,"AsyncRead",53],[10,"AsyncWrite",54],[5,"Codec",55],[5,"Framed",56],[6,"WsClientError",57]],"r":[],"b":[],"c":"OjAAAAAAAAA=","e":"OjAAAAEAAAAAAAcAEAAAAAMABAAHAAwAHQAeAB8AIgA="}],\ +["actix_multipart",{"t":"PPFPPPFGPPPPPPPPNNNNNNNNEENNNCNNNNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNOOKRFKFYFNNNNNNCNNNNNNONNNNMMNNNNCMNONMCCNNONNNNNNNNNNNNNFNNOOONNNNNNNNPPFFGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNPFFGNNNNNNNNONNNOONNNNNNNNNNONNNNNNNNNNNNNNNNPPFFGPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHH","n":["Boundary","DuplicateField","Field","Field","Incomplete","MissingField","Multipart","MultipartError","Nested","NoContentDisposition","NoContentType","NotConsumed","Parse","ParseContentType","Payload","UnsupportedField","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","content_disposition","content_type","create_form_data_payload_and_headers","create_form_data_payload_and_headers_with_boundary","fmt","fmt","fmt","form","from","from","from","from","from","from","from_request","headers","into","into","into","name","new","poll_next","poll_next","source","status_code","test","to_string","try_from","try_from","try_from","try_into","try_into","try_into","try_poll_next","try_poll_next","type_id","type_id","type_id","vzip","vzip","vzip","field_name","source","FieldReader","Future","Limits","MultipartCollect","MultipartForm","MultipartForm","MultipartFormConfig","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","bytes","clone","clone_into","default","deref","deref_mut","error_handler","field_limit_remaining","from","from","from","from_request","from_state","handle_field","into","into","into","into_inner","json","limit","memory_limit","memory_limit_remaining","new","read_field","tempfile","text","to_owned","total_limit","total_limit_remaining","try_consume_limits","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","vzip","vzip","vzip","Bytes","borrow","borrow_mut","content_type","data","file_name","fmt","from","into","read_field","try_from","try_into","type_id","vzip","ContentType","Deserialize","Json","JsonConfig","JsonFieldError","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone_into","default","deref","deref_mut","error_handler","fmt","fmt","fmt","from","from","from","into","into","into","into_inner","read_field","source","status_code","to_owned","to_string","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","validate_content_type","vzip","vzip","vzip","FileIo","TempFile","TempFileConfig","TempFileError","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone_into","content_type","default","directory","error_handler","file","file_name","fmt","fmt","fmt","from","from","from","into","into","into","read_field","size","source","status_code","to_owned","to_string","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","vzip","vzip","vzip","ContentType","Deserialize","Text","TextConfig","TextError","Utf8Error","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone_into","default","deref","deref_mut","error_handler","fmt","fmt","fmt","from","from","from","into","into","into","into_inner","read_field","source","status_code","to_owned","to_string","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","validate_content_type","vzip","vzip","vzip","create_form_data_payload_and_headers","create_form_data_payload_and_headers_with_boundary"],"q":[[0,"actix_multipart"],[63,"actix_multipart::MultipartError"],[65,"actix_multipart::form"],[120,"actix_multipart::form::bytes"],[134,"actix_multipart::form::json"],[179,"actix_multipart::form::tempfile"],[224,"actix_multipart::form::text"],[270,"actix_multipart::test"],[272,"actix_multipart::server"],[273,"actix_web::http::header::content_disposition"],[274,"mime"],[275,"core::option"],[276,"core::fmt"],[277,"actix_multipart::error"],[278,"actix_http::error"],[279,"alloc::string"],[280,"actix_web::error::error"],[281,"actix_web::request"],[282,"actix_http::payload"],[283,"actix_http::header::map"],[284,"bytes::bytes"],[285,"core::result"],[286,"futures_core::stream"],[287,"core::pin"],[288,"core::task::wake"],[289,"core::task::poll"],[290,"core::error"],[291,"http::status"],[292,"core::any"],[293,"core::ops::function"],[294,"core::marker"],[295,"futures_core::future"],[296,"serde::de"],[297,"std::path"],[298,"core::convert"],[299,"actix_multipart_derive"]],"i":[9,9,0,9,9,9,0,0,9,9,9,9,9,9,9,9,19,3,9,19,3,9,3,3,0,0,3,9,9,0,19,3,9,9,9,9,19,3,19,3,9,3,19,19,3,9,9,0,9,19,3,9,19,3,9,19,3,19,3,9,19,3,9,56,56,0,57,0,0,0,0,0,38,32,30,38,32,30,0,30,30,30,32,32,30,38,38,32,30,32,33,33,38,32,30,32,0,33,30,38,38,57,0,0,30,30,38,38,38,32,30,38,32,30,38,32,30,38,32,30,0,42,42,42,42,42,42,42,42,42,42,42,42,42,46,46,0,0,0,44,46,43,44,46,43,43,43,43,44,44,43,44,46,46,44,46,43,44,46,43,44,44,46,46,43,46,44,46,43,44,46,43,44,46,43,43,44,46,43,51,0,0,0,52,51,48,52,51,48,48,48,52,48,48,48,52,52,52,51,51,52,51,48,52,51,48,52,52,51,51,48,51,52,51,48,52,51,48,52,51,48,52,51,48,55,55,0,0,0,55,54,55,53,54,55,53,53,53,53,54,54,53,54,55,55,54,55,53,54,55,53,54,54,55,55,53,55,54,55,53,54,55,53,54,55,53,53,54,55,53,0,0],"f":"````````````````{{{b{c}}}{{b{e}}}{}{}}00{{{b{dc}}}{{b{de}}}{}{}}00{{{b{f}}}{{b{h}}}}{{{b{f}}}{{l{{b{j}}}}}}``{{{b{f}}{b{dn}}}A`}{{{b{Ab}}{b{dn}}}A`}0`{cc{}}00{AdAb}{{{Aj{AfAh}}}Ab}{AlAb}{{{b{An}}{b{dB`}}}c{}}{{{b{f}}}{{b{Bb}}}}{ce{}{}}00{{{b{f}}}{{b{Bd}}}}{{{b{Bb}}c}Bf{{Bn{}{{Bh{{Bl{BjAd}}}}}}}}{{{C`{{b{dBf}}}}{b{dCb}}}{{Cd{{l{c}}}}}{}}{{{C`{{b{df}}}}{b{dCb}}}{{Cd{{l{c}}}}}{}}{{{b{Ab}}}{{l{{b{Cf}}}}}}{{{b{Ab}}}Ch}`{{{b{c}}}Af{}}{c{{Bl{e}}}{}{}}00000{{{C`{{b{dc}}}}{b{dCb}}}{{Cd{{l{Bl}}}}}{}}0{{{b{c}}}Cj{}}00:::`````````{{{b{c}}}{{b{e}}}{}{}}00{{{b{dc}}}{{b{de}}}{}{}}00`{{{b{Cl}}}Cl}{{{b{c}}{b{de}}}Cn{}{}}{{}Cl}{{{b{{D`{c}}}}}{{b{e}}}Db{}}{{{b{d{D`{c}}}}}{{b{de}}}Db{}}{{Clc}Cl{{Df{Ab{b{An}}}{{Dd{Ah}}}}DhDj}}`{cc{}}00{{{b{An}}{b{dB`}}}c{}}`{{{b{An}}f{b{dDl}}{b{d`}}}{{Dn{{Bl{CnAb}}}}}}{ce{}{}}00{{{D`{c}}}cDb}`{{{b{Bd}}}{{l{E`}}}}{{ClE`}Cl}`{{E`E`}Dl}{{{b{An}}f{b{dDl}}}c{}}``{{{b{c}}}e{}{}}3`{{{b{dDl}}E`Eb}{{Bl{CnAb}}}}{c{{Bl{e}}}{}{}}00000{{{b{c}}}Cj{}}00999`{{{b{c}}}{{b{e}}}{}{}}{{{b{dc}}}{{b{de}}}{}{}}```{{{b{Ed}}{b{dn}}}A`}?<7443<`````222111{{{b{Ef}}}Ef}{{{b{c}}{b{de}}}Cn{}{}}{{}Ef}{{{b{{Eh{c}}}}}{{b{e}}}Ej{}}{{{b{d{Eh{c}}}}}{{b{de}}}Ej{}}{{Efc}Ef{{Df{El{b{An}}}{{Dd{Ah}}}}DhDj}}{{{b{{Eh{c}}}}{b{dn}}}A`{EnEj}}{{{b{El}}{b{dn}}}A`}0{cc{}}00{ce{}{}}00{{{Eh{c}}}cEj}{{{b{An}}f{b{dDl}}}c{}}{{{b{El}}}{{l{{b{Cf}}}}}}{{{b{El}}}Ch}{{{b{c}}}e{}{}}{{{b{c}}}Af{}}{c{{Bl{e}}}{}{}}00000{{{b{c}}}Cj{}}00{{EfEb}Ef}999````{{{b{c}}}{{b{e}}}{}{}}00{{{b{dc}}}{{b{de}}}{}{}}00{{{b{F`}}}F`}{{{b{c}}{b{de}}}Cn{}{}}`{{}F`}{{F`c}F`{{Fd{Fb}}}}{{F`c}F`{{Df{Ff{b{An}}}{{Dd{Ah}}}}DhDj}}``{{{b{Fh}}{b{dn}}}A`}{{{b{Ff}}{b{dn}}}A`}0{cc{}}00{ce{}{}}00{{{b{An}}f{b{dDl}}}c{}}`{{{b{Ff}}}{{l{{b{Cf}}}}}}{{{b{Ff}}}Ch}{{{b{c}}}e{}{}}{{{b{c}}}Af{}}{c{{Bl{e}}}{}{}}00000{{{b{c}}}Cj{}}00777``````{{{b{c}}}{{b{e}}}{}{}}00{{{b{dc}}}{{b{de}}}{}{}}00{{{b{Fj}}}Fj}{{{b{c}}{b{de}}}Cn{}{}}{{}Fj}{{{b{{Fl{c}}}}}{{b{e}}}Ej{}}{{{b{d{Fl{c}}}}}{{b{de}}}Ej{}}{{Fjc}Fj{{Df{Fn{b{An}}}{{Dd{Ah}}}}DhDj}}{{{b{{Fl{c}}}}{b{dn}}}A`{EnEj}}{{{b{Fn}}{b{dn}}}A`}0{cc{}}00{ce{}{}}00{{{Fl{c}}}cEj}{{{b{An}}f{b{dDl}}}c{}}{{{b{Fn}}}{{l{{b{Cf}}}}}}{{{b{Fn}}}Ch}{{{b{c}}}e{}{}}{{{b{c}}}Af{}}{c{{Bl{e}}}{}{}}00000{{{b{c}}}Cj{}}00{{FjEb}Fj}999{{{b{Bd}}{l{Af}}{l{j}}Bj}{{Aj{BjBb}}}}{{{b{Bd}}{b{Bd}}{l{Af}}{l{j}}Bj}{{Aj{BjBb}}}}","D":"Ln","p":[[1,"reference"],[0,"mut"],[5,"Field",0,272],[5,"ContentDisposition",273],[5,"Mime",274],[6,"Option",275],[5,"Formatter",276],[8,"Result",276],[6,"MultipartError",0,277],[6,"PayloadError",278],[5,"String",279],[5,"Error",280],[1,"tuple"],[6,"ParseError",278],[5,"HttpRequest",281],[6,"Payload",282],[5,"HeaderMap",283],[1,"str"],[5,"Multipart",0,272],[17,"Item"],[5,"Bytes",284],[6,"Result",285],[10,"Stream",286],[5,"Pin",287],[5,"Context",288],[6,"Poll",289],[10,"Error",290],[5,"StatusCode",291],[5,"TypeId",292],[5,"MultipartFormConfig",65],[1,"unit"],[5,"MultipartForm",65],[10,"MultipartCollect",65],[17,"Output"],[10,"Fn",293],[10,"Send",294],[10,"Sync",294],[5,"Limits",65],[8,"LocalBoxFuture",295],[1,"usize"],[1,"bool"],[5,"Bytes",120],[5,"JsonConfig",134],[5,"Json",134],[10,"DeserializeOwned",296],[6,"JsonFieldError",134],[10,"Debug",276],[5,"TempFileConfig",179],[5,"Path",297],[10,"AsRef",298],[6,"TempFileError",179],[5,"TempFile",179],[5,"TextConfig",224],[5,"Text",224],[6,"TextError",224],[15,"Field",63],[10,"FieldReader",65]],"r":[[2,272],[6,272],[7,277],[24,270],[25,270],[70,299]],"b":[[27,"impl-Debug-for-MultipartError"],[28,"impl-Display-for-MultipartError"],[33,"impl-From%3CPayloadError%3E-for-MultipartError"],[34,"impl-From%3C(String,+Error)%3E-for-MultipartError"],[35,"impl-From%3CParseError%3E-for-MultipartError"],[152,"impl-Debug-for-JsonFieldError"],[153,"impl-Display-for-JsonFieldError"],[198,"impl-Debug-for-TempFileError"],[199,"impl-Display-for-TempFileError"],[243,"impl-Debug-for-TextError"],[244,"impl-Display-for-TextError"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAKkAHAARAAUAGQAEACIAAwAsABUASQAFAFAABABWAAAAWgAAAGQAAQBpAAAAawAAAG0ACwB6AAEAfwAAAIIABACLAA8AoQAOALEAAgC3AAgAwQAAAMYAAgDPAAAA0QAPAOUAAADnAAoA8wACAP0ADQAMAQIA"}],\ +["actix_multipart_derive",{"t":"Y","n":["MultipartForm"],"q":[[0,"actix_multipart_derive"]],"i":[0],"f":"`","D":"d","p":[],"r":[],"b":[],"c":"OjAAAAAAAAA=","e":"OjAAAAAAAAA="}],\ +["actix_router",{"t":"KPFRFGFKFFKFFPFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNMNNNNNNNNNNNNMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN","n":["IntoPatterns","List","Path","Path","PathDeserializer","Patterns","Quoter","Resource","ResourceDef","ResourceId","ResourcePath","Router","RouterBuilder","Single","Url","as_str","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build","capture_match_info","capture_match_info_fn","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","default","default","deserialize_any","deserialize_bool","deserialize_byte_buf","deserialize_bytes","deserialize_char","deserialize_enum","deserialize_f32","deserialize_f64","deserialize_i16","deserialize_i32","deserialize_i64","deserialize_i8","deserialize_identifier","deserialize_ignored_any","deserialize_map","deserialize_newtype_struct","deserialize_option","deserialize_seq","deserialize_str","deserialize_string","deserialize_struct","deserialize_tuple","deserialize_tuple_struct","deserialize_u16","deserialize_u32","deserialize_u64","deserialize_u8","deserialize_unit","deserialize_unit_struct","eq","eq","eq","find_match","finish","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","get","get_mut","get_ref","hash","hash","id","index","index","into","into","into","into","into","into","into","into","into","is_empty","is_empty","is_match","is_prefix","iter","join","load","name","new","new","new","new","new","new_with_quoter","path","path","path","path","pattern","pattern_iter","patterns","patterns","prefix","prefix","push","query","rdef","recognize","recognize_fn","recognize_mut","recognize_mut_fn","requote","reset","resource_path","resource_path","resource_path_from_iter","resource_path_from_map","root_prefix","segment_count","set","set_id","set_name","skip","to_owned","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","unprocessed","update","update_with_quoter","uri"],"q":[[0,"actix_router"],[195,"actix_router::path"],[196,"actix_router::resource_path"],[197,"actix_router::router"],[198,"actix_router::resource"],[199,"core::ops::function"],[200,"core::clone"],[201,"actix_router::pattern"],[202,"actix_router::url"],[203,"core::default"],[204,"actix_router::de"],[205,"core::result"],[206,"serde::de"],[207,"core::option"],[208,"core::fmt"],[209,"alloc::string"],[210,"core::hash"],[211,"serde::de::value"],[212,"actix_router::quoter"],[213,"http::uri"],[214,"core::iter::traits::iterator"],[215,"alloc::vec"],[216,"core::iter::traits::collect"],[217,"std::collections::hash::map"],[218,"core::borrow"],[219,"core::cmp"],[220,"core::convert"],[221,"core::any"]],"i":[0,13,0,9,0,0,0,0,0,0,0,0,0,13,0,1,18,34,24,6,1,13,7,14,15,18,34,24,6,1,13,7,14,15,24,7,7,1,13,7,14,15,1,13,7,14,15,1,15,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,18,13,7,14,7,6,1,13,7,14,15,18,34,24,6,1,13,7,7,7,14,15,1,1,1,13,7,7,1,1,18,34,24,6,1,13,7,14,15,1,13,7,7,1,7,1,7,18,34,1,7,15,15,4,6,15,15,7,7,35,13,6,7,6,1,6,24,24,24,24,34,1,9,1,7,7,7,1,1,7,7,1,1,13,7,14,15,18,34,24,6,1,13,7,14,15,18,34,24,6,1,13,7,14,15,18,34,24,6,1,13,7,14,15,1,15,15,15],"f":"```````````````{{{d{{b{c}}}}}{{d{f}}}h}{{{d{c}}}{{d{e}}}{}{}}00000000{{{d{jc}}}{{d{je}}}{}{}}00000000{{}{{l{ce}}}{}{}}{{{d{n}}{d{jc}}}A`Ab}{{{d{n}}{d{jc}}e}A`Ab{{Af{{d{c}}}{{Ad{A`}}}}}}{{{d{{b{c}}}}}{{b{c}}}Ah}{{{d{Aj}}}Aj}{{{d{n}}}n}{{{d{Al}}}Al}{{{d{An}}}An}{{{d{c}}{d{je}}}B`{}{}}0000{{}{{b{c}}}Bb}{{}An}{{{Bd{c}}e}{{Bf{g}}}hBh{}}0000{{{Bd{c}}{d{f}}{d{{Bj{{d{f}}}}}}e}{{Bf{g}}}hBh{}}111111111{{{Bd{c}}{d{f}}e}{{Bf{g}}}hBh{}}22221{{{Bd{c}}Ble}{{Bf{g}}}hBh{}}{{{Bd{c}}{d{f}}Ble}{{Bf{g}}}hBh{}}444442{{{d{Aj}}{d{Aj}}}A`}{{{d{n}}{d{n}}}A`}{{{d{Al}}{d{Al}}}A`}{{{d{n}}{d{f}}}{{Bn{Bl}}}}{{{l{ce}}}{{C`{ce}}}{}{}}{{{d{{b{c}}}}{d{jCb}}}CdCf}{{{d{Aj}}{d{jCb}}}Cd}{{{d{n}}{d{jCb}}}Cd}{{{d{Al}}{d{jCb}}}Cd}{{{d{An}}{d{jCb}}}Cd}{cc{}}000000{{{d{f}}}n}{Chn}22{{{d{{b{c}}}}{d{f}}}{{Bn{{d{f}}}}}h}{{{d{j{b{c}}}}}{{d{jc}}}h}{{{d{{b{c}}}}}{{d{c}}}h}{{{d{Aj}}{d{jc}}}B`Cj}{{{d{n}}{d{jc}}}B`Cj}{{{d{n}}}Cl}{{{d{{b{c}}}}Bl}{{d{f}}}h}{{{d{{b{c}}}}{d{f}}}{{d{f}}}h}{ce{}{}}00000000{{{d{{b{c}}}}}A`h}{{{d{Aj}}}A`}{{{d{n}}{d{f}}}A`}{{{d{n}}}A`}{{{d{{b{c}}}}}{{`{c}}}h}{{{d{n}}{d{n}}}n}{{{d{{b{c}}}}}{{Bf{eCn}}}hD`}{{{d{n}}}{{Bn{{d{f}}}}}}{{{d{{b{c}}}}}{{Bd{c}}}h}{{{d{{Bj{Db}}}}{d{{Bj{Db}}}}}Dd}{c{{b{c}}}h}{cnDf}{DhAn}{{Dh{d{Dd}}}An}{{{d{h}}}{{d{f}}}}{{{d{j{l{ce}}}}gc}{{Dj{{d{jn}}{d{jc}}{d{je}}}}}{}BbDf}{{{d{An}}}{{d{f}}}}09{{{d{n}}}{{`{{Dn{}{{Dl{{d{f}}}}}}}}}}{{{d{Df}}}Aj}{{{d{Aj}}}Aj}48{{{d{j{l{ce}}}}nce}{{Dj{{d{jn}}{d{jc}}{d{je}}}}}{}{}}{{{d{{b{c}}}}{d{f}}}{{d{f}}}h}{{{d{j{l{ce}}}}nc}{{Dj{{d{jn}}{d{jc}}{d{je}}}}}{}Bb}{{{d{{C`{ce}}}}{d{jg}}}{{Bn{{Dj{{d{c}}Al}}}}}{}{}Ab}{{{d{{C`{ce}}}}{d{jg}}i}{{Bn{{Dj{{d{c}}Al}}}}}{}{}Ab{{E`{{d{g}}{d{e}}}{{Ad{A`}}}}}}{{{d{j{C`{ce}}}}{d{jg}}}{{Bn{{Dj{{d{jc}}Al}}}}}{}{}Ab}{{{d{j{C`{ce}}}}{d{jg}}i}{{Bn{{Dj{{d{jc}}Al}}}}}{}{}Ab{{E`{{d{g}}{d{e}}}{{Ad{A`}}}}}}{{{d{Dd}}{d{{Bj{Db}}}}}{{Bn{{Eb{Db}}}}}}{{{d{j{b{c}}}}}B`h}{{{d{j{Ab{}{{Ed{c}}}}}}}{{d{j{b{c}}}}}h}{{{d{j{b{c}}}}}{{d{j{b{e}}}}}h{}}{{{d{n}}{d{jCh}}c}A`Ef}{{{d{n}}{d{jCh}}{d{{Eh{ceg}}}}}A`{{Ej{f}}ElEn}{{F`{f}}}Fb}{{{d{f}}}n}{{{d{{b{c}}}}}Blh}{{{d{j{b{c}}}}c}B`h}{{{d{jn}}Cl}B`}{{{d{jn}}c}B`{{Fd{Ch}}}}{{{d{j{b{c}}}}Cl}B`h}{{{d{c}}}e{}{}}0000{c{{Bf{e}}}{}{}}00000000000000000{{{d{c}}}Ff{}}00000000{{{d{{b{c}}}}}{{d{f}}}h}{{{d{jAn}}{d{Dh}}}B`}{{{d{jAn}}{d{Dh}}{d{Dd}}}B`}{{{d{An}}}{{d{Dh}}}}","D":"Hn","p":[[5,"Path",0,195],[1,"reference"],[1,"str"],[10,"ResourcePath",0,196],[0,"mut"],[5,"RouterBuilder",0,197],[5,"ResourceDef",0,198],[1,"bool"],[10,"Resource",0,196],[17,"Output"],[10,"FnOnce",199],[10,"Clone",200],[6,"Patterns",0,201],[5,"ResourceId",0,197],[5,"Url",0,202],[1,"unit"],[10,"Default",203],[5,"PathDeserializer",0,204],[6,"Result",205],[10,"Visitor",206],[1,"slice"],[1,"usize"],[6,"Option",207],[5,"Router",0,197],[5,"Formatter",208],[8,"Result",208],[10,"Debug",208],[5,"String",209],[10,"Hasher",210],[1,"u16"],[5,"Error",211],[10,"Deserialize",206],[1,"u8"],[5,"Quoter",0,212],[10,"IntoPatterns",0,201],[5,"Uri",213],[1,"tuple"],[17,"Item"],[10,"Iterator",214],[10,"FnMut",199],[5,"Vec",215],[17,"Path"],[10,"IntoIterator",216],[5,"HashMap",217],[10,"Borrow",218],[10,"Eq",219],[10,"Hash",210],[10,"AsRef",220],[10,"BuildHasher",210],[10,"Into",220],[5,"TypeId",221]],"r":[[0,201],[2,195],[4,204],[5,201],[6,212],[7,196],[8,198],[9,197],[10,196],[11,197],[12,197],[14,202]],"b":[[95,"impl-From%3C%26str%3E-for-ResourceDef"],[96,"impl-From%3CString%3E-for-ResourceDef"],[105,"impl-Index%3Cusize%3E-for-Path%3CT%3E"],[106,"impl-Index%3C%26str%3E-for-Path%3CT%3E"],[132,"impl-ResourcePath-for-Url"],[133,"impl-Url"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAHwAFAACAAAABQAAAAgAAAAKAAEADgABABEAEQAmACsAVAAEAGAAAQBnAAEAagABAHYAAAB9AAAAfwAAAIEAAgCFAAAAiQABAJYAAQCgAB8AwQABAA=="}],\ +["actix_test",{"t":"FFFFPPPPPGFFFFPNNNNNNNNNNNNNNNNNNNNNNNNNNNHHHNNNNNNNHNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNNNNNNNHHONNNNNNNNNNNNNNNNNNNNNHHNNHNNNNNHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNONNN","n":["Client","ClientRequest","ClientResponse","Connector","EncodingCorrupted","Http2Payload","Incomplete","Io","Overflow","PayloadError","TestBuffer","TestRequest","TestServer","TestServerConfig","UnknownLength","addr","address","app_data","append_header","append_header","basic_auth","bearer_auth","body","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","builder","call_and_read_body","call_and_read_body_json","call_service","camel_case","client_headers","client_request_timeout","clone","clone","clone_into","clone_into","config","conn_keep_alive","conn_lifetime","connector","content_length","content_type","cookie","cookie","cookie","cookies","default","default","default","delete","delete","delete","disconnect_timeout","drop","empty","err","extend_read_buf","extensions","extensions_mut","finish","flush","fmt","fmt","fmt","fmt","fmt","force_close","freeze","from","from","from","from","from","from","from","from","from","from","from","from","get","get","get","get_method","get_peer_addr","get_uri","get_version","h1","h2","handshake_timeout","head","head","headers","headers","headers","headers","headers_mut","init_service","initial_connection_window_size","initial_window_size","insert_header","insert_header","insert_header_if_none","into","into","into","into","into","into","into","into","into","json","limit","load_body","local_address","map_body","max_http_version","method","method","new","new","new","no_decompress","ok_service","openssl","openssl","options","options","param","patch","patch","patch","peer_addr","poll_flush","poll_next","poll_read","poll_shutdown","poll_write","port","post","post","post","put","put","put","query","read","read_body","read_body_json","read_buf","request","request","request_from","rustls","rustls_021","rustls_0_20","rustls_0_21","rustls_0_22","rustls_0_22","rustls_0_23","rustls_0_23","send","send_body","send_form","send_json","send_request","send_stream","set_form","set_json","set_payload","source","start","start_with","status","status_code","status_service","stop","take_payload","timeout","timeout","timeout","to_bytes","to_http_parts","to_http_request","to_owned","to_owned","to_request","to_srv_request","to_srv_response","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_poll_next","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","unused_addr","uri","uri","url","version","version","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","with_uri","workers","write","write_buf","ws","ws","ws_at"],"q":[[0,"actix_test"],[257,"core::net::socket_addr"],[258,"awc::request"],[259,"actix_web::test::test_request"],[260,"actix_http::header::into_pair"],[261,"core::fmt"],[262,"awc::responses::response"],[263,"awc::responses::response_body"],[264,"bytes::bytes"],[265,"actix_http::error"],[266,"core::result"],[267,"futures_core::stream"],[268,"http::uri"],[269,"actix_tls::connect::info"],[270,"tokio::net::tcp::stream"],[271,"actix_tls::connect::connection"],[272,"actix_tls::connect::error"],[273,"actix_service"],[274,"core::clone"],[275,"awc::builder"],[276,"actix_http::requests::request"],[277,"actix_http::body::message_body"],[278,"actix_web::service"],[279,"actix_web::error::error"],[280,"serde::de"],[281,"actix_http::header::map"],[282,"core::option"],[283,"core::time"],[284,"awc::client"],[285,"awc::client::connector"],[286,"actix_rt::net"],[287,"cookie"],[288,"alloc::vec"],[289,"core::cell"],[290,"cookie::parse"],[291,"core::convert"],[292,"actix_http::test"],[293,"actix_http::extensions"],[294,"alloc::rc"],[295,"awc::client::connection"],[296,"alloc::boxed"],[297,"std::io::error"],[298,"awc::frozen"],[299,"awc::client::error"],[300,"h2::error"],[301,"http::method"],[302,"http::version"],[303,"actix_web::config"],[304,"awc::responses::json_body"],[305,"core::marker"],[306,"core::net::ip_addr"],[307,"actix_http::responses::head"],[308,"actix_http::payload"],[309,"core::ops::function"],[310,"bytes::bytes_mut"],[311,"openssl::ssl::connector"],[312,"alloc::borrow"],[313,"core::pin"],[314,"core::task::wake"],[315,"core::task::poll"],[316,"tokio::io::read_buf"],[317,"serde_urlencoded::ser"],[318,"serde::ser"],[319,"actix_http::requests::head"],[320,"rustls::client::client_conn"],[321,"alloc::sync"],[322,"rustls::server::server_conn"],[323,"awc::sender"],[324,"core::error"],[325,"http::status"],[326,"actix_web::request"],[327,"actix_web::response::response"],[328,"alloc::string"],[329,"core::any"],[330,"tokio::io::async_read"],[331,"tokio::io::async_write"],[332,"actix_http::ws::codec"],[333,"actix_codec::framed"],[334,"awc::error"],[335,"awc::ws"],[336,"actix_web::test::test_utils"],[337,"actix_web::test::test_services"],[338,"actix_http::body::utils"],[339,"actix_http_test"]],"i":[0,0,0,0,13,13,13,13,13,0,0,0,0,0,13,1,4,5,4,5,4,4,9,1,34,38,4,36,9,5,13,47,1,34,38,4,36,9,5,13,47,36,0,0,0,4,1,34,34,36,34,36,0,38,38,38,4,4,4,9,5,9,34,36,5,1,36,5,38,1,47,47,47,9,9,38,47,4,9,13,13,47,4,4,1,34,38,4,36,9,5,13,13,13,13,47,1,36,5,4,4,4,4,34,34,38,1,36,4,36,9,9,4,0,38,38,4,5,4,1,34,38,4,36,9,5,13,47,9,38,1,38,9,38,4,5,38,36,47,4,0,34,38,1,36,5,1,36,5,5,47,9,47,47,47,34,1,36,5,1,36,5,4,47,0,0,47,1,36,36,38,38,34,34,34,38,34,38,4,4,4,4,5,4,5,5,5,13,0,0,9,13,0,1,9,38,4,9,0,5,5,34,36,5,5,5,13,1,34,38,4,36,9,5,13,47,1,34,38,4,36,9,5,13,47,9,1,34,38,4,36,9,5,13,47,0,4,5,1,9,5,1,34,38,4,36,9,5,13,47,5,34,47,47,1,36,1],"f":"```````````````{{{d{b}}}f}{{hf}h}{{jc}j{}}{{hc}hl}{{jc}jl}{{hce}hnn}{{hc}hn}{{{d{A`{Ab{c}}}}}{{Ad{c}}}{{An{}{{Af{{Al{AhAj}}}}}}}}{{{d{c}}}{{d{e}}}{}{}}00000000{{{d{A`c}}}{{d{A`e}}}{}{}}00000000{{}{{Cb{{`{{Bn{{Bb{B`}}}{{Bd{{Bh{B`Bf}}}}{Bj{Bl}}}}C`}}}}}}{{{d{e}}Cd}AhCf{{Bn{Cd}{{Bd{{Ch{c}}}}{Bj{Cj}}}}}}{{{d{e}}Cd}gCf{{Bn{Cd}{{Bd{{Ch{c}}}}{Bj{Cj}}}}}Cl}{{{d{i}}c}{}{}{}Cn{{Bn{c}{{Bd{{Ch{e}}}}{Bj{g}}}}}}{hh}{{{d{A`b}}}{{Db{{d{A`D`}}}}}}{{DdDf}Dd}{{{d{Dd}}}Dd}{{{d{Dh}}}Dh}{{{d{c}}{d{A`e}}}Dj{}{}}0{{}Dd}{{{Dl{e}}Df}{{Dl{e}}}{DnCn}{{Bn{{Bb{B`}}}{{Bd{{Bh{B`c}}}}{Bj{Bl}}}}C`}}0{{{Dl{c}}g}{{Dl{g}}}{}{DnCn}{{Bn{{Bb{B`}}}{{Bd{{Bh{B`e}}}}{Bj{Bl}}}}C`}}{{hE`}h}{{hc}h{}}{{hEb}h}{{{d{{Ab{c}}}}{d{Ed}}}{{Db{Eb}}}{}}{{jEb}j}{{{d{{Ab{c}}}}}{{Al{{Eh{{Ef{Eb}}}}Ej}}}{}}8{{}Dh}{{}j}{{{d{b}}c}h{{El{Ed}}}}{{{d{Dh}}c}h{}}2;{{{d{A`b}}}Dj}{{}En}`{{{d{A`En}}c}Dj{{El{{Fb{F`}}}}}}{{{d{{Ab{c}}}}}{{Eh{Fd}}}{}}{{{d{{Ab{c}}}}}{{Ff{Fd}}}{}}{{{Dl{e}}}{{Gb{{Fj{{Fh{e}}}}{Fl{Bn}}c{G`{Fn}}}}}{DnCn}{{Bn{{Bb{B`}}}{{Bd{{Bh{B`c}}}}{Bj{Bl}}}}C`}}{{{d{A`En}}}{{Al{DjGd}}}}{{{d{h}}{d{A`Gf}}}{{Al{DjGh}}}}{{{d{{Ab{c}}}}{d{A`Gf}}}{{Al{DjGh}}}{}}{{{d{Aj}}{d{A`Gf}}}{{Al{DjGh}}}}0{{{d{En}}{d{A`Gf}}}{{Al{DjGh}}}}{hh}{h{{Al{GjGl}}}}{cc{}}0000000{GdAj}{GnAj}{{{Db{Gd}}}Aj}3{{{d{b}}c}h{{El{Ed}}}}{{{d{Dh}}c}h{}}{{}j}{{{d{h}}}{{d{H`}}}}{{{d{h}}}{{d{{Db{f}}}}}}{{{d{h}}}{{d{B`}}}}{{{d{h}}}{{d{Hb}}}}{DdDd}0{{{Dl{e}}Df}{{Dl{e}}}{DnCn}{{Bn{{Bb{B`}}}{{Bd{{Bh{B`c}}}}{Bj{Bl}}}}C`}}87{{{d{h}}}{{d{D`}}}}{{{d{A`Dh}}}{{Db{{d{A`D`}}}}}}{{{d{{Ab{c}}}}}{{d{D`}}}{}}0{{{d{A`h}}}{{d{A`D`}}}}{i{{`{{Bn{Cd}{{Bd{{Ch{c}}}}{Bj{e}}}}}}}{}{}{{Hh{Cd}{{Hd{Hf}}{Bd{{Ch{c}}}}{Bj{e}}}}}{{Hj{gCd}}}}{{{Dl{e}}Hl}{{Dl{e}}}{DnCn}{{Bn{{Bb{B`}}}{{Bd{{Bh{B`c}}}}{Bj{Bl}}}}C`}}0{{hc}hl}{{jc}jl}1{ce{}{}}00000000{{{d{A`{Ab{c}}}}}{{Hn{ce}}}{{An{}{{Af{{Al{AhAj}}}}}}}Cl}{{{Dl{e}}I`}{{Dl{e}}}{DnCn}{{Bn{{Bb{B`}}}{{Bd{{Bh{B`c}}}}{Bj{Bl}}}}C`}}{{{d{A`b}}{Ab{c}}}{{Al{AhAj}}}{{An{}{{Af{{Al{AhAj}}}}}}Ib}}{{{Dl{e}}Id}{{Dl{e}}}{DnCn}{{Bn{{Bb{B`}}}{{Bd{{Bh{B`c}}}}{Bj{Bl}}}}C`}}{{{Ab{c}}g}{{Ab{e}}}{}{}{{Il{{d{A`If}}{Ih{c}}}{{Ij{{Ih{e}}}}}}}}{{{Dl{e}}Hb}{{Dl{e}}}{DnCn}{{Bn{{Bb{B`}}}{{Bd{{Bh{B`c}}}}{Bj{Bl}}}}C`}}{{hH`}h}{{jH`}j}{{}{{Dl{{`{{Bn{{Bb{B`}}}{{Bd{{Bh{B`Bf}}}}{Bj{Bl}}}}C`}}}}}}{{}Dh}{cEn{{J`{In}}}}{hh}{{}{{`{{Bn{Jb}{{Bd{Ch}}{Bj{Cj}}}}}}}}{{DdJd}Dd}{{{Dl{e}}Jf}{{Dl{e}}}{DnCn}{{Bn{{Bb{B`}}}{{Bd{{Bh{B`c}}}}{Bj{Bl}}}}C`}}{{{d{b}}c}h{{El{Ed}}}}{{{d{Dh}}c}h{}}{{jce}j{{J`{{Jh{Ed}}}}}{{J`{{Jh{Ed}}}}}}21{{}j}{{jf}j}{{{Jj{{d{A`En}}}}{d{A`Jl}}}{{Jn{{Al{DjGd}}}}}}{{{Jj{{d{A`{Ab{c}}}}}}{d{A`Jl}}}{{Jn{Db}}}{{An{}{{Af{{Al{AhAj}}}}}}Ib}}{{{Jj{{d{A`En}}}}{d{A`Jl}}{d{A`K`}}}{{Jn{{Al{DjGd}}}}}}2{{{Jj{{d{A`En}}}}{d{A`Jl}}{d{{Fb{F`}}}}}{{Jn{{Al{I`Gd}}}}}}{{DdKb}Dd}986986{{h{d{c}}}{{Al{hKd}}}Kf}{{{d{A`En}}{d{A`{Fb{F`}}}}}{{Al{I`Gd}}}}{{{Ch{c}}}AhCf}{{{Ch{c}}}eCfCl}`{{{d{b}}H`c}h{{El{Ed}}}}{{{d{Dh}}H`c}h{}}{{{d{Dh}}c{d{Kh}}}h{}}{{{Dl{e}}{Kl{Kj}}}{{Dl{e}}}{DnCn}{{Bn{{Bb{B`}}}{{Bd{{Bh{B`c}}}}{Bj{Bl}}}}C`}}{{{Dl{e}}{Kl{Kn}}}{{Dl{e}}}{DnCn}{{Bn{{Bb{B`}}}{{Bd{{Bh{B`c}}}}{Bj{Bl}}}}C`}}{{DdL`}Dd}{{DdLb}Dd}{{DdLd}Dd}{{{Dl{e}}{Kl{Lf}}}{{Dl{e}}}{DnCn}{{Bn{{Bb{B`}}}{{Bd{{Bh{B`c}}}}{Bj{Bl}}}}C`}}{{DdLh}Dd}{{{Dl{e}}{Kl{Lj}}}{{Dl{e}}}{DnCn}{{Bn{{Bb{B`}}}{{Bd{{Bh{B`c}}}}{Bj{Bl}}}}C`}}{hLl}{{hc}LlCf}{{h{d{c}}}LlKf}0{{j{d{g}}}{}{}Cn{{Bn{Cd}{{Bd{{Ch{c}}}}{Bj{e}}}}}}{{he}Ll{{J`{{G`{Ln}}}}}{{An{}{{Af{{Al{Ahc}}}}}}}}{{jc}jKf}0{{jc}j{{J`{Ah}}}}{{{d{Aj}}}{{Db{{d{Ln}}}}}}{gb{{Hh{Cd}{{Hd{Hf}}}}}{{Hj{cCd}}}{{M`{}{{Ij{e}}}}MbC`}}{{Ddg}b{{Hh{Cd}{{Hd{Hf}}}}}{{Hj{cCd}}}{{M`{}{{Ij{e}}}}MbC`}}{{{d{{Ab{c}}}}}Md{}}{{{d{Aj}}}Md}{Md{{`{{Bn{Jb}{{Bd{Ch}}{Bj{Cj}}}}}}}}{bDj}{{{d{A`{Ab{c}}}}}{{Ih{c}}}{}}{{{Dl{e}}Df}{{Dl{e}}}{DnCn}{{Bn{{Bb{B`}}}{{Bd{{Bh{B`c}}}}{Bj{Bl}}}}C`}}{{hDf}h}{{{Ab{c}}Df}{{Ab{c}}}{}}{c{{Al{Ah}}}Cf}{j{{Mh{MfIh}}}}{jMf}{{{d{c}}}e{}{}}0{jCd}{jJb}{{j{Mj{c}}}{{Ch{c}}}{}}{{{d{c}}}Ml{}}{c{{Al{e}}}{}{}}00000000000000000{{{Jj{{d{A`c}}}}{d{A`Jl}}}{{Jn{{Db{Al}}}}}{}}{{{d{c}}}Mn{}}00000000{{}f}{{hc}h{}}{{j{d{Ed}}}j}{{{d{b}}{d{Ed}}}Ml}{{{d{{Ab{c}}}}}Hb{}}{{jHb}j}{ce{}{}}00000000{{{d{Ed}}}j}{{DdI`}Dd}{{{d{A`En}}{d{{Fb{F`}}}}}{{Al{I`Gd}}}}`{{{d{A`b}}}{{Al{{Nf{{`{N`Nb}}Nd}}Nh}}}}{{{d{Dh}}c}Nj{}}{{{d{A`b}}{d{Ed}}}{{Al{{Nf{{`{N`Nb}}Nd}}Nh}}}}","D":"ADj","p":[[5,"TestServer",0],[1,"reference"],[6,"SocketAddr",257],[5,"ClientRequest",0,258],[5,"TestRequest",0,259],[10,"TryIntoHeaderPair",260],[10,"Display",261],[0,"mut"],[5,"ClientResponse",0,262],[5,"ResponseBody",263],[17,"Item"],[5,"Bytes",264],[6,"PayloadError",0,265],[6,"Result",266],[10,"Stream",267],[5,"Uri",268],[5,"ConnectInfo",269],[17,"Response"],[5,"TcpStream",270],[5,"Connection",271],[17,"Error"],[6,"ConnectError",272],[10,"Service",273],[10,"Clone",274],[5,"ClientBuilder",275],[5,"Request",276],[10,"MessageBody",277],[5,"ServiceResponse",278],[5,"Error",279],[10,"DeserializeOwned",280],[10,"Debug",261],[5,"HeaderMap",281],[6,"Option",282],[5,"TestServerConfig",0],[5,"Duration",283],[5,"Client",0,284],[1,"unit"],[5,"Connector",0,285],[10,"ActixStream",286],[1,"u64"],[5,"Cookie",287],[1,"str"],[5,"Vec",288],[5,"Ref",289],[6,"ParseError",290],[10,"AsRef",291],[5,"TestBuffer",0,292],[1,"u8"],[1,"slice"],[5,"Extensions",293],[5,"RefMut",289],[5,"TcpConnectorInnerService",285],[5,"TcpConnectorService",285],[5,"Rc",294],[10,"ConnectionIo",295],[5,"Box",296],[5,"ConnectorServicePriv",285],[5,"Error",297],[5,"Formatter",261],[5,"Error",261],[5,"FrozenClientRequest",298],[6,"FreezeRequestError",299],[5,"Error",300],[5,"Method",301],[5,"Version",302],[17,"Config"],[5,"AppConfig",303],[10,"ServiceFactory",273],[10,"IntoServiceFactory",273],[1,"u32"],[5,"JsonBody",304],[1,"usize"],[10,"Unpin",305],[6,"IpAddr",306],[5,"ResponseHead",307],[6,"Payload",308],[17,"Output"],[10,"FnOnce",309],[5,"BytesMut",310],[10,"Into",291],[5,"ServiceRequest",278],[5,"SslAcceptor",311],[5,"SslConnector",311],[6,"Cow",312],[5,"Pin",313],[5,"Context",314],[6,"Poll",315],[5,"ReadBuf",316],[1,"u16"],[6,"Error",317],[10,"Serialize",318],[5,"RequestHead",319],[5,"ClientConfig",320],[5,"Arc",321],[5,"ClientConfig",320],[5,"ServerConfig",322],[5,"ServerConfig",322],[5,"ServerConfig",322],[5,"ClientConfig",320],[5,"ServerConfig",322],[5,"ClientConfig",320],[6,"SendClientRequest",323],[10,"Error",324],[10,"Fn",309],[10,"Send",305],[5,"StatusCode",325],[5,"HttpRequest",326],[1,"tuple"],[5,"HttpResponse",327],[5,"String",328],[5,"TypeId",329],[10,"AsyncRead",330],[10,"AsyncWrite",331],[5,"Codec",332],[5,"Framed",333],[6,"WsClientError",334],[5,"WebsocketsRequest",335]],"r":[[0,284],[1,258],[2,262],[3,285],[9,265],[10,292],[11,259],[42,336],[43,336],[44,336],[113,336],[140,337],[164,336],[165,336],[192,337],[198,338],[235,339]],"b":[[79,"impl-Display-for-PayloadError"],[80,"impl-Debug-for-PayloadError"],[92,"impl-From%3CError%3E-for-PayloadError"],[93,"impl-From%3CError%3E-for-PayloadError"],[94,"impl-From%3COption%3CError%3E%3E-for-PayloadError"],[110,"impl-ClientResponse%3CS%3E"],[111,"impl-HttpMessage-for-ClientResponse%3CS%3E"]],"c":"OjAAAAAAAAA=","e":"OzAAAAEAAFwAFQAOAAAAGAARADEAAwA/AAIARgAAAEgAAABKAAEATQAFAF0AAgBwAAAAgwAAAJcABACkAAAApwAAALwAAADAAAAAwwAAAMoAAQDPABwA8gAIAP0AAQA="}],\ +["actix_web",{"t":"NNFNNRNNNFGPERNNNNKRRNNKKFFFFNNNNPNNNNNNNNNNNNNNNNNPRNNNNNNNNNNNNFKEIPFFNNRNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNXNNNNNNNNNNNNNNNNNNXCNNNNCNMNNNMNNNNNNNNNNNNNNNNNNNNNNNNMNNXCNNNNNNXNMNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNXNNNNNNNNNNNNCNNNNNNNNNNNNXNXNNNNXNXNNNNNMNNNNNNXXCNNNNNQNNNNNNNNMNCXNNNNNXNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNNNNNNNFGFFGRPKFPPPFPTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNMNNNNNHHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOFFFPFFPGFFGPPPGFGPFPPPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNPPPPTFPPFPGPPPTFPPPPPTTTTTTTTTTPPPGTPPFPPFITPPPPFPPTTPFTPGTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNFFFFFFFFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNFPPFPFPGPGPPPPPPGPPPFPPPPGGPPPGPPPPPPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOKKKNMMMMMMMMMMMMMMMMMMNMGGPPPPPPPPPPPGPPPPPPPPPPPPPPGPPPPPPPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCHHHNNNNNNNNNNNNNNNNNNCFPFPPPFFPPPPPPFPPFGPPPPFFFPPFGFFPPPPPPFGPPPPFGFGFGFGPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTTTFTTFFTTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNPFTPGPPIGPPFPPPPGPPPPGPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOKQQQQQKFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHHHHFFPRFFPRRRFRRRPPKRRGPFGFFFFFKFRRRFFFKRKFFPKRFFFNNQNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHHQNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNMMNNNNNNNNMNNNNNNNNONNNNNNMNNNNNOMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNOONNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOFPPPPGPPPPPGPPPPFHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHPPPPFPPFPPPPGPPPPPPPPPPGPPGPPPGGGPKIPPPPPPPPPPPPGGPPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOFHFHFHHHKFHHHEHFHHHHHNNNNNNNNNNNMNNNNNNNNHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTTTTTTTPGTPTFTTTTTTTTTTTTTTTTTGPTTTTTTTTFTTTTTTTTTTPTTTTTTTTTTTTTTTTTTFTTTPTTTTTTTPFTFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNNNSSSSSSSSSSSSSSSSSFFFFFPPPKPPPGPPSSSSSSSSSSSSSSSSSFGGFGFFFGFSSFPPGGSFSSGFPRRPPFPPFPSSPPPPPPPSKFFFFSSSSSPGFGGFPFFPPPPPPPPPPPPPPPPPPPPPSSSFPFTSTPPPPPPPPSPSSSSSSGPPPFFSSSSSGSSSSSSSPSPPSSSFKKSSSPPPPPPSSSSSSSSSSSTPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNNHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNONNNCNNNMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOMNNNNNNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNNNNHONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNNNNNNNNNNNNNNMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNOOOOFFFFFFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNFFTTFFFFFFFNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNPFFFFGFPFPFPGPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNFFFNNNNNNNNNNNNNNNNNNNNNNNNCNNQNNCHNNNCCNNNNNNNNNNNNNNNTTTTTTFFFFFFFFTTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHCFFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNFFNNNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNHFFFFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHHNNNNNNNNNNNNNNNNNNNNNNNHHNNNNHNNNNNNNNNNNNNNNNNNFFNNNNNNHHHNNENNONNNNNNHNNNNNHNNNNNNNNNNHHOEENNNNEHNNNNNHHNNNNHHNNNNNNNNOPKKFFFGPFFFFGFPFFFFFFFFFPFFMNNMNNNNNNHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNNNNNNHNNNNHHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHNMNNMNNNHNNNNNNNNNNNHNHNNNNHNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOO","n":["Accepted","AlreadyReported","App","BadGateway","BadRequest","Body","Conflict","Continue","Created","CustomizeResponder","Either","Err","Error","Error","ExpectationFailed","FailedDependency","Forbidden","Found","FromRequest","Future","Future","GatewayTimeout","Gone","Handler","HttpMessage","HttpRequest","HttpResponse","HttpResponseBuilder","HttpServer","ImATeapot","ImUsed","InsufficientStorage","InternalServerError","Left","LengthRequired","Locked","LoopDetected","MethodNotAllowed","MisdirectedRequest","MovedPermanently","MultiStatus","MultipleChoices","NetworkAuthenticationRequired","NoContent","NonAuthoritativeInformation","NotAcceptable","NotExtended","NotFound","NotImplemented","NotModified","Ok","Ok","Output","PartialContent","PayloadTooLarge","PaymentRequired","PermanentRedirect","PreconditionFailed","PreconditionRequired","Processing","ProxyAuthenticationRequired","RangeNotSatisfiable","RequestHeaderFieldsTooLarge","RequestTimeout","ResetContent","Resource","Responder","ResponseError","Result","Right","Route","Scope","SeeOther","ServiceUnavailable","Stream","SwitchingProtocols","TemporaryRedirect","TooManyRequests","Unauthorized","UnavailableForLegalReasons","UnprocessableEntity","UnsupportedMediaType","UpgradeRequired","UriTooLong","UseProxy","VariantAlsoNegotiates","VersionNotSupported","add_cookie","add_removal_cookie","addrs","addrs_with_scheme","app_config","app_data","app_data","app_data","app_data","append_header","append_header","backlog","bind","bind_auto_h2c","bind_openssl","bind_rustls","bind_rustls_021","bind_rustls_0_22","bind_rustls_0_23","bind_uds","body","body","body","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build","call","chunked","client_disconnect_timeout","client_request_timeout","clone","clone_into","configure","configure","conn_data","connect","connection_info","content_type","content_type","cookie","cookie","cookies","cookies","customize","customize","data","data","data","data_factory","default_service","default_service","default_service","del_cookie","delete","delete","dev","disable_signals","drop","drop_body","encoding","error","error","extensions","extensions","extensions","extensions","extensions_mut","extensions_mut","extensions_mut","extensions_mut","external_resource","extract","extract","finish","fmt","fmt","force_close","from","from","from","from","from","from","from","from","from","from","from","from","from","from_error","from_request","from_request","get","get","guard","guard","guard","guard","head","head","head","head","head_mut","headers","headers","headers","headers","headers_mut","http","insert_header","insert_header","into","into","into","into","into","into","into","into","into","into_body","into_factory","into_future","into_parts","json","keep_alive","keep_alive","keep_alive","listen","listen_auto_h2c","listen_openssl","listen_rustls","listen_rustls_0_21","listen_rustls_0_22","listen_rustls_0_23","listen_uds","main","map_body","map_into_boxed_body","map_into_left_body","map_into_right_body","match_info","match_name","match_pattern","max_connection_rate","max_connections","message_body","method","method","middleware","mime_type","name","new","new","new","new","new","new","new","new_service","no_chunking","on_connect","options","patch","patch","path","peer_addr","poll","post","post","put","put","query_string","reason","register","register","resource_map","respond_to","respond_to","respond_to","respond_to","route","route","route","route","routes","rt","run","server_hostname","service","service","service","services","set_body","shutdown_timeout","status","status","status_mut","streaming","system_exit","take","take_payload","take_payload","test","test","tls_handshake_timeout","to","to","to_owned","trace","trace","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_poll","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","upgrade","upgrade","uri","url_for","url_for_static","version","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","web","with_body","with_status","worker_max_blocking_threads","workers","wrap","wrap","wrap","wrap","wrap_fn","wrap_fn","wrap_fn","BodyLimitExceeded","BodySize","BodyStream","BoxBody","EitherBody","Error","Left","MessageBody","None","None","Right","Sized","SizedStream","Stream","ZERO","as_pin_mut","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","boxed","boxed","boxed","clone","clone","clone","clone_into","clone_into","clone_into","default","eq","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","into","into","into","into","into","into","into","is_eof","left","new","new","new","new","new","poll_next","poll_next","poll_next","poll_next","poll_next","poll_next","right","size","size","size","size","size","size","to_bytes","to_bytes_limited","to_owned","to_owned","to_owned","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into_bytes","try_into_bytes","try_into_bytes","try_into_bytes","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","body","body","Cookie","CookieBuilder","CookieJar","DateTime","Delta","Display","EmptyName","Expiration","Iter","Key","KeyError","Lax","MissingPair","None","ParseError","PrivateJar","SameSite","Session","SignedJar","Strict","TooShort","Utf8Error","add","add","add","add_original","add_original","add_original","as_str","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","datetime","decrypt","default","delta","derive_from","description","domain","domain","domain_raw","encoded","encoded","encryption","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","expires","expires","expires_datetime","finish","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","force_remove","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_str","generate","get","get","get","hash","hash","http_only","http_only","into","into","into","into","into","into","into","into","into","into","into","into","into","into_iter","into_iter","into_owned","is_datetime","is_lax","is_none","is_session","is_strict","iter","make_permanent","make_removal","map","master","max_age","max_age","name","name_raw","name_value","named","new","new","new","next","next","parse","parse_encoded","path","path","path_raw","permanent","private","private_mut","remove","remove","remove","reset_delta","same_site","same_site","secure","secure","set_domain","set_expires","set_http_only","set_max_age","set_name","set_path","set_same_site","set_secure","set_value","signed","signed_mut","signing","stripped","stripped","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_generate","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","unset_domain","unset_expires","unset_path","value","value_raw","verify","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","April","August","ComponentRange","ConversionRange","DAY","Date","December","DifferentVariant","Duration","Err","Error","February","Format","Friday","HOUR","Instant","InvalidFormatDescription","InvalidVariant","January","July","June","MAX","MAX","MAX","MICROSECOND","MIDNIGHT","MILLISECOND","MIN","MIN","MIN","MINUTE","March","May","Monday","Month","NANOSECOND","November","October","OffsetDateTime","Ok","ParseFromDescription","PrimitiveDateTime","Result","SECOND","Saturday","September","Sunday","Thursday","Time","TryFromParsed","Tuesday","UNIX_EPOCH","UTC","UnexpectedTrailingCharacters","UtcOffset","WEEK","Wednesday","Weekday","ZERO","abs","add","add","add","add","add","add","add","add","add","add","add","add","add_assign","add_assign","add_assign","add_assign","add_assign","add_assign","add_assign","add_assign","add_assign","add_assign","add_assign","add_assign","as_hms","as_hms","as_hms","as_hms_micro","as_hms_micro","as_hms_milli","as_hms_milli","as_hms_nano","as_hms_nano","as_ref","as_seconds_f32","as_seconds_f64","assume_offset","assume_utc","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","checked_add","checked_add","checked_add","checked_add","checked_add","checked_add_std","checked_div","checked_mul","checked_neg","checked_seconds_f32","checked_seconds_f64","checked_sub","checked_sub","checked_sub","checked_sub","checked_sub","checked_sub_std","checked_to_offset","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","cmp","cmp","cmp","cmp","compare","compare","compare","compare","compare","compare","compare","convert","date","date","day","day","day","days","default","div","div","div","div","div","div","div","div","div","div","div_assign","div_assign","div_assign","div_assign","div_assign","div_assign","div_assign","div_assign","elapsed","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","error","ext","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt_with_metadata","fmt_with_metadata","fmt_with_metadata","fmt_with_metadata","fmt_with_metadata","format","format","format","format","format","format_description","format_into","format_into","format_into","format_into","format_into","formatting","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_calendar_date","from_hms","from_hms","from_hms_micro","from_hms_milli","from_hms_nano","from_iso_week_date","from_julian_day","from_ordinal_date","from_str","from_str","from_unix_timestamp","from_unix_timestamp_nanos","from_whole_seconds","hash","hash","hash","hash","hash","hash","hash","hash","hash","hour","hour","hour","hours","into","into","into","into","into","into","into","into","into","into","into_inner","is_negative","is_negative","is_positive","is_positive","is_utc","is_zero","iso_week","iso_week","iso_week","macros","metadata","metadata","metadata","metadata","metadata","metadata","metadata","microsecond","microsecond","microsecond","microseconds","midnight","millisecond","millisecond","millisecond","milliseconds","minute","minute","minute","minutes","minutes_past_hour","monday_based_week","monday_based_week","monday_based_week","month","month","month","mul","mul","mul","mul","mul","mul","mul","mul","mul_assign","mul_assign","mul_assign","mul_assign","mul_assign","mul_assign","mul_assign","mul_assign","nanosecond","nanosecond","nanosecond","nanoseconds","neg","neg","new","new","new_in_offset","new_utc","next","next","next_day","next_occurrence","now","now_utc","nth_next","nth_next","nth_next_occurrence","nth_prev","nth_prev","nth_prev_occurrence","number_days_from_monday","number_days_from_sunday","number_from_monday","number_from_sunday","offset","ordinal","ordinal","ordinal","parse","parse","parse","parse","parse","parsing","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","prev_occurrence","previous","previous","previous_day","replace_date","replace_date","replace_date_time","replace_day","replace_day","replace_day","replace_hour","replace_hour","replace_hour","replace_microsecond","replace_microsecond","replace_microsecond","replace_millisecond","replace_millisecond","replace_millisecond","replace_minute","replace_minute","replace_minute","replace_month","replace_month","replace_month","replace_nanosecond","replace_nanosecond","replace_nanosecond","replace_offset","replace_ordinal","replace_ordinal","replace_ordinal","replace_second","replace_second","replace_second","replace_time","replace_time","replace_year","replace_year","replace_year","saturating_add","saturating_add","saturating_add","saturating_add","saturating_mul","saturating_seconds_f32","saturating_seconds_f64","saturating_sub","saturating_sub","saturating_sub","saturating_sub","second","second","second","seconds","seconds_f32","seconds_f64","seconds_past_minute","source","sub","sub","sub","sub","sub","sub","sub","sub","sub","sub","sub","sub","sub","sub","sub","sub","sub","sub","sub","sub_assign","sub_assign","sub_assign","sub_assign","sub_assign","sub_assign","sub_assign","sub_assign","sub_assign","sub_assign","sub_assign","sub_assign","subsec_microseconds","subsec_milliseconds","subsec_nanoseconds","sum","sum","sunday_based_week","sunday_based_week","sunday_based_week","time","time","time_fn","to_calendar_date","to_calendar_date","to_calendar_date","to_hms","to_hms_micro","to_hms_milli","to_hms_nano","to_iso_week_date","to_iso_week_date","to_iso_week_date","to_julian_day","to_julian_day","to_julian_day","to_offset","to_ordinal_date","to_ordinal_date","to_ordinal_date","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","unix_timestamp","unix_timestamp_nanos","unsigned_abs","util","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","weekday","weekday","weekday","weeks","whole_days","whole_hours","whole_hours","whole_microseconds","whole_milliseconds","whole_minutes","whole_minutes","whole_nanoseconds","whole_seconds","whole_seconds","whole_weeks","with_hms","with_hms_micro","with_hms_milli","with_hms_nano","with_time","year","year","year","Day","Hour","Microsecond","Millisecond","Minute","Nanosecond","Second","Week","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","into","into","into","into","into","into","into","into","per","per","per","per","per","per","per","per","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","ComponentRange","ComponentRange","ComponentRange","ConversionRange","ConversionRange","DifferentVariant","DifferentVariant","Error","Expected","Format","Format","InsufficientInformation","InsufficientTypeInformation","InvalidComponent","InvalidComponent","InvalidComponentName","InvalidFormatDescription","InvalidFormatDescription","InvalidLiteral","InvalidModifier","InvalidVariant","InvalidVariant","MissingComponentName","MissingRequiredModifier","NotSupported","Parse","ParseFromDescription","ParseFromDescription","ParseFromDescription","StdIo","TryFromParsed","TryFromParsed","TryFromParsed","UnclosedOpeningBracket","UnexpectedTrailingCharacters","UnexpectedTrailingCharacters","UnexpectedTrailingCharacters","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","eq","eq","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","hash","into","into","into","into","into","into","into","into","into","is_conditional","name","source","source","source","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","context","index","index","index","index","index","index","index","name","name","value","what","what","InstantExt","NumericalDuration","NumericalStdDuration","add_signed","checked_add_signed","checked_sub_signed","days","hours","microseconds","milliseconds","minutes","nanoseconds","seconds","signed_duration_since","std_days","std_hours","std_microseconds","std_milliseconds","std_minutes","std_nanoseconds","std_seconds","std_weeks","sub_signed","weeks","BorrowedFormatItem","Component","Component","Component","Component","Compound","Compound","Compound","Day","End","First","First","First","FormatItem","Hour","Ignore","Literal","Literal","Literal","Minute","Month","OffsetHour","OffsetMinute","OffsetSecond","Optional","Optional","Optional","Ordinal","OwnedFormatItem","Period","Second","Subsecond","UnixTimestamp","WeekNumber","Weekday","Year","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone_into","clone_into","clone_into","eq","eq","eq","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","into","into","into","modifier","parse","parse_borrowed","parse_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","vzip","vzip","vzip","well_known","Day","Eight","End","Five","Four","Full","Hour","Ignore","Iso","LastTwo","Long","Long","Microsecond","Millisecond","Minute","Monday","Monday","Month","MonthRepr","Nanosecond","Nine","None","Numerical","OffsetHour","OffsetMinute","OffsetSecond","One","OneOrMore","Ordinal","Padding","Period","Second","Second","Seven","Short","Short","Six","Space","Subsecond","SubsecondDigits","Sunday","Sunday","Three","Two","UnixTimestamp","UnixTimestampPrecision","WeekNumber","WeekNumberRepr","Weekday","WeekdayRepr","Year","YearRepr","Zero","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","case_sensitive","case_sensitive","case_sensitive","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","count","count","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","digits","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","is_12_hour_clock","is_uppercase","iso_week_based","one_indexed","padding","padding","padding","padding","padding","padding","padding","padding","padding","padding","padding","precision","repr","repr","repr","repr","sign_is_mandatory","sign_is_mandatory","sign_is_mandatory","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","DATE","DATE_TIME","DATE_TIME_OFFSET","DEFAULT","Iso8601","OFFSET","PARSING","Rfc2822","Rfc3339","TIME","TIME_OFFSET","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone_into","clone_into","clone_into","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","from","from","from","into","into","into","iso8601","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","vzip","vzip","vzip","Calendar","Config","DEFAULT","Date","DateKind","DateTime","DateTimeOffset","EncodedConfig","FormattedComponents","Hour","Hour","Iso8601","Minute","Minute","None","Offset","OffsetPrecision","Ordinal","Second","Time","TimeOffset","TimePrecision","Week","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","encode","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","into","into","into","into","into","set_date_kind","set_formatted_components","set_offset_precision","set_time_precision","set_use_separators","set_year_is_six_digits","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","decimal_digits","decimal_digits","decimal_digits","Formattable","date","datetime","format_description","offset","time","Parsable","Parsed","borrow","borrow_mut","clone","clone_into","day","default","fmt","from","hour_12","hour_12_is_pm","hour_24","into","iso_week_number","iso_year","iso_year_last_two","minute","monday_week_number","month","new","offset_hour","offset_minute_signed","offset_second_signed","ordinal","parse_component","parse_item","parse_items","parse_literal","second","set_day","set_hour_12","set_hour_12_is_pm","set_hour_24","set_iso_week_number","set_iso_year","set_iso_year_last_two","set_minute","set_monday_week_number","set_month","set_offset_hour","set_offset_minute_signed","set_offset_second_signed","set_ordinal","set_second","set_subsecond","set_sunday_week_number","set_unix_timestamp_nanos","set_weekday","set_year","set_year_last_two","subsecond","sunday_week_number","to_owned","try_from","try_into","type_id","unix_timestamp_nanos","vzip","weekday","with_day","with_hour_12","with_hour_12_is_pm","with_hour_24","with_iso_week_number","with_iso_year","with_iso_year_last_two","with_minute","with_monday_week_number","with_month","with_offset_hour","with_offset_minute_signed","with_offset_second_signed","with_ordinal","with_second","with_subsecond","with_sunday_week_number","with_unix_timestamp_nanos","with_weekday","with_year","with_year_last_two","year","year_last_two","days_in_year","days_in_year_month","is_leap_year","weeks_in_year","AppConfig","AppService","Body","Config","ConnectionInfo","Decompress","Error","Error","Error","Error","Extensions","Future","Future","Future","H1","H2","HttpServiceFactory","InitError","InitError","JsonBody","None","Path","Payload","PeerAddr","Readlines","RequestHead","ResourceDef","ResourceMap","ResourcePath","Response","Response","Response","Response","ResponseHead","Server","ServerHandle","Service","Service","ServiceFactory","ServiceRequest","ServiceResponse","Stream","Transform","Transform","Url","UrlEncoded","WebService","add","add_data_container","always_ready","app_config","app_data","as_str","bad_request","body","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build","build","call","camel_case_headers","capture_match_info","capture_match_info_fn","chunked","chunked","clear","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","compare","config","conn_data","connection_info","connection_type","connection_type","contains","cookie","cookies","default","default","default","default","default","default","default","default_service","drop_body","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","error_response","error_response","expect","extend","extensions","extensions","extensions_mut","extensions_mut","extract","find_match","finish","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fn_factory","fn_service","forward_ready","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_err","from_headers","from_parts","from_request","from_request","from_request","get","get","get_mut","get_mut","get_ref","guard","guard_ctx","handle","has_resource","hash","hash","head","head","head_mut","head_mut","headers","headers","headers","headers","headers","headers","headers","headers","headers_mut","headers_mut","headers_mut","headers_mut","headers_mut","host","host","id","index","index","insert","internal_server_error","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into_body","into_body","into_future","into_future","into_future","into_inner","into_parts","into_parts","into_parts","into_response","into_response","is_empty","is_match","is_prefix","is_root","iter","join","keep_alive","keep_alive","limit","limit","limit","load","local_addr","map_body","map_body","map_into_boxed_body","map_into_boxed_body","map_into_left_body","map_into_right_body","match_info","match_info_mut","match_name","match_name","match_pattern","match_pattern","method","method","name","name","new","new","new","new","new","new","new","new","new","new","new","new","new","new_service","new_transform","new_with_quoter","no_chunking","no_chunking","not_found","ok","partial_cmp","parts","parts_mut","path","path","path","path","pattern","pattern_iter","pause","peer_addr","peer_addr","peer_addr","poll","poll","poll","poll_next","poll_next","poll_next","poll_ready","prefix","query","query_string","realip_remote_addr","reason","reason","register","register_service","remove","request","request","reset","resource_map","resource_path","resource_path","resource_path_from_iter","resource_path_from_map","respond_to","response","response_mut","resume","root_prefix","scheme","secure","segment_count","set","set_body","set_camel_case_headers","set_camel_case_headers","set_connection_type","set_connection_type","set_id","set_name","set_payload","skip","status","status","status","status_mut","stop","take","take_payload","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_poll","try_poll","try_poll","try_poll_next","try_poll_next","try_poll_next","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","unprocessed","update","update_with_quoter","upgrade","upgrade","upgrade","uri","uri","uri","url_for","version","version","version","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","with_body","_res","buf","length","limit","payload","payload","payload","payload","BlockingError","Body","Chunked","ContentType","ContentType","ContentTypeError","ContentTypeError","Deserialize","Deserialize","Deserialize","DisconnectTimeout","DispatchError","Encoding","EncodingCorrupted","EncodingError","Err","Error","ErrorBadGateway","ErrorBadRequest","ErrorConflict","ErrorExpectationFailed","ErrorFailedDependency","ErrorForbidden","ErrorGatewayTimeout","ErrorGone","ErrorHttpVersionNotSupported","ErrorImATeapot","ErrorInsufficientStorage","ErrorInternalServerError","ErrorLengthRequired","ErrorLocked","ErrorLoopDetected","ErrorMethodNotAllowed","ErrorMisdirectedRequest","ErrorNetworkAuthenticationRequired","ErrorNotAcceptable","ErrorNotExtended","ErrorNotFound","ErrorNotImplemented","ErrorPayloadTooLarge","ErrorPaymentRequired","ErrorPreconditionFailed","ErrorPreconditionRequired","ErrorProxyAuthenticationRequired","ErrorRangeNotSatisfiable","ErrorRequestHeaderFieldsTooLarge","ErrorRequestTimeout","ErrorServiceUnavailable","ErrorTooManyRequests","ErrorUnauthorized","ErrorUnavailableForLegalReasons","ErrorUnprocessableEntity","ErrorUnsupportedMediaType","ErrorUpgradeRequired","ErrorUriTooLong","ErrorVariantAlsoNegotiates","H2","HandlerDroppedPayload","Header","Http2Payload","HttpError","Incomplete","Incomplete","InternalError","InternalError","Io","Io","Io","JsonPayloadError","LimitOverflow","Method","NotEnoughElements","Ok","Overflow","Overflow","Overflow","OverflowKnownLength","Parse","Parse","ParseError","ParseError","ParseError","PathError","Payload","Payload","Payload","PayloadError","QueryPayloadError","ReadlinesError","ResourceNotFound","ResponseError","Result","Serialize","Serialize","Service","SlowRequestTimeout","Status","Timeout","TooLarge","UnknownEncoding","UnknownLength","UnknownLength","Upgrade","Uri","UrlGenerationError","UrlencodedError","Utf8","Version","as_error","as_response_error","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","downcast_mut","downcast_ref","eq","equivalent","equivalent","equivalent","error_response","error_response","error_response","error_response","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_response","get_ref","into","into","into","into","into","into","into","into","into","into","into","into","into","into","is","new","respond_to","source","source","source","source","source","source","source","source","source","source","source","status_code","status_code","status_code","status_code","status_code","status_code","status_code","status_code","status_code","status_code","status_code","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","length","limit","limit","limit","size","Acceptable","All","AllGuard","Any","AnyGuard","Connect","Delete","Get","Guard","GuardContext","Head","Header","Host","HostGuard","Method","Not","Options","Patch","Post","Put","Trace","and","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","check","check","check","check","check","clone","clone_into","fmt","fmt","fn_guard","from","from","from","from","from","head","header","into","into","into","into","into","match_star_star","new","or","req_data","req_data_mut","to_owned","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","ACCEPTED","ALREADY_REPORTED","BAD_GATEWAY","BAD_REQUEST","CONFLICT","CONNECT","CONTINUE","CREATED","Close","ConnectionType","DELETE","Disabled","EXPECTATION_FAILED","Error","FAILED_DEPENDENCY","FORBIDDEN","FOUND","GATEWAY_TIMEOUT","GET","GONE","HEAD","HTTP_09","HTTP_10","HTTP_11","HTTP_2","HTTP_3","HTTP_VERSION_NOT_SUPPORTED","IM_A_TEAPOT","IM_USED","INSUFFICIENT_STORAGE","INTERNAL_SERVER_ERROR","KeepAlive","KeepAlive","LENGTH_REQUIRED","LOCKED","LOOP_DETECTED","METHOD_NOT_ALLOWED","MISDIRECTED_REQUEST","MOVED_PERMANENTLY","MULTIPLE_CHOICES","MULTI_STATUS","Method","NETWORK_AUTHENTICATION_REQUIRED","NON_AUTHORITATIVE_INFORMATION","NOT_ACCEPTABLE","NOT_EXTENDED","NOT_FOUND","NOT_IMPLEMENTED","NOT_MODIFIED","NO_CONTENT","OK","OPTIONS","Os","PARTIAL_CONTENT","PATCH","PAYLOAD_TOO_LARGE","PAYMENT_REQUIRED","PERMANENT_REDIRECT","POST","PRECONDITION_FAILED","PRECONDITION_REQUIRED","PROCESSING","PROXY_AUTHENTICATION_REQUIRED","PUT","RANGE_NOT_SATISFIABLE","REQUEST_HEADER_FIELDS_TOO_LARGE","REQUEST_TIMEOUT","RESET_CONTENT","SEE_OTHER","SERVICE_UNAVAILABLE","SWITCHING_PROTOCOLS","StatusCode","TEMPORARY_REDIRECT","TOO_MANY_REQUESTS","TRACE","Timeout","UNAUTHORIZED","UNAVAILABLE_FOR_LEGAL_REASONS","UNPROCESSABLE_ENTITY","UNSUPPORTED_MEDIA_TYPE","UPGRADE_REQUIRED","URI_TOO_LONG","USE_PROXY","Upgrade","Uri","VARIANT_ALSO_NEGOTIATES","Version","as_ref","as_str","as_str","as_u16","authority","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","builder","canonical_reason","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","compare","compare","default","default","default","default","default","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","error_response","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_bytes","from_bytes","from_maybe_shared","from_parts","from_request","from_request","from_static","from_str","from_str","from_str","from_u16","hash","hash","hash","hash","header","host","hostname","into","into","into","into","into","into","into","into_parts","is_client_error","is_idempotent","is_informational","is_redirection","is_safe","is_server_error","is_success","partial_cmp","partial_cmp","path","path","path_and_query","port","port","port_u16","query","scheme","scheme_str","source","status_code","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","uri","vzip","vzip","vzip","vzip","vzip","vzip","vzip","ACCEPT","ACCEPT_CHARSET","ACCEPT_ENCODING","ACCEPT_LANGUAGE","ACCEPT_RANGES","ACCESS_CONTROL_ALLOW_CREDENTIALS","ACCESS_CONTROL_ALLOW_HEADERS","ACCESS_CONTROL_ALLOW_METHODS","ACCESS_CONTROL_ALLOW_ORIGIN","ACCESS_CONTROL_EXPOSE_HEADERS","ACCESS_CONTROL_MAX_AGE","ACCESS_CONTROL_REQUEST_HEADERS","ACCESS_CONTROL_REQUEST_METHOD","AGE","ALLOW","ALT_SVC","AUTHORIZATION","Accept","AcceptCharset","AcceptEncoding","AcceptLanguage","Allow","Any","Any","Any","AsHeaderName","Attachment","Big5","Brotli","ByteRangeSpec","Bytes","Bytes","CACHE_CONTROL","CACHE_STATUS","CDN_CACHE_CONTROL","CONNECTION","CONTENT_DISPOSITION","CONTENT_ENCODING","CONTENT_LANGUAGE","CONTENT_LENGTH","CONTENT_LOCATION","CONTENT_RANGE","CONTENT_SECURITY_POLICY","CONTENT_SECURITY_POLICY_REPORT_ONLY","CONTENT_TYPE","COOKIE","CROSS_ORIGIN_EMBEDDER_POLICY","CROSS_ORIGIN_OPENER_POLICY","CROSS_ORIGIN_RESOURCE_POLICY","CacheControl","CacheDirective","Charset","ContentDisposition","ContentEncoding","ContentLanguage","ContentLength","ContentRange","ContentRangeSpec","ContentType","DATE","DNT","Date","Date","Deflate","DispositionParam","DispositionType","ETAG","ETag","EXPECT","EXPIRES","Encoding","EntityTag","EntityTag","Error","Error","Euc_Jp","Euc_Kr","Expires","Ext","Ext","ExtendedValue","Extension","FORWARDED","FROM","Filename","FilenameExt","FormData","From","FromTo","Gb2312","Gzip","HOST","Header","HeaderMap","HeaderName","HeaderValue","HttpDate","IF_MATCH","IF_MODIFIED_SINCE","IF_NONE_MATCH","IF_RANGE","IF_UNMODIFIED_SINCE","Identity","IfMatch","IfModifiedSince","IfNoneMatch","IfRange","IfUnmodifiedSince","Inline","InvalidHeaderName","InvalidHeaderValue","Iso_2022_Jp","Iso_2022_Jp_2","Iso_2022_Kr","Iso_8859_1","Iso_8859_10","Iso_8859_2","Iso_8859_3","Iso_8859_4","Iso_8859_5","Iso_8859_6","Iso_8859_6_E","Iso_8859_6_I","Iso_8859_7","Iso_8859_8","Iso_8859_8_E","Iso_8859_8_I","Iso_8859_9","Items","Items","Known","Koi8_R","LAST_MODIFIED","LINK","LOCATION","LanguageTag","Last","LastModified","MAX","MAX_FORWARDS","MIN","MaxAge","MaxStale","MinFresh","MustRevalidate","Name","NoCache","NoStore","NoTransform","ORIGIN","OnlyIfCached","PERMISSIONS_POLICY","PRAGMA","PROXY_AUTHENTICATE","PROXY_AUTHORIZATION","PUBLIC_KEY_PINS","PUBLIC_KEY_PINS_REPORT_ONLY","Preference","Private","ProxyRevalidate","Public","Quality","QualityItem","RANGE","REFERER","REFERRER_POLICY","REFRESH","RETRY_AFTER","Range","SEC_WEBSOCKET_ACCEPT","SEC_WEBSOCKET_EXTENSIONS","SEC_WEBSOCKET_KEY","SEC_WEBSOCKET_PROTOCOL","SEC_WEBSOCKET_VERSION","SERVER","SET_COOKIE","SMaxAge","STRICT_TRANSPORT_SECURITY","Shift_Jis","Specific","TE","TRAILER","TRANSFER_ENCODING","ToStrError","TryIntoHeaderPair","TryIntoHeaderValue","UPGRADE","UPGRADE_INSECURE_REQUESTS","USER_AGENT","Unknown","Unknown","UnknownExt","Unregistered","Unregistered","Us_Ascii","VARY","VIA","WARNING","WWW_AUTHENTICATE","X_CONTENT_TYPE_OPTIONS","X_DNS_PREFETCH_CONTROL","X_FORWARDED_FOR","X_FORWARDED_HOST","X_FORWARDED_PROTO","X_FRAME_OPTIONS","X_XSS_PROTECTION","ZERO","Zstd","append","as_bytes","as_filename","as_filename_ext","as_name","as_ref","as_ref","as_ref","as_str","as_str","as_str","as_unknown","as_unknown_ext","attachment","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","brotli","bytes","bytes_multi","canonicalize","capacity","charset","clear","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","cmp","compare","compare","compare","compare","contains_key","default","default","default","deflate","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","disposition","drain","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","extended_language","extended_language_subtags","extension","extension_subtags","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt_comma_delimited","form_url_encoded","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_bytes","from_bytes","from_comma_delimited","from_lowercase","from_maybe_shared","from_maybe_shared_unchecked","from_name","from_one_raw_str","from_raw","from_static","from_static","from_str","from_str","from_str","from_str","from_str","from_str","from_str","from_str","from_str","from_str","from_str","from_str","from_str","from_str","from_str","from_str","full_language","get","get_all","get_filename","get_filename_ext","get_mut","get_name","get_unknown","get_unknown_ext","gzip","hash","hash","hash","hash","hash","hash","html","html","http_percent_encode","identity","image","insert","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into_inner","into_item","into_iter","into_iter","into_string","is_any","is_attachment","is_empty","is_empty","is_ext","is_filename","is_filename_ext","is_form_data","is_inline","is_language_range","is_name","is_sensitive","is_specific","is_unknown","is_unknown_ext","is_valid","item","item","iter","jpeg","json","json","keys","language_tag","len","len","len_keys","map","matches","max","min","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name","negotiate","new","new","new","new_strong","new_weak","now","octet_stream","parameters","parse","parse","parse","parse","parse","parse","parse","parse","parse","parse","parse","parse","parse","parse","parse","parse","parse","parse","parse","parse","parse","parse","parse","parse","parse_extended_value","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","plaintext","png","preference","preference","preference","primary_language","private_use","private_use_subtags","q","quality","ranked","ranked","ranked","region","remove","reserve","retain","script","set_sensitive","set_tag","star","status_code","strong","strong_eq","strong_ne","tag","text","to_header_value","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_satisfiable_range","to_str","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_pair","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","validate","value","variant","variant_subtags","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","weak","weak","weak_eq","weak_ne","with_capacity","xml","zero","zstd","instance_length","range","resp","unit","Drain","HeaderMap","IntoIter","Iter","Keys","Removed","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","into","into","into","into","into","into_iter","into_iter","into_iter","into_iter","into_iter","is_empty","next","next","next","next","next","size_hint","size_hint","size_hint","size_hint","size_hint","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","Authority","Builder","HTTP","HTTPS","InvalidUri","InvalidUriParts","Parts","PathAndQuery","Port","Scheme","Uri","as_ref","as_ref","as_ref","as_str","as_str","as_str","as_str","as_u16","authority","authority","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build","clone","clone","clone","clone_into","clone_into","clone_into","default","default","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from_maybe_shared","from_maybe_shared","from_static","from_static","from_str","from_str","from_str","hash","hash","hash","host","into","into","into","into","into","into","into","into","new","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","path","path_and_query","path_and_query","port","port_u16","query","scheme","scheme","to_owned","to_owned","to_owned","to_string","to_string","to_string","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","Always","Compat","Compress","Condition","DefaultHeaders","ErrorHandlerResponse","ErrorHandlers","Future","Logger","MergeOnly","NormalizePath","Response","TrailingSlash","Trim","add","add_content_type","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","custom_request_replace","custom_response_replace","default","default","default","default","default","default","default_handler","default_handler_client","default_handler_server","exclude","exclude_regex","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","handler","into","into","into","into","into","into","into","into","into","log_target","new","new","new","new","new","new","new_transform","new_transform","new_transform","new_transform","new_transform","new_transform","new_transform","to_owned","to_owned","to_owned","to_owned","trim","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","Runtime","System","SystemRunner","arbiter","block_on","block_on","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone_into","current","fmt","fmt","fmt","from","from","from","from","id","into","into","into","is_registered","net","new","new","pin","run","run_with_code","signal","spawn","spawn","stop","stop_with_code","task","time","to_owned","tokio_runtime","try_current","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","vzip","vzip","vzip","ALL","EMPTY","ERROR","PRIORITY","READABLE","READ_CLOSED","Ready","TcpListener","TcpSocket","TcpStream","UdpSocket","UnixDatagram","UnixListener","UnixStream","WRITABLE","WRITE_CLOSED","accept","accept","as_fd","as_fd","as_fd","as_fd","as_fd","as_fd","as_fd","as_raw_fd","as_raw_fd","as_raw_fd","as_raw_fd","as_raw_fd","as_raw_fd","as_raw_fd","async_io","async_io","async_io","async_io","bind","bind","bind","bind","bind","bind_device","bind_device","bitand","bitor","bitor_assign","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","broadcast","clone","clone_into","cmp","compare","connect","connect","connect","connect","connect","device","device","eq","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from_mio","from_mio","from_raw_fd","from_std","from_std","from_std","from_std","from_std","from_std","from_std_stream","into","into","into","into","into","into","into","into","into_raw_fd","into_split","into_split","into_std","into_std","into_std","into_std","into_std","into_std","is_empty","is_error","is_priority","is_read_closed","is_readable","is_writable","is_write_closed","is_write_vectored","is_write_vectored","join_multicast_v4","join_multicast_v6","keepalive","leave_multicast_v4","leave_multicast_v6","linger","linger","listen","local_addr","local_addr","local_addr","local_addr","local_addr","local_addr","local_addr","multicast_loop_v4","multicast_loop_v6","multicast_ttl_v4","new_v4","new_v6","nodelay","nodelay","pair","pair","partial_cmp","peek","peek_from","peek_sender","peer_addr","peer_addr","peer_addr","peer_addr","peer_cred","poll_accept","poll_accept","poll_flush","poll_flush","poll_peek","poll_peek_from","poll_peek_sender","poll_read","poll_read","poll_read_ready","poll_read_ready","poll_recv","poll_recv","poll_recv_from","poll_recv_from","poll_recv_ready","poll_recv_ready","poll_send","poll_send","poll_send_ready","poll_send_ready","poll_send_to","poll_send_to","poll_shutdown","poll_shutdown","poll_write","poll_write","poll_write_ready","poll_write_ready","poll_write_vectored","poll_write_vectored","readable","readable","readable","readable","ready","ready","ready","ready","recv","recv","recv_buf","recv_buf","recv_buf_from","recv_buf_from","recv_buffer_size","recv_from","recv_from","reuseaddr","reuseport","send","send","send_buffer_size","send_to","send_to","set_broadcast","set_keepalive","set_linger","set_linger","set_multicast_loop_v4","set_multicast_loop_v6","set_multicast_ttl_v4","set_nodelay","set_nodelay","set_recv_buffer_size","set_reuseaddr","set_reuseport","set_send_buffer_size","set_tos","set_tos","set_ttl","set_ttl","set_ttl","shutdown","split","split","sub","take_error","take_error","take_error","take_error","take_error","take_error","to_owned","tos","tos","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_io","try_io","try_io","try_io","try_peek_from","try_peek_sender","try_read","try_read","try_read_buf","try_read_buf","try_read_vectored","try_read_vectored","try_recv","try_recv","try_recv_buf","try_recv_buf","try_recv_buf_from","try_recv_buf_from","try_recv_from","try_recv_from","try_send","try_send","try_send_to","try_send_to","try_write","try_write","try_write_vectored","try_write_vectored","ttl","ttl","ttl","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","unbound","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","writable","writable","writable","writable","ctrl_c","unix","Signal","SignalKind","alarm","as_raw_value","borrow","borrow","borrow_mut","borrow_mut","child","clone","clone_into","eq","equivalent","equivalent","equivalent","fmt","fmt","from","from","from","from_raw","hangup","hash","interrupt","into","into","io","pipe","poll_recv","quit","recv","signal","terminate","to_owned","try_from","try_from","try_into","try_into","type_id","type_id","user_defined1","user_defined2","vzip","vzip","window_change","JoinError","JoinHandle","abort","abort_handle","borrow","borrow","borrow_mut","borrow_mut","drop","fmt","fmt","fmt","from","from","into","into","into_future","into_panic","is_cancelled","is_finished","is_panic","poll","spawn_blocking","to_string","try_from","try_from","try_into","try_into","try_into_panic","try_poll","type_id","type_id","vzip","vzip","yield_now","Instant","Interval","Sleep","Timeout","add","add_assign","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","checked_add","checked_duration_since","checked_sub","clone","clone_into","cmp","compare","deadline","duration_since","elapsed","eq","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","from","from","from","from","from","from_std","get_mut","get_ref","hash","interval","interval_at","into","into","into","into","into_future","into_future","into_inner","into_std","is_elapsed","missed_tick_behavior","now","partial_cmp","period","poll","poll","poll_tick","reset","reset","reset_after","reset_at","reset_immediately","saturating_duration_since","set_missed_tick_behavior","sleep","sleep_until","sub","sub","sub_assign","tick","timeout","to_owned","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_poll","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","TestBuffer","TestRequest","app_data","append_header","borrow","borrow","borrow_mut","borrow_mut","call_and_read_body","call_and_read_body_json","call_service","cookie","default","default_service","delete","empty","err","extend_read_buf","flush","fmt","from","from","get","init_service","insert_header","into","into","method","new","ok_service","param","patch","peer_addr","poll_flush","poll_read","poll_shutdown","poll_write","post","put","read","read_body","read_body_json","read_buf","read_response","read_response_json","send_request","set_form","set_json","set_payload","simple_service","status_service","to_http_parts","to_http_request","to_request","to_srv_request","to_srv_response","try_call_and_read_body_json","try_call_service","try_from","try_from","try_into","try_into","try_read_body","try_read_body_json","type_id","type_id","uri","version","vzip","vzip","with_uri","write","write_buf","Body","Buf","BufMut","Bytes","BytesMut","Data","Either","Error","Form","FormConfig","Header","Json","JsonBody","JsonConfig","Left","Path","PathConfig","Payload","PayloadConfig","Query","QueryConfig","Readlines","Redirect","ReqData","Right","ServiceConfig","UrlEncoded","advance","advance","advance","advance_mut","advance_mut","app_data","as_mut","as_ref","as_ref","as_ref","block","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","bytes_init","bytes_init","bytes_total","bytes_total","capacity","chain","chain_mut","chunk","chunk","chunk","chunk_mut","chunk_mut","chunks_vectored","clear","clear","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","cmp","cmp","cmp","compare","compare","compare","compare","compare","compare","configure","content_type","content_type_required","copy_from_slice","copy_to_bytes","copy_to_bytes","copy_to_bytes","copy_to_slice","data","default","default","default","default","default","default","default","default","default_service","delete","deref","deref","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deserialize","drop","drop","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","error_handler","error_handler","error_handler","error_handler","extend","extend","extend","extend_from_slice","external_resource","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","freeze","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_iter","from_iter","from_iter","from_query","from_request","from_request","from_request","from_request","from_request","from_request","from_request","from_request","from_request","from_request","from_static","get","get_f32","get_f32_le","get_f32_ne","get_f64","get_f64_le","get_f64_ne","get_i128","get_i128_le","get_i128_ne","get_i16","get_i16_le","get_i16_ne","get_i32","get_i32_le","get_i32_ne","get_i64","get_i64_le","get_i64_ne","get_i8","get_int","get_int_le","get_int_ne","get_ref","get_u128","get_u128_le","get_u128_ne","get_u16","get_u16_le","get_u16_ne","get_u32","get_u32_le","get_u32_ne","get_u64","get_u64_le","get_u64_ne","get_u8","get_uint","get_uint_le","get_uint_ne","has_remaining","has_remaining_mut","hash","hash","head","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into_inner","into_inner","into_inner","into_inner","into_inner","into_inner","into_inner","into_inner","into_inner","into_inner","into_iter","into_iter","into_iter","into_iter","is_empty","is_empty","is_unique","len","len","limit","limit","limit","limit","method","mimetype","new","new","new","new","new","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","patch","permanent","poll_next","poll_next","poll_next","post","put","put","put","put_bytes","put_bytes","put_f32","put_f32_le","put_f32_ne","put_f64","put_f64_le","put_f64_ne","put_i128","put_i128_le","put_i128_ne","put_i16","put_i16_le","put_i16_ne","put_i32","put_i32_le","put_i32_ne","put_i64","put_i64_le","put_i64_ne","put_i8","put_int","put_int_le","put_int_ne","put_slice","put_slice","put_u128","put_u128_le","put_u128_ne","put_u16","put_u16_le","put_u16_ne","put_u32","put_u32_le","put_u32_ne","put_u64","put_u64_le","put_u64_ne","put_u8","put_uint","put_uint_le","put_uint_ne","reader","redirect","register","remaining","remaining","remaining","remaining_mut","remaining_mut","reserve","resize","resource","resource_path","resource_path","resource_path","resource_path","resource_path","respond_to","respond_to","respond_to","respond_to","respond_to","respond_to","route","route","scope","see_other","serialize","serialize","serialize","service","service","set_init","set_len","size","size","slice","slice_ref","spare_capacity_mut","split","split_off","split_off","split_to","split_to","stable_mut_ptr","stable_ptr","stable_ptr","take","temporary","to","to","to_bytes","to_bytes_limited","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string","to_string","to_string","trace","truncate","truncate","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into_bytes","try_into_bytes","try_into_value","try_poll_next","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","unsplit","using_status_code","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","with_capacity","write_fmt","write_str","writer","zeroed","_res","buf","length","limit","payload"],"q":[[0,"actix_web"],[370,"actix_web::body"],[492,"actix_web::body::EitherBody"],[494,"actix_web::cookie"],[771,"actix_web::cookie::time"],[1414,"actix_web::cookie::time::convert"],[1526,"actix_web::cookie::time::error"],[1741,"actix_web::cookie::time::error::InvalidFormatDescription"],[1754,"actix_web::cookie::time::ext"],[1778,"actix_web::cookie::time::format_description"],[1887,"actix_web::cookie::time::format_description::modifier"],[2399,"actix_web::cookie::time::format_description::well_known"],[2459,"actix_web::cookie::time::format_description::well_known::iso8601"],[2562,"actix_web::cookie::time::format_description::well_known::iso8601::TimePrecision"],[2565,"actix_web::cookie::time::formatting"],[2566,"actix_web::cookie::time::macros"],[2571,"actix_web::cookie::time::parsing"],[2654,"actix_web::cookie::time::util"],[2658,"actix_web::dev"],[3195,"actix_web::dev::JsonBody"],[3200,"actix_web::dev::Payload"],[3203,"actix_web::error"],[3536,"actix_web::error::JsonPayloadError"],[3539,"actix_web::error::UrlencodedError"],[3541,"actix_web::guard"],[3621,"actix_web::http"],[3910,"actix_web::http::header"],[5200,"actix_web::http::header::ContentRangeSpec"],[5204,"actix_web::http::header::map"],[5271,"actix_web::http::uri"],[5451,"actix_web::middleware"],[5585,"actix_web::rt"],[5640,"actix_web::rt::net"],[5963,"actix_web::rt::signal"],[5965,"actix_web::rt::signal::unix"],[6010,"actix_web::rt::task"],[6045,"actix_web::rt::time"],[6136,"actix_web::test"],[6209,"actix_web::web"],[6807,"actix_web::web::JsonBody"],[6812,"actix_web::response::builder"],[6813,"actix_web::response::response"],[6814,"cookie"],[6815,"core::result"],[6816,"actix_web::server"],[6817,"core::net::socket_addr"],[6818,"alloc::vec"],[6819,"actix_http::requests::request"],[6820,"actix_service"],[6821,"core::ops::function"],[6822,"core::marker"],[6823,"core::clone"],[6824,"actix_http::body::message_body"],[6825,"actix_web::request"],[6826,"actix_web::config"],[6827,"actix_web::app"],[6828,"actix_web::service"],[6829,"actix_web::error::error"],[6830,"actix_web::resource"],[6831,"actix_web::scope"],[6832,"core::option"],[6833,"actix_http::header::into_pair"],[6834,"actix_web::response::customize_responder"],[6835,"actix_web::response::responder"],[6836,"std::io::error"],[6837,"std::net::socket_addr"],[6838,"openssl::ssl::connector"],[6839,"rustls::server::server_conn"],[6840,"std::path"],[6841,"core::convert"],[6842,"actix_http::body::boxed"],[6843,"http::status"],[6844,"actix_web::handler"],[6845,"core::future::future"],[6846,"actix_http::http_message"],[6847,"actix_http::error"],[6848,"core::time"],[6849,"actix_web::info"],[6850,"core::cell"],[6851,"actix_http::header::into_value"],[6852,"cookie::parse"],[6853,"core::fmt"],[6854,"actix_web::extract"],[6855,"encoding_rs"],[6856,"actix_http::extensions"],[6857,"actix_http::responses::response"],[6858,"actix_http::payload"],[6859,"actix_web::route"],[6860,"actix_http::responses::head"],[6861,"actix_http::requests::head"],[6862,"actix_http::header::map"],[6863,"serde::ser"],[6864,"actix_http::keep_alive"],[6865,"std::net::tcp"],[6866,"std::os::unix::net::listener"],[6867,"actix_http::body::either"],[6868,"actix_router::url"],[6869,"actix_router::path"],[6870,"alloc::string"],[6871,"http::method"],[6872,"mime"],[6873,"actix_router::pattern"],[6874,"core::any"],[6875,"core::pin"],[6876,"core::task::wake"],[6877,"core::task::poll"],[6878,"actix_web::rmap"],[6879,"actix_server::server"],[6880,"core::error"],[6881,"alloc::boxed"],[6882,"bytes::bytes"],[6883,"futures_core::stream"],[6884,"http::uri"],[6885,"url"],[6886,"core::iter::traits::collect"],[6887,"http::version"],[6888,"actix_service::transform"],[6889,"actix_service::boxed"],[6890,"actix_http::body::none"],[6891,"actix_http::body::size"],[6892,"actix_http::body::utils"],[6893,"actix_http::body::body_stream"],[6894,"actix_http::body::sized_stream"],[6895,"cookie::secure::private"],[6896,"cookie::jar"],[6897,"core::borrow"],[6898,"cookie::secure::signed"],[6899,"cookie::builder"],[6900,"alloc::borrow"],[6901,"cookie::draft"],[6902,"cookie::expiration"],[6903,"cookie::secure::key"],[6904,"time::offset_date_time"],[6905,"core::str::error"],[6906,"core::hash"],[6907,"time::duration"],[6908,"time::date"],[6909,"time::instant"],[6910,"time::primitive_date_time"],[6911,"time::time"],[6912,"time::utc_offset"],[6913,"std::time"],[6914,"time::month"],[6915,"time::weekday"],[6916,"core::cmp"],[6917,"time::error"],[6918,"powerfmt::smart_display"],[6919,"time::error::format"],[6920,"time::formatting::formattable"],[6921,"std::io"],[6922,"time::error::parse"],[6923,"time::error::conversion_range"],[6924,"time::error::component_range"],[6925,"time::error::invalid_format_description"],[6926,"time::error::try_from_parsed"],[6927,"time::error::parse_from_description"],[6928,"time::error::invalid_variant"],[6929,"time::error::different_variant"],[6930,"time::parsing::parsable"],[6931,"core::iter::traits::iterator"],[6932,"time::parsing::parsed"],[6933,"time_core::convert"],[6934,"time::format_description::parse"],[6935,"time::ext::instant"],[6936,"time::ext::numerical_duration"],[6937,"time::ext::numerical_std_duration"],[6938,"time::format_description::component"],[6939,"time::format_description::owned_format_item"],[6940,"time::format_description::parse::format_item"],[6941,"time::format_description::modifier"],[6942,"core::num::nonzero"],[6943,"time::format_description::well_known::iso8601"],[6944,"time::format_description::well_known::rfc2822"],[6945,"time::format_description::well_known::rfc3339"],[6946,"time::parsing::parsed::sealed"],[6947,"actix_router::resource"],[6948,"alloc::rc"],[6949,"actix_router::resource_path"],[6950,"actix_server::builder"],[6951,"actix_http::responses::builder"],[6952,"actix_server::handle"],[6953,"actix_http::message"],[6954,"core::default"],[6955,"actix_service::fn_service"],[6956,"actix_http::ws"],[6957,"actix_http::ws::dispatcher::inner"],[6958,"tokio_util::codec::encoder"],[6959,"tokio_util::codec::decoder"],[6960,"bytestring"],[6961,"bytes::bytes_mut"],[6962,"h2::share"],[6963,"actix_http::h2"],[6964,"actix_http::h1::payload"],[6965,"actix_web::types::form"],[6966,"actix_web::types::json"],[6967,"serde::de"],[6968,"actix_web::types::readlines"],[6969,"serde::de::value"],[6970,"actix_http::header::shared::content_encoding"],[6971,"actix_router::quoter"],[6972,"std::collections::hash::map"],[6973,"actix_web::error::response_error"],[6974,"actix_web::error::internal"],[6975,"http::header::map"],[6976,"http::header::name"],[6977,"http::header::value"],[6978,"url::parser"],[6979,"serde_urlencoded::ser"],[6980,"httparse"],[6981,"h2::error"],[6982,"actix_web::guard::acceptable"],[6983,"actix_http::header"],[6984,"http::uri::authority"],[6985,"http::uri::builder"],[6986,"actix_http::encoding::encoder"],[6987,"http::uri::path"],[6988,"http::uri::port"],[6989,"http::uri::scheme"],[6990,"actix_web::http::header::content_disposition"],[6991,"actix_http::header::shared::extended"],[6992,"language_tags"],[6993,"actix_web::http::header::encoding"],[6994,"actix_web::http::header::range"],[6995,"actix_http::header::shared::charset"],[6996,"actix_http::header::shared::http_date"],[6997,"actix_http::header::shared::quality"],[6998,"actix_http::header::shared::quality_item"],[6999,"actix_web::http::header::accept"],[7000,"actix_web::http::header::accept_charset"],[7001,"actix_web::http::header::accept_encoding"],[7002,"actix_web::http::header::accept_language"],[7003,"actix_web::http::header::allow"],[7004,"actix_web::http::header::cache_control"],[7005,"actix_web::http::header::content_language"],[7006,"actix_web::http::header::content_length"],[7007,"actix_web::http::header::content_range"],[7008,"actix_web::http::header::content_type"],[7009,"actix_web::http::header::date"],[7010,"actix_web::http::header::entity"],[7011,"actix_web::http::header::etag"],[7012,"actix_web::http::header::expires"],[7013,"actix_web::http::header::if_match"],[7014,"actix_web::http::header::if_modified_since"],[7015,"actix_web::http::header::if_none_match"],[7016,"actix_web::http::header::if_range"],[7017,"actix_web::http::header::if_unmodified_since"],[7018,"actix_web::http::header::last_modified"],[7019,"actix_web::http::header::preference"],[7020,"actix_http::header::as_name"],[7021,"core::str::traits"],[7022,"core::slice::iter"],[7023,"actix_web::middleware::default_headers"],[7024,"actix_web::middleware::normalize"],[7025,"actix_web::middleware::compress"],[7026,"actix_web::middleware::logger"],[7027,"actix_web::middleware::err_handlers"],[7028,"actix_web::middleware::compat"],[7029,"actix_web::middleware::condition"],[7030,"actix_rt::system"],[7031,"actix_rt::arbiter"],[7032,"actix_rt::runtime"],[7033,"tokio::runtime::runtime"],[7034,"tokio::runtime::task::join"],[7035,"tokio::net::tcp::listener"],[7036,"tokio::net::tcp::stream"],[7037,"tokio::net::unix::listener"],[7038,"tokio::net::unix::stream"],[7039,"tokio::net::unix::socketaddr"],[7040,"std::os::fd::owned"],[7041,"tokio::net::tcp::socket"],[7042,"tokio::net::udp"],[7043,"tokio::net::unix::datagram::socket"],[7044,"tokio::io::interest"],[7045,"tokio::net::addr"],[7046,"tokio::io::ready"],[7047,"actix_server::socket"],[7048,"std::net::udp"],[7049,"std::os::unix::net::datagram"],[7050,"std::os::unix::net::stream"],[7051,"tokio::net::tcp::split_owned"],[7052,"tokio::net::unix::split_owned"],[7053,"core::net::ip_addr"],[7054,"tokio::net::unix::ucred"],[7055,"tokio::io::read_buf"],[7056,"bytes::buf::buf_mut"],[7057,"std::net"],[7058,"tokio::net::tcp::split"],[7059,"tokio::net::unix::split"],[7060,"tokio::signal::unix"],[7061,"tokio::runtime::task::abort"],[7062,"tokio::runtime::task::error"],[7063,"tokio::time::instant"],[7064,"tokio::time::sleep"],[7065,"tokio::time::interval"],[7066,"tokio::time::timeout"],[7067,"actix_web::test::test_request"],[7068,"actix_http::test"],[7069,"bytes::buf::buf_impl"],[7070,"actix_web::types::path"],[7071,"bytes::buf::chain"],[7072,"bytes::buf::uninit_slice"],[7073,"actix_web::data"],[7074,"actix_web::redirect"],[7075,"actix_web::request_data"],[7076,"actix_web::types::header"],[7077,"actix_web::types::payload"],[7078,"actix_web::types::query"],[7079,"alloc::sync"],[7080,"actix_web::types::either"],[7081,"http::byte_str"],[7082,"bytes::buf::limit"],[7083,"bytes::buf::reader"],[7084,"core::ops::range"],[7085,"core::mem::maybe_uninit"],[7086,"bytes::buf::take"],[7087,"bytes::buf::writer"],[7088,"actix_http"],[7089,"actix_web_codegen"],[7090,"time"],[7091,"time_core"],[7092,"time::format_description::borrowed_format_item"],[7093,"time::format_description"],[7094,"time::format_description::well_known"],[7095,"time::format_description::well_known::iso8601::adt_hack"],[7096,"time_macros"],[7097,"time_core::util"],[7098,"time::util"],[7099,"actix_web::guard::host"],[7100,"http"],[7101,"actix_http::header::common"],[7102,"actix_http::header::utils"],[7103,"actix_rt"],[7104,"tokio"],[7105,"tokio::signal::ctrl_c"],[7106,"actix_rt::signal"],[7107,"tokio::task::blocking"],[7108,"tokio::task::yield_now"],[7109,"actix_web::test::test_utils"],[7110,"actix_web::test::test_services"]],"i":[3,3,0,3,3,35,3,3,3,0,0,382,0,67,3,3,3,3,0,67,49,3,3,0,0,0,0,0,0,3,3,3,3,454,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,382,49,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,454,0,0,3,3,52,3,3,3,3,3,3,3,3,3,3,3,3,3,3,9,9,23,25,30,31,23,1,34,9,9,9,9,9,9,9,9,9,0,1,3,25,30,1,34,3,78,31,9,23,25,30,1,34,3,78,31,9,23,3,49,52,9,9,23,23,25,31,23,0,23,1,52,1,23,3,23,35,35,25,30,31,25,25,30,31,3,30,0,0,9,23,3,52,0,3,52,1,3,23,52,1,3,23,25,67,67,1,3,23,1,25,30,1,34,3,3,3,3,3,78,31,9,23,3,67,23,30,0,0,30,78,31,30,3,23,0,3,52,3,23,23,3,0,1,34,25,30,1,34,3,78,31,9,23,3,78,1,3,1,1,3,9,9,9,9,9,9,9,9,9,0,3,3,3,3,23,23,23,9,9,1,78,23,0,52,30,25,30,1,3,78,31,9,78,1,9,0,30,0,23,23,1,30,0,30,0,23,1,30,31,23,35,1,34,3,25,30,31,0,0,0,9,9,25,78,31,0,3,9,1,3,3,1,9,1,52,23,0,0,9,30,78,23,30,0,25,30,1,34,3,78,31,9,23,25,30,1,34,3,78,31,9,23,1,25,30,1,34,3,78,31,9,23,1,3,23,23,23,23,25,30,1,34,3,78,31,9,23,0,3,34,9,9,25,30,78,31,25,30,31,0,0,0,0,0,20,86,0,0,117,86,117,0,117,117,46,120,46,86,116,117,121,119,120,46,86,116,117,121,119,20,46,86,86,116,117,86,116,117,116,117,117,117,117,46,86,116,117,119,119,120,46,86,116,117,121,119,120,46,86,116,117,121,119,117,86,120,46,86,116,121,20,120,46,86,116,121,86,20,120,46,86,116,121,0,0,86,116,117,119,120,46,86,116,117,121,119,120,46,86,116,117,121,119,20,46,86,116,120,46,86,116,117,121,119,120,46,86,116,117,121,119,469,470,0,0,0,129,0,0,61,0,0,0,0,128,61,128,0,0,0,129,0,128,136,61,122,125,123,122,125,123,61,132,140,122,125,135,126,61,123,128,129,130,136,5,132,140,122,125,135,126,61,123,128,129,130,136,5,5,126,61,123,128,129,130,5,126,61,123,128,129,130,5,129,122,123,123,130,61,126,5,5,135,5,130,61,128,129,130,5,61,61,61,128,128,128,129,129,129,126,5,5,126,135,126,61,61,123,128,128,129,136,136,5,5,123,132,140,122,125,135,126,61,61,123,128,129,129,130,130,136,5,5,130,122,125,123,128,129,126,5,132,140,122,125,135,126,61,123,128,129,130,136,5,132,140,5,129,128,128,129,128,123,5,5,129,130,126,5,5,5,5,5,126,123,5,132,140,5,5,126,5,5,126,123,123,122,125,123,123,126,5,126,5,5,5,5,5,5,5,5,5,5,123,123,130,135,5,126,61,123,128,129,130,5,135,61,128,136,5,132,140,122,125,135,126,61,123,128,129,130,130,136,5,130,132,140,122,125,135,126,61,123,128,129,130,136,5,132,140,122,125,135,126,61,123,128,129,130,136,5,5,5,5,5,5,125,132,140,122,125,135,126,61,123,128,129,130,136,5,153,153,159,159,141,0,153,159,0,471,0,153,159,154,141,0,159,159,153,153,153,142,141,144,141,145,141,142,141,144,141,153,153,154,0,141,153,153,0,471,159,0,0,141,154,153,154,154,0,159,154,131,146,159,0,141,154,0,141,141,142,142,141,141,143,143,131,131,144,144,145,145,142,142,141,141,143,143,131,131,144,144,145,145,144,145,146,144,145,144,145,144,145,143,141,141,144,144,142,141,159,143,143,153,131,144,145,146,154,142,141,159,143,153,131,144,145,146,154,142,141,143,131,144,142,141,141,141,141,141,142,141,143,131,144,142,131,142,141,143,153,131,144,145,146,154,142,141,143,153,131,144,145,146,154,142,141,143,131,144,145,146,142,141,143,131,144,145,146,0,131,144,142,131,144,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,143,142,141,141,143,143,153,131,131,144,145,146,154,142,142,142,141,141,141,143,143,143,153,153,153,131,131,131,144,144,144,145,145,145,146,146,146,154,154,154,0,0,142,142,141,141,159,159,143,153,153,153,131,131,144,144,145,145,146,146,154,154,154,142,131,144,145,146,142,131,144,145,146,0,142,131,144,145,146,0,142,141,159,159,159,159,159,159,159,159,159,159,143,143,153,131,131,144,145,146,154,142,145,146,145,145,145,142,142,142,153,154,131,131,146,142,141,143,153,131,144,145,146,154,131,144,145,141,142,141,159,143,153,131,144,145,146,154,143,141,146,141,146,146,141,142,131,144,0,142,153,131,144,145,146,154,131,144,145,141,142,131,144,145,141,131,144,145,141,146,142,131,144,142,131,144,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,131,144,145,141,141,146,141,144,131,131,153,154,142,142,143,131,153,154,142,153,154,142,154,154,154,154,131,142,131,144,142,131,144,145,146,0,142,141,141,143,143,131,131,144,145,146,142,153,154,142,131,144,131,142,131,144,131,144,145,131,144,145,131,144,145,131,144,145,142,131,144,131,144,145,131,142,131,144,131,144,145,131,144,142,131,144,142,141,131,144,141,141,141,142,141,131,144,131,144,145,141,141,141,146,159,142,142,142,141,141,143,143,143,143,131,131,131,131,144,144,144,145,145,145,142,142,141,141,143,143,131,131,144,144,145,145,141,141,141,141,141,142,131,144,131,144,141,142,131,144,131,131,131,131,142,131,144,142,131,144,131,142,131,144,142,141,143,153,131,144,145,146,154,142,141,159,153,131,144,145,146,154,142,142,141,141,159,143,153,153,131,131,144,144,145,145,146,146,154,142,141,159,143,153,131,144,145,146,154,142,141,159,143,153,131,144,145,146,154,131,131,141,0,142,141,159,143,153,131,144,145,146,154,142,131,144,141,141,141,146,141,141,141,146,141,141,146,141,142,142,142,142,142,142,131,144,0,0,0,0,0,0,0,0,178,179,180,181,182,183,184,185,178,179,180,181,182,183,184,185,178,179,180,181,182,183,184,185,178,179,180,181,182,183,184,185,178,179,180,181,182,183,184,185,178,179,180,181,182,183,184,185,178,179,180,181,182,183,184,185,178,179,180,181,182,183,184,185,178,179,180,181,182,183,184,185,178,179,180,181,182,183,184,185,178,179,180,181,182,183,184,185,178,179,180,181,182,183,184,185,178,179,180,181,182,183,184,185,0,169,159,0,159,0,159,0,168,0,159,169,161,161,170,168,0,159,170,168,0,159,168,168,168,0,0,165,159,161,0,165,159,168,165,170,159,167,166,172,161,168,171,165,170,169,167,166,172,161,168,171,165,170,169,167,166,172,168,171,165,170,169,167,166,172,168,171,165,170,169,167,166,172,168,171,165,170,169,167,167,167,166,166,166,172,172,172,168,168,168,171,171,171,165,165,165,170,170,170,169,169,169,167,167,166,166,172,172,161,161,168,168,171,171,165,165,170,170,169,169,167,166,172,161,161,168,168,171,165,165,165,170,169,169,167,167,166,172,161,168,171,165,170,169,167,167,161,165,169,167,166,172,168,171,165,170,169,167,166,172,161,168,171,165,170,169,167,167,167,166,166,172,172,161,161,168,168,171,171,165,165,170,170,170,169,169,169,167,166,172,161,168,171,165,170,169,167,166,172,161,168,171,165,170,169,167,166,172,161,168,171,165,170,169,472,473,474,475,476,477,478,472,474,477,475,478,472,0,0,0,189,189,189,190,190,190,190,190,190,190,189,191,191,191,191,191,191,191,191,189,190,0,0,192,192,194,192,192,194,193,193,192,192,194,0,193,193,192,192,194,193,193,193,193,193,192,192,194,193,0,193,193,193,193,193,193,193,192,193,194,192,193,194,192,193,194,192,193,194,192,192,192,193,193,193,194,194,194,192,192,192,193,193,193,194,194,194,192,193,194,192,192,192,193,193,194,194,194,194,194,194,194,194,194,192,193,194,0,0,0,0,192,193,194,192,192,193,193,193,194,192,193,194,192,193,194,192,193,194,0,0,211,0,211,211,205,0,0,203,205,198,201,218,218,0,201,203,0,0,218,211,216,198,0,0,0,211,211,0,0,0,0,218,211,198,201,211,216,0,0,201,203,211,211,0,0,0,0,0,0,0,0,216,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,199,202,209,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,217,217,197,197,198,199,199,200,200,201,202,202,203,204,204,205,206,206,207,207,208,208,209,209,210,210,211,212,212,213,213,214,214,215,215,216,218,219,219,220,220,212,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,197,197,197,198,198,198,199,199,199,200,200,200,201,201,201,202,202,202,203,203,203,204,204,204,205,205,205,206,206,206,207,207,207,208,208,208,209,209,209,210,210,210,211,211,211,212,212,212,213,213,213,214,214,214,215,215,215,216,216,216,217,217,217,218,218,218,219,219,219,220,220,220,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,197,198,198,199,200,201,201,202,203,203,204,205,205,206,207,208,209,210,211,211,212,213,214,215,216,216,217,218,218,219,220,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,207,209,206,202,197,199,200,204,206,207,208,210,213,214,215,219,199,202,204,206,206,213,219,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,229,229,229,229,0,229,229,0,0,229,229,229,230,231,229,230,231,229,230,231,229,230,231,229,230,231,229,229,229,230,230,230,231,231,231,229,230,231,229,230,231,229,230,231,0,229,230,231,229,230,231,229,230,231,229,230,231,229,230,231,233,0,236,232,0,232,232,0,0,234,235,0,234,235,232,232,0,233,234,232,232,0,233,232,233,234,235,236,232,233,234,235,236,232,233,234,235,232,233,234,235,236,232,233,234,235,232,232,232,233,233,233,234,234,234,235,235,235,232,233,234,235,236,232,233,234,235,236,232,233,234,235,236,236,236,236,236,236,236,232,233,234,235,232,233,234,235,236,232,233,234,235,236,232,233,234,235,236,232,233,234,235,236,479,480,481,0,0,0,0,0,0,0,0,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,177,0,0,0,0,0,0,271,14,0,0,271,114,244,14,0,114,244,14,76,76,0,114,14,0,76,0,0,0,0,0,0,0,0,0,114,244,14,0,0,0,0,14,0,0,0,76,0,114,0,0,0,100,26,0,26,26,88,74,74,101,99,88,239,246,87,74,26,65,251,270,271,273,266,24,70,76,80,79,58,247,100,101,99,88,239,246,87,74,26,65,251,270,271,273,266,24,70,76,80,79,58,247,100,101,74,244,80,239,239,80,79,70,88,239,246,87,24,80,79,58,247,100,88,239,246,87,24,80,79,58,247,100,247,247,99,26,26,80,79,70,26,26,88,87,74,24,70,80,58,99,74,239,247,239,239,239,247,247,247,26,65,80,70,74,26,74,26,26,239,251,88,239,246,87,74,26,65,24,70,80,79,58,247,247,100,0,0,0,101,99,88,239,239,239,246,87,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,74,26,65,251,270,271,273,266,24,70,76,76,76,76,76,80,79,58,247,100,65,266,26,26,58,247,88,70,88,70,88,251,26,101,100,239,247,74,26,74,26,74,26,26,65,80,79,80,79,74,26,65,80,79,24,58,239,88,88,70,74,101,99,88,239,246,87,74,26,65,251,270,271,273,266,24,70,76,80,79,58,247,100,74,65,101,270,271,247,74,26,65,26,65,88,239,239,99,88,239,74,79,270,271,273,88,24,74,65,74,65,65,65,26,26,26,100,26,100,26,80,239,251,88,239,87,74,65,251,270,271,273,266,70,79,100,14,114,87,80,79,74,74,247,26,26,241,87,87,26,239,239,246,26,58,80,101,270,271,273,266,76,244,239,88,26,58,79,79,102,99,70,26,65,88,26,88,26,239,239,74,65,65,246,239,58,24,88,88,74,80,79,80,79,239,239,26,88,74,65,79,74,246,76,26,88,239,246,87,24,80,79,58,247,100,247,101,99,88,239,246,87,74,26,65,251,270,271,273,266,24,70,76,80,79,58,247,100,101,99,88,239,246,87,74,26,65,251,270,271,273,266,24,70,76,80,79,58,247,100,101,270,271,273,266,76,101,99,88,239,246,87,74,26,65,251,270,271,273,266,24,70,76,80,79,58,247,100,88,87,87,74,80,79,87,26,80,100,26,80,79,101,99,88,239,246,87,74,26,65,251,270,271,273,266,24,70,76,80,79,58,247,100,74,482,482,482,482,482,483,484,485,0,289,287,287,288,0,292,288,290,291,289,0,287,267,292,382,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,289,289,54,267,0,54,267,0,289,54,267,289,0,292,54,111,382,287,288,267,288,287,289,0,111,69,0,287,288,292,0,0,0,111,0,0,287,288,289,289,54,54,54,69,287,267,289,54,0,0,54,54,28,28,28,285,7,286,111,287,54,288,267,289,290,291,292,69,28,285,7,286,111,287,54,288,267,289,290,291,292,69,284,284,111,111,111,111,28,285,284,284,28,28,285,285,7,7,286,286,111,111,287,287,54,54,288,288,267,267,289,289,290,290,291,291,292,292,69,69,28,28,285,7,7,7,7,7,7,7,7,7,7,286,111,111,287,287,287,287,287,54,54,54,54,54,54,288,288,267,267,267,267,289,289,289,289,289,289,290,291,291,292,292,292,69,285,7,28,285,7,286,111,287,54,288,267,289,290,291,292,69,7,285,285,28,7,111,287,54,288,267,289,290,291,292,285,284,284,287,54,288,267,290,291,292,69,28,285,7,286,111,287,54,288,267,289,290,291,292,69,28,285,7,286,111,287,54,288,267,289,290,291,292,69,28,285,7,286,111,287,54,288,267,289,290,291,292,69,28,285,7,286,111,287,54,288,267,289,290,291,292,69,28,285,7,286,111,287,54,288,267,289,290,291,292,69,486,486,487,488,488,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,306,307,306,308,309,268,307,306,308,309,268,77,307,306,308,309,309,309,309,268,0,307,306,308,309,268,268,268,307,306,308,309,268,309,309,307,268,268,309,307,306,308,309,268,307,306,308,309,268,307,306,308,309,268,307,306,308,309,268,47,47,47,47,47,90,47,47,248,0,90,83,47,0,47,47,47,47,90,47,90,113,113,113,113,113,47,47,47,47,47,0,248,47,47,47,47,47,47,47,47,0,47,47,47,47,47,47,47,47,47,90,83,47,90,47,47,47,90,47,47,47,47,90,47,47,47,47,47,47,47,0,47,47,90,83,47,47,47,47,47,47,47,248,0,47,0,90,90,47,47,109,260,90,47,109,113,83,248,260,90,47,109,113,83,248,109,47,90,47,109,113,83,248,90,47,109,113,83,248,47,113,47,113,90,47,109,113,83,90,90,90,90,90,47,47,109,109,109,113,83,248,90,90,90,47,47,47,109,109,109,113,113,113,83,83,83,248,248,248,260,260,260,90,90,47,47,109,109,113,83,248,260,260,260,260,260,260,260,260,90,90,47,47,109,109,109,113,83,83,83,248,90,47,109,109,90,109,109,90,47,109,47,90,47,109,113,0,109,109,260,90,47,109,113,83,248,109,47,90,47,47,90,47,47,47,113,109,109,109,109,109,109,109,109,109,260,260,90,47,109,113,83,248,260,90,47,109,260,90,90,90,47,47,47,47,109,109,109,109,109,109,109,109,113,83,248,260,90,47,109,113,83,248,260,90,47,109,113,83,248,0,260,90,47,109,113,83,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,349,351,355,0,339,328,276,0,343,326,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,352,276,0,0,0,0,0,0,0,0,352,33,60,328,328,0,328,339,0,338,0,0,321,321,339,356,356,328,276,0,0,0,0,0,0,0,0,0,0,0,276,0,0,0,0,0,339,0,0,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,328,349,351,325,328,0,0,0,0,356,0,330,0,330,338,338,338,338,321,338,338,338,0,338,0,0,0,0,0,0,0,338,338,338,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,338,0,328,355,0,0,0,0,0,0,0,0,0,321,325,321,343,326,328,0,0,0,0,0,0,0,0,0,0,0,330,276,81,320,321,321,321,319,319,320,323,319,276,321,321,324,323,295,300,319,319,320,361,81,328,276,322,329,330,331,332,333,334,335,336,337,338,339,321,324,340,341,342,343,344,345,325,346,347,348,349,350,351,352,353,354,355,326,356,323,295,300,319,320,361,81,328,276,322,329,330,331,332,333,334,335,336,337,338,339,321,324,340,341,342,343,344,345,325,346,347,348,349,350,351,352,353,354,355,326,356,325,326,326,323,81,322,81,323,319,320,81,328,276,322,329,330,331,332,333,334,335,336,337,338,339,321,324,340,341,342,343,344,345,325,346,347,348,349,350,351,352,353,354,355,326,356,323,319,320,81,328,276,322,329,330,331,332,333,334,335,336,337,338,339,321,324,340,341,342,343,344,345,325,346,347,348,349,350,351,352,353,354,355,326,356,320,329,330,341,320,329,330,341,81,81,276,330,325,332,333,334,335,336,337,340,341,342,344,345,347,348,350,353,354,332,333,334,335,336,337,340,341,342,344,345,347,348,350,353,354,324,81,323,319,319,319,319,319,320,320,320,320,320,320,328,276,322,329,330,331,332,333,334,335,336,337,338,339,321,324,340,341,341,342,343,344,345,325,346,347,348,349,350,351,352,353,354,355,326,356,323,323,323,319,319,319,320,320,320,328,328,328,276,276,276,322,322,322,329,329,329,330,330,330,331,331,331,332,332,332,333,333,333,334,334,334,335,335,335,336,336,336,337,337,337,338,338,338,339,339,339,321,321,321,324,324,324,340,340,340,341,341,341,342,342,342,343,343,343,344,344,344,345,345,345,325,325,325,346,346,346,347,347,347,348,348,348,349,349,349,350,350,350,351,351,351,352,352,352,353,353,353,354,354,354,355,355,355,326,326,326,356,356,356,323,323,323,323,323,323,295,295,300,300,319,319,320,361,361,81,328,328,276,322,322,329,329,330,330,331,331,332,332,333,333,334,334,335,335,336,336,337,337,338,338,339,339,321,321,324,324,340,340,341,342,342,343,343,344,344,345,345,325,325,346,346,347,347,348,348,349,349,350,350,351,351,352,352,353,353,354,354,355,355,326,326,356,356,0,344,323,295,300,319,319,320,320,320,320,320,320,320,320,320,320,320,361,81,81,328,276,322,329,329,330,331,332,333,334,335,336,337,338,339,339,321,324,340,341,341,342,343,344,345,325,346,347,348,349,350,351,352,353,354,355,326,356,319,320,0,319,320,320,320,0,324,319,320,323,319,320,320,328,276,329,331,338,341,343,325,346,355,326,356,323,81,81,324,324,81,324,324,324,325,323,319,320,276,325,355,332,344,0,325,332,81,323,295,300,319,320,361,81,328,276,322,329,330,331,332,333,334,335,336,337,338,339,321,324,340,341,342,343,344,345,325,346,347,348,349,350,351,352,353,354,355,326,356,341,355,81,81,323,355,324,320,81,324,321,321,324,324,323,321,320,355,321,321,323,355,331,81,344,332,344,81,322,320,81,81,0,323,331,331,310,276,332,333,334,335,336,337,324,340,341,342,344,345,347,348,349,350,351,352,353,354,326,334,81,331,346,346,346,345,344,324,310,323,276,332,333,334,335,336,337,324,340,341,342,344,345,347,348,349,350,351,352,353,354,326,0,320,320,320,320,320,320,329,330,331,341,341,355,344,344,332,334,335,323,323,323,0,331,332,334,335,323,81,81,81,323,320,346,332,300,346,346,346,346,332,276,323,319,320,81,328,276,322,329,330,331,332,333,334,335,336,337,338,339,321,324,340,341,342,343,344,345,325,346,347,348,349,350,351,352,353,354,355,326,356,356,320,323,295,300,319,361,328,322,329,330,331,332,333,334,335,336,337,338,339,321,324,340,342,343,344,345,325,346,347,348,349,350,351,352,353,354,355,326,356,323,295,300,319,319,319,319,319,319,320,320,320,320,320,320,361,81,328,276,276,322,329,330,330,331,332,333,334,335,336,337,338,339,321,324,340,341,342,343,344,345,325,346,347,348,349,350,351,352,353,354,355,326,356,323,295,300,319,320,361,81,328,276,322,329,330,331,332,333,334,335,336,337,338,339,321,324,340,341,342,343,344,345,325,346,347,348,349,350,351,352,353,354,355,326,356,33,276,332,333,334,335,336,337,324,340,341,342,344,345,347,348,349,350,351,352,353,354,326,60,320,320,276,329,332,333,334,335,336,337,324,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,326,323,295,300,319,320,361,81,328,276,322,329,330,331,332,333,334,335,336,337,338,339,321,324,340,341,342,343,344,345,325,346,347,348,349,350,351,352,353,354,355,326,356,323,322,323,323,323,295,300,319,320,361,81,328,276,322,329,330,331,332,333,334,335,336,337,338,339,321,324,340,341,342,343,344,345,325,346,347,348,349,350,351,352,353,354,355,326,356,346,346,346,346,81,344,331,325,489,489,490,490,0,0,0,0,0,0,367,369,368,358,373,367,369,368,358,373,367,369,368,358,373,367,369,368,358,373,367,369,368,358,373,367,369,368,358,373,367,367,369,368,358,373,367,369,368,358,373,367,369,368,358,373,367,369,368,358,373,367,369,368,358,373,367,369,368,358,373,0,0,318,318,0,0,0,0,0,0,0,317,311,318,317,311,315,318,317,312,316,317,311,312,315,318,316,298,299,317,311,312,315,318,316,298,299,312,311,315,318,311,315,318,312,316,317,317,311,311,311,311,315,315,315,315,318,318,311,311,311,315,315,315,318,318,318,317,317,311,311,312,315,315,318,318,316,298,298,299,299,317,311,312,315,318,316,316,298,298,299,299,311,315,311,315,311,315,318,311,315,318,311,317,311,312,315,318,316,298,299,312,311,311,311,311,315,315,315,315,315,312,316,311,311,315,312,316,311,315,318,317,311,315,318,298,299,317,311,311,311,311,311,312,315,315,315,315,315,315,318,318,318,316,298,299,317,311,312,315,318,316,298,299,317,311,312,315,318,316,298,299,317,311,312,315,318,316,298,299,376,0,0,0,0,0,0,381,0,376,0,381,0,376,375,375,383,384,381,380,375,379,376,377,378,383,384,381,380,375,379,376,377,378,375,376,377,378,375,376,377,378,379,379,380,375,379,376,377,378,380,380,380,379,379,375,379,376,377,378,383,384,381,380,375,379,376,377,378,380,383,384,381,380,375,379,376,377,378,379,383,384,380,375,379,377,383,384,380,375,379,377,378,375,376,377,378,377,383,384,381,380,375,379,376,377,378,383,384,381,380,375,379,376,377,378,383,384,381,380,375,379,376,377,378,383,384,381,380,375,379,376,377,378,0,0,0,385,387,388,387,385,388,387,385,388,385,385,385,387,385,388,387,387,385,388,385,387,385,388,385,0,387,385,0,388,388,0,0,387,385,385,0,0,385,387,385,387,385,388,387,385,388,387,385,388,387,385,388,402,402,402,402,402,402,0,0,0,0,0,0,0,0,402,402,391,393,391,397,392,398,399,393,394,391,397,392,398,399,393,394,392,398,399,394,391,397,398,399,393,397,398,402,402,402,402,391,397,392,398,399,393,394,402,391,397,392,398,399,393,394,398,402,402,402,402,397,392,398,399,394,397,398,402,402,402,402,402,391,397,392,398,399,393,394,402,391,397,392,398,399,393,394,392,394,397,391,392,398,399,393,394,397,402,391,397,392,398,399,393,394,397,392,394,391,392,398,399,393,394,402,402,402,402,402,402,402,392,394,398,398,397,398,398,397,392,397,391,397,392,398,399,393,394,398,398,398,397,397,397,392,399,394,402,392,398,398,392,398,399,394,394,391,393,392,394,392,398,398,392,394,392,394,398,399,398,399,398,399,398,399,398,399,398,399,392,394,392,394,392,394,392,394,392,398,399,394,392,398,399,394,398,399,398,399,398,399,397,398,399,397,397,398,399,397,398,399,398,397,397,392,398,398,398,397,392,397,397,397,397,397,398,391,392,398,399,392,394,402,397,392,398,399,393,394,402,397,398,402,391,391,397,392,392,398,398,399,399,393,393,394,394,402,391,397,392,398,399,393,394,392,398,399,394,398,398,392,394,392,394,392,394,398,399,398,399,398,399,398,399,398,399,398,399,392,394,392,394,391,392,398,402,391,397,392,398,399,393,394,399,402,391,397,392,398,399,393,394,392,398,399,394,0,0,0,0,424,424,424,425,424,425,424,424,424,424,424,424,424,424,425,424,424,425,424,424,424,424,424,425,424,424,425,424,425,0,424,424,424,425,424,425,424,425,424,424,424,425,424,0,0,390,390,427,390,427,390,390,427,427,390,427,390,427,390,390,427,427,390,427,390,0,427,427,390,427,390,427,390,427,390,427,390,0,0,0,0,0,428,428,428,430,431,429,428,430,431,429,428,428,428,428,428,428,428,429,428,428,428,428,428,428,428,430,431,429,428,428,430,431,429,428,431,431,428,0,0,428,430,431,429,431,429,431,428,429,430,428,428,430,431,429,430,430,429,430,430,430,428,430,0,0,428,428,428,430,0,428,428,430,431,429,428,430,431,429,431,428,430,431,429,428,430,431,429,0,0,433,433,433,434,433,434,0,0,0,433,433,0,433,434,434,434,434,434,433,434,433,0,433,433,434,433,434,0,433,433,433,434,434,434,434,433,433,434,0,0,434,0,0,433,433,433,433,0,0,433,433,433,433,433,0,0,433,434,433,434,0,0,433,434,433,433,433,434,433,434,434,271,0,0,0,0,0,0,271,0,0,0,0,0,0,454,0,0,0,0,0,0,0,0,0,454,0,0,435,106,262,417,262,56,262,106,262,436,0,56,106,106,262,262,460,439,440,441,454,449,442,443,452,444,436,445,446,447,448,56,106,262,262,460,439,440,441,454,449,442,443,452,444,436,445,446,447,448,106,262,106,262,262,435,417,435,106,262,417,262,435,106,262,106,262,439,440,441,442,443,444,445,446,447,448,106,262,439,440,441,442,443,444,445,446,447,448,106,262,449,443,436,447,106,262,449,443,436,447,56,444,444,106,435,106,262,435,56,106,262,439,442,444,445,446,448,56,0,106,262,439,441,449,443,452,436,447,262,449,443,452,436,447,439,106,262,106,106,106,106,106,106,106,262,262,262,262,262,262,262,454,449,443,436,447,106,106,106,262,262,262,454,454,454,449,449,449,443,443,443,436,436,436,447,447,447,442,444,445,448,262,262,262,262,56,106,106,106,262,262,262,439,440,441,454,449,449,443,443,452,452,436,436,447,447,262,56,106,106,106,106,106,106,106,106,106,106,106,262,262,262,460,439,439,440,441,454,449,442,443,452,444,436,436,436,445,446,447,448,106,262,262,447,106,460,439,441,454,449,443,452,436,447,106,0,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,439,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,435,417,106,262,0,56,106,262,460,439,440,441,454,449,442,443,452,444,436,445,446,447,448,460,439,441,454,454,449,443,452,436,447,106,106,262,262,106,262,106,106,262,417,442,444,446,0,446,106,262,439,440,446,106,106,106,106,106,106,262,262,262,262,262,262,449,443,436,447,0,440,106,262,460,0,0,417,262,417,262,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,262,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,417,435,0,440,435,106,262,417,262,262,262,0,449,443,452,436,447,106,262,440,454,449,452,0,56,0,440,439,449,452,0,56,262,262,106,262,106,106,262,262,106,262,106,262,262,106,262,435,440,0,440,460,460,106,262,439,440,441,442,443,444,445,446,447,448,449,443,452,436,447,0,106,262,56,106,262,460,439,440,441,454,449,442,443,452,444,436,445,446,447,448,56,106,262,460,439,440,441,454,449,442,443,452,444,436,445,446,447,448,106,262,106,460,56,106,262,460,439,440,441,454,449,442,443,452,444,436,445,446,447,448,262,440,56,106,262,460,439,440,441,454,449,442,443,452,444,436,445,446,447,448,262,262,262,417,262,482,482,482,482,482],"f":"{{}b}0`00`000`````0000```00``````0000`00000000000000000``000000000000```````00`000000000000{{{h{d{f{c}}}}{h{j}}}{{A`{ln}}}{}}0{{{h{{Ab{geci}}}}}{{Af{Ad}}}{{Al{Ah}{{Aj{}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}{{{h{{Ab{geci}}}}}{{Af{{Bl{Ad{h{Bj}}}}}}}{{Al{Ah}{{Aj{}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}{{{h{Bn}}}{{h{C`}}}}{{{Cb{c}}e}{{Cb{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}{}}{{{Cl{c}}e}{{Cl{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}{}}{{{Cn{c}}e}{{Cn{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}{}}{{{h{Bn}}}{{D`{{h{c}}}}}{}}{{{h{db}}c}{{h{db}}}Db}{{{Dd{c}}e}{{Dd{c}}}DfDb}{{{Ab{geci}}Dh}{{Ab{geci}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}{{{Ab{geci}}k}{{Dj{{Ab{geci}}}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}BhDl}0{{{Ab{geci}}kDn}{{Dj{{Ab{geci}}}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}BhDl}{{{Ab{geci}}kE`}{{Dj{{Ab{geci}}}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}BhDl}{{{Ab{geci}}kEb}{{Dj{{Ab{geci}}}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}BhDl}{{{Ab{geci}}kEd}{{Dj{{Ab{geci}}}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}BhDl}{{{Ab{geci}}kEf}{{Dj{{Ab{geci}}}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}BhDl}{{{Ab{geci}}k}{{Dj{{Ab{geci}}}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh{{Ej{Eh}}}}`{{{h{db}}c}{{f{El}}}Bh}{{{h{{f{c}}}}}{{h{c}}}{}}{{{h{c}}}{{h{e}}}{}{}}00000000{{{h{dc}}}{{h{de}}}{}{}}00000000{Enb}{{{h{{Fb{}{{B`{c}}{F`{e}}}}}}g}e{}{{Fd{}{{B`{c}}}}}{}}{{{h{{Fh{}{{Ff{c}}}}}}}{{A`{FjFl}}}{}}{{{Ab{geci}}Fn}{{Ab{geci}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}0{{{h{Bn}}}Bn}{{{h{c}}{h{de}}}l{}{}}{{{Cb{c}}e}{{Cb{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}{{Gb{{h{dG`}}}}}}{{{Cn{c}}e}{{Cn{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}{{Gb{{h{dG`}}}}}}{{{h{Bn}}}{{D`{{h{c}}}}}{}}`{{{h{Bn}}}{{Gf{Gd}}}}{{{h{db}}c}{{h{db}}}Gh}{{{h{{Fh{}{{Ff{c}}}}}}}{{h{Bj}}}{}}{{{h{db}}j}{{h{db}}}}{{{h{Bn}}{h{Bj}}}{{D`{j}}}}`{{{h{Bn}}}{{A`{{Gf{{Af{j}}}}Gj}}}}{{{Df{}{{Gl{c}}}}}{{Dd{{Df{}{{Gl{c}}}}}}}Bh}0{{{Cb{c}}e}{{Cb{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}{}}{{{Cl{c}}e}{{Cl{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}{}}{{{Cn{c}}e}{{Cn{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}{}}{{{Cb{c}}k}{{Cb{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}{}Gn{{Fd{}{{B`{{A`{eg}}}}}}}{{Bb{}{{B`{i}}}}}}{{{Cb{c}}g}{{Cb{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}{{Al{Cd}{{Aj{l}}{H`{Hb}}{Cf{Ch}}}}}{{An{eCd}}}}{{{Cl{c}}g}{{Cl{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}{{Al{Cd}{{Aj{l}}{H`{Hb}}{Cf{Ch}}}}}{{An{eCd}}}}{{{Cn{c}}g}{{Cn{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}{{Al{Cd}{{Aj{l}}{H`{Hb}}{Cf{Ch}}}}}{{An{eCd}}}}{{{h{d{f{c}}}}{h{Bj}}}Hd{}}{{{Cl{c}}g}{{Cl{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}Hf{{Fb{e}}}}``{{{Ab{geci}}}{{Ab{geci}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}{{{h{dBn}}}l}{{{f{c}}}{{f{l}}}{}}{{{h{{Fh{}{{Ff{c}}}}}}}{{A`{{h{Hh}}Hj}}}{}}`{{{h{{f{c}}}}}{{D`{{h{Ch}}}}}{}}{{{h{{Fh{}{{Ff{c}}}}}}}{{Gf{Hl}}}{}}{{{h{b}}}{{Gf{Hl}}}}{{{h{{f{c}}}}}{{Gf{Hl}}}{}}{{{h{Bn}}}{{Gf{Hl}}}}{{{h{{Fh{}{{Ff{c}}}}}}}{{Hn{Hl}}}{}}{{{h{db}}}{{Hn{Hl}}}}{{{h{d{f{c}}}}}{{Hn{Hl}}}{}}{{{h{Bn}}}{{Hn{Hl}}}}{{{Cb{c}}eg}{{Cb{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}{{Ej{Bj}}}{{Ej{Bj}}}}{{{h{Bn}}}c{}}0{{{h{db}}}f}{{{h{{f{c}}}}{h{dI`}}}IbBh}{{{h{Bn}}{h{dI`}}}Ib}{{{h{db}}}{{h{db}}}}{cc{}}000{bf}1{{{Id{c}}}{{f{c}}}{}}{{{Hb{c}}}{{f{c}}}{}}{Chf}4444{c{{f{El}}}{{If{Ch}}}}{{{h{Bn}}{h{dIh}}}c{}}0{{{Cl{c}}g}{{Cl{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}Hf{{Fb{e}}}}``{{{Cl{c}}e}{{Cl{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}Ij}{{Ilc}IlIj}{{{Cn{c}}e}{{Cn{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}Ij}3{{{h{{f{c}}}}}{{h{In}}}{}}{{{h{Bn}}}{{h{J`}}}}`{{{h{d{f{c}}}}}{{h{dIn}}}{}}{{{h{{Fh{}{{Ff{c}}}}}}}{{h{Jb}}}{}}{{{h{{f{c}}}}}{{h{Jb}}}{}}{{{h{Bn}}}{{h{Jb}}}}0{{{h{d{f{c}}}}}{{h{dJb}}}{}}`{{{h{db}}c}{{h{db}}}Db}{{{Dd{c}}e}{{Dd{c}}}DfDb}{ce{}{}}00000000{{{f{c}}}c{}}1{c{}{}}{{{f{c}}}{{Bl{{f{l}}c}}}{}}{{{h{db}}c}fJd}{{{h{db}}}{{h{db}}}}{{{h{{f{c}}}}}Fj{}}{{{Ab{geci}}k}{{Ab{geci}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh{{If{Jf}}}}{{{Ab{geci}}Jh}{{Dj{{Ab{geci}}}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}0{{{Ab{geci}}JhDn}{{Dj{{Ab{geci}}}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}{{{Ab{geci}}JhE`}{{Dj{{Ab{geci}}}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}{{{Ab{geci}}JhEb}{{Dj{{Ab{geci}}}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}{{{Ab{geci}}JhEd}{{Dj{{Ab{geci}}}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}{{{Ab{geci}}JhEf}{{Dj{{Ab{geci}}}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}{{{Ab{geci}}Jj}{{Dj{{Ab{geci}}}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}`{{{f{c}}g}{{f{e}}}{}{}{{Gb{{h{dIn}}c}{{B`{e}}}}}}{{{f{c}}}{{f{El}}}Bh}{{{f{c}}}{{f{{Jl{ce}}}}}{}{}}{{{f{c}}}{{f{{Jl{ec}}}}}{}{}}{{{h{Bn}}}{{h{{K`{Jn}}}}}}{{{h{Bn}}}{{D`{{h{Bj}}}}}}{{{h{Bn}}}{{D`{Kb}}}}{{{Ab{geci}}Hd}{{Ab{geci}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}0{{{h{db}}c}{{A`{{f{c}}Ch}}}{}}{{IlKd}Il}{{{h{Bn}}}{{h{Kd}}}}`{{{h{{Fh{}{{Ff{c}}}}}}}{{A`{{D`{Kf}}Hj}}}{}}{{{Cl{c}}{h{Bj}}}{{Cl{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}}{{}{{Cb{`}}}}{cClKh}{Enb}{En{{f{El}}}}{{}Il}{{{h{Bj}}}Cn}{g{{Ab{geci}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}{{{h{Il}}l}c{}}{{{h{db}}Kj}{{h{db}}}}{{{Ab{geci}}k}{{Ab{geci}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh{{Bb{{h{Kl}}{h{dHl}}}}BdKn}}`{{{Cl{c}}g}{{Cl{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}Hf{{Fb{e}}}}`{{{h{Bn}}}{{h{Bj}}}}{{{h{Bn}}}{{D`{Ad}}}}{{{L`{{h{db}}}}{h{dLb}}}{{Ld{c}}}{}}3`3`2{{{h{db}}{h{Bj}}}{{h{db}}}}{{{Cl{e}}{h{dLf}}}lBh{{Al{Cd}{{Aj{l}}{H`{{Hb{c}}}}{Cf{Ch}}{Cj{l}}}}}}{{{Cn{e}}{h{dLf}}}lBh{{Al{Cd}{{Aj{l}}{H`{{Hb{c}}}}{Cf{Ch}}{Cj{l}}}}}}{{{h{Bn}}}{{h{Lh}}}}{{{Df{}{{Gl{c}}}}{h{Bn}}}{{f{c}}}Bh}{{b{h{Bn}}}{{f{c}}}{}}{{{Dd{c}}{h{Bn}}}{{f{e}}}Df{}}{{{f{c}}{h{Bn}}}{{f{e}}}Bh{}}{{{Cb{c}}{h{Bj}}Il}{{Cb{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}}{{{Cl{c}}Il}{{Cl{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}}{{{Cn{c}}{h{Bj}}Il}{{Cn{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}}```{{{Ab{geci}}}Lj{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}{{{Ab{geci}}k}{{Ab{geci}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh{{Ej{Bj}}}}{{{Cb{c}}e}{{Cb{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}Ll}{{Ile}Il{{If{Ch}}}{{Al{Cd}{{H`{Hb}}{Cf{c}}{Cj{l}}{Aj{l}}}}}}{{{Cn{c}}e}{{Cn{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}Ll}`{{{f{c}}e}{{f{e}}}{}{}}{{{Ab{geci}}Kj}{{Ab{geci}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}{{{h{db}}En}{{h{db}}}}{{{h{{f{c}}}}}En{}}{{{h{d{f{c}}}}}{{h{dEn}}}{}}{{{h{db}}e}f{{If{{M`{Ln}}}}}{{Mf{}{{Mb{{A`{Mdc}}}}}}}}{{{Ab{geci}}}{{Ab{geci}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}{{{h{db}}}b}{{{h{d{Fh{}{{Ff{c}}}}}}}{{Ih{c}}}{}}{{{h{dBn}}}{{Ih{c}}}{}}``{{{Ab{geci}}Fn}{{Ab{geci}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}{{{Cl{c}}g}{{Cl{c}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}Hf{{Fb{e}}}}{{Ile}IlHf{{Fb{c}}}}{{{h{c}}}e{}{}}2`{c{{A`{e}}}{}{}}00000000000000000{{{L`{{h{dc}}}}{h{dLb}}}Ld{}}{{{h{c}}}Mh{}}00000000{{{h{db}}c}{{h{db}}}Gh}{{{h{{f{c}}}}}Fj{}}{{{h{Bn}}}{{h{Mj}}}}{{{h{Bn}}{h{Bj}}e}{{A`{MlMn}}}{{Ej{Bj}}}{{N`{}{{Mb{c}}}}}}{{{h{Bn}}{h{Bj}}}{{A`{MlMn}}}}{{{h{Bn}}}Nb}{ce{}{}}00000000`{{Enc}{{f{c}}}{}}{{{Dd{c}}En}{{Dd{c}}}Df}{{{Ab{geci}}Hd}{{Ab{geci}}}{{Al{Ah}{{Aj{C`}}}}}{{An{cAh}}}{{Bb{}{{B`{e}}}}BdBf}Bh}0{{{Cb{c}}g}{{Cb{{`{{Al{Cd}{{Aj{l}}{H`{{Hb{e}}}}{Cf{Ch}}{Cj{l}}}}}}}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}Bh{{Nd{Cd}{{H`{{Hb{e}}}}{Cf{Ch}}{Cj{l}}}}}}{{{Cl{c}}g}{{Cl{{`{{Al{Cd}{{Aj{l}}{H`{{Hb{e}}}}{Cf{Ch}}{Cj{l}}}}}}}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}Bh{{Nd{Cd}{{H`{{Hb{e}}}}{Cf{Ch}}{Cj{l}}}}}}{{Ile}IlBh{{Nd{{Nf{CdHbCh}}Cd}{{H`{{Hb{c}}}}{Cf{Ch}}{Cj{l}}}}}}{{{Cn{c}}g}{{Cn{{`{{Al{Cd}{{Aj{l}}{H`{{Hb{e}}}}{Cf{Ch}}{Cj{l}}}}}}}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}Bh{{Nd{Cd}{{H`{{Hb{e}}}}{Cf{Ch}}{Cj{l}}}}}}{{{Cb{c}}i}{{Cb{{`{{Al{Cd}{{Aj{l}}{H`{{Hb{e}}}}{Cf{Ch}}{Cj{l}}}}}}}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}Bh{{Fd{}{{B`{{A`{{Hb{e}}Ch}}}}}}}{{Bb{Cdh}{{B`{g}}}}Bf}}{{{Cl{c}}i}{{Cl{{`{{Al{Cd}{{Aj{l}}{H`{{Hb{e}}}}{Cf{Ch}}{Cj{l}}}}}}}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}Bh{{Fd{}{{B`{{A`{{Hb{e}}Ch}}}}}}}{{Bb{Cdh}{{B`{g}}}}Bf}}{{{Cn{c}}i}{{Cn{{`{{Al{Cd}{{Aj{l}}{H`{{Hb{e}}}}{Cf{Ch}}{Cj{l}}}}}}}}}{{Al{Cd}{{Aj{l}}{Cf{Ch}}{Cj{l}}}}}Bh{{Fd{}{{B`{{A`{{Hb{e}}Ch}}}}}}}{{Bb{Cdh}{{B`{g}}}}Bf}}```````````````{{{h{dEl}}}{{L`{{h{dEl}}}}}}{{{h{c}}}{{h{e}}}{}{}}000000{{{h{dc}}}{{h{de}}}{}{}}000000{{{Bh{}{{Cf{c}}}}}El{{If{{M`{Ln}}}}}}{ElEl}{{{Jl{ce}}}ElBhBh}{{{h{{Jl{ce}}}}}{{Jl{ce}}}BfBf}{{{h{Nh}}}Nh}{{{h{Nj}}}Nj}{{{h{c}}{h{de}}}l{}{}}00{{}Nh}{{{h{Nj}}{h{Nj}}}Fj}{{{h{c}}{h{e}}}Fj{}{}}00{{{h{El}}{h{dI`}}}{{A`{lNl}}}}{{{h{{Jl{ce}}}}{h{dI`}}}{{A`{lNl}}}GnGn}{{{h{Nh}}{h{dI`}}}{{A`{lNl}}}}{{{h{Nj}}{h{dI`}}}{{A`{lNl}}}}{{{h{Nn}}{h{dI`}}}{{A`{lNl}}}}0{cc{}}000000{ce{}{}}000000{{{h{Nj}}}Fj}{c{{Jl{ce}}}{}{}}{e{{O`{e}}}{{If{{M`{Ln}}}}}{{Mf{}{{Mb{{A`{Mdc}}}}}}}}{cElBh}{c{{Jl{c}}}{}}>{{Kje}{{Ob{e}}}{{If{{M`{Ln}}}}}{{Mf{}{{Mb{{A`{Mdc}}}}}}}}{{{L`{{h{d{Bh{}{{Cf{c}}}}}}}}{h{dLb}}}{{Ld{{D`{{A`{Mdc}}}}}}}{{If{{M`{Ln}}}}}}{{{L`{{h{d{O`{e}}}}}}{h{dLb}}}{{Ld{{D`{{A`{Md}}}}}}}{{If{M`}}}{{Mf{}{{Mb{{A`{Mdc}}}}}}}}{{{L`{{h{dEl}}}}{h{dLb}}}{{Ld{{D`{{A`{Md}}}}}}}}{{{L`{{h{d{Jl{ce}}}}}}{h{dLb}}}{{Ld{{D`{{A`{Md}}}}}}}BhBh}{{{L`{{h{dNh}}}}{h{dLb}}}{{Ld{{D`{{A`{Md}}}}}}}}{{{L`{{h{d{Ob{e}}}}}}{h{dLb}}}{{Ld{{D`{{A`{Md}}}}}}}{{If{M`}}}{{Mf{}{{Mb{{A`{Mdc}}}}}}}}{c{{Jl{ec}}}{}{}}{{{h{{Bh{}{{Cf{c}}}}}}}Nj{{If{{M`{Ln}}}}}}{{{h{{O`{e}}}}}Nj{{If{{M`{Ln}}}}}{{Mf{}{{Mb{{A`{Mdc}}}}}}}}{{{h{El}}}Nj}{{{h{{Jl{ce}}}}}NjBhBh}{{{h{Nh}}}Nj}{{{h{{Ob{e}}}}}Nj{{If{{M`{Ln}}}}}{{Mf{}{{Mb{{A`{Mdc}}}}}}}}{c{{A`{Md}}}Bh}{{cHd}{{A`{{A`{Md}}Nn}}}Bh}{{{h{c}}}e{}{}}00{{{h{c}}}Kb{}}{c{{A`{e}}}{}{}}0000000000000{{{Bh{}{{Cf{c}}}}}{{A`{Md{Bh{}{{Cf{c}}}}}}}{{If{{M`{Ln}}}}}}{El{{A`{MdEl}}}}{{{Jl{ce}}}{{A`{Md{Jl{ce}}}}}BhBh}{Nh{{A`{MdNh}}}}{{{h{c}}}Mh{}}000000{ce{}{}}000000````````````````````````{{{h{d{Od{c}}}}j}l{{Oh{Of}}}}{{{h{d{Oj{c}}}}j}l{{Oh{Of}}}}{{{h{dOf}}j}l}210{{{h{Gj}}}{{h{Bj}}}}{{{h{c}}}{{h{e}}}{}{}}000000000000{{{h{dc}}}{{h{de}}}{}{}}000000000000{{ce}Ol{{If{{On{Bj}}}}}{{If{{On{Bj}}}}}}{{{h{Ol}}}Ol}{{{h{Gj}}}Gj}{{{h{Of}}}Of}{{{h{A@`}}}A@`}{{{h{A@b}}}A@b}{{{h{A@d}}}A@d}{{{h{j}}}j}{{{h{c}}{h{de}}}l{}{}}000000{A@b{{D`{A@f}}}}{{{h{{Od{c}}}}j}{{D`{j}}}{}}{{}Of}{{{h{Of}}}A@h}{{{h{{A@l{A@j}}}}}A@d}{{{h{Gj}}}{{h{Bj}}}}{{Olc}Ol{{If{{On{Bj}}}}}}{{{h{j}}}{{D`{{h{Bj}}}}}}0{A@nA@n}{{{h{j}}}A@n}{{{h{A@d}}}{{h{{A@l{A@j}}}}}}{{{h{Gj}}{h{Gj}}}Fj}{{{h{A@`}}{h{A@`}}}Fj}{{{h{A@b}}{h{A@b}}}Fj}{{{h{A@d}}{h{A@d}}}Fj}{{{h{j}}{h{j}}}Fj}{{{h{c}}{h{e}}}Fj{}{}}00000000{{Olc}Ol{{If{A@b}}}}{{{h{j}}}{{D`{A@b}}}}{{{h{j}}}{{D`{A@f}}}}{Olj}{{{h{A@n}}{h{dI`}}}{{A`{lNl}}}}{{{h{Ol}}{h{dI`}}}{{A`{lNl}}}}{{{h{Gj}}{h{dI`}}}{{A`{lNl}}}}0{{{h{Of}}{h{dI`}}}{{A`{lNl}}}}{{{h{A@`}}{h{dI`}}}{{A`{lNl}}}}0{{{h{A@b}}{h{dI`}}}{{A`{lNl}}}}{{{h{AA`}}{h{dI`}}}{{A`{lNl}}}}0{{{h{j}}{h{dI`}}}{{A`{lNl}}}}0{{{h{dOf}}{h{j}}}l}{cc{}}00000{AAbGj}1111{cA@b{{If{{D`{A@f}}}}}}2{{{h{{A@l{A@j}}}}}A@d}33{{{h{Bj}}}{{A`{jGj}}}}{{}A@d}{{{h{{Od{c}}}}{h{Bj}}}{{D`{j}}}{{AAd{Of}}}}{{{h{{Oj{c}}}}{h{Bj}}}{{D`{j}}}{{AAd{Of}}}}{{{h{Of}}{h{Bj}}}{{D`{{h{j}}}}}}{{{h{A@`}}{h{dc}}}lAAf}{{{h{A@b}}{h{dc}}}lAAf}{{OlFj}Ol}{{{h{j}}}{{D`{Fj}}}}{ce{}{}}00000000000000{jj}{{{h{A@b}}}Fj}{{{h{A@`}}}Fj}010{{{h{Of}}}AAh}{{{h{dj}}}l}0{{A@bc}A@b{{Gb{A@f}{{B`{A@f}}}}}}{{{h{A@d}}}{{h{{A@l{A@j}}}}}}{{OlAAj}Ol}{{{h{j}}}{{D`{AAj}}}}{{{h{j}}}{{h{Bj}}}}{{{h{j}}}{{D`{{h{Bj}}}}}}{{{h{j}}}{{Bl{{h{Bj}}{h{Bj}}}}}}{cj{{If{{On{Bj}}}}}}{{ce}Ol{{If{{On{Bj}}}}}{{If{{On{Bj}}}}}}{{}Of}{{ce}j{{If{{On{Bj}}}}}{{If{{On{Bj}}}}}}{{{h{dA@h}}}{{D`{{h{j}}}}}}{{{h{dAAh}}}{{D`{{h{j}}}}}}{c{{A`{jGj}}}{{If{{On{Bj}}}}}}0{{Olc}Ol{{If{{On{Bj}}}}}}99{OlOl}{{{h{Of}}{h{A@d}}}{{Od{{h{Of}}}}}}{{{h{dOf}}{h{A@d}}}{{Od{{h{dOf}}}}}}{{{h{d{Od{c}}}}j}l{{Oh{Of}}}}{{{h{d{Oj{c}}}}j}l{{Oh{Of}}}}{{{h{dOf}}j}l}{{{h{dOf}}}l}{{OlA@`}Ol}{{{h{j}}}{{D`{A@`}}}}{{OlFj}Ol}{{{h{j}}}{{D`{Fj}}}}{{{h{dj}}c}l{{If{{On{Bj}}}}}}{{{h{dj}}c}l{{If{A@b}}}}{{{h{dj}}c}l{{If{{D`{Fj}}}}}}{{{h{dj}}c}l{{If{{D`{AAj}}}}}}33{{{h{dj}}c}l{{If{{D`{A@`}}}}}}24{{{h{Of}}{h{A@d}}}{{Oj{{h{Of}}}}}}{{{h{dOf}}{h{A@d}}}{{Oj{{h{dOf}}}}}}{{{h{A@d}}}{{h{{A@l{A@j}}}}}}{A@nA@n}{{{h{j}}}A@n}{{{h{c}}}e{}{}}000000{{{h{c}}}Kb{}}0000{c{{A`{e}}}{}{}}0000000000{{{h{{A@l{A@j}}}}}{{A`{A@d}}}}11{{}{{D`{A@d}}}}2222222222222{{{h{c}}}Mh{}}000000000000{{{h{dj}}}l}00{{{h{j}}}{{h{Bj}}}}{{{h{j}}}{{D`{{h{Bj}}}}}}{{{h{{Oj{c}}}}j}{{D`{j}}}{}}{ce{}{}}000000000000```````````````````````````````````````````````````````````{AAjAAj}{{AAlFn}}{{AAlAAj}}{{AAjFn}}{{AAjAAj}}{{AAnAAj}}{{AAnFn}}{{A@fFn}}{{A@fAAj}}{{AB`AAj}}{{AB`Fn}}{{ABbAAj}}{{ABbFn}}{{{h{dAAl}}Fn}l}{{{h{dAAl}}AAj}l}{{{h{dAAj}}Fn}l}{{{h{dAAj}}AAj}l}{{{h{dAAn}}Fn}l}{{{h{dAAn}}AAj}l}{{{h{dA@f}}Fn}l}{{{h{dA@f}}AAj}l}{{{h{dAB`}}AAj}l}{{{h{dAB`}}Fn}l}{{{h{dABb}}Fn}l}{{{h{dABb}}AAj}l}{AB`{{Bl{A@jA@jA@j}}}}{ABb{{Bl{A@jA@jA@j}}}}{ABd{{Bl{ABfABfABf}}}}{AB`{{Bl{A@jA@jA@jDh}}}}{ABb{{Bl{A@jA@jA@jDh}}}}{AB`{{Bl{A@jA@jA@jABh}}}}{ABb{{Bl{A@jA@jA@jABh}}}}32{{{h{AAn}}}{{h{ABj}}}}{AAjABl}{AAjABn}{{AB`ABd}A@f}{AB`A@f}{{{h{c}}}{{h{e}}}{}{}}0005000000{{{h{dc}}}{{h{de}}}{}{}}000000000{{AAlAAj}{{D`{AAl}}}}{{AAjAAj}{{D`{AAj}}}}{{AAnAAj}{{D`{AAn}}}}{{A@fAAj}{{D`{A@f}}}}{{AB`AAj}{{D`{AB`}}}}{{AAlFn}{{D`{AAl}}}}{{AAjAC`}{{D`{AAj}}}}0{AAj{{D`{AAj}}}}{ABl{{D`{AAj}}}}{ABn{{D`{AAj}}}}987654{{A@fABd}{{D`{A@f}}}}{{{h{AAl}}}AAl}{{{h{AAj}}}AAj}{{{h{AAn}}}AAn}{{{h{ACb}}}ACb}{{{h{A@f}}}A@f}{{{h{AB`}}}AB`}{{{h{ABb}}}ABb}{{{h{ABd}}}ABd}{{{h{ACd}}}ACd}{{{h{c}}{h{de}}}l{}{}}00000000{{{h{AAl}}{h{AAl}}}ACf}{{{h{AAj}}{h{AAj}}}ACf}{{{h{AAn}}{h{AAn}}}ACf}{{{h{A@f}}{h{A@f}}}ACf}{{{h{AB`}}{h{AB`}}}ACf}{{{h{ABb}}{h{ABb}}}ACf}{{{h{ABd}}{h{ABd}}}ACf}{{{h{c}}{h{e}}}ACf{}{}}000000`{A@fAAl}{AB`AAl}{AAlA@j}{A@fA@j}{AB`A@j}{AChAAj}{{}AAj}{{AAjAAj}}{{AAjA@j}}{{AAjABh}}{{AAjFn}}{{AAjABn}}{{AAjDh}}{{AAjABf}}{{AAjABl}}{{AAjAC`}}{{AAjACj}}{{{h{dAAj}}ABf}l}{{{h{dAAj}}A@j}l}{{{h{dAAj}}Dh}l}{{{h{dAAj}}ABl}l}{{{h{dAAj}}ABn}l}{{{h{dAAj}}ABh}l}{{{h{dAAj}}AC`}l}{{{h{dAAj}}ACj}l}{AAnAAj}{{{h{AAl}}{h{AAl}}}Fj}{{{h{AAj}}{h{Fn}}}Fj}{{{h{AAj}}{h{AAj}}}Fj}{{{h{AAn}}{h{ABj}}}Fj}{{{h{AAn}}{h{AAn}}}Fj}{{{h{ACb}}{h{ACb}}}Fj}{{{h{A@f}}{h{A@f}}}Fj}{{{h{A@f}}{h{ACl}}}Fj}{{{h{AB`}}{h{AB`}}}Fj}{{{h{ABb}}{h{ABb}}}Fj}{{{h{ABd}}{h{ABd}}}Fj}{{{h{ACd}}{h{ACd}}}Fj}{{{h{c}}{h{e}}}Fj{}{}}00000000000000000000000000``{{{h{AAl}}{h{dI`}}}{{A`{lNl}}}}0{{{h{AAj}}{h{dI`}}}{{A`{lNl}}}}0{{{h{ACn}}{h{dI`}}}{{A`{lNl}}}}0{{{h{AAn}}{h{dI`}}}{{A`{lNl}}}}{{{h{ACb}}{h{dI`}}}{{A`{lNl}}}}00{{{h{A@f}}{h{dI`}}}{{A`{lNl}}}}0{{{h{AB`}}{h{dI`}}}{{A`{lNl}}}}0{{{h{ABb}}{h{dI`}}}{{A`{lNl}}}}0{{{h{ABd}}{h{dI`}}}{{A`{lNl}}}}0{{{h{ACd}}{h{dI`}}}{{A`{lNl}}}}00{{{h{AAl}}{h{dI`}}{AD`{AAl}}}{{A`{lNl}}}}{{{h{A@f}}{h{dI`}}{AD`{A@f}}}{{A`{lNl}}}}{{{h{AB`}}{h{dI`}}{AD`{AB`}}}{{A`{lNl}}}}{{{h{ABb}}{h{dI`}}{AD`{ABb}}}{{A`{lNl}}}}{{{h{ABd}}{h{dI`}}{AD`{ABd}}}{{A`{lNl}}}}{{AAl{h{c}}}{{A`{KbADb}}}{ADdADf}}{{A@f{h{c}}}{{A`{KbADb}}}{ADdADf}}{{AB`{h{c}}}{{A`{KbADb}}}{ADdADf}}{{ABb{h{c}}}{{A`{KbADb}}}{ADdADf}}{{ABd{h{c}}}{{A`{KbADb}}}{ADdADf}}`{{AAl{h{dc}}{h{e}}}{{A`{HdADb}}}ADh{ADdADf}}{{A@f{h{dc}}{h{e}}}{{A`{HdADb}}}ADh{ADdADf}}{{AB`{h{dc}}{h{e}}}{{A`{HdADb}}}ADh{ADdADf}}{{ABb{h{dc}}{h{e}}}{{A`{HdADb}}}ADh{ADdADf}}{{ABd{h{dc}}{h{e}}}{{A`{HdADb}}}ADh{ADdADf}}`{cc{}}0{ADjACn}{ADlACn}{ADnACn}{ADbACn}{AE`ACn}5{AEbACn}{AEdACn}{AEfACn}{AEhACn}{ABjAAn}:::{AClA@f};;;;{{AC`ACbA@j}{{A`{AAlADn}}}}{{A@jA@jA@j}{{A`{ABbADn}}}}{{ABfABfABf}{{A`{ABdADn}}}}{{A@jA@jA@jDh}{{A`{ABbADn}}}}{{A@jA@jA@jABh}{{A`{ABbADn}}}}1{{AC`A@jACd}{{A`{AAlADn}}}}{AC`{{A`{AAlADn}}}}{{AC`ABh}{{A`{AAlADn}}}}{{{h{Bj}}}{{A`{ACb}}}}{{{h{Bj}}}{{A`{ACd}}}}{ACh{{A`{A@fADn}}}}{AEj{{A`{A@fADn}}}}{AC`{{A`{ABdADn}}}}{{{h{AAl}}{h{dc}}}lAAf}{{{h{AAj}}{h{dc}}}lAAf}{{{h{AAn}}{h{dc}}}lAAf}{{{h{ACb}}{h{dc}}}lAAf}{{{h{A@f}}{h{dc}}}lAAf}{{{h{AB`}}{h{dc}}}lAAf}{{{h{ABb}}{h{dc}}}lAAf}{{{h{ABd}}{h{dc}}}lAAf}{{{h{ACd}}{h{dc}}}lAAf}{A@fA@j}{AB`A@j}{ABbA@j}{AChAAj}{ce{}{}}000000000{AAnABj}{AAjFj}{ABdFj}1001{AAlA@j}87`{{{h{AAl}}AEl}{{AD`{AAl}}}}{{{h{ACb}}AEl}{{AD`{ACb}}}}{{{h{A@f}}AEl}{{AD`{A@f}}}}{{{h{AB`}}AEl}{{AD`{AB`}}}}{{{h{ABb}}AEl}{{AD`{ABb}}}}{{{h{ABd}}AEl}{{AD`{ABd}}}}{{{h{ACd}}AEl}{{AD`{ACd}}}}{A@fDh}{AB`Dh}{ABbDh}?{AAlAB`}{A@fABh}{AB`ABh}{ABbABh}{AChAAj}{A@fA@j}{AB`A@j}{ABbA@j}3{ABdABf}{AAlA@j}43{AAlACb}{A@fACb}{AB`ACb}{{AAjABl}}{{AAjACj}}{{AAjABn}}{{AAjA@j}}{{AAjABf}}{{AAjDh}}{{AAjAC`}}{{AAjABh}}{{{h{dAAj}}ACj}l}{{{h{dAAj}}AC`}l}{{{h{dAAj}}Dh}l}{{{h{dAAj}}ABh}l}{{{h{dAAj}}A@j}l}{{{h{dAAj}}ABn}l}{{{h{dAAj}}ABf}l}{{{h{dAAj}}ABl}l}{A@fDh}{AB`Dh}{ABbDh}{AChAAj}{AAj}{ABd}{{AChAC`}AAj}{{AAlABb}AB`}{{AAlABbABd}A@f}{{AAlABb}A@f}{ACbACb}{ACdACd}{AAl{{D`{AAl}}}}{{AAlACd}AAl}{{}AAn}{{}A@f}{{ACbA@j}ACb}{{ACdA@j}ACd}{{AAlACdA@j}AAl}210{ACdA@j}000{A@fABd}{AAlABh}{A@fABh}{AB`ABh}{{{h{Bj}}{h{c}}}{{A`{AAlADj}}}{AEnADf}}{{{h{Bj}}{h{c}}}{{A`{A@fADj}}}{AEnADf}}{{{h{Bj}}{h{c}}}{{A`{AB`ADj}}}{AEnADf}}{{{h{Bj}}{h{c}}}{{A`{ABbADj}}}{AEnADf}}{{{h{Bj}}{h{c}}}{{A`{ABdADj}}}{AEnADf}}`{{{h{AAl}}{h{AAl}}}{{D`{ACf}}}}{{{h{AAj}}{h{AAj}}}{{D`{ACf}}}}{{{h{AAj}}{h{Fn}}}{{D`{ACf}}}}{{{h{AAn}}{h{ABj}}}{{D`{ACf}}}}{{{h{AAn}}{h{AAn}}}{{D`{ACf}}}}{{{h{A@f}}{h{A@f}}}{{D`{ACf}}}}{{{h{A@f}}{h{ACl}}}{{D`{ACf}}}}{{{h{AB`}}{h{AB`}}}{{D`{ACf}}}}{{{h{ABb}}{h{ABb}}}{{D`{ACf}}}}{{{h{ABd}}{h{ABd}}}{{D`{ACf}}}}{{AAlACd}AAl}{ACbACb}{ACdACd}{AAl{{D`{AAl}}}}{{A@fAAl}A@f}{{AB`AAl}AB`}{{A@fAB`}A@f}{{AAlA@j}{{A`{AAlADn}}}}{{A@fA@j}{{A`{A@fADn}}}}{{AB`A@j}{{A`{AB`ADn}}}}10{{ABbA@j}{{A`{ABbADn}}}}{{A@fDh}{{A`{A@fADn}}}}{{AB`Dh}{{A`{AB`ADn}}}}{{ABbDh}{{A`{ABbADn}}}}{{A@fABh}{{A`{A@fADn}}}}{{AB`ABh}{{A`{AB`ADn}}}}{{ABbABh}{{A`{ABbADn}}}}876{{AAlACb}{{A`{AAlADn}}}}{{A@fACb}{{A`{A@fADn}}}}{{AB`ACb}{{A`{AB`ADn}}}}876{{A@fABd}A@f}{{AAlABh}{{A`{AAlADn}}}}76=<;{{A@fABb}A@f}{{AB`ABb}AB`}{{AAlAC`}{{A`{AAlADn}}}}{{A@fAC`}{{A`{A@fADn}}}}{{AB`AC`}{{A`{AB`ADn}}}}{{AAlAAj}AAl}{{AAjAAj}AAj}{{A@fAAj}A@f}{{AB`AAj}AB`}{{AAjAC`}AAj}{ABlAAj}{ABnAAj}6543{A@fA@j}{AB`A@j}{ABbA@j}{AChAAj}54{ABdABf}{{{h{ACn}}}{{D`{{h{Ln}}}}}}{{AAlAAj}}{{AAlAAl}}{{AAlFn}}{{AAjAAj}}{{AAjFn}}{{AAnAAj}}{{AAnABj}}{{AAnAAn}}{{AAnFn}}{{A@fACl}}{{A@fFn}}{{A@fAAj}}{{A@fA@f}}{{AB`AB`}}{{AB`Fn}}{{AB`AAj}}{{ABbABb}}{{ABbFn}}{{ABbAAj}}{{{h{dAAl}}Fn}l}{{{h{dAAl}}AAj}l}{{{h{dAAj}}Fn}l}{{{h{dAAj}}AAj}l}{{{h{dAAn}}Fn}l}{{{h{dAAn}}AAj}l}{{{h{dA@f}}Fn}l}{{{h{dA@f}}AAj}l}{{{h{dAB`}}AAj}l}{{{h{dAB`}}Fn}l}{{{h{dABb}}Fn}l}{{{h{dABb}}AAj}l}{AAjAC`}{AAjACj}1{cAAj{{AF`{}{{Mb{AAj}}}}}}{cAAj{{AF`{}{{Mb{{h{AAj}}}}}}}}{AAlA@j}{A@fA@j}{AB`A@j}{A@fABb}{AB`ABb}{e{{Bl{AAjc}}}{}{{Gb{}{{B`{c}}}}}}{AAl{{Bl{AC`ACbA@j}}}}{A@f{{Bl{AC`ACbA@j}}}}{AB`{{Bl{AC`ACbA@j}}}}{A@f{{Bl{A@jA@jA@j}}}}{A@f{{Bl{A@jA@jA@jDh}}}}{A@f{{Bl{A@jA@jA@jABh}}}}1{AAl{{Bl{AC`A@jACd}}}}{A@f{{Bl{AC`A@jACd}}}}{AB`{{Bl{AC`A@jACd}}}}{AAlAC`}{A@fAC`}{AB`AC`}{{A@fABd}A@f}{AAl{{Bl{AC`ABh}}}}{A@f{{Bl{AC`ABh}}}}{AB`{{Bl{AC`ABh}}}}{{{h{c}}}e{}{}}00000000{{{h{c}}}Kb{}}00000000{AFb{{A`{AAl}}}}{c{{A`{e}}}{}{}}{Fn{{A`{AAjADl}}}}111{A@j{{A`{ACb}}}}22{AFb{{A`{A@f}}}}{AFb{{A`{AB`}}}}4{AFb{{A`{ABb}}}}5{AFb{{A`{ABd}}}}666666666666{{{h{c}}}Mh{}}000000000{A@fACh}{A@fAEj}{AAjFn}`{ce{}{}}000000000{AAlACd}{A@fACd}{AB`ACd}{AChAAj}{AAjACh}0{ABdABf}{AAjAEj}02{ABdACj}13{ABdAC`}4{{AAlA@jA@jA@j}{{A`{AB`ADn}}}}{{AAlA@jA@jA@jDh}{{A`{AB`ADn}}}}{{AAlA@jA@jA@jABh}{{A`{AB`ADn}}}}1{{AAlABb}AB`}{AAlAC`}{A@fAC`}{AB`AC`}````````{{{h{c}}}{{h{e}}}{}{}}0000000{{{h{dc}}}{{h{de}}}{}{}}0000000{{{h{AFd}}}AFd}{{{h{AFf}}}AFf}{{{h{AFh}}}AFh}{{{h{AFj}}}AFj}{{{h{AFl}}}AFl}{{{h{AFn}}}AFn}{{{h{AG`}}}AG`}{{{h{AGb}}}AGb}{{{h{c}}{h{de}}}l{}{}}0000000{{{h{AFd}}{h{dI`}}}{{A`{lNl}}}}{{{h{AFf}}{h{dI`}}}{{A`{lNl}}}}{{{h{AFh}}{h{dI`}}}{{A`{lNl}}}}{{{h{AFj}}{h{dI`}}}{{A`{lNl}}}}{{{h{AFl}}{h{dI`}}}{{A`{lNl}}}}{{{h{AFn}}{h{dI`}}}{{A`{lNl}}}}{{{h{AG`}}{h{dI`}}}{{A`{lNl}}}}{{{h{AGb}}{h{dI`}}}{{A`{lNl}}}}{cc{}}0000000{ce{}{}}0000000{c{}AGd}0000000{{{h{c}}}e{}{}}0000000{c{{A`{e}}}{}{}}000000000000000{{{h{c}}}Mh{}}000000044444444`````````````````````````````````````{{{h{c}}}{{h{e}}}{}{}}00000000{{{h{dc}}}{{h{de}}}{}{}}00000000{{{h{ADn}}}ADn}{{{h{ADl}}}ADl}{{{h{AEh}}}AEh}{{{h{AE`}}}AE`}{{{h{AEf}}}AEf}{{{h{ADj}}}ADj}{{{h{AEd}}}AEd}{{{h{AEb}}}AEb}{{{h{c}}{h{de}}}l{}{}}0000000{{{h{ADn}}{h{ADn}}}Fj}{{{h{ADl}}{h{ADl}}}Fj}{{{h{AEh}}{h{AEh}}}Fj}{{{h{AE`}}{h{AE`}}}Fj}{{{h{AEf}}{h{AEf}}}Fj}{{{h{ADj}}{h{ADj}}}Fj}{{{h{AEd}}{h{AEd}}}Fj}{{{h{AEb}}{h{AEb}}}Fj}{{{h{c}}{h{e}}}Fj{}{}}00000000000000000000000{{{h{ADn}}{h{dI`}}}{{A`{lNl}}}}0{{{h{ADl}}{h{dI`}}}{{A`{lNl}}}}0{{{h{AEh}}{h{dI`}}}{{A`{lNl}}}}0{{{h{ADb}}{h{dI`}}}{{A`{lNl}}}}0{{{h{AE`}}{h{dI`}}}{{A`{lNl}}}}0{{{h{AEf}}{h{dI`}}}{{A`{lNl}}}}0{{{h{ADj}}{h{dI`}}}{{A`{lNl}}}}0{{{h{AEd}}{h{dI`}}}{{A`{lNl}}}}0{{{h{AEb}}{h{dI`}}}{{A`{lNl}}}}0{cc{}}000{AGfADb}1{AGhAE`}2{AEbADj}{AEdADj}44{ADnAEb}5{{{h{ADn}}{h{dc}}}lAAf}{ce{}{}}00000000{ADnFj}{ADn{{h{Bj}}}}{{{h{ADb}}}{{D`{{h{Ln}}}}}}{{{h{ADj}}}{{D`{{h{Ln}}}}}}{{{h{AEb}}}{{D`{{h{Ln}}}}}}{{{h{c}}}e{}{}}0000000{{{h{c}}}Kb{}}00000000{c{{A`{e}}}{}{}}{AEb{{A`{ADn}}}}{ACn{{A`{ADn}}}}2{ACn{{A`{ADl}}}}{ACn{{A`{AEh}}}}44{ACn{{A`{ADb}}}}5{ACn{{A`{AE`}}}}6{ACn{{A`{AEf}}}}7{ACn{{A`{ADj}}}}{ACn{{A`{AEd}}}}9{ADj{{A`{AEd}}}}{ADj{{A`{AEb}}}};{ACn{{A`{AEb}}}}<<<<<<<<<{{{h{c}}}Mh{}}00000000{ce{}{}}00000000````````````````{{AGjAAj}AGj}{{{h{AGj}}AAj}{{D`{AGj}}}}0{AGlAAj}000000{{{h{AGj}}AGj}AAj}{AGnFn}000000042````````````````````````````````````{{{h{c}}}{{h{e}}}{}{}}00{{{h{dc}}}{{h{de}}}{}{}}00{{{h{AH`}}}AH`}{{{h{AHb}}}AHb}{{{h{AHd}}}AHd}{{{h{c}}{h{de}}}l{}{}}00{{{h{AH`}}{h{AH`}}}Fj}{{{h{AH`}}{h{AHb}}}Fj}{{{h{AH`}}{h{{h{{A@l{AH`}}}}}}}Fj}{{{h{AHb}}{h{AHb}}}Fj}{{{h{AHb}}{h{AH`}}}Fj}{{{h{AHb}}{h{AHd}}}Fj}{{{h{AHd}}{h{{h{{A@l{AHd}}}}}}}Fj}{{{h{AHd}}{h{AHd}}}Fj}{{{h{AHd}}{h{AHb}}}Fj}{{{h{c}}{h{e}}}Fj{}{}}00000000{{{h{AH`}}{h{dI`}}}{{A`{lNl}}}}{{{h{AHb}}{h{dI`}}}{{A`{lNl}}}}{{{h{AHd}}{h{dI`}}}{{A`{lNl}}}}{AHbAH`}{cc{}}{{{h{{A@l{AH`}}}}}AH`}{AHfAHb}22{AH`AHd}{{{h{AH`}}}AHd}{AHbAHd}{{{h{c}}}AHd{{Ej{{A@l{AH`}}}}ADf}}{{{Af{AH`}}}AHd}{{{M`{{A@l{AHh}}}}}AHd}{AHhAHd}{{{Af{AHd}}}AHd}{ce{}{}}00`{{{h{Bj}}}{{A`{{Af{AH`}}AE`}}}}0{{{h{Bj}}}{{A`{AHdAE`}}}}{{{h{c}}}e{}{}}00{c{{A`{e}}}{}{}}{AHh{{A`{AH`}}}}1{AHd{{A`{AHb}}}}{AH`{{A`{AHb}}}}3333{{{h{c}}}Mh{}}00888``````````````````````````````````````````````````````{{{h{c}}}{{h{e}}}{}{}}00000000000000000000000{{{h{dc}}}{{h{de}}}{}{}}00000000000000000000000```{{{h{AHj}}}AHj}{{{h{AHl}}}AHl}{{{h{AHn}}}AHn}{{{h{AI`}}}AI`}{{{h{AIb}}}AIb}{{{h{AId}}}AId}{{{h{AIf}}}AIf}{{{h{AIh}}}AIh}{{{h{AIj}}}AIj}{{{h{AIl}}}AIl}{{{h{AIn}}}AIn}{{{h{AJ`}}}AJ`}{{{h{AJb}}}AJb}{{{h{AJd}}}AJd}{{{h{AJf}}}AJf}{{{h{AJh}}}AJh}{{{h{AJj}}}AJj}{{{h{AJl}}}AJl}{{{h{AJn}}}AJn}{{{h{AK`}}}AK`}{{{h{AKb}}}AKb}{{{h{AKd}}}AKd}{{{h{AKf}}}AKf}{{{h{AKh}}}AKh}{{{h{c}}{h{de}}}l{}{}}00000000000000000000000{{{AKj{ABh}}}AKb}`{{}AHj}0{{}AHl}{{}AHn}0{{}AI`}0{{}AIb}{{}AId}0{{}AIf}{{}AIh}0{{}AIj}{{}AIl}0{{}AIn}0{{}AJ`}0{{}AJb}0{{}AJd}0{{}AJf}{{}AJh}0{{}AJj}0{{}AJl}0{{}AJn}0{{}AK`}{{}AKd}{{}AKf}0{{}AKh}0`{{{h{AHj}}{h{AHj}}}Fj}{{{h{AHl}}{h{AHl}}}Fj}{{{h{AHn}}{h{AHn}}}Fj}{{{h{AI`}}{h{AI`}}}Fj}{{{h{AIb}}{h{AIb}}}Fj}{{{h{AId}}{h{AId}}}Fj}{{{h{AIf}}{h{AIf}}}Fj}{{{h{AIh}}{h{AIh}}}Fj}{{{h{AIj}}{h{AIj}}}Fj}{{{h{AIl}}{h{AIl}}}Fj}{{{h{AIn}}{h{AIn}}}Fj}{{{h{AJ`}}{h{AJ`}}}Fj}{{{h{AJb}}{h{AJb}}}Fj}{{{h{AJd}}{h{AJd}}}Fj}{{{h{AJf}}{h{AJf}}}Fj}{{{h{AJh}}{h{AJh}}}Fj}{{{h{AJj}}{h{AJj}}}Fj}{{{h{AJl}}{h{AJl}}}Fj}{{{h{AJn}}{h{AJn}}}Fj}{{{h{AK`}}{h{AK`}}}Fj}{{{h{AKb}}{h{AKb}}}Fj}{{{h{AKd}}{h{AKd}}}Fj}{{{h{AKf}}{h{AKf}}}Fj}{{{h{AKh}}{h{AKh}}}Fj}{{{h{c}}{h{e}}}Fj{}{}}00000000000000000000000000000000000000000000000000000000000000000000000{{{h{AHj}}{h{dI`}}}{{A`{lNl}}}}{{{h{AHl}}{h{dI`}}}{{A`{lNl}}}}{{{h{AHn}}{h{dI`}}}{{A`{lNl}}}}{{{h{AI`}}{h{dI`}}}{{A`{lNl}}}}{{{h{AIb}}{h{dI`}}}{{A`{lNl}}}}{{{h{AId}}{h{dI`}}}{{A`{lNl}}}}{{{h{AIf}}{h{dI`}}}{{A`{lNl}}}}{{{h{AIh}}{h{dI`}}}{{A`{lNl}}}}{{{h{AIj}}{h{dI`}}}{{A`{lNl}}}}{{{h{AIl}}{h{dI`}}}{{A`{lNl}}}}{{{h{AIn}}{h{dI`}}}{{A`{lNl}}}}{{{h{AJ`}}{h{dI`}}}{{A`{lNl}}}}{{{h{AJb}}{h{dI`}}}{{A`{lNl}}}}{{{h{AJd}}{h{dI`}}}{{A`{lNl}}}}{{{h{AJf}}{h{dI`}}}{{A`{lNl}}}}{{{h{AJh}}{h{dI`}}}{{A`{lNl}}}}{{{h{AJj}}{h{dI`}}}{{A`{lNl}}}}{{{h{AJl}}{h{dI`}}}{{A`{lNl}}}}{{{h{AJn}}{h{dI`}}}{{A`{lNl}}}}{{{h{AK`}}{h{dI`}}}{{A`{lNl}}}}{{{h{AKb}}{h{dI`}}}{{A`{lNl}}}}{{{h{AKd}}{h{dI`}}}{{A`{lNl}}}}{{{h{AKf}}{h{dI`}}}{{A`{lNl}}}}{{{h{AKh}}{h{dI`}}}{{A`{lNl}}}}{cc{}}{AKlAHl}1111{AKnAIb}22{AL`AIf}3{ALbAIj}444444{ALdAJf}55555{ALfAK`}666{ALhAKd}77{ce{}{}}00000000000000000000000```````````````````````{{{h{c}}}e{}{}}00000000000000000000000{c{{A`{e}}}{}{}}00000000000000000000000000000000000000000000000{{{h{c}}}Mh{}}00000000000000000000000333333333333333333333333```````````{{{h{c}}}{{h{e}}}{}{}}00{{{h{dc}}}{{h{de}}}{}{}}00{{{h{ALj}}}ALj}{{{h{ALl}}}ALl}{{{h{ALn}}}ALn}{{{h{c}}{h{de}}}l{}{}}00{{{h{ALj}}{h{ALj}}}Fj}{{{h{ALl}}{h{ALl}}}Fj}{{{h{ALn}}{h{ALn}}}Fj}{{{h{c}}{h{e}}}Fj{}{}}00000000{{{h{ALj}}{h{dI`}}}{{A`{lNl}}}}{{{h{ALl}}{h{dI`}}}{{A`{lNl}}}}{{{h{ALn}}{h{dI`}}}{{A`{lNl}}}}{cc{}}00{ce{}{}}00`{{{h{c}}}e{}{}}00{c{{A`{e}}}{}{}}00000{{{h{c}}}Mh{}}00333```````````````````````{{{h{c}}}{{h{e}}}{}{}}0000{{{h{dc}}}{{h{de}}}{}{}}0000{{{h{AM`}}}AM`}{{{h{AMb}}}AMb}{{{h{AMd}}}AMd}{{{h{AMf}}}AMf}{{{h{c}}{h{de}}}l{}{}}000{{{h{AMh}}}AMj}{{{h{AM`}}{h{AM`}}}Fj}{{{h{AMb}}{h{AMb}}}Fj}{{{h{AMd}}{h{AMd}}}Fj}{{{h{AMf}}{h{AMf}}}Fj}{{{h{c}}{h{e}}}Fj{}{}}00000000000{{{h{AM`}}{h{dI`}}}{{A`{lNl}}}}{{{h{AMb}}{h{dI`}}}{{A`{lNl}}}}{{{h{AMd}}{h{dI`}}}{{A`{lNl}}}}{{{h{AMf}}{h{dI`}}}{{A`{lNl}}}}{{{h{AMh}}{h{dI`}}}{{A`{lNl}}}}{cc{}}0000{ce{}{}}0000{{AMhAMb}AMh}{{AMhAM`}AMh}{{AMhAMf}AMh}{{AMhAMd}AMh}{{AMhFj}AMh}0{{{h{c}}}e{}{}}000{c{{A`{e}}}{}{}}000000000{{{h{c}}}Mh{}}000088888```````````{{{h{c}}}{{h{e}}}{}{}}{{{h{dc}}}{{h{de}}}{}{}}{{{h{AFb}}}AFb}{{{h{c}}{h{de}}}l{}{}}{{{h{AFb}}}{{D`{{AKj{A@j}}}}}}{{}AFb}{{{h{AFb}}{h{dI`}}}{{A`{lNl}}}}{cc{}}3{{{h{AFb}}}{{D`{Fj}}}}{{{h{AFb}}}{{D`{A@j}}}}{ce{}{}}6{{{h{AFb}}}{{D`{AC`}}}}222{{{h{AFb}}}{{D`{ACb}}}}7{{{h{AFb}}}{{D`{ABf}}}}00{{{h{AFb}}}{{D`{{AKj{ABh}}}}}}{{{h{dAFb}}{h{{A@l{A@j}}}}AHb}{{A`{{h{{A@l{A@j}}}}AEd}}}}{{{h{dAFb}}{h{{A@l{A@j}}}}{h{c}}}{{A`{{h{{A@l{A@j}}}}AEd}}}AMl}{{{h{dAFb}}{h{{A@l{A@j}}}}{h{{A@l{c}}}}}{{A`{{h{{A@l{A@j}}}}AEd}}}AMl}{{{h{{A@l{A@j}}}}{h{{A@l{A@j}}}}}{{A`{{h{{A@l{A@j}}}}AEd}}}}9{{{h{dAFb}}{AKj{A@j}}}{{D`{l}}}}0{{{h{dAFb}}Fj}{{D`{l}}}}{{{h{dAFb}}A@j}{{D`{l}}}}2{{{h{dAFb}}AC`}{{D`{l}}}}111{{{h{dAFb}}ACb}{{D`{l}}}}{{{h{dAFb}}ABf}{{D`{l}}}}00{{{h{dAFb}}{AKj{ABh}}}{{D`{l}}}}4{{{h{dAFb}}Dh}{{D`{l}}}}5{{{h{dAFb}}AEj}{{D`{l}}}}{{{h{dAFb}}ACd}{{D`{l}}}}67{{{h{AFb}}}{{D`{Dh}}}}{{{h{AFb}}}{{D`{A@j}}}}{{{h{c}}}e{}{}}{c{{A`{e}}}{}{}}0{{{h{c}}}Mh{}}{{{h{AFb}}}{{D`{AEj}}}}{ce{}{}}{{{h{AFb}}}{{D`{ACd}}}}{{AFb{AKj{A@j}}}{{D`{AFb}}}}0{{AFbFj}{{D`{AFb}}}}{{AFbA@j}{{D`{AFb}}}}2{{AFbAC`}{{D`{AFb}}}}111{{AFbACb}{{D`{AFb}}}}{{AFbABf}{{D`{AFb}}}}00{{AFb{AKj{ABh}}}{{D`{AFb}}}}4{{AFbDh}{{D`{AFb}}}}5{{AFbAEj}{{D`{AFb}}}}{{AFbACd}{{D`{AFb}}}}67{{{h{AFb}}}{{D`{AC`}}}}{{{h{AFb}}}{{D`{A@j}}}}{AC`ABh}{{AC`ACb}A@j}{AC`Fj}{AC`A@j}```````````````````````````````````````````````{{{h{dLh}}{h{dAMn}}{D`{{AN`{Lh}}}}}l}{{{h{dCd}}{AN`{Hl}}}l}`{{{h{Cd}}}{{h{C`}}}}{{{h{Cd}}}{{D`{{h{c}}}}}{}}{{{h{{K`{c}}}}}{{h{Bj}}}ANb}{{}{{Id{El}}}}{{{h{{Id{c}}}}}{{h{c}}}{}}{{{h{c}}}{{h{e}}}{}{}}000000000000000000000{{{h{dc}}}{{h{de}}}{}{}}000000000000000000000{{}ANd}{EnANf}{{{h{{ANh{}{{H`{c}}{Cf{e}}{F`{g}}}}}}i}g{}{}{{Fd{}{{B`{{A`{ce}}}}}}}{}}{{{h{J`}}}Fj}{{{h{AMn}}{h{dc}}}FjANj}{{{h{AMn}}{h{dc}}e}FjANj{{Gb{{h{c}}}{{B`{Fj}}}}}}2{{{h{In}}}Fj}{{{h{dHl}}}l}{{{h{{K`{c}}}}}{{K`{c}}}Bf}{{{h{AMn}}}AMn}{{{h{ANl}}}ANl}{{{h{Jn}}}Jn}{{{h{C`}}}C`}{{{h{J`}}}J`}{{{h{In}}}In}{{{h{Gd}}}Gd}{{{h{ANn}}}ANn}{{{h{Lh}}}Lh}{{{h{c}}{h{de}}}l{}{}}000000000{{{h{ANn}}{h{ANn}}}ACf}{{{h{c}}{h{e}}}ACf{}{}}{{{h{Lf}}}{{h{C`}}}}{{{h{Cd}}}{{D`{{h{c}}}}}{}}{{{h{Cd}}}{{Gf{Gd}}}}{{{h{J`}}}AO`}{{{h{In}}}AO`}{{{h{Hl}}}Fj}{{{h{Cd}}{h{Bj}}}{{D`{j}}}}{{{h{Cd}}}{{A`{{Gf{{Af{j}}}}Gj}}}}{{}{{K`{c}}}AOb}{{}Jn}{{}{{Id{c}}}AOb}{{}C`}{{}Hl}{{}J`}{{}Gd}{{{h{Lf}}}{{AN`{{AOd{lCd{Hb{El}}Chl}}}}}}{{{Id{c}}}{{Id{l}}}{}}{{{h{AMn}}{h{AMn}}}Fj}{{{h{ANn}}{h{ANn}}}Fj}{{{h{c}}{h{e}}}Fj{}{}}00000{{Cdc}Hb{{If{Ch}}}}{{{Hb{c}}e}Hb{}{{If{Ch}}}}{{{h{J`}}}Fj}{{{h{dHl}}Hl}l}{{{h{{Id{c}}}}}{{Gf{Hl}}}{}}{{{h{Cd}}}{{Gf{Hl}}}}{{{h{d{Id{c}}}}}{{Hn{Hl}}}{}}{{{h{Cd}}}{{Hn{Hl}}}}{{{h{dCd}}}}{{{h{AMn}}{h{Bj}}}{{D`{Hd}}}}{{AOfe}{{`{Ll}}}{{Al{Cd}{{Aj{l}}{H`{Hb}}{Cf{Ch}}{Cj{l}}}}}{{An{cCd}}}}{{{h{{K`{c}}}}{h{dI`}}}{{A`{lNl}}}Gn}{{{h{AMn}}{h{dI`}}}{{A`{lNl}}}}{{{h{ANl}}{h{dI`}}}{{A`{lNl}}}}{{{h{Jn}}{h{dI`}}}{{A`{lNl}}}}{{{h{{Id{c}}}}{h{dI`}}}{{A`{lNl}}}Bh}{{{h{Cd}}{h{dI`}}}Ib}{{{h{{Hb{c}}}}{h{dI`}}}IbBh}{{{h{C`}}{h{dI`}}}Ib}{{{h{Hl}}{h{dI`}}}{{A`{lNl}}}}{{{h{J`}}{h{dI`}}}{{A`{lNl}}}}{{{h{In}}{h{dI`}}}{{A`{lNl}}}}{{{h{Gd}}{h{dI`}}}Ib}{{{h{ANn}}{h{dI`}}}Ib}0{{{h{Lh}}{h{dI`}}}Ib}{k{{AOh{kmecig}}}{}{{ANh{c}}}{}{{Fd{}{{B`{{A`{eg}}}}}}}{{Bb{}{{B`{i}}}}}{}}{k{{AOj{kicegm}}}{}{}{}{{Fd{}{{B`{{A`{eg}}}}}}}{{Bb{c}{{B`{i}}}}Bf}{}}`{cc{}}00{{{h{Bj}}}AMn}{KbAMn}222{{{h{Kb}}}{{Id{Kb}}}}{ANf{{Id{{Jl{l}}}}}}{{{h{{Af{A@j}}}}}{{Id{{Af{A@j}}}}}}{Fl{{Id{El}}}}{{{h{{A@l{A@j}}}}}{{Id{{h{{A@l{A@j}}}}}}}}{AOl{{Id{El}}}}{{{AOn{cge}}}{{Id{El}}}{GnB@`}{}{{B@b{e}}B@d}}{{{Hb{c}}}{{Id{c}}}{}}{Kb{{Id{Kb}}}}{B@f{{Id{B@f}}}}{{{h{Bj}}}{{Id{{h{Bj}}}}}}{{{h{AOl}}}{{Id{El}}}}{Ch{{Id{El}}}}{b{{Id{El}}}}{{{Af{A@j}}}{{Id{{Af{A@j}}}}}}{cc{}}{{{f{c}}}{{Id{c}}}{}}{Md{{Id{Md}}}}{{{A`{ce}}}{{Id{El}}}{{If{{Id{El}}}}}{{If{B@h}}}}{B@j{{Id{El}}}}{B@h{{Id{El}}}}{B@l{{Id{B@l}}}}666666666{B@n{{Ih{c}}}{}}{BA`{{Ih{c}}}{}}8{{{L`{{M`{Mf}}}}}Ih}{BAb{{Ih{c}}}{}}:::::{{cBn}{{Hb{El}}}{{If{Ch}}}}{{c{h{Jb}}}{{BAd{c}}}{{Mf{}{{Mb{{A`{MdBAf}}}}}}}}{{BnIh}Cd}{BnCd}{{{h{Bn}}{h{dIh}}}c{}}0{{{h{{K`{c}}}}{h{Bj}}}{{D`{{h{Bj}}}}}ANb}{{{h{Hl}}}{{D`{{h{c}}}}}{}}{{{h{d{K`{c}}}}}{{h{dc}}}ANb}{{{h{dHl}}}{{D`{{h{dc}}}}}{}}{{{h{{K`{c}}}}}{{h{c}}}ANb}{{AOfc}AOfIj}{{{h{Cd}}}BAh}{{{h{Lj}}}ANl}{{{h{Lh}}{h{Bj}}}Fj}{{{h{AMn}}{h{dc}}}lAAf}{{{h{ANn}}{h{dc}}}lAAf}{{{h{{Id{c}}}}}{{h{In}}}{}}{{{h{Cd}}}{{h{J`}}}}{{{h{d{Id{c}}}}}{{h{dIn}}}{}}{{{h{dCd}}}{{h{dJ`}}}}{{{h{{Id{c}}}}}{{h{Jb}}}{}}{{{h{Cd}}}{{h{Jb}}}}0{{{h{{Hb{c}}}}}{{h{Jb}}}{}}{{{h{J`}}}{{h{Jb}}}}{{{h{In}}}{{h{Jb}}}}``{{{h{d{Id{c}}}}}{{h{dJb}}}{}}{{{h{dCd}}}{{h{dJb}}}}{{{h{d{Hb{c}}}}}{{h{dJb}}}{}}{{{h{dJ`}}}{{h{dJb}}}}{{{h{dIn}}}{{h{dJb}}}}{{{h{C`}}}{{h{Bj}}}}{{{h{Gd}}}{{h{Bj}}}}{{{h{AMn}}}ABh}{{{h{{K`{c}}}}Hd}{{h{Bj}}}ANb}{{{h{{K`{c}}}}{h{Bj}}}{{h{Bj}}}ANb}{{{h{dHl}}c}{{D`{c}}}{}}{{}{{Id{El}}}}{ce{}{}}000000000000000000000{{{Id{c}}}c{}}{{{Hb{c}}}c{}}{c{}{}}00{ANnAd}{{{Id{c}}}{{Bl{{Id{l}}c}}}{}}{Cd{{Bl{BnIh}}}}{{{Hb{c}}}{{Bl{Bn{f{c}}}}}{}}{{Cde}{{Hb{c}}}{}{{If{{Id{c}}}}}}{{{Hb{c}}{f{e}}}{{Hb{e}}}{}{}}{{{h{{K`{c}}}}}FjANb}{{{h{AMn}}{h{Bj}}}Fj}{{{h{AMn}}}Fj}{{{h{Lf}}}Fj}{{{h{{K`{c}}}}}{{BAj{c}}}ANb}{{{h{AMn}}{h{AMn}}}AMn}{{{h{{Id{c}}}}}Fj{}}{{{h{In}}}Fj}{{{BAl{c}}Hd}{{BAl{c}}}{}}{{{BAn{c}}Hd}{{BAn{c}}}BB`}{{{BBb{c}}Hd}{{BBb{c}}}Fh}{{{h{{K`{c}}}}}{{A`{eBBd}}}ANbBBf}{{{h{C`}}}Ad}{{{Id{c}}g}{{Id{e}}}{}{}{{Gb{{h{dIn}}c}{{B`{e}}}}}}{{{Hb{c}}g}{{Hb{e}}}{}{}{{Gb{{h{dIn}}c}{{B`{e}}}}}}{{{Id{c}}}{{Id{El}}}Bh}{{{Hb{c}}}{{Hb{El}}}Bh}{{{Hb{c}}}{{Hb{{Jl{ce}}}}}{}{}}{{{Hb{c}}}{{Hb{{Jl{ec}}}}}{}{}}{{{h{Cd}}}{{h{{K`{Jn}}}}}}{{{h{dCd}}}{{h{d{K`{Jn}}}}}}{{{h{Cd}}}{{D`{{h{Bj}}}}}}{{{h{Lh}}{h{Bj}}}{{D`{{h{Bj}}}}}}{{{h{Cd}}}{{D`{Kb}}}}{{{h{Lh}}{h{Bj}}}{{D`{Kb}}}}{{{h{Cd}}}{{h{Kd}}}}`{{{h{AMn}}}{{D`{{h{Bj}}}}}}{{AOf{h{Bj}}}AOf}{c{{K`{c}}}ANb}{cAMnKh}{MjJn}{En{{Id{El}}}}{{Bn{f{c}}}{{Hb{c}}}{}}{cAOfKh}{{{h{Bn}}{h{dIh}}}{{BAl{c}}}{}}{{{h{Bn}}{h{dIh}}{D`{{h{Bb}}}}Fj}{{BAn{c}}}BB`}{{{h{dc}}}{{BBb{c}}}Fh}{{cBBh}{{BAd{c}}}{{Mf{}{{Mb{{A`{MdBAf}}}}}}}}{{}Hl}{EnIn}{AMnLh}{{{h{{Al{}{{H`{c}}{Cf{e}}{Aj{g}}{BBj{i}}{Cj{m}}{F`{o}}}}}}g}o{}{}{}{{ANh{k}{{H`{c}}{Cf{e}}}}}{}{}{{Fd{}{{B`{{A`{im}}}}}}}}{{{h{{Nd{}{{H`{c}}{Cf{e}}{BBl{g}}{Cj{k}}{F`{m}}}}}}o}m{}{}{{ANh{i}{{H`{c}}{Cf{e}}}}}{}{}{{Fd{}{{B`{{A`{gk}}}}}}}{}}{{Mj{h{BBn}}}Jn}{{{h{dJ`}}Fj}l}{{{h{dIn}}Fj}l}{{}{{Id{El}}}}0{{{h{ANn}}{h{ANn}}}{{D`{ACf}}}}{{{h{Cd}}}{{Bl{{h{Bn}}{h{Ih}}}}}}{{{h{dCd}}}{{Bl{{h{dBn}}{h{dIh}}}}}}{{{h{ANb}}}{{h{Bj}}}}{{{h{Jn}}}{{h{Bj}}}}0{{{h{Cd}}}{{h{Bj}}}}{{{h{AMn}}}{{D`{{h{Bj}}}}}}{{{h{AMn}}}{{`{{AF`{}{{Mb{{h{Bj}}}}}}}}}}{{{h{ANl}}}{{`{{Fd{}{{B`{l}}}}}}}}{{{h{Cd}}}{{D`{Ad}}}}{{{h{Gd}}}{{D`{{h{Bj}}}}}}`{{{L`{{h{dLj}}}}{h{dLb}}}Ld}{{{L`{{h{d{BAl{c}}}}}}{h{dLb}}}{{Ld{e}}}BB`{}}{{{L`{{h{d{BAn{c}}}}}}{h{dLb}}}{{Ld{e}}}BB`{}}{{{L`{{h{d{BBb{c}}}}}}{h{dLb}}}{{Ld{{D`{e}}}}}Fh{}}{{{L`{{h{d{BAd{c}}}}}}{h{dLb}}}{{Ld{D`}}}{{Mf{}{{Mb{{A`{MdBAf}}}}}}}}{{{L`{{h{d{Ih{c}}}}}}{h{dLb}}}{{Ld{D`}}}{{Mf{}{{Mb{{A`{MdBAf}}}}}}}}{{{h{{ANh{}{{H`{c}}{Cf{e}}{F`{g}}}}}}{h{dLb}}}{{Ld{{A`{le}}}}}{}{}{{Fd{}{{B`{{A`{ce}}}}}}}}{cAMnKh}{{{h{{K`{c}}}}{h{Bj}}}{{h{Bj}}}ANb}>9{{{h{In}}}{{h{Bj}}}}`{{Ll{h{dLf}}}l}{{{h{dLf}}AMn{D`{{Af{{M`{Ij}}}}}}e{D`{{AN`{Lh}}}}}l{{Al{Cd}{{H`{Hb}}{Cf{Ch}}{Aj{l}}{Cj{l}}}}}{{An{cCd}}}}{{{h{dHl}}}{{D`{c}}}{}}{{{h{Cd}}}{{h{Bn}}}}{{{h{{Hb{c}}}}}{{h{Bn}}}{}}{{{h{d{K`{c}}}}}lANb}{{{h{Cd}}}{{h{Lh}}}}{{{h{d{K`{c}}}}}{{h{dK`}}}ANb}{{{h{dCd}}}{{h{d{K`{c}}}}}{}}{{{h{AMn}}{h{dKb}}c}FjN`}{{{h{AMn}}{h{dKb}}{h{{BC`{ceg}}}}}Fj{{AAd{Bj}}BCbBCd}{{Ej{Bj}}}BCf}{{{Id{El}}{h{Bn}}}{{f{c}}}{}}{{{h{{Hb{c}}}}}{{h{{f{c}}}}}{}}{{{h{d{Hb{c}}}}}{{h{d{f{c}}}}}{}}{{{h{ANl}}}{{`{{Fd{}{{B`{l}}}}}}}}{{{h{Bj}}}AMn}{{{h{Gd}}}{{h{Bj}}}}{{{h{C`}}}Fj}{{{h{{K`{c}}}}}HdANb}{{{h{d{K`{c}}}}c}lANb}{{{Id{c}}e}{{Id{e}}}{}{}}{{{h{dJ`}}Fj}l}{{{h{dIn}}Fj}l}{{{h{dJ`}}AO`}l}{{{h{dIn}}AO`}l}{{{h{dAMn}}ABh}l}{{{h{dAMn}}c}l{{If{Kb}}}}{{{h{dCd}}Ih}l}{{{h{d{K`{c}}}}ABh}lANb}{{{h{{Id{c}}}}}En{}}{{{h{{Hb{c}}}}}En{}}`{{{h{d{Id{c}}}}}{{h{dEn}}}{}}{{{h{ANl}}Fj}{{`{{Fd{}{{B`{l}}}}}}}}{{{h{d{Ih{c}}}}}{{Ih{c}}}{}}{{{h{dCd}}}{{Ih{c}}}{}}{{{h{c}}}e{}{}}000000000{{{h{c}}}Kb{}}{c{{A`{e}}}{}{}}0000000000000000000000000000000000000000000{{{L`{{h{dc}}}}{h{dLb}}}Ld{}}00{{{L`{{h{dc}}}}{h{dLb}}}{{Ld{{D`{A`}}}}}{}}00{{{h{c}}}Mh{}}000000000000000000000{{{h{{K`{c}}}}}{{h{Bj}}}ANb}{{{h{dJn}}{h{Mj}}}l}{{{h{dJn}}{h{Mj}}{h{BBn}}}l}{{{h{{Id{c}}}}}Fj{}}{{{h{J`}}}Fj}{{{h{In}}}Fj}{{{h{Jn}}}{{h{Mj}}}}{{{h{Cd}}}{{h{Mj}}}}`{{{h{Lh}}{h{Bn}}{h{Bj}}e}{{A`{MlMn}}}{{Ej{Bj}}}{{N`{}{{Mb{c}}}}}}{{{h{Cd}}}Nb}``{ce{}{}}000000000000000000000{{Enc}{{Id{c}}}{}}`````````````````````````{cCh{GnB@`}}00000000000000000000000000000000000000````````````````````````````````````````````````````{{{h{Ch}}}{{D`{{h{c}}}}}BCh}{{{h{Ch}}}{{h{BCh}}}}{{{h{c}}}{{h{e}}}{}{}}0000000000000{{{h{dc}}}{{h{de}}}{}{}}0000000000000{{{h{dBCh}}}{{D`{{h{dc}}}}}BCh}{{{h{BCh}}}{{D`{{h{c}}}}}BCh}{{{h{Mn}}{h{Mn}}}Fj}{{{h{c}}{h{e}}}Fj{}{}}00{{{h{Ch}}}f}{{{h{{BCj{c}}}}}f{GnB@`}}{{{h{BCh}}}{{f{El}}}}0{{{h{Ch}}{h{dI`}}}Ib}0{{{h{{BCj{c}}}}{h{dI`}}}IbGn}{{{h{{BCj{c}}}}{h{dI`}}}IbB@`}{{{h{n}}{h{dI`}}}{{A`{lNl}}}}0{{{h{BCl}}{h{dI`}}}Ib}0{{{h{Mn}}{h{dI`}}}Ib}0{{{h{BCn}}{h{dI`}}}Ib}0{{{h{Fl}}{h{dI`}}}{{A`{lNl}}}}0{{{h{BD`}}{h{dI`}}}Ib}0{{{h{BAf}}{h{dI`}}}{{A`{lNl}}}}0{{{h{BDb}}{h{dI`}}}{{A`{lNl}}}}0{{{h{BDd}}{h{dI`}}}Ib}0{{{h{BDf}}{h{dI`}}}Ib}0{{{h{BDh}}{h{dI`}}}Ib}0{{{h{Hj}}{h{dI`}}}{{A`{lNl}}}}0{cc{}}{cChBCh}1{BDjn}{BDln}{BDnn}{BE`n}{BEbn}6{BEdn}{BEfn}{BEhn}{B@jn}:{BEjMn};{BElBCn}{BAfBCn}{BBdBCn}{{{Bl{HdHd}}}BCn}??{BEnFl}{AGfFl}{AAbFl}{BF`Fl}{BEdFl}{BAfBD`}{cc{}}{BFbBAf}{{{D`{AGf}}}BAf}2{AGfBAf}{BFbBDb}{AGfBDb}5{{{Id{El}}}BDb}{{{M`{Ln}}}BDb}{FlBDb}8{BBdBDf}9{HjBDh}:{BAfBDh};{{cf}{{BCj{c}}}{}}{{{h{n}}}{{h{Ln}}}}{ce{}{}}0000000000000{{{h{n}}}Fj}{{cEn}{{BCj{c}}}{}}{{{BCj{c}}{h{Bn}}}{{f{e}}}{GnB@`}{}}{{{h{Ch}}}{{D`{{h{Ln}}}}}}{{{h{n}}}{{D`{{h{Ln}}}}}}{{{h{Mn}}}{{D`{{h{Ln}}}}}}{{{h{BCn}}}{{D`{{h{Ln}}}}}}{{{h{Fl}}}{{D`{{h{Ln}}}}}}{{{h{BD`}}}{{D`{{h{Ln}}}}}}{{{h{BAf}}}{{D`{{h{Ln}}}}}}{{{h{BDb}}}{{D`{{h{Ln}}}}}}{{{h{BDd}}}{{D`{{h{Ln}}}}}}{{{h{BDf}}}{{D`{{h{Ln}}}}}}{{{h{BDh}}}{{D`{{h{Ln}}}}}}{{{h{{BCj{c}}}}}En{GnB@`}}{{{h{BCh}}}En}0{{{h{BCn}}}En}{{{h{Fl}}}En}{{{h{BD`}}}En}{{{h{BAf}}}En}{{{h{BDd}}}En}{{{h{BDf}}}En}{{{h{BDh}}}En}{{{h{Hj}}}En}{{{h{c}}}Kb{}}0000000000000{c{{A`{e}}}{}{}}000000000000000000000000000{{{h{c}}}Mh{}}0000000000000{ce{}{}}0000000000000``````{cBFdIj}`{cBFfIj}`{{}{{`{Ij}}}}00``0{{{h{Bj}}{h{Bj}}}{{`{Ij}}}}``{Kd{{`{Ij}}}}`22222{{BFdc}BFdIj}{{{h{c}}}{{h{e}}}{}{}}0000{{{h{dc}}}{{h{de}}}{}{}}0000{{{h{Ij}}{h{BAh}}}Fj}{{{h{BFf}}{h{BAh}}}Fj}{{{h{BFd}}{h{BAh}}}Fj}{{{h{{BFh{c}}}}{h{BAh}}}FjIj}{{{h{BFj}}{h{BAh}}}Fj}{{{h{BFj}}}BFj}{{{h{c}}{h{de}}}l{}{}}{{{h{BFj}}{h{dI`}}}Ib}{{{h{BAh}}{h{dI`}}}Ib}{c{{`{Ij}}}{{Bb{{h{BAh}}}{{B`{Fj}}}}}}{cc{}}0000{{{h{BAh}}}{{h{J`}}}}{{{h{BAh}}}{{D`{c}}}BFl}{ce{}{}}0000{BFjBFj}{KfBFj}{{BFfc}BFfIj}{{{h{BAh}}}{{Gf{Hl}}}}{{{h{BAh}}}{{Hn{Hl}}}}{{{h{c}}}e{}{}}{c{{A`{e}}}{}{}}000000000{{{h{c}}}Mh{}}000088888```````````````````````````````````````````````````````````````````````````````````````{{{h{Kd}}}{{h{Bj}}}}0{{{h{En}}}{{h{Bj}}}}{{{h{En}}}ABh}{{{h{Mj}}}{{D`{{h{BFn}}}}}}{{{h{c}}}{{h{e}}}{}{}}000000{{{h{dc}}}{{h{de}}}{}{}}000000{{}BG`}{{{h{En}}}{{D`{{h{Bj}}}}}}{{{h{Kd}}}Kd}{{{h{En}}}En}{{{h{Mj}}}Mj}{{{h{Nb}}}Nb}{{{h{Jf}}}Jf}{{{h{AO`}}}AO`}{{{h{c}}{h{de}}}l{}{}}00000{{{h{En}}{h{En}}}ACf}{{{h{Nb}}{h{Nb}}}ACf}{{{h{c}}{h{e}}}ACf{}{}}0{{}Kd}{{}En}{{}Mj}{{}Nb}{{}Jf}{{{h{Kd}}{h{Kd}}}Fj}{{{h{Kd}}{h{{h{Kd}}}}}Fj}{{{h{Kd}}{h{{h{Bj}}}}}Fj}{{{h{{h{Kd}}}}{h{Kd}}}Fj}{{{h{Kd}}{h{Bj}}}Fj}{{{h{En}}{h{ABh}}}Fj}{{{h{En}}{h{En}}}Fj}{{{h{Mj}}{h{Bj}}}Fj}{{{h{Mj}}{h{{h{Bj}}}}}Fj}{{{h{Mj}}{h{Mj}}}Fj}{{{h{Nb}}{h{Nb}}}Fj}{{{h{Jf}}{h{Jf}}}Fj}{{{h{AO`}}{h{AO`}}}Fj}{{{h{c}}{h{e}}}Fj{}{}}00000000000000000{{{h{B@h}}}{{f{El}}}}{{{h{B@h}}{h{dI`}}}{{A`{lNl}}}}0{{{h{Kd}}{h{dI`}}}{{A`{lNl}}}}0{{{h{En}}{h{dI`}}}{{A`{lNl}}}}0{{{h{Mj}}{h{dI`}}}{{A`{lNl}}}}0{{{h{Nb}}{h{dI`}}}{{A`{lNl}}}}{{{h{Jf}}{h{dI`}}}{{A`{lNl}}}}{{{h{AO`}}{h{dI`}}}{{A`{lNl}}}}{BGbB@h}{nB@h}{AOlB@h}{B@jB@h}{FlB@h}{BGdB@h}{BAfB@h}{cc{}}0{{{h{Kd}}}Kd}1{{{h{En}}}En}{BGfMj}3{BFnMj}4{{{D`{Fn}}}Jf}5{FnJf}6{{{h{{A@l{A@j}}}}}{{A`{KdBE`}}}}{{{h{{A@l{A@j}}}}}{{A`{EnBDl}}}}{c{{A`{MjBEd}}}{{Ej{{A@l{A@j}}}}}}{BGh{{A`{MjBEf}}}}{{{h{Bn}}{h{dIh}}}c{}}0{{{h{Bj}}}Mj}{{{h{Bj}}}{{A`{Kd}}}}{{{h{Bj}}}{{A`{EnBDl}}}}{{{h{Bj}}}{{A`{MjBEd}}}}{ABh{{A`{EnBDl}}}}{{{h{Kd}}{h{dc}}}lAAf}{{{h{En}}{h{dc}}}lAAf}{{{h{Mj}}{h{dc}}}lAAf}{{{h{Nb}}{h{dc}}}lAAf}`{{{h{Mj}}}{{D`{{h{Bj}}}}}}{{{h{Mj}}}{{h{Bj}}}}{ce{}{}}000000{MjBGh}{{{h{En}}}Fj}{{{h{Kd}}}Fj}11011{{{h{En}}{h{En}}}{{D`{ACf}}}}{{{h{Nb}}{h{Nb}}}{{D`{ACf}}}}66{{{h{Mj}}}{{D`{{h{BGf}}}}}}{{{h{Mj}}}{{D`{ABh}}}}{{{h{Mj}}}{{D`{{BGj{{h{Bj}}}}}}}}1:{{{h{Mj}}}{{D`{{h{BGl}}}}}};{{{h{B@h}}}{{D`{{h{Ln}}}}}}{{{h{B@h}}}En}{{{h{c}}}e{}{}}00000{{{h{c}}}Kb{}}000{c{{A`{e}}}{}{}}{{{h{Bj}}}{{A`{Kd}}}}{{{h{{A@l{A@j}}}}}{{A`{Kd}}}}2{{{h{{A@l{A@j}}}}}{{A`{En}}}}{{{h{Bj}}}{{A`{En}}}}{ABh{{A`{En}}}}5{BGh{{A`{Mj}}}}{{{h{{A@l{A@j}}}}}{{A`{Mj}}}}7{{{Af{A@j}}}{{A`{Mj}}}}{Kb{{A`{Mj}}}}{{{h{Kb}}}{{A`{Mj}}}}{{{h{Mj}}}{{A`{Mj}}}}{{{h{Bj}}}{{A`{Mj}}}}<<<<<<<<<<{{{h{c}}}Mh{}}000000`{ce{}{}}000000````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````{{{h{dJb}}BGnBH`}l}{{{h{BH`}}}{{h{{A@l{A@j}}}}}}{{{h{BHb}}}{{D`{{h{Bj}}}}}}{{{h{BHb}}}{{D`{{h{BHd}}}}}}1{{{h{BGn}}}{{h{{A@l{A@j}}}}}}{{{h{BGn}}}{{h{Bj}}}}4{{{h{BHf}}}{{h{Bj}}}}1{BBh{{h{Bj}}}}{{{h{BHb}}c}{{D`{{h{Bj}}}}}{{Ej{Bj}}}}{{{h{BHb}}c}{{D`{{h{BHd}}}}}{{Ej{Bj}}}}{cBHh{{If{Kb}}}}{{{h{c}}}{{h{e}}}{}{}}000600000000000000000000000000000000000000{{{h{dc}}}{{h{de}}}{}{}}00000000000000000000000000000000000000000{{}BHj}{{KjKj}BHl}{{{Af{{Bl{KjKj}}}}}BHl}{{{h{BHf}}}{{A`{BHfBHn}}}}{{{h{Jb}}}Hd}`{{{h{dJb}}}l}{{{h{BHf}}}BHf}{{{h{BGn}}}BGn}{{{h{BH`}}}BH`}{{{h{Jb}}}Jb}{{{h{BI`}}}BI`}{{{h{BBh}}}BBh}{{{h{BHd}}}BHd}{{{h{BIb}}}BIb}{{{h{BId}}}BId}{{{h{{BIf{c}}}}}{{BIf{c}}}Bf}{{{h{BIh}}}BIh}{{{h{BIj}}}BIj}{{{h{BIl}}}BIl}{{{h{BIn}}}BIn}{{{h{BJ`}}}BJ`}{{{h{BJb}}}BJb}{{{h{BJd}}}BJd}{{{h{BJf}}}BJf}{{{h{BHb}}}BHb}{{{h{BHh}}}BHh}{{{h{BJh}}}BJh}{{{h{BJj}}}BJj}{{{h{BJl}}}BJl}{{{h{BJn}}}BJn}{{{h{BK`}}}BK`}{{{h{BKb}}}BKb}{{{h{BHj}}}BHj}{{{h{BKd}}}BKd}{{{h{BKf}}}BKf}{{{h{BKh}}}BKh}{{{h{BKj}}}BKj}{{{h{BKl}}}BKl}{{{h{BKn}}}BKn}{{{h{BL`}}}BL`}{{{h{BLb}}}BLb}{{{h{BLd}}}BLd}{{{h{{BLf{c}}}}}{{BLf{c}}}Bf}{{{h{BHl}}}BHl}{{{h{BLh}}}BLh}{{{h{c}}{h{de}}}l{}{}}00000000000000000000000000000000000000{{{h{BH`}}{h{BH`}}}ACf}{{{h{BIb}}{h{BIb}}}ACf}{{{h{BId}}{h{BId}}}ACf}{{{h{BJj}}{h{BJj}}}ACf}{{{h{c}}{h{e}}}ACf{}{}}000{{{h{Jb}}c}FjBLj}{{}Jb}{{}BBh}{{}BId}{{}BHj}{{{h{BIh}}}{{h{c}}}{}}{{{h{BIj}}}{{h{c}}}{}}{{{h{BIl}}}{{h{c}}}{}}{{{h{BIn}}}{{h{c}}}{}}{{{h{BJ`}}}{{h{c}}}{}}{{{h{BJb}}}{{h{c}}}{}}{{{h{BJh}}}{{h{c}}}{}}{{{h{BJj}}}{{h{c}}}{}}{{{h{BJl}}}{{h{c}}}{}}{{{h{BK`}}}{{h{c}}}{}}{{{h{BKb}}}{{h{c}}}{}}{{{h{BKf}}}{{h{c}}}{}}{{{h{BKh}}}{{h{c}}}{}}{{{h{BKl}}}{{h{c}}}{}}{{{h{BLb}}}{{h{c}}}{}}{{{h{BLd}}}{{h{c}}}{}}{{{h{dBIh}}}{{h{dc}}}{}}{{{h{dBIj}}}{{h{dc}}}{}}{{{h{dBIl}}}{{h{dc}}}{}}{{{h{dBIn}}}{{h{dc}}}{}}{{{h{dBJ`}}}{{h{dc}}}{}}{{{h{dBJb}}}{{h{dc}}}{}}{{{h{dBJh}}}{{h{dc}}}{}}{{{h{dBJj}}}{{h{dc}}}{}}{{{h{dBJl}}}{{h{dc}}}{}}{{{h{dBK`}}}{{h{dc}}}{}}{{{h{dBKb}}}{{h{dc}}}{}}{{{h{dBKf}}}{{h{dc}}}{}}{{{h{dBKh}}}{{h{dc}}}{}}{{{h{dBKl}}}{{h{dc}}}{}}{{{h{dBLb}}}{{h{dc}}}{}}{{{h{dBLd}}}{{h{dc}}}{}}`{{{h{dJb}}}BLl}{{{h{BHf}}{h{BHf}}}Fj}{{{h{{h{BGn}}}}{h{BGn}}}Fj}{{{h{BGn}}{h{{h{BGn}}}}}Fj}{{{h{BGn}}{h{{h{Bj}}}}}Fj}{{{h{BGn}}{h{BGn}}}Fj}{{{h{BGn}}{h{Bj}}}Fj}{{{h{{h{BH`}}}}{h{BH`}}}Fj}{{{h{BH`}}{h{BH`}}}Fj}{{{h{BH`}}{h{{h{c}}}}}FjADf}{{{h{BH`}}{h{Bj}}}Fj}{{{h{BH`}}{h{Kb}}}Fj}{{{h{BH`}}{h{{A@l{A@j}}}}}Fj}{{{h{BI`}}{h{BI`}}}Fj}{{{h{BBh}}{h{BBh}}}Fj}{{{h{BHd}}{h{BHd}}}Fj}{{{h{BIb}}{h{BIb}}}Fj}{{{h{BId}}{h{BId}}}Fj}{{{h{{BIf{c}}}}{h{{BIf{c}}}}}FjBLn}{{{h{BIh}}{h{BIh}}}Fj}{{{h{BIj}}{h{BIj}}}Fj}{{{h{BIl}}{h{BIl}}}Fj}{{{h{BIn}}{h{BIn}}}Fj}{{{h{BJ`}}{h{BJ`}}}Fj}{{{h{BJb}}{h{BJb}}}Fj}{{{h{BJd}}{h{BJd}}}Fj}{{{h{BJf}}{h{BJf}}}Fj}{{{h{BHb}}{h{BHb}}}Fj}{{{h{BHh}}{h{BHh}}}Fj}{{{h{BJh}}{h{BJh}}}Fj}{{{h{BJj}}{h{Hd}}}Fj}{{{h{BJj}}{h{BJj}}}Fj}{{{h{BJl}}{h{BJl}}}Fj}{{{h{BJn}}{h{BJn}}}Fj}{{{h{BK`}}{h{BK`}}}Fj}{{{h{BKb}}{h{BKb}}}Fj}{{{h{BHj}}{h{BHj}}}Fj}{{{h{BKd}}{h{BKd}}}Fj}{{{h{BKf}}{h{BKf}}}Fj}{{{h{BKh}}{h{BKh}}}Fj}{{{h{BKj}}{h{BKj}}}Fj}{{{h{BKl}}{h{BKl}}}Fj}{{{h{BKn}}{h{BKn}}}Fj}{{{h{BL`}}{h{BL`}}}Fj}{{{h{BLb}}{h{BLb}}}Fj}{{{h{BLd}}{h{BLd}}}Fj}{{{h{{BLf{c}}}}{h{{BLf{c}}}}}FjBLn}{{{h{BHl}}{h{BHl}}}Fj}{{{h{BLh}}{h{BLh}}}Fj}{{{h{c}}{h{e}}}Fj{}{}}00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000{{{h{BHf}}}{{D`{{h{Bj}}}}}}{{{h{BHf}}}{{`{{AF`{}{{Mb{{h{Bj}}}}}}}}}}1{{{h{BHf}}}{{`{{AF`{}{{Mb{{Bl{BM`{h{Bj}}}}}}}}}}}}{{{h{BHf}}{h{dI`}}}{{A`{lNl}}}}0{{{h{BDn}}{h{dI`}}}{{A`{lNl}}}}0{{{h{BEh}}{h{dI`}}}{{A`{lNl}}}}0{{{h{BGn}}{h{dI`}}}{{A`{lNl}}}}0{{{h{BH`}}{h{dI`}}}{{A`{lNl}}}}{{{h{BMb}}{h{dI`}}}{{A`{lNl}}}}0{{{h{Jb}}{h{dI`}}}{{A`{lNl}}}}{{{h{BI`}}{h{dI`}}}{{A`{lNl}}}}0{{{h{BBh}}{h{dI`}}}{{A`{lNl}}}}{{{h{BHd}}{h{dI`}}}{{A`{lNl}}}}0{{{h{BIb}}{h{dI`}}}{{A`{lNl}}}}0{{{h{BId}}{h{dI`}}}{{A`{lNl}}}}0{{{h{{BIf{c}}}}{h{dI`}}}{{A`{lNl}}}Gn}{{{h{{BIf{c}}}}{h{dI`}}}{{A`{lNl}}}B@`}{{{h{BIh}}{h{dI`}}}Ib}0{{{h{BIj}}{h{dI`}}}Ib}0{{{h{BIl}}{h{dI`}}}Ib}0{{{h{BIn}}{h{dI`}}}Ib}0{{{h{BJ`}}{h{dI`}}}Ib}0{{{h{BJb}}{h{dI`}}}Ib}0{{{h{BJd}}{h{dI`}}}Ib}0{{{h{BJf}}{h{dI`}}}Ib}0{{{h{BHb}}{h{dI`}}}Ib}0{{{h{BHh}}{h{dI`}}}Ib}0{{{h{BJh}}{h{dI`}}}Ib}0{{{h{BJj}}{h{dI`}}}Ib}{{{h{BJl}}{h{dI`}}}Ib}0{{{h{BJn}}{h{dI`}}}Ib}0{{{h{BK`}}{h{dI`}}}Ib}0{{{h{BKb}}{h{dI`}}}Ib}0{{{h{BHj}}{h{dI`}}}Ib}0{{{h{BKd}}{h{dI`}}}Ib}0{{{h{BKf}}{h{dI`}}}Ib}0{{{h{BKh}}{h{dI`}}}Ib}0{{{h{BKj}}{h{dI`}}}Ib}0{{{h{BKl}}{h{dI`}}}Ib}0{{{h{BKn}}{h{dI`}}}Ib}0{{{h{BL`}}{h{dI`}}}Ib}0{{{h{BLb}}{h{dI`}}}Ib}0{{{h{BLd}}{h{dI`}}}Ib}0{{{h{{BLf{c}}}}{h{dI`}}}IbGn}{{{h{{BLf{c}}}}{h{dI`}}}IbB@`}{{{h{BHl}}{h{dI`}}}Ib}0{{{h{BLh}}{h{dI`}}}Ib}0{{{h{dI`}}{h{{A@l{c}}}}}{{A`{lNl}}}B@`}{{}BK`}{cc{}}00{{{h{BGn}}}BGn}1{DhBH`}{BGnBH`}{BMdBH`}{AChBH`}{HdBH`}6{{{h{BH`}}}BH`}{KjBH`}{ACjBH`}{ABhBH`}{AC`BH`};{BMfJb}<<<<{AClBIb}==========={{{h{Bj}}}BJf}>>>>{HdBJj}?????????????????{{{h{{A@l{A@j}}}}}{{A`{BGnBDn}}}}{{{h{{A@l{A@j}}}}}{{A`{BH`BEh}}}}{c{{A`{{Af{e}}Fl}}}{{AF`{}{{Mb{{h{BH`}}}}}}}BMh}2{c{{A`{BH`BEh}}}{{Ej{{A@l{A@j}}}}}}{cBH`{{Ej{{A@l{A@j}}}}}}{BGnBH`}{{{D`{{h{BH`}}}}}{{A`{cFl}}}BMh}{{{h{BH`}}}{{A`{BHhFl}}}}{{{h{Bj}}}BGn}{{{h{Bj}}}BH`}{{{h{Bj}}}{{A`{BHfBMj}}}}{{{h{Bj}}}{{A`{BGnBDn}}}}{{{h{Bj}}}{{A`{BH`}}}}{{{h{Bj}}}{{A`{BH`BEh}}}}{{{h{Bj}}}{{A`{BI`B@h}}}}{{{h{Bj}}}{{A`{BBh}}}}{{{h{Bj}}}{{A`{BIbFl}}}}{{{h{Bj}}}{{A`{{BIf{c}}}}}BMh}{{{h{Bj}}}{{A`{BJdc}}}{}}{{{h{Bj}}}{{A`{BJjc}}}{}}{{{h{Bj}}}{{A`{BJnFl}}}}{{{h{Bj}}}{{A`{BHjFl}}}}{{{h{Bj}}}{{A`{BKdFl}}}}{{{h{Bj}}}{{A`{{BLf{c}}e}}}BMh{}}{{{h{Bj}}}{{A`{BHlFl}}}}{{{h{Bj}}}{{A`{BLhFl}}}}{{{h{BHf}}}{{h{Bj}}}}{{{h{Jb}}c}{{D`{{h{BH`}}}}}BLj}{{{h{Jb}}c}{{BMl{BH`}}}BLj}{{{h{BHh}}}{{D`{{h{Bj}}}}}}{{{h{BHh}}}{{D`{{h{BHd}}}}}}{{{h{dJb}}c}{{D`{{h{dBH`}}}}}BLj}2{{{h{BHh}}c}{{D`{{h{Bj}}}}}{{Ej{Bj}}}}{{{h{BHh}}c}{{D`{{h{BHd}}}}}{{Ej{Bj}}}}{{}BHj}{{{h{BHf}}{h{dc}}}lAAf}{{{h{BGn}}{h{dc}}}lAAf}{{{h{BH`}}{h{dc}}}lAAf}{{{h{BBh}}{h{dc}}}lAAf}{{{h{BHj}}{h{dc}}}lAAf}{{{h{{BLf{c}}}}{h{de}}}lBCdAAf}{{}BIh}{{}BK`}{{{h{dI`}}{h{{A@l{A@j}}}}}{{A`{lNl}}}}92{{{h{dJb}}BGnBH`}BMn}{ce{}{}}00000000000000000000000000000000000000000{{{h{BJj}}}Hd}{{{BLf{c}}}{{D`{c}}}{}}{Jb}{{{h{Jb}}}}{BHfKb}{{{h{{BLf{c}}}}}Fj{}}{{{h{BHh}}}Fj}{{{h{BH`}}}Fj}{{{h{Jb}}}Fj}{{{h{BHh}}c}Fj{{Ej{Bj}}}}{{{h{BHb}}}Fj}044{{{h{BHf}}}Fj}146{{{h{BHb}}c}Fj{{Ej{Bj}}}}01{{{h{{BLf{c}}}}}{{D`{{h{c}}}}}{}}`{{{h{Jb}}}BN`}{{}BK`}{{}BIh}1{{{h{Jb}}}BNb}`{{{h{BH`}}}Hd}{{{h{Jb}}}Hd}0`{{{h{BHf}}{h{BHf}}}Fj}{c{{BIf{c}}}{}}0{{}BGn}0000000000000000000000{{{h{BIl}}c}{{D`{BHj}}}{{AF`{}{{Mb{{h{BHj}}}}}}}}{{}Jb}{{cBId}{{BIf{c}}}{}}{{FjKb}BKd}{KbBKd}0{{}BKb}=`{{{h{c}}}{{A`{BFlFl}}}Fh}{{{h{Bj}}}{{A`{BHfBMj}}}}{{{h{c}}}{{A`{BBhFl}}}Fh}{{{h{c}}}{{A`{BIhFl}}}Fh}{{{h{c}}}{{A`{BIjFl}}}Fh}{{{h{c}}}{{A`{BIlFl}}}Fh}{{{h{c}}}{{A`{BInFl}}}Fh}{{{h{c}}}{{A`{BJ`Fl}}}Fh}{{{h{c}}}{{A`{BJbFl}}}Fh}{{{h{c}}}{{A`{BHhFl}}}Fh}{{{h{c}}}{{A`{BJhFl}}}Fh}{{{h{c}}}{{A`{BJjFl}}}Fh}{{{h{c}}}{{A`{BJlFl}}}Fh}{{{h{c}}}{{A`{BK`Fl}}}Fh}{{{h{c}}}{{A`{BKbFl}}}Fh}{{{h{c}}}{{A`{BKfFl}}}Fh}{{{h{c}}}{{A`{BKhFl}}}Fh}{{{h{c}}}{{A`{BKjFl}}}Fh}{{{h{c}}}{{A`{BKlFl}}}Fh}{{{h{c}}}{{A`{BKnFl}}}Fh}{{{h{c}}}{{A`{BL`Fl}}}Fh}{{{h{c}}}{{A`{BLbFl}}}Fh}{{{h{c}}}{{A`{BLdFl}}}Fh}{{{h{c}}}{{A`{BHlFl}}}Fh}{{{h{Bj}}}{{A`{BHdFl}}}}{{{h{BH`}}{h{BH`}}}{{D`{ACf}}}}{{{h{BH`}}{h{Bj}}}{{D`{ACf}}}}{{{h{BH`}}{h{{h{c}}}}}{{D`{ACf}}}ADf}{{{h{BH`}}{h{Kb}}}{{D`{ACf}}}}{{{h{{h{BH`}}}}{h{BH`}}}{{D`{ACf}}}}{{{h{BH`}}{h{{A@l{A@j}}}}}{{D`{ACf}}}}{{{h{BIb}}{h{BIb}}}{{D`{ACf}}}}{{{h{BId}}{h{BId}}}{{D`{ACf}}}}{{{h{{BIf{c}}}}{h{{BIf{c}}}}}{{D`{ACf}}}BLn}{{{h{BJj}}{h{BJj}}}{{D`{ACf}}}}{{{h{BJj}}{h{Hd}}}{{D`{ACf}}}}{{{h{{BLf{c}}}}{h{{BLf{c}}}}}{{D`{ACf}}}BNd}{{}BK`}0{{{h{BIh}}}Kf}{{{h{BIl}}}{{D`{{BLf{BHj}}}}}}{{{h{BIn}}}{{BLf{BHf}}}}{{{h{BHf}}}{{h{Bj}}}}{{{h{BHf}}}{{D`{{h{Bj}}}}}}{{{h{BHf}}}{{`{{AF`{}{{Mb{{h{Bj}}}}}}}}}}{cBId{{BNf{BId}}}}`{{{h{BIh}}}{{Af{Kf}}}}{{{h{BIl}}}{{Af{{BLf{BHj}}}}}}{{{h{BIn}}}{{Af{{BLf{BHf}}}}}}5{{{h{dJb}}c}BMnBLj}{{{h{dJb}}Hd}l}{{{h{dJb}}c}l{{BNh{{h{BGn}}{h{dBH`}}}{{B`{Fj}}}}}}8{{{h{dBH`}}Fj}l}{{{h{dBKd}}c}l{{If{Kb}}}}{{}BIh}{{{h{BEh}}}En}{KbBKd}{{{h{BKd}}{h{BKd}}}Fj}0{{{h{BKd}}}{{h{Bj}}}}4{BBhBH`}{{{h{c}}}e{}{}}00000000000000000000000000000000000000{{{h{BLh}}Kj}{{D`{{Bl{KjKj}}}}}}{{{h{BH`}}}{{A`{{h{Bj}}BMb}}}}{{{h{c}}}Kb{}}0000000000000000000000000000000000000{c{{A`{e}}}{}{}}000{{{h{Bj}}}{{A`{BGn}}}}{{{h{Kb}}}{{A`{BGn}}}}{{{Af{A@j}}}{{A`{BGn}}}}{Kb{{A`{BGn}}}}{{{h{{A@l{A@j}}}}}{{A`{BGn}}}}{Kb{{A`{BH`}}}}{{{h{Bj}}}{{A`{BH`}}}}7{{{Af{A@j}}}{{A`{BH`}}}}{{{h{{A@l{A@j}}}}}{{A`{BH`}}}}{{{h{Kb}}}{{A`{BH`}}}}::::{{{h{Bj}}}{{A`{BBh}}}};;;{ABl{{A`{BId}}}}<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<{{{Db{}{{Cf{c}}}}}{{A`{{Bl{BGnBH`}}c}}}{{If{n}}}}{c{{A`{{Bl{BGnBH`}}}}}{}}000000000000000000000{{{Gh{}{{Cf{c}}}}}{{A`{BH`c}}}{{If{n}}}}{BH`{{A`{BH`}}}}{{{h{BH`}}}{{A`{BH`}}}}{BBh{{A`{BH`}}}}{BIb{{A`{BH`}}}}{BIh{{A`{BH`c}}}{}}{BIj{{A`{BH`c}}}{}}{BIl{{A`{BH`c}}}{}}{BIn{{A`{BH`c}}}{}}{BJ`{{A`{BH`c}}}{}}{BJb{{A`{BH`c}}}{}}{BHh{{A`{BH`c}}}{}}{BJh{{A`{BH`c}}}{}}{BJj{{A`{BH`c}}}{}}{BJl{{A`{BH`c}}}{}}{BJn{{A`{BH`c}}}{}}{BK`{{A`{BH`c}}}{}}{BKb{{A`{BH`c}}}{}}{BKd{{A`{BH`c}}}{}}{BKf{{A`{BH`c}}}{}}{BKh{{A`{BH`c}}}{}}{BKj{{A`{BH`c}}}{}}{BKl{{A`{BH`c}}}{}}{BKn{{A`{BH`c}}}{}}{BL`{{A`{BH`c}}}{}}{BLb{{A`{BH`c}}}{}}{BLd{{A`{BH`c}}}{}}{BHl{{A`{BH`c}}}{}}{{{h{c}}}Mh{}}00000000000000000000000000000000000000000{{{h{BHf}}}{{A`{lBHn}}}}`{{{h{BHf}}}{{D`{{h{Bj}}}}}}{{{h{BHf}}}{{`{{AF`{}{{Mb{{h{Bj}}}}}}}}}}{ce{}{}}00000000000000000000000000000000000000000{KbBKd}`{{{h{BKd}}{h{BKd}}}Fj}0{HdJb}{{}BK`}{c{{BIf{c}}}{}}{{}BHj}``````````{{{h{c}}}{{h{e}}}{}{}}0000{{{h{dc}}}{{h{de}}}{}{}}0000{{{h{BMn}}{h{dI`}}}{{A`{lNl}}}}{{{h{BNb}}{h{dI`}}}{{A`{lNl}}}}{{{h{BN`}}{h{dI`}}}{{A`{lNl}}}}{{{h{BLl}}{h{dI`}}}{{A`{lNl}}}}{{{h{BNj}}{h{dI`}}}{{A`{lNl}}}}{cc{}}0000>>>>>>>>>>{{{h{BMn}}}Fj}{{{h{dBMn}}}D`}{{{h{dBNb}}}D`}{{{h{dBN`}}}D`}{{{h{dBLl}}}D`}{{{h{dBNj}}}D`}{{{h{BMn}}}{{Bl{Hd{D`{Hd}}}}}}{{{h{BNb}}}{{Bl{Hd{D`{Hd}}}}}}{{{h{BN`}}}{{Bl{Hd{D`{Hd}}}}}}{{{h{BLl}}}{{Bl{Hd{D`{Hd}}}}}}{{{h{BNj}}}{{Bl{Hd{D`{Hd}}}}}}{c{{A`{e}}}{}{}}000000000{{{h{c}}}Mh{}}0000{ce{}{}}0000```````````{{{h{{BGj{c}}}}}{{h{Bj}}}{{Ej{Bj}}}}{{{h{BFn}}}{{h{Bj}}}}{{{h{BGl}}}{{h{Bj}}}}21{{{h{BGf}}}{{h{Bj}}}}1{{{h{{BGj{c}}}}}ABh{}}{{BG`c}BG`{}}`{{{h{c}}}{{h{e}}}{}{}}0000000{{{h{dc}}}{{h{de}}}{}{}}0000000{BG`{{A`{Mjn}}}}{{{h{BFn}}}BFn}{{{h{BGf}}}BGf}{{{h{BGl}}}BGl}{{{h{c}}{h{de}}}l{}{}}00{{}BG`}{{}BGh}{{{h{{BGj{c}}}}{h{{BGj{e}}}}}Fj{}{}}{{{h{{BGj{c}}}}{h{ABh}}}Fj{}}{{{h{BFn}}{h{BFn}}}Fj}{{{h{BFn}}{h{Kb}}}Fj}{{{h{BFn}}{h{{h{Bj}}}}}Fj}{{{h{BFn}}{h{Bj}}}Fj}{{{h{BGf}}{h{Kb}}}Fj}{{{h{BGf}}{h{BGf}}}Fj}{{{h{BGf}}{h{Bj}}}Fj}{{{h{BGf}}{h{{h{Bj}}}}}Fj}{{{h{BGl}}{h{BGl}}}Fj}{{{h{BGl}}{h{Bj}}}Fj}{{{h{c}}{h{e}}}Fj{}{}}00000000{{{h{{BGj{c}}}}{h{dI`}}}{{A`{lNl}}}Gn}{{{h{{BGj{c}}}}{h{dI`}}}{{A`{lNl}}}{}}{{{h{BFn}}{h{dI`}}}{{A`{lNl}}}}0{{{h{BG`}}{h{dI`}}}{{A`{lNl}}}}{{{h{BGf}}{h{dI`}}}{{A`{lNl}}}}0{{{h{BGl}}{h{dI`}}}{{A`{lNl}}}}0{{{h{BGh}}{h{dI`}}}{{A`{lNl}}}}{{{h{BEd}}{h{dI`}}}{{A`{lNl}}}}0{{{h{BEf}}{h{dI`}}}{{A`{lNl}}}}0{cc{}}0000{MjBGh}11{BNlBEd}2{BNlBEf}{c{{A`{BFnBEd}}}{{Ej{{A@l{A@j}}}}}}{c{{A`{BGfBEd}}}{{Ej{{A@l{A@j}}}}}}{{{h{Bj}}}BFn}{{{h{Bj}}}BGf}{{{h{Bj}}}{{A`{BFnBEd}}}}{{{h{Bj}}}{{A`{BGfBEd}}}}{{{h{Bj}}}{{A`{BGl}}}}{{{h{BFn}}{h{dc}}}lAAf}{{{h{BGf}}{h{dc}}}lAAf}{{{h{BGl}}{h{dc}}}lAAf}{{{h{BFn}}}{{h{Bj}}}}{ce{}{}}0000000{{}BG`}{{{h{BFn}}{h{Bj}}}{{D`{ACf}}}}{{{h{BFn}}{h{Kb}}}{{D`{ACf}}}}{{{h{BFn}}{h{{h{Bj}}}}}{{D`{ACf}}}}{{{h{BFn}}{h{BFn}}}{{D`{ACf}}}}{{{h{BGf}}{h{Bj}}}{{D`{ACf}}}}{{{h{BGf}}{h{{h{Bj}}}}}{{D`{ACf}}}}{{{h{BGf}}{h{BGf}}}{{D`{ACf}}}}{{{h{BGf}}{h{Kb}}}{{D`{ACf}}}}{{{h{BGf}}}{{h{Bj}}}}{{BG`c}BG`{}}`{{{h{BFn}}}{{D`{{BGj{{h{Bj}}}}}}}}{{{h{BFn}}}{{D`{ABh}}}}{{{h{BGf}}}{{D`{{h{Bj}}}}}}3`{{{h{c}}}e{}{}}00{{{h{c}}}Kb{}}00000{c{{A`{e}}}{}{}}{Kb{{A`{BFn}}}}1{{{h{{A@l{A@j}}}}}{{A`{BFn}}}}{{{h{Bj}}}{{A`{BFn}}}}{{{Af{A@j}}}{{A`{BFn}}}}44{{{h{Kb}}}{{A`{BGf}}}}{{{Af{A@j}}}{{A`{BGf}}}}{{{h{Bj}}}{{A`{BGf}}}}{Kb{{A`{BGf}}}}{{{h{{A@l{A@j}}}}}{{A`{BGf}}}}9{{{h{{A@l{A@j}}}}}{{A`{BGl}}}}{{{h{Bj}}}{{A`{BGl}}}};;;;;;;;;;;{{{h{c}}}Mh{}}0000000{ce{}{}}0000000``````````````{{BNnc}BNnDb}{BNnBNn}{{{h{c}}}{{h{e}}}{}{}}00000000{{{h{dc}}}{{h{de}}}{}{}}00000000{{{h{BNn}}}BNn}{{{h{BO`}}}BO`}{{{h{BOb}}}BOb}{{{h{BOd}}}BOd}{{{h{c}}{h{de}}}l{}{}}000{{BOf{h{Bj}}c}BOf{{Bb{{h{Cd}}}{{B`{Kb}}}}}}{{BOf{h{Bj}}c}BOf{{Bb{{h{Hb}}}{{B`{Kb}}}}}}{{}{{BOh{c}}}{}}{{}BNn}{{}BOf}{{}BO`}{{}BOb}{{}BOd}{{{BOh{c}}e}{{BOh{c}}}{}{{Bb{{Hb{c}}}{{B`{{BOl{{BOj{c}}}}}}}}}}00{{BOfc}BOf{{If{Kb}}}}0{{{h{BNn}}{h{dI`}}}Ib}{{{h{BOf}}{h{dI`}}}Ib}{{{h{BO`}}{h{dI`}}}Ib}{{{h{BOb}}{h{dI`}}}Ib}{{{h{BOd}}{h{dI`}}}Ib}{cc{}}00000000{{{BOh{c}}Ene}{{BOh{c}}}{}{{Bb{{Hb{c}}}{{B`{{BOl{{BOj{c}}}}}}}}}}{ce{}{}}00000000{{BOfc}BOf{{If{{On{Bj}}}}}}{c{{BOn{c}}}{}}{{Fjc}{{C@`{c}}}{}}{{}{{BOh{c}}}{}}{{}BNn}{{{h{Bj}}}BOf}{BO`BOb}{{{h{{BOn{g}}}}e}i{}{{ANh{c}}}{{Nd{ec}}}{}}{{{h{{C@`{m}}}}i}o{}{}{}{{ANh{c}{{H`{{Hb{e}}}}{Cf{g}}}}}{}{{Nd{ic}{{H`{{Hb{k}}}}{Cf{g}}}}}{}}{{{h{{BOh{c}}}}e}g{}{{ANh{Cd}{{H`{{Hb{c}}}}{Cf{Ch}}}}}{}}{{{h{BNn}}e}g{}{{ANh{Cd}{{H`{{Hb{c}}}}{Cf{Ch}}}}}{}}{{{h{BOf}}e}gBh{{ANh{Cd}{{H`{{Hb{c}}}}{Cf{Ch}}}}}{}}{{{h{BOb}}e}g{}{{ANh{Cd}{{H`{{Hb{c}}}}{Cf{Ch}}}}}{}}{{{h{BOd}}e}gBh{{ANh{Cd}{{H`{{Hb{c}}}}{Cf{Ch}}}}}{}}{{{h{c}}}e{}{}}000{{}BOb}{c{{A`{e}}}{}{}}00000000000000000{{{h{c}}}Mh{}}00000000{ce{}{}}00000000```{{{h{C@b}}}{{h{C@d}}}}{{{h{C@f}}c}{}Fd}{{{h{C@h}}c}{}Fd}{{{h{c}}}{{h{e}}}{}{}}00{{{h{dc}}}{{h{de}}}{}{}}00{{{h{C@b}}}C@b}{{{h{c}}{h{de}}}l{}{}}{{}C@b}{{{h{C@f}}{h{dI`}}}{{A`{lNl}}}}{{{h{C@b}}{h{dI`}}}{{A`{lNl}}}}{{{h{C@h}}{h{dI`}}}{{A`{lNl}}}}{C@jC@f}{cc{}}00{{{h{C@b}}}Hd}>>>{{}Fj}`{{}{{A`{C@fAGf}}}}{{}C@h}`{C@h{{A`{lAGf}}}}{C@h{{A`{AC`AGf}}}}`{cC@lFd}{{{h{C@f}}c}C@lFd}{{{h{C@b}}}l}{{{h{C@b}}AC`}l}``{{{h{c}}}e{}{}}{{{h{C@f}}}{{h{C@j}}}}{{}{{D`{C@b}}}}{c{{A`{e}}}{}{}}00000{{{h{c}}}Mh{}}00{ce{}{}}00````````````````{{{h{C@n}}}{{A`{{Bl{CA`Ad}}AGf}}}}{{{h{CAb}}}{{A`{{Bl{CAdCAf}}AGf}}}}{{{h{C@n}}}CAh}{{{h{CAj}}}CAh}{{{h{CA`}}}CAh}{{{h{CAl}}}CAh}{{{h{CAn}}}CAh}{{{h{CAb}}}CAh}{{{h{CAd}}}CAh}{{{h{C@n}}}AC`}{{{h{CAj}}}AC`}{{{h{CA`}}}AC`}{{{h{CAl}}}AC`}{{{h{CAn}}}AC`}{{{h{CAb}}}AC`}{{{h{CAd}}}AC`}{{{h{CA`}}CB`e}{{A`{cAGf}}}{}{{BNh{}{{B`{{A`{cAGf}}}}}}}}{{{h{CAl}}CB`e}{{A`{cAGf}}}{}{{BNh{}{{B`{{A`{cAGf}}}}}}}}{{{h{CAn}}CB`e}{{A`{cAGf}}}{}{{BNh{}{{B`{{A`{cAGf}}}}}}}}{{{h{CAd}}CB`e}{{A`{cAGf}}}{}{{BNh{}{{B`{{A`{cAGf}}}}}}}}{c{{A`{C@nAGf}}}CBb}{{{h{CAj}}Ad}{{A`{lAGf}}}}{c{{A`{CAlAGf}}}CBb}{c{{A`{CAnAGf}}}{{Ej{Eh}}}}{c{{A`{CAbAGf}}}{{Ej{Eh}}}}{{{h{CAj}}{D`{{h{{A@l{A@j}}}}}}}{{A`{lAGf}}}}{{{h{CAl}}{D`{{h{{A@l{A@j}}}}}}}{{A`{lAGf}}}}{{CBdCBd}CBd}0{{{h{dCBd}}CBd}l}{{{h{c}}}{{h{e}}}{}{}}0000000{{{h{dc}}}{{h{de}}}{}{}}0000000{{{h{CAl}}}{{A`{FjAGf}}}}{{{h{CBd}}}CBd}{{{h{c}}{h{de}}}l{}{}}{{{h{CBd}}{h{CBd}}}ACf}{{{h{c}}{h{e}}}ACf{}{}}{{CAjAd}{{A`{CA`AGf}}}}{c{{A`{CA`AGf}}}CBb}{{{h{CAl}}c}{{A`{lAGf}}}CBb}{{{h{CAn}}c}{{A`{lAGf}}}{{Ej{Eh}}}}{c{{A`{CAdAGf}}}{{Ej{Eh}}}}{{{h{CAj}}}{{A`{{D`{{Af{A@j}}}}AGf}}}}{{{h{CAl}}}{{A`{{D`{{Af{A@j}}}}AGf}}}}{{{h{CBd}}{h{CBd}}}Fj}{{{h{c}}{h{e}}}Fj{}{}}00{{{h{CBd}}{h{dI`}}}{{A`{lNl}}}}{{{h{C@n}}{h{dI`}}}{{A`{lNl}}}}{{{h{CAj}}{h{dI`}}}{{A`{lNl}}}}{{{h{CA`}}{h{dI`}}}{{A`{lNl}}}}{{{h{CAl}}{h{dI`}}}{{A`{lNl}}}}{{{h{CAn}}{h{dI`}}}{{A`{lNl}}}}{{{h{CAb}}{h{dI`}}}{{A`{lNl}}}}{{{h{CAd}}{h{dI`}}}{{A`{lNl}}}}{cc{}}0000000{CBf{{A`{CA`AGf}}}}{CBf{{A`{CAdAGf}}}}{AC`CAj}{Jh{{A`{C@nAGf}}}}{CBh{{A`{CA`AGf}}}}{CBj{{A`{CAlAGf}}}}{CBl{{A`{CAnAGf}}}}{Jj{{A`{CAbAGf}}}}{CBn{{A`{CAdAGf}}}}{CBhCAj}{ce{}{}}0000000{CAjAC`}{CA`{{Bl{CC`CCb}}}}{CAd{{Bl{CCdCCf}}}}{C@n{{A`{JhAGf}}}}{CA`{{A`{CBhAGf}}}}{CAl{{A`{CBjAGf}}}}{CAn{{A`{CBlAGf}}}}{CAb{{A`{JjAGf}}}}{CAd{{A`{CBnAGf}}}}{CBdFj}000000{{{h{CA`}}}Fj}{{{h{CAd}}}Fj}{{{h{CAl}}CChCCh}{{A`{lAGf}}}}{{{h{CAl}}{h{CCj}}Dh}{{A`{lAGf}}}}{{{h{CAj}}}{{A`{FjAGf}}}}21{{{h{CAj}}}{{A`{{D`{Fn}}AGf}}}}{{{h{CA`}}}{{A`{{D`{Fn}}AGf}}}}{{CAjDh}{{A`{C@nAGf}}}}{{{h{C@n}}}{{A`{AdAGf}}}}{{{h{CAj}}}{{A`{AdAGf}}}}{{{h{CA`}}}{{A`{AdAGf}}}}{{{h{CAl}}}{{A`{AdAGf}}}}{{{h{CAn}}}{{A`{CAfAGf}}}}{{{h{CAb}}}{{A`{CAfAGf}}}}{{{h{CAd}}}{{A`{CAfAGf}}}}{{{h{CAl}}}{{A`{FjAGf}}}}0{{{h{CAl}}}{{A`{DhAGf}}}}{{}{{A`{CAjAGf}}}}0={{{h{CA`}}}{{A`{FjAGf}}}}{{}{{A`{{Bl{CAnCAn}}AGf}}}}{{}{{A`{{Bl{CAdCAd}}AGf}}}}{{{h{CBd}}{h{CBd}}}{{D`{ACf}}}}{{{h{CA`}}{h{d{A@l{A@j}}}}}{{A`{HdAGf}}}}{{{h{CAl}}{h{d{A@l{A@j}}}}}{{A`{{Bl{HdAd}}AGf}}}}<=<;9{{{h{CAd}}}{{A`{CClAGf}}}}{{{h{C@n}}{h{dLb}}}{{Ld{{A`{{Bl{CA`Ad}}AGf}}}}}}{{{h{CAb}}{h{dLb}}}{{Ld{{A`{{Bl{CAdCAf}}AGf}}}}}}{{{L`{{h{dCA`}}}}{h{dLb}}}{{Ld{{A`{lAGf}}}}}}{{{L`{{h{dCAd}}}}{h{dLb}}}{{Ld{{A`{lAGf}}}}}}{{{h{CA`}}{h{dLb}}{h{dCCn}}}{{Ld{{A`{HdAGf}}}}}}{{{h{CAl}}{h{dLb}}{h{dCCn}}}{{Ld{{A`{AdAGf}}}}}}{{{h{CAl}}{h{dLb}}}{{Ld{{A`{AdAGf}}}}}}{{{L`{{h{dCA`}}}}{h{dLb}}{h{dCCn}}}{{Ld{{A`{lAGf}}}}}}{{{L`{{h{dCAd}}}}{h{dLb}}{h{dCCn}}}{{Ld{{A`{lAGf}}}}}}{{{h{CA`}}{h{dLb}}}{{Ld{{A`{lAGf}}}}}}{{{h{CAd}}{h{dLb}}}{{Ld{{A`{lAGf}}}}}}{{{h{CAl}}{h{dLb}}{h{dCCn}}}{{Ld{{A`{lAGf}}}}}}{{{h{CAn}}{h{dLb}}{h{dCCn}}}{{Ld{{A`{lAGf}}}}}}7{{{h{CAn}}{h{dLb}}{h{dCCn}}}{{Ld{{A`{CAfAGf}}}}}}{{{h{CAl}}{h{dLb}}}{{Ld{{A`{lAGf}}}}}}{{{h{CAn}}{h{dLb}}}{{Ld{{A`{lAGf}}}}}}{{{h{CAl}}{h{dLb}}{h{{A@l{A@j}}}}}{{Ld{{A`{HdAGf}}}}}}{{{h{CAn}}{h{dLb}}{h{{A@l{A@j}}}}}{{Ld{{A`{HdAGf}}}}}}32{{{h{CAl}}{h{dLb}}{h{{A@l{A@j}}}}Ad}{{Ld{{A`{HdAGf}}}}}}{{{h{CAn}}{h{dLb}}{h{{A@l{A@j}}}}c}{{Ld{{A`{HdAGf}}}}}{{Ej{Eh}}}}{{{L`{{h{dCA`}}}}{h{dLb}}}{{Ld{{A`{lAGf}}}}}}{{{L`{{h{dCAd}}}}{h{dLb}}}{{Ld{{A`{lAGf}}}}}}{{{L`{{h{dCA`}}}}{h{dLb}}{h{{A@l{A@j}}}}}{{Ld{{A`{HdAGf}}}}}}{{{L`{{h{dCAd}}}}{h{dLb}}{h{{A@l{A@j}}}}}{{Ld{{A`{HdAGf}}}}}}>={{{L`{{h{dCA`}}}}{h{dLb}}{h{{A@l{CD`}}}}}{{Ld{{A`{HdAGf}}}}}}{{{L`{{h{dCAd}}}}{h{dLb}}{h{{A@l{CD`}}}}}{{Ld{{A`{HdAGf}}}}}}{{{h{CA`}}}{{A`{lAGf}}}}{{{h{CAl}}}{{A`{lAGf}}}}{{{h{CAn}}}{{A`{lAGf}}}}{{{h{CAd}}}{{A`{lAGf}}}}{{{h{CA`}}CB`}{{A`{CBdAGf}}}}{{{h{CAl}}CB`}{{A`{CBdAGf}}}}{{{h{CAn}}CB`}{{A`{CBdAGf}}}}{{{h{CAd}}CB`}{{A`{CBdAGf}}}}{{{h{CAl}}{h{d{A@l{A@j}}}}}{{A`{HdAGf}}}}{{{h{CAn}}{h{d{A@l{A@j}}}}}{{A`{HdAGf}}}}{{{h{CAl}}{h{dc}}}{{A`{HdAGf}}}CDb}{{{h{CAn}}{h{dc}}}{{A`{HdAGf}}}CDb}{{{h{CAl}}{h{dc}}}{{A`{{Bl{HdAd}}AGf}}}CDb}{{{h{CAn}}{h{dc}}}{{A`{{Bl{HdCAf}}AGf}}}CDb}{{{h{CAj}}}{{A`{DhAGf}}}}{{{h{CAl}}{h{d{A@l{A@j}}}}}{{A`{{Bl{HdAd}}AGf}}}}{{{h{CAn}}{h{d{A@l{A@j}}}}}{{A`{{Bl{HdCAf}}AGf}}}}{{{h{CAj}}}{{A`{FjAGf}}}}0{{{h{CAl}}{h{{A@l{A@j}}}}}{{A`{HdAGf}}}}{{{h{CAn}}{h{{A@l{A@j}}}}}{{A`{HdAGf}}}}5{{{h{CAl}}{h{{A@l{A@j}}}}c}{{A`{HdAGf}}}CBb}{{{h{CAn}}{h{{A@l{A@j}}}}c}{{A`{HdAGf}}}{{Ej{Eh}}}}{{{h{CAl}}Fj}{{A`{lAGf}}}}{{{h{CAj}}Fj}{{A`{lAGf}}}}{{{h{CAj}}{D`{Fn}}}{{A`{lAGf}}}}{{{h{CA`}}{D`{Fn}}}{{A`{lAGf}}}}33{{{h{CAl}}Dh}{{A`{lAGf}}}}3{{{h{CA`}}Fj}{{A`{lAGf}}}}{{{h{CAj}}Dh}{{A`{lAGf}}}}55002{{{h{C@n}}Dh}{{A`{lAGf}}}}{{{h{CA`}}Dh}{{A`{lAGf}}}}4{{{h{CAn}}CDd}{{A`{lAGf}}}}{{{h{dCA`}}}{{Bl{CDfCDh}}}}{{{h{dCAd}}}{{Bl{CDjCDl}}}}{{CBdCBd}CBd}{{{h{CAj}}}{{A`{{D`{AGf}}AGf}}}}{{{h{CA`}}}{{A`{{D`{AGf}}AGf}}}}{{{h{CAl}}}{{A`{{D`{AGf}}AGf}}}}{{{h{CAn}}}{{A`{{D`{AGf}}AGf}}}}{{{h{CAb}}}{{A`{{D`{AGf}}AGf}}}}{{{h{CAd}}}{{A`{{D`{AGf}}AGf}}}}{{{h{c}}}e{}{}}{{{h{CAj}}}{{A`{DhAGf}}}}{{{h{CAl}}}{{A`{DhAGf}}}}{c{{A`{e}}}{}{}}0{Jh{{A`{C@n}}}}11{CBh{{A`{CA`}}}}2{CBj{{A`{CAl}}}}{CBl{{A`{CAn}}}}4{Jj{{A`{CAbAGf}}}}55{CBn{{A`{CAdAGf}}}}66666666{{{h{CA`}}CB`e}{{A`{cAGf}}}{}{{Gb{}{{B`{{A`{cAGf}}}}}}}}{{{h{CAl}}CB`e}{{A`{cAGf}}}{}{{Gb{}{{B`{{A`{cAGf}}}}}}}}{{{h{CAn}}CB`e}{{A`{cAGf}}}{}{{Gb{}{{B`{{A`{cAGf}}}}}}}}{{{h{CAd}}CB`e}{{A`{cAGf}}}{}{{Gb{}{{B`{{A`{cAGf}}}}}}}}{{{h{CAl}}{h{d{A@l{A@j}}}}}{{A`{{Bl{HdAd}}AGf}}}}{{{h{CAl}}}{{A`{AdAGf}}}}{{{h{CA`}}{h{d{A@l{A@j}}}}}{{A`{HdAGf}}}}{{{h{CAd}}{h{d{A@l{A@j}}}}}{{A`{HdAGf}}}}{{{h{CA`}}{h{dc}}}{{A`{HdAGf}}}CDb}{{{h{CAd}}{h{dc}}}{{A`{HdAGf}}}CDb}{{{h{CA`}}{h{d{A@l{CDn}}}}}{{A`{HdAGf}}}}{{{h{CAd}}{h{d{A@l{CDn}}}}}{{A`{HdAGf}}}}{{{h{CAl}}{h{d{A@l{A@j}}}}}{{A`{HdAGf}}}}{{{h{CAn}}{h{d{A@l{A@j}}}}}{{A`{HdAGf}}}}{{{h{CAl}}{h{dc}}}{{A`{HdAGf}}}CDb}{{{h{CAn}}{h{dc}}}{{A`{HdAGf}}}CDb}{{{h{CAl}}{h{dc}}}{{A`{{Bl{HdAd}}AGf}}}CDb}{{{h{CAn}}{h{dc}}}{{A`{{Bl{HdCAf}}AGf}}}CDb}={{{h{CAn}}{h{d{A@l{A@j}}}}}{{A`{{Bl{HdCAf}}AGf}}}}{{{h{CAl}}{h{{A@l{A@j}}}}}{{A`{HdAGf}}}}{{{h{CAn}}{h{{A@l{A@j}}}}}{{A`{HdAGf}}}}{{{h{CAl}}{h{{A@l{A@j}}}}Ad}{{A`{HdAGf}}}}{{{h{CAn}}{h{{A@l{A@j}}}}c}{{A`{HdAGf}}}{{Ej{Eh}}}}{{{h{CA`}}{h{{A@l{A@j}}}}}{{A`{HdAGf}}}}{{{h{CAd}}{h{{A@l{A@j}}}}}{{A`{HdAGf}}}}{{{h{CA`}}{h{{A@l{CD`}}}}}{{A`{HdAGf}}}}{{{h{CAd}}{h{{A@l{CD`}}}}}{{A`{HdAGf}}}}{{{h{C@n}}}{{A`{DhAGf}}}}{{{h{CA`}}}{{A`{DhAGf}}}}{{{h{CAl}}}{{A`{DhAGf}}}}{{{h{c}}}Mh{}}0000000{{}{{A`{CAnAGf}}}}{ce{}{}}0000000{{{h{CA`}}}{{A`{lAGf}}}}{{{h{CAl}}}{{A`{lAGf}}}}{{{h{CAn}}}{{A`{lAGf}}}}{{{h{CAd}}}{{A`{lAGf}}}}{{}{{A`{lAGf}}}}```{{}CE`}{{{h{CE`}}}AC`}{{{h{c}}}{{h{e}}}{}{}}0{{{h{dc}}}{{h{de}}}{}{}}03{{{h{CE`}}}CE`}{{{h{c}}{h{de}}}l{}{}}{{{h{CE`}}{h{CE`}}}Fj}{{{h{c}}{h{e}}}Fj{}{}}00{{{h{CE`}}{h{dI`}}}{{A`{lNl}}}}{{{h{CEb}}{h{dI`}}}{{A`{lNl}}}}{AC`CE`}{cc{}}01;{{{h{CE`}}{h{dc}}}lAAf}<{ce{}{}}0=={{{h{dCEb}}{h{dLb}}}{{Ld{{D`{l}}}}}}>{{{h{dCEb}}}{{D`{l}}}}{CE`{{A`{CEbAGf}}}}{{}CE`}{{{h{c}}}e{}{}}{c{{A`{e}}}{}{}}000{{{h{c}}}Mh{}}033773``{{{h{{C@l{c}}}}}l{}}{{{h{{C@l{c}}}}}CEd{}}{{{h{c}}}{{h{e}}}{}{}}0{{{h{dc}}}{{h{de}}}{}{}}0{{{h{d{C@l{c}}}}}l{}}{{{h{CEf}}{h{dI`}}}{{A`{lNl}}}}0{{{h{{C@l{c}}}}{h{dI`}}}{{A`{lNl}}}Gn}{cc{}}0??{c{}{}}{CEf{{M`{Kl}}}}{{{h{CEf}}}Fj}{{{h{{C@l{c}}}}}Fj{}}1{{{L`{{h{d{C@l{c}}}}}}{h{dLb}}}Ld{}}{e{{C@l{c}}}Bd{{Gb{}{{B`{c}}}}Bd}}{{{h{c}}}Kb{}}{c{{A`{e}}}{}{}}000{CEf{{A`{{M`{Kl}}CEf}}}}{{{L`{{h{dc}}}}{h{dLb}}}Ld{}}{{{h{c}}}Mh{}}0{ce{}{}}0{{}l}````{{CEhFn}CEh}{{{h{dCEh}}Fn}l}{{{h{c}}}{{h{e}}}{}{}}000{{{h{dc}}}{{h{de}}}{}{}}000{{{h{CEh}}Fn}{{D`{CEh}}}}{{{h{CEh}}CEh}{{D`{Fn}}}}1{{{h{CEh}}}CEh}{{{h{c}}{h{de}}}l{}{}}{{{h{CEh}}{h{CEh}}}ACf}{{{h{c}}{h{e}}}ACf{}{}}{{{h{CEj}}}CEh}{{{h{CEh}}CEh}Fn}{{{h{CEh}}}Fn}{{{h{CEh}}{h{CEh}}}Fj}{{{h{c}}{h{e}}}Fj{}{}}00{{{h{CEh}}{h{dI`}}}{{A`{lNl}}}}{{{h{CEl}}{h{dI`}}}{{A`{lNl}}}}{{{h{{CEn{c}}}}{h{dI`}}}{{A`{lNl}}}Gn}{{{h{CEj}}{h{dI`}}}{{A`{lNl}}}}{cc{}}{ABjCEh}1110{{{h{d{CEn{c}}}}}{{h{dc}}}{}}{{{h{{CEn{c}}}}}{{h{c}}}{}}{{{h{CEh}}{h{dc}}}lAAf}{FnCEl}{{CEhFn}CEl}{ce{}{}}000{c{}{}}0{{{CEn{c}}}c{}}{CEhABj}{{{h{CEj}}}Fj}{{{h{CEl}}}CF`}{{}CEh}{{{h{CEh}}{h{CEh}}}{{D`{ACf}}}}{{{h{CEl}}}Fn}{{{L`{{h{d{CEn{c}}}}}}{h{dLb}}}LdFd}{{{L`{{h{dCEj}}}}{h{dLb}}}Ld}{{{h{dCEl}}{h{dLb}}}{{Ld{CEh}}}}{{{h{dCEl}}}l}{{{L`{{h{dCEj}}}}CEh}l}{{{h{dCEl}}Fn}l}{{{h{dCEl}}CEh}l}3{{{h{CEh}}CEh}Fn}{{{h{dCEl}}CF`}l}{FnCEj}{CEhCEj}{{CEhFn}CEh}{{CEhCEh}Fn}{{{h{dCEh}}Fn}l}{{{h{dCEl}}}CEh}{{Fnc}{{CEn{c}}}Fd}{{{h{c}}}e{}{}}{c{{A`{e}}}{}{}}0000000{{{L`{{h{dc}}}}{h{dLb}}}Ld{}}{{{h{c}}}Mh{}}000{ce{}{}}000``{{CFbc}CFb{}}{{CFbc}CFbDb}{{{h{c}}}{{h{e}}}{}{}}0{{{h{dc}}}{{h{de}}}{}{}}0{{{h{e}}Ah}MdBh{{ANh{Ah}{{H`{{Hb{c}}}}{Cf{Ch}}}}}}{{{h{e}}Ah}gBh{{ANh{Ah}{{H`{{Hb{c}}}}{Cf{Ch}}}}}BB`}{{{h{i}}c}{}{}{}Gn{{ANh{c}{{H`{{Hb{e}}}}{Cf{g}}}}}}{{CFbj}CFb}{{}CFb}`0{{}CFd}`{{{h{dCFd}}c}l{{Ej{{A@l{A@j}}}}}}{{{h{dCFd}}}{{A`{lAGf}}}}{{{h{CFd}}{h{dI`}}}{{A`{lNl}}}}{cc{}}05{i{{`{{ANh{Ah}{{H`{{Hb{c}}}}{Cf{e}}}}}}}{}{}{{Al{Ah}{{Aj{C`}}{H`{{Hb{c}}}}{Cf{e}}}}}{{An{gAh}}}}=??{{CFbKd}CFb}{cCFd{{If{B@l}}}}{{}{{`{{ANh{Cd}{{H`{{Hb{El}}}}{Cf{Ch}}}}}}}}{{CFbce}CFb{{If{{On{Bj}}}}}{{If{{On{Bj}}}}}}:{{CFbAd}CFb}{{{L`{{h{dCFd}}}}{h{dLb}}}{{Ld{{A`{lAGf}}}}}}{{{L`{{h{dCFd}}}}{h{dLb}}{h{dCCn}}}{{Ld{{A`{lAGf}}}}}}1{{{L`{{h{dCFd}}}}{h{dLb}}{h{{A@l{A@j}}}}}{{Ld{{A`{HdAGf}}}}}}>>{{{h{dCFd}}{h{d{A@l{A@j}}}}}{{A`{HdAGf}}}}{{{Hb{c}}}MdBh}{{{Hb{c}}}eBhBB`}```{{CFb{h{g}}}{}{}Gn{{ANh{Ah}{{H`{{Hb{c}}}}{Cf{e}}}}}}{{CFbc}CFbJd}0{{CFbc}CFb{{If{Md}}}}`{En{{`{{ANh{Cd}{{H`{{Hb{El}}}}{Cf{Ch}}}}}}}}{CFb{{Bl{BnIh}}}}{CFbBn}{CFbAh}{CFbCd}{{CFb{f{c}}}{{Hb{c}}}{}}{{{h{e}}Ah}{{A`{g{M`{Ln}}}}}Bh{{ANh{Ah}{{H`{{Hb{c}}}}{Cf{Ch}}}}}BB`}{{{h{i}}c}{{A`{g}}}{}{}Gn{{ANh{c}{{H`{{Hb{e}}}}{Cf{g}}}}}}{c{{A`{e}}}{}{}}000{{{Hb{c}}}{{A`{Md}}}Bh}{{{Hb{c}}}{{A`{e{M`{Ln}}}}}BhBB`}{{{h{c}}}Mh{}}0{{CFb{h{Bj}}}CFb}{{CFbNb}CFb}{ce{}{}}0{{{h{Bj}}}CFb}{{{h{dCFd}}{h{{A@l{A@j}}}}}{{A`{HdAGf}}}}````````````````````````````{{{h{dCFf}}Hd}l}{{{h{dMd}}Hd}l}{{{h{dB@l}}Hd}l}{{{h{dCDb}}Hd}l}1{{{h{dG`}}c}{{h{dG`}}}{}}{{{h{dB@l}}}{{h{d{A@l{A@j}}}}}}{{{h{Md}}}{{h{{A@l{A@j}}}}}}{{{h{B@l}}}{{h{{A@l{A@j}}}}}}{{{h{{CFh{c}}}}}{{h{c}}}{}}{e{{`{{Fd{}{{B`{{A`{cBCl}}}}}}}}}Bd{{Gb{}{{B`{c}}}}Bd}}{{{h{c}}}{{h{e}}}{}{}}4003000000000000000{{{h{dc}}}{{h{de}}}{}{}}060000000000000000{{{h{Md}}}Hd}{{{h{B@l}}}Hd}100{{CFfc}{{CFj{CFfc}}}CFf}{{CDbc}{{CFj{CDbc}}}CDb}{{{h{CFf}}}{{h{{A@l{A@j}}}}}}:9{{{h{dCDb}}}{{h{dCFl}}}}{{{h{dB@l}}}{{h{dCFl}}}}{{{h{CFf}}{h{d{A@l{CD`}}}}}Hd}{{{h{dMd}}}l}{{{h{dB@l}}}l}{{{h{Md}}}Md}{{{h{B@l}}}B@l}{{{h{{CFn{c}}}}}{{CFn{c}}}ADf}{{{h{CG`}}}CG`}{{{h{{CGb{c}}}}}{{CGb{c}}}{BfBf}}{{{h{CGd}}}CGd}{{{h{{CGf{c}}}}}{{CGf{c}}}Bf}{{{h{CGh}}}CGh}{{{h{CGj}}}CGj}{{{h{CGl}}}CGl}{{{h{{CGn{c}}}}}{{CGn{c}}}Bf}{{{h{CH`}}}CH`}{{{h{c}}{h{de}}}l{}{}}00000000000{{{h{Md}}{h{Md}}}ACf}{{{h{B@l}}{h{B@l}}}ACf}{{{h{{CHb{c}}}}{h{{CHb{c}}}}}ACfCHd}{{{h{{CGf{c}}}}{h{{CGf{c}}}}}ACfCHd}{{{h{{CFh{c}}}}{h{{CFh{c}}}}}ACfCHd}{{{h{{CGn{c}}}}{h{{CGn{c}}}}}ACfCHd}{{{h{c}}{h{e}}}ACf{}{}}00000{{{h{dG`}}c}{{h{dG`}}}{{Gb{{h{dG`}}}}}}{{CGhc}CGh{{Bb{Kf}{{B`{Fj}}}}BdKn}}{{CGhFj}CGh}{{{h{{A@l{A@j}}}}}Md}{{{h{dCFf}}Hd}Md}{{{h{dMd}}Hd}Md}{{{h{dB@l}}Hd}Md}{{{h{dCFf}}{h{d{A@l{A@j}}}}}l}{{{h{dG`}}c}{{h{dG`}}}{}}{{}Md}{{}B@l}{{}{{CFn{c}}}AOb}{{}CGd}{{}CGh}{{}CGj}{{}CGl}{{}CH`}{{{h{dG`}}e}{{h{dG`}}}{{Al{Cd}{{Aj{l}}{H`{Hb}}{Cf{Ch}}}}}{{An{cCd}}}}{{}Il}{{{h{Md}}}{{h{{A@l{A@j}}}}}}{{{h{B@l}}}{{h{{A@l{A@j}}}}}}{{{h{{CFn{c}}}}}{{h{{CHf{c}}}}}ADf}{{{h{{CGb{c}}}}}{{h{c}}}Bf}{{{h{{CHb{c}}}}}{{h{c}}}{}}{{{h{{CGf{c}}}}}{{h{c}}}{}}{{{h{{CHh{c}}}}}{{h{c}}}{}}{{{h{{CFh{c}}}}}{{h{e}}}{}{}}{{{h{{CGn{c}}}}}{{h{c}}}{}}{{{h{dB@l}}}{{h{d{A@l{A@j}}}}}}{{{h{d{CHb{c}}}}}{{h{dc}}}{}}{{{h{d{CGf{c}}}}}{{h{dc}}}{}}{{{h{d{CHh{c}}}}}{{h{dc}}}{}}{{{h{d{CFh{c}}}}}{{h{de}}}{}{}}{{{h{d{CGn{c}}}}}{{h{dc}}}{}}{c{{A`{{CFn{e}}}}}CHjBBf}{{{h{dMd}}}l}{{{h{dB@l}}}l}{{{h{Md}}{h{{Af{A@j}}}}}Fj}{{{h{Md}}{h{Md}}}Fj}{{{h{Md}}{h{Bj}}}Fj}{{{h{Md}}{h{{h{c}}}}}FjADf}{{{h{Md}}{h{Kb}}}Fj}{{{h{Md}}{h{B@l}}}Fj}{{{h{Md}}{h{{A@l{A@j}}}}}Fj}{{{h{B@l}}{h{Bj}}}Fj}{{{h{B@l}}{h{Md}}}Fj}{{{h{B@l}}{h{Kb}}}Fj}{{{h{B@l}}{h{B@l}}}Fj}{{{h{B@l}}{h{{Af{A@j}}}}}Fj}{{{h{B@l}}{h{{A@l{A@j}}}}}Fj}{{{h{B@l}}{h{{h{c}}}}}FjADf}{{{h{{CHl{ce}}}}{h{{CHl{ce}}}}}FjBLnBLn}{{{h{{CHb{c}}}}{h{{CHb{c}}}}}FjBLn}{{{h{{CGf{c}}}}{h{{CGf{c}}}}}FjBLn}{{{h{{CFh{c}}}}{h{{CFh{c}}}}}FjBLn}{{{h{{CGn{c}}}}{h{{CGn{c}}}}}FjBLn}{{{h{c}}{h{e}}}Fj{}{}}00000000000000000000{{CGdc}CGd{{Bb{BCn{h{Bn}}}{{B`{Ch}}}}}}{{CGhc}CGh{{Bb{BD`{h{Bn}}}{{B`{Ch}}}}BdKn}}{{CGjc}CGj{{Bb{BDd{h{Bn}}}{{B`{Ch}}}}BdKn}}{{CH`c}CH`{{Bb{BDf{h{Bn}}}{{B`{Ch}}}}BdKn}}{{{h{dB@l}}c}l{{N`{}{{Mb{A@j}}}}}}{{{h{dB@l}}c}l{{N`{}{{Mb{Md}}}}}}{{{h{dB@l}}c}l{{N`{}{{Mb{{h{A@j}}}}}}}}{{{h{dB@l}}{h{{A@l{A@j}}}}}l}{{{h{dG`}}ce}{{h{dG`}}}{{Ej{Bj}}}{{Ej{Bj}}}}{{{h{Md}}{h{dI`}}}{{A`{lNl}}}}00{{{h{B@l}}{h{dI`}}}{{A`{lNl}}}}00{{{h{{CFn{c}}}}{h{dI`}}}Ib{GnADf}}{{{h{CG`}}{h{dI`}}}Ib}{{{h{{CGb{c}}}}{h{dI`}}}Ib{GnBf}}{{{h{{CHl{ce}}}}{h{dI`}}}IbGnGn}{{{h{{CHb{c}}}}{h{dI`}}}IbB@`}{{{h{{CHb{c}}}}{h{dI`}}}IbGn}{{{h{{CGf{c}}}}{h{dI`}}}IbB@`}{{{h{{CGf{c}}}}{h{dI`}}}IbGn}{{{h{{CHh{c}}}}{h{dI`}}}IbB@`}{{{h{{CHh{c}}}}{h{dI`}}}IbGn}{{{h{{CFh{c}}}}{h{dI`}}}IbGn}{{{h{{CFh{c}}}}{h{dI`}}}IbB@`}{{{h{{CGn{c}}}}{h{dI`}}}IbB@`}{{{h{{CGn{c}}}}{h{dI`}}}IbGn}{B@lMd}{cc{}}{CHnMd}1{{{Af{A@j}}}Md}{{{h{Bj}}}Md}{{{M`{{A@l{A@j}}}}}Md}5{{{h{{A@l{A@j}}}}}Md}{KbMd}{CI`Md}{CIbMd}{CIdMd}{{{h{Bj}}}B@l}{{{h{{A@l{A@j}}}}}B@l};;{{{CHf{c}}}{{CFn{c}}}ADf}<<<<<<<<<{c{{CFh{c}}}{}}={CIfc{}}>>>>{cMd{{N`{}{{Mb{A@j}}}}}}{cB@l{{N`{}{{Mb{{h{A@j}}}}}}}}{cB@l{{N`{}{{Mb{A@j}}}}}}{{{h{Bj}}}{{A`{{CGn{c}}BDf}}}BB`}{{{h{Bn}}{h{dIh}}}c{}}000000000>{{}Il}{{{h{dCFf}}}ABl}00{{{h{dCFf}}}ABn}00{{{h{dCFf}}}AEj}00{{{h{dCFf}}}ACj}00{{{h{dCFf}}}AC`}00{{{h{dCFf}}}ACh}00{{{h{dCFf}}}ABf}{{{h{dCFf}}Hd}ACh}00{{{h{{CFn{c}}}}}{{h{c}}}ADf}{{{h{dCFf}}}AMj}00{{{h{dCFf}}}ABh}00{{{h{dCFf}}}Dh}00{{{h{dCFf}}}Kj}00{{{h{dCFf}}}A@j}{{{h{dCFf}}Hd}Kj}00{{{h{CFf}}}Fj}{{{h{CDb}}}Fj}{{{h{Md}}{h{dc}}}lAAf}{{{h{B@l}}{h{dc}}}lAAf}{{}Il}{ce{}{}}00000000000000000{CIhIh}{{{CFn{c}}}{{CHf{c}}}ADf}{{{CGb{c}}}cBf}{{{CHl{{CHh{c}}{CHb{c}}}}}c{}}{{{CHl{{CHb{c}}{CHh{c}}}}}c{}}{{{CHb{c}}}c{}}{{{CGf{c}}}c{}}{{{CHh{c}}}c{}}{{{CFh{c}}}c{}}{{{CGn{c}}}c{}}{{{h{Md}}}}{Md}{{{h{B@l}}}}{B@l}{{{h{Md}}}Fj}{{{h{B@l}}}Fj}1{{{h{Md}}}Hd}{{{h{B@l}}}Hd}{{CDbHd}{{CIj{CDb}}}}{{CGdHd}CGd}{{CGhHd}CGh}{{CGlHd}CGl}{KdIl}{{CGlKf}CGl}{{}Md}{{}B@l}{c{{CFn{c}}}{}}{{ce}CG`{{If{{On{Bj}}}}}{{If{{On{Bj}}}}}}{HdCGl}{{{h{Md}}{h{{h{c}}}}}{{D`{ACf}}}ADf}{{{h{Md}}{h{{A@l{A@j}}}}}{{D`{ACf}}}}{{{h{Md}}{h{Kb}}}{{D`{ACf}}}}{{{h{Md}}{h{Md}}}{{D`{ACf}}}}{{{h{Md}}{h{Bj}}}{{D`{ACf}}}}{{{h{Md}}{h{{Af{A@j}}}}}{{D`{ACf}}}}{{{h{B@l}}{h{{A@l{A@j}}}}}{{D`{ACf}}}}{{{h{B@l}}{h{{h{c}}}}}{{D`{ACf}}}ADf}{{{h{B@l}}{h{Kb}}}{{D`{ACf}}}}{{{h{B@l}}{h{Bj}}}{{D`{ACf}}}}{{{h{B@l}}{h{{Af{A@j}}}}}{{D`{ACf}}}}{{{h{B@l}}{h{B@l}}}{{D`{ACf}}}}{{{h{{CHb{c}}}}{h{{CHb{c}}}}}{{D`{ACf}}}BNd}{{{h{{CGf{c}}}}{h{{CGf{c}}}}}{{D`{ACf}}}BNd}{{{h{{CFh{c}}}}{h{{CFh{c}}}}}{{D`{ACf}}}BNd}{{{h{{CGn{c}}}}{h{{CGn{c}}}}}{{D`{ACf}}}BNd}{{}Il}{CG`CG`}{{{L`{{h{dMd}}}}{h{dLb}}}{{Ld{{D`{{A`{Md}}}}}}}}{{{L`{{h{dB@l}}}}{h{dLb}}}{{Ld{{D`{{A`{Md}}}}}}}}{{{L`{{h{dCIh}}}}{h{dLb}}}{{Ld{{D`{c}}}}}{}}44{{{h{dCDb}}c}lCFf}{{{h{dB@l}}c}lCFf}{{{h{dCDb}}A@jHd}l}{{{h{dB@l}}A@jHd}l}{{{h{dCDb}}ABl}l}00{{{h{dCDb}}ABn}l}00{{{h{dCDb}}AEj}l}00{{{h{dCDb}}ACj}l}00{{{h{dCDb}}AC`}l}00{{{h{dCDb}}ACh}l}00{{{h{dCDb}}ABf}l}{{{h{dCDb}}AChHd}l}00{{{h{dCDb}}{h{{A@l{A@j}}}}}l}{{{h{dB@l}}{h{{A@l{A@j}}}}}l}{{{h{dCDb}}AMj}l}00{{{h{dCDb}}ABh}l}00{{{h{dCDb}}Dh}l}00{{{h{dCDb}}Kj}l}00{{{h{dCDb}}A@j}l}{{{h{dCDb}}KjHd}l}00{CFf{{CIl{CFf}}}}{{ce}CG`{{If{{On{Bj}}}}}{{If{{On{Bj}}}}}}{{CG`{h{dLf}}}l}{{{h{CFf}}}Hd}{{{h{Md}}}Hd}{{{h{B@l}}}Hd}{{{h{CDb}}}Hd}1{{{h{dB@l}}Hd}l}{{{h{dB@l}}HdA@j}l}{cClKh}{{{h{dc}}}{{h{dK`}}}{}}0000{{Md{h{Bn}}}{{f{c}}}{}}{{B@l{h{Bn}}}{{f{c}}}{}}{{CG`{h{Bn}}}{{f{c}}}{}}{{{CHl{ce}}{h{Bn}}}{{f{g}}}DfDf{}}{{{CHb{c}}{h{Bn}}}{{f{e}}}Jd{}}{{{CHh{c}}{h{Bn}}}{{f{e}}}Jd{}}{{}Il}{{{h{dG`}}{h{Bj}}Il}{{h{dG`}}}}{{{h{Bj}}}Cn}{CG`CG`}{{{h{{CFn{c}}}}e}A`JdCIn}{{{h{{CHb{c}}}}e}A`JdCIn}{{{h{{CHh{c}}}}e}A`JdCIn}{cAOfKh}{{{h{dG`}}c}{{h{dG`}}}Ll}{{{h{dB@l}}Hd}l}0{{{h{Md}}}Nj}{{{h{B@l}}}Nj}{{{h{Md}}c}Md{{CJ`{Hd}}}}{{{h{Md}}{h{{A@l{A@j}}}}}Md}{{{h{dB@l}}}{{h{d{A@l{{CJb{A@j}}}}}}}}{{{h{dB@l}}}B@l}{{{h{dMd}}Hd}Md}{{{h{dB@l}}Hd}B@l}10{{{h{dB@l}}}A@j}{{{h{Md}}}A@j}{{{h{B@l}}}A@j}{{CFfHd}{{CJd{CFf}}}}{CG`CG`}{eIlHf{{Fb{c}}}}{cCG`{{If{{On{Bj}}}}}}{CIh{{BOl{Md}}}}{{CIhHd}{{A`{{BOl{Md}}Nn}}}}{{{h{c}}}e{}{}}00000000000{{{h{c}}}Kb{}}0000{{}Il}{{{h{dMd}}Hd}l}{{{h{dB@l}}Hd}l}{c{{A`{e}}}{}{}}00000000000000000000000000000000000{Md{{A`{MdMd}}}}{B@l{{A`{MdB@l}}}}{Md{{A`{BH`}}}}{{{L`{{h{dc}}}}{h{dLb}}}{{Ld{{D`{A`}}}}}{}}{{{h{c}}}Mh{}}00000000000000000{{{h{dB@l}}B@l}l}{{CG`En}CG`}{ce{}{}}00000000000000000{HdB@l}{{{h{dB@l}}CJf}{{A`{lNl}}}}{{{h{dB@l}}{h{Bj}}}{{A`{lNl}}}}{CDb{{CJh{CDb}}}}3`````","D":"AEJhACb","p":[[5,"HttpResponseBuilder",0,6812],[0,"mut"],[5,"HttpResponse",0,6813],[1,"reference"],[5,"Cookie",494,6814],[1,"unit"],[5,"HttpError",3203],[6,"Result",6815],[5,"HttpServer",0,6816],[6,"SocketAddr",6817],[5,"Vec",6818],[5,"Request",6819],[17,"Config"],[10,"ServiceFactory",2658,6820],[10,"IntoServiceFactory",6820],[17,"Output"],[10,"Fn",6821],[10,"Send",6822],[10,"Clone",6823],[10,"MessageBody",370,6824],[1,"str"],[1,"tuple"],[5,"HttpRequest",0,6825],[5,"AppConfig",2658,6826],[5,"App",0,6827],[5,"ServiceRequest",2658,6828],[17,"Error"],[5,"Error",3203,6829],[17,"InitError"],[5,"Resource",0,6830],[5,"Scope",0,6831],[6,"Option",6832],[10,"TryIntoHeaderPair",3910,6833],[5,"CustomizeResponder",0,6834],[10,"Responder",0,6835],[1,"u32"],[8,"Result",6836],[10,"ToSocketAddrs",6837],[5,"SslAcceptorBuilder",6838],[5,"ServerConfig",6839],[5,"ServerConfig",6839],[5,"ServerConfig",6839],[5,"ServerConfig",6839],[5,"Path",6840],[10,"AsRef",6841],[5,"BoxBody",370,6842],[5,"StatusCode",3621,6843],[17,"Future"],[10,"Handler",0,6844],[10,"Future",6845],[17,"Stream"],[10,"HttpMessage",0,6846],[1,"bool"],[6,"ParseError",3203,6847],[5,"Duration",6848],[5,"ServiceConfig",6209,6826],[10,"FnOnce",6821],[5,"ConnectionInfo",2658,6849],[5,"Ref",6850],[10,"TryIntoHeaderValue",3910,6851],[6,"ParseError",494,6852],[17,"Body"],[10,"Debug",6853],[17,"Response"],[5,"ServiceResponse",2658,6828],[1,"usize"],[10,"FromRequest",0,6854],[5,"Encoding",6855],[6,"ContentTypeError",3203,6847],[5,"Extensions",2658,6856],[5,"RefMut",6850],[5,"Formatter",6853],[8,"Result",6853],[5,"Response",2658,6857],[10,"Into",6841],[6,"Payload",2658,6858],[10,"Guard",3541],[5,"Route",0,6859],[5,"ResponseHead",2658,6860],[5,"RequestHead",2658,6861],[5,"HeaderMap",3910,6862],[10,"Serialize",6863],[6,"KeepAlive",3621,6864],[5,"TcpListener",6865],[5,"UnixListener",6866],[6,"EitherBody",370,6867],[5,"Url",2658,6868],[5,"Path",2658,6869],[5,"String",6870],[5,"Method",3621,6871],[5,"Mime",6872],[10,"IntoPatterns",6873],[1,"u64"],[10,"Any",6874],[10,"Sync",6822],[5,"Pin",6875],[5,"Context",6876],[6,"Poll",6877],[5,"AppService",2658,6826],[5,"ResourceMap",2658,6878],[5,"Server",2658,6879],[10,"HttpServiceFactory",2658,6828],[10,"Error",6880],[5,"Box",6881],[17,"Item"],[5,"Bytes",6209,6882],[10,"Stream",6883],[5,"TypeId",6874],[5,"Uri",3621,6884],[5,"Url",6885],[6,"UrlGenerationError",3203],[10,"IntoIterator",6886],[5,"Version",3621,6887],[10,"Transform",2658,6888],[8,"BoxService",6889],[5,"None",370,6890],[6,"BodySize",370,6891],[5,"Error",6853],[5,"BodyLimitExceeded",370,6892],[5,"BodyStream",370,6893],[5,"SizedStream",370,6894],[5,"PrivateJar",494,6895],[5,"CookieJar",494,6896],[10,"BorrowMut",6897],[5,"SignedJar",494,6898],[5,"CookieBuilder",494,6899],[6,"Cow",6900],[6,"SameSite",494,6901],[6,"Expiration",494,6902],[5,"Key",494,6903],[5,"OffsetDateTime",771,6904],[5,"Delta",494,6896],[1,"u8"],[1,"slice"],[5,"Display",494,6814],[6,"KeyError",494,6903],[5,"Utf8Error",6905],[10,"Borrow",6897],[10,"Hasher",6906],[5,"Iter",494,6896],[5,"Duration",771,6907],[5,"Date",771,6908],[5,"Instant",771,6909],[5,"PrimitiveDateTime",771,6910],[5,"Time",771,6911],[5,"UtcOffset",771,6912],[1,"i8"],[1,"u16"],[5,"Instant",6913],[1,"f32"],[1,"f64"],[1,"i32"],[6,"Month",771,6914],[6,"Weekday",771,6915],[6,"Ordering",6916],[1,"i64"],[1,"i16"],[5,"SystemTime",6913],[6,"Error",771,6917],[5,"Metadata",6918],[6,"Format",1526,6919],[10,"Formattable",2565,6920],[10,"Sized",6822],[10,"Write",6921],[6,"Parse",1526,6922],[5,"ConversionRange",1526,6923],[5,"ComponentRange",1526,6924],[6,"InvalidFormatDescription",1526,6925],[6,"TryFromParsed",1526,6926],[6,"ParseFromDescription",1526,6927],[5,"InvalidVariant",1526,6928],[5,"DifferentVariant",1526,6929],[1,"i128"],[5,"FormatterOptions",6918],[10,"Parsable",2571,6930],[10,"Iterator",6931],[5,"Parsed",2571,6932],[5,"Nanosecond",1414,6933],[5,"Microsecond",1414,6933],[5,"Millisecond",1414,6933],[5,"Second",1414,6933],[5,"Minute",1414,6933],[5,"Hour",1414,6933],[5,"Day",1414,6933],[5,"Week",1414,6933],[10,"Copy",6822],[5,"Error",6836],[5,"Error",6934],[10,"InstantExt",1754,6935],[10,"NumericalDuration",1754,6936],[10,"NumericalStdDuration",1754,6937],[6,"FormatItem",1778],[6,"Component",1778,6938],[6,"OwnedFormatItem",1778,6939],[6,"Component",6940],[6,"Item",6940],[5,"Day",1887,6941],[6,"MonthRepr",1887,6941],[5,"Month",1887,6941],[5,"Ordinal",1887,6941],[6,"WeekdayRepr",1887,6941],[5,"Weekday",1887,6941],[6,"WeekNumberRepr",1887,6941],[5,"WeekNumber",1887,6941],[6,"YearRepr",1887,6941],[5,"Year",1887,6941],[5,"Hour",1887,6941],[5,"Minute",1887,6941],[5,"Period",1887,6941],[5,"Second",1887,6941],[6,"SubsecondDigits",1887,6941],[5,"Subsecond",1887,6941],[5,"OffsetHour",1887,6941],[5,"OffsetMinute",1887,6941],[5,"OffsetSecond",1887,6941],[6,"Padding",1887,6941],[5,"Ignore",1887,6941],[6,"UnixTimestampPrecision",1887,6941],[5,"UnixTimestamp",1887,6941],[5,"End",1887,6941],[5,"NonZero",6942],[6,"MonthRepr",6940],[6,"WeekdayRepr",6940],[6,"WeekNumberRepr",6940],[6,"YearRepr",6940],[6,"SubsecondDigits",6940],[6,"Padding",6940],[6,"UnixTimestampPrecision",6940],[5,"Iso8601",2399,6943],[5,"Rfc2822",2399,6944],[5,"Rfc3339",2399,6945],[6,"FormattedComponents",2459,6943],[6,"DateKind",2459,6943],[6,"TimePrecision",2459,6943],[6,"OffsetPrecision",2459,6943],[5,"Config",2459,6943],[1,"u128"],[10,"AnyFormatItem",6946],[5,"ResourceDef",2658,6947],[5,"Rc",6948],[10,"ResourcePath",2658,6949],[5,"ServerBuilder",6950],[5,"ResponseBuilder",6951],[10,"Service",2658,6820],[10,"Resource",6949],[5,"ServerHandle",2658,6952],[5,"PeerAddr",2658,6849],[6,"ConnectionType",3621,6953],[10,"Default",6954],[5,"BoxServiceFactory",6889],[5,"WebService",2658,6828],[5,"FnServiceNoConfig",6955],[5,"FnServiceFactory",6955],[6,"HandshakeError",6956],[6,"DispatcherError",6957],[10,"Display",6853],[10,"Encoder",6958],[10,"Decoder",6959],[5,"ByteString",6960],[5,"Error",3621,6847],[6,"Infallible",6841],[5,"BytesMut",6209,6961],[5,"RecvStream",6962],[5,"Payload",6963],[5,"Payload",6964],[5,"Decompress",2658],[6,"PayloadError",3203,6847],[5,"GuardContext",3541],[5,"PathIter",6869],[5,"UrlEncoded",2658,6965],[6,"JsonBody",2658,6966],[10,"DeserializeOwned",6967],[5,"Readlines",2658,6968],[5,"Error",6969],[10,"Deserialize",6967],[6,"ContentEncoding",3910,6970],[17,"Service"],[17,"Transform"],[5,"Quoter",6971],[5,"HashMap",6972],[10,"Eq",6916],[10,"Hash",6906],[10,"BuildHasher",6906],[10,"ResponseError",3203,6973],[5,"InternalError",3203,6974],[5,"BlockingError",3203],[6,"UrlencodedError",3203],[6,"JsonPayloadError",3203],[6,"DispatchError",3203,6847],[6,"PathError",3203],[6,"QueryPayloadError",3203],[6,"ReadlinesError",3203],[5,"MaxSizeReached",6975],[5,"InvalidStatusCode",6843],[5,"InvalidHeaderName",3910,6976],[5,"InvalidMethod",6871],[6,"InvalidHeaderPart",6833],[5,"InvalidUri",5271,6884],[5,"InvalidUriParts",5271,6884],[5,"InvalidHeaderValue",3910,6977],[6,"ParseError",6978],[6,"Error",6979],[5,"FromUtf8Error",6870],[6,"Error",6980],[5,"Error",6981],[5,"AllGuard",3541],[5,"AnyGuard",3541],[5,"Not",3541],[5,"Acceptable",3541,6982],[10,"Header",3910,6983],[5,"Authority",5271,6984],[5,"Builder",5271,6985],[6,"EncoderError",6986],[6,"ProtocolError",6956],[5,"PathAndQuery",5271,6987],[5,"Parts",5271,6884],[5,"Port",5271,6988],[5,"Scheme",5271,6989],[5,"HeaderName",3910,6976],[5,"HeaderValue",3910,6977],[6,"DispositionParam",3910,6990],[5,"ExtendedValue",3910,6991],[5,"LanguageTag",3910,6992],[5,"ContentDisposition",3910,6990],[6,"Encoding",3910,6993],[6,"Range",3910,6994],[6,"ValidationError",6992],[6,"Charset",3910,6995],[5,"HttpDate",3910,6996],[5,"Quality",3910,6997],[5,"QualityItem",3910,6998],[5,"Accept",3910,6999],[5,"AcceptCharset",3910,7000],[5,"AcceptEncoding",3910,7001],[5,"AcceptLanguage",3910,7002],[5,"Allow",3910,7003],[5,"CacheControl",3910,7004],[6,"CacheDirective",3910,7004],[6,"DispositionType",3910,6990],[5,"ContentLanguage",3910,7005],[5,"ContentLength",3910,7006],[5,"ContentRange",3910,7007],[6,"ContentRangeSpec",3910,7007],[5,"ContentType",3910,7008],[5,"Date",3910,7009],[5,"EntityTag",3910,7010],[5,"ETag",3910,7011],[5,"Expires",3910,7012],[6,"IfMatch",3910,7013],[5,"IfModifiedSince",3910,7014],[6,"IfNoneMatch",3910,7015],[6,"IfRange",3910,7016],[5,"IfUnmodifiedSince",3910,7017],[5,"LastModified",3910,7018],[6,"Preference",3910,7019],[6,"ByteRangeSpec",3910,6994],[10,"AsHeaderName",3910,7020],[5,"Drain",5204,6862],[10,"PartialEq",6916],[1,"char"],[5,"ToStrError",3910,6977],[1,"isize"],[5,"HeaderMap",6975],[10,"FromStr",7021],[6,"ParseError",6992],[5,"Iter",7022],[5,"Removed",5204,6862],[5,"Iter",5204,6862],[5,"Keys",5204,6862],[10,"PartialOrd",6916],[10,"TryInto",6841],[10,"FnMut",6821],[5,"IntoIter",5204,6862],[6,"ErrorKind",6884],[5,"DefaultHeaders",5451,7023],[6,"TrailingSlash",5451,7024],[5,"NormalizePath",5451,7024],[5,"Compress",5451,7025],[5,"Logger",5451,7026],[5,"ErrorHandlers",5451,7027],[6,"ErrorHandlerResponse",5451,7027],[8,"Result",0,3203],[5,"Compat",5451,7028],[5,"Condition",5451,7029],[5,"System",5585,7030],[5,"ArbiterHandle",7031],[5,"Runtime",5585,7032],[5,"SystemRunner",5585,7030],[5,"Runtime",7033],[5,"JoinHandle",6010,7034],[5,"TcpListener",5640,7035],[5,"TcpStream",5640,7036],[5,"UnixListener",5640,7037],[5,"UnixStream",5640,7038],[5,"SocketAddr",7039],[5,"BorrowedFd",7040],[5,"TcpSocket",5640,7041],[5,"UdpSocket",5640,7042],[5,"UnixDatagram",5640,7043],[5,"Interest",7044],[10,"ToSocketAddrs",7045],[5,"Ready",5640,7046],[6,"MioStream",7047],[5,"TcpStream",6865],[5,"UdpSocket",7048],[5,"UnixDatagram",7049],[5,"UnixStream",7050],[5,"OwnedReadHalf",7051],[5,"OwnedWriteHalf",7051],[5,"OwnedReadHalf",7052],[5,"OwnedWriteHalf",7052],[5,"Ipv4Addr",7053],[5,"Ipv6Addr",7053],[5,"UCred",7054],[5,"ReadBuf",7055],[5,"IoSlice",6921],[10,"BufMut",6209,7056],[6,"Shutdown",7057],[5,"ReadHalf",7058],[5,"WriteHalf",7058],[5,"ReadHalf",7059],[5,"WriteHalf",7059],[5,"IoSliceMut",6921],[5,"SignalKind",5965,7060],[5,"Signal",5965,7060],[5,"AbortHandle",7061],[5,"JoinError",6010,7062],[5,"Instant",6045,7063],[5,"Sleep",6045,7064],[5,"Interval",6045,7065],[5,"Timeout",6045,7066],[6,"MissedTickBehavior",7065],[5,"TestRequest",6136,7067],[5,"TestBuffer",6136,7068],[10,"Buf",6209,7069],[5,"Path",6209,7070],[5,"Chain",7071],[5,"UninitSlice",7072],[5,"Data",6209,7073],[5,"Redirect",6209,7074],[5,"ReqData",6209,7075],[5,"FormConfig",6209,6965],[5,"Header",6209,7076],[5,"JsonConfig",6209,6966],[5,"PathConfig",6209,7070],[5,"PayloadConfig",6209,7077],[5,"Query",6209,7078],[5,"QueryConfig",6209,7078],[5,"Form",6209,6965],[10,"Ord",6916],[5,"Arc",7079],[5,"Json",6209,6966],[10,"Deserializer",6967],[6,"Either",6209,7080],[5,"Custom",6976],[5,"Custom",6976],[5,"ByteStr",7081],[5,"ByteStr",7081],[1,"never"],[5,"Payload",6209,7077],[5,"Limit",7082],[5,"Reader",7083],[10,"Serializer",6863],[10,"RangeBounds",7084],[20,"MaybeUninit",7085],[5,"Take",7086],[5,"Arguments",6853],[5,"Writer",7087],[15,"Left",492],[15,"Right",492],[8,"Result",771],[15,"NotSupported",1741],[15,"UnclosedOpeningBracket",1741],[15,"InvalidComponentName",1741],[15,"InvalidModifier",1741],[15,"MissingComponentName",1741],[15,"MissingRequiredModifier",1741],[15,"Expected",1741],[15,"Hour",2562],[15,"Minute",2562],[15,"Second",2562],[15,"Body",3195],[15,"H1",3200],[15,"H2",3200],[15,"Stream",3200],[15,"OverflowKnownLength",3536],[15,"Overflow",3536],[15,"Overflow",3539],[15,"Bytes",5200],[15,"Unregistered",5200]],"r":[[2,6827],[9,6834],[10,7080],[12,6829],[18,6854],[23,6844],[24,6846],[25,6825],[26,6813],[27,6812],[28,6816],[65,6830],[66,6835],[67,6973],[68,3203],[70,6859],[71,6831],[107,7088],[138,7089],[157,7089],[197,7089],[205,7089],[240,7089],[266,7089],[268,7089],[273,7089],[275,7089],[288,7089],[289,7089],[308,7089],[314,7089],[370,6892],[371,6891],[372,6893],[373,6842],[374,6867],[377,6824],[378,6890],[382,6894],[454,6892],[455,6892],[494,6814],[495,6899],[496,6896],[498,6896],[499,6814],[501,6902],[502,6896],[503,6903],[504,6903],[508,6852],[509,6895],[510,6901],[512,6898],[776,6908],[779,6907],[781,6917],[786,6909],[805,6914],[809,6904],[812,6910],[813,7090],[819,6911],[825,6912],[828,6915],[940,7091],[1006,7090],[1007,7090],[1039,7090],[1045,7090],[1114,7090],[1193,7090],[1380,7090],[1414,6933],[1415,6933],[1416,6933],[1417,6933],[1418,6933],[1419,6933],[1420,6933],[1421,6933],[1526,6924],[1529,6923],[1531,6929],[1533,6917],[1535,6919],[1542,6925],[1546,6928],[1551,6922],[1552,6927],[1556,6926],[1754,6935],[1755,6936],[1756,6937],[1778,7092],[1779,6938],[1806,6939],[1864,7093],[1865,6934],[1866,6934],[1867,6934],[1886,7093],[1887,6941],[1889,6941],[1893,6941],[1894,6941],[1901,6941],[1904,6941],[1905,6941],[1910,6941],[1911,6941],[1912,6941],[1915,6941],[1916,6941],[1917,6941],[1918,6941],[1925,6941],[1926,6941],[1931,6941],[1932,6941],[1933,6941],[1934,6941],[1935,6941],[1936,6941],[1937,6941],[1938,6941],[2403,6943],[2406,6944],[2407,6945],[2443,7094],[2460,6943],[2463,6943],[2466,7095],[2467,6943],[2470,6943],[2475,6943],[2480,6943],[2565,6920],[2566,7096],[2567,7096],[2568,7096],[2569,7096],[2570,7096],[2571,6930],[2572,6932],[2654,7097],[2655,7098],[2656,7097],[2657,7097],[2658,6826],[2659,6826],[2662,6849],[2668,6856],[2674,6828],[2677,6966],[2679,6869],[2680,6858],[2681,6849],[2682,6968],[2683,6861],[2684,6947],[2685,6878],[2686,6949],[2687,6857],[2691,6860],[2692,6879],[2693,6952],[2694,6820],[2696,6820],[2697,6828],[2698,6828],[2700,6888],[2702,6868],[2703,6965],[2704,6828],[2707,6820],[2839,6955],[2840,6955],[2841,6820],[3208,6847],[3214,6847],[3219,6829],[3220,6974],[3221,6974],[3222,6974],[3223,6974],[3224,6974],[3225,6974],[3226,6974],[3227,6974],[3228,6974],[3229,6974],[3230,6974],[3231,6974],[3232,6974],[3233,6974],[3234,6974],[3235,6974],[3236,6974],[3237,6974],[3238,6974],[3239,6974],[3240,6974],[3241,6974],[3242,6974],[3243,6974],[3244,6974],[3245,6974],[3246,6974],[3247,6974],[3248,6974],[3249,6974],[3250,6974],[3251,6974],[3252,6974],[3253,6974],[3254,6974],[3255,6974],[3256,6974],[3257,6974],[3258,6974],[3266,6974],[3282,6847],[3289,6847],[3293,6973],[3541,6982],[3553,7099],[3554,7099],[3630,6953],[3634,6847],[3652,6864],[3662,6871],[3692,6843],[3705,6884],[3707,6887],[3902,7100],[3910,6976],[3911,6976],[3912,6976],[3913,6976],[3914,6976],[3915,6976],[3916,6976],[3917,6976],[3918,6976],[3919,6976],[3920,6976],[3921,6976],[3922,6976],[3923,6976],[3924,6976],[3925,6976],[3926,6976],[3927,6999],[3928,7000],[3929,7001],[3930,7002],[3931,7003],[3935,7020],[3939,6994],[3942,6976],[3943,7101],[3944,7101],[3945,6976],[3946,6976],[3947,6976],[3948,6976],[3949,6976],[3950,6976],[3951,6976],[3952,6976],[3953,6976],[3954,6976],[3955,6976],[3956,7101],[3957,7101],[3958,7101],[3959,7004],[3960,7004],[3961,6995],[3962,6990],[3963,6970],[3964,7005],[3965,7006],[3966,7007],[3967,7007],[3968,7008],[3969,6976],[3970,6976],[3971,7009],[3974,6990],[3975,6990],[3976,6976],[3977,7011],[3978,6976],[3979,6976],[3980,6993],[3981,7010],[3987,7012],[3990,6991],[3992,6976],[3993,6976],[4001,6976],[4002,6983],[4003,6862],[4004,6976],[4005,6977],[4006,6996],[4007,6976],[4008,6976],[4009,6976],[4010,6976],[4011,6976],[4013,7013],[4014,7014],[4015,7015],[4016,7016],[4017,7017],[4019,6976],[4020,6977],[4042,6976],[4043,6976],[4044,6976],[4045,6992],[4047,7018],[4049,6976],[4059,6976],[4061,7101],[4062,6976],[4063,6976],[4064,6976],[4065,6976],[4066,6976],[4067,7019],[4071,6997],[4072,6998],[4073,6976],[4074,6976],[4075,6976],[4076,6976],[4077,6976],[4078,6994],[4079,6976],[4080,6976],[4081,6976],[4082,6976],[4083,6976],[4084,6976],[4085,6976],[4087,6976],[4090,6976],[4091,6976],[4092,6976],[4093,6977],[4094,6833],[4095,6851],[4096,6976],[4097,6976],[4098,6976],[4105,6976],[4106,6976],[4107,6976],[4108,6976],[4109,6976],[4110,6976],[4111,7101],[4112,7101],[4113,7101],[4114,6976],[4115,6976],[4595,7102],[4656,7102],[4661,7102],[4699,7102],[4777,6983],[4837,6991],[4858,6997],[5204,6862],[5205,6862],[5206,6862],[5207,6862],[5208,6862],[5209,6862],[5271,6984],[5272,6985],[5275,6884],[5276,6884],[5277,6884],[5278,6987],[5279,6988],[5280,6989],[5281,6884],[5452,7028],[5453,7025],[5454,7029],[5455,7023],[5456,7027],[5457,7027],[5459,7026],[5461,7024],[5463,7024],[5585,7032],[5586,7030],[5587,7030],[5612,7103],[5615,7104],[5618,7103],[5619,7103],[5623,7103],[5624,7103],[5646,7046],[5647,7035],[5648,7041],[5649,7036],[5650,7042],[5651,7043],[5652,7037],[5653,7038],[5963,7105],[5964,7106],[5965,7060],[5966,7060],[5996,7060],[6010,7062],[6011,7034],[6032,7107],[6044,7108],[6045,7063],[6046,7065],[6047,7064],[6048,7066],[6086,7065],[6087,7065],[6111,7064],[6112,7064],[6117,7066],[6136,7068],[6137,7067],[6144,7109],[6145,7109],[6146,7109],[6149,7110],[6159,7109],[6165,7110],[6176,7109],[6177,7109],[6179,7109],[6180,7109],[6185,7110],[6186,7110],[6192,7109],[6193,7109],[6198,7109],[6199,7109],[6210,7069],[6211,7056],[6212,6882],[6213,6961],[6214,7073],[6215,7080],[6217,6965],[6218,6965],[6219,7076],[6220,6966],[6221,6966],[6222,6966],[6224,7070],[6225,7070],[6226,7077],[6227,7077],[6228,7078],[6229,7078],[6230,6968],[6231,7074],[6232,7075],[6234,6826],[6235,6965]],"b":[[184,"impl-From%3CHttpResponseBuilder%3E-for-HttpResponse"],[186,"impl-From%3CResponse%3CB%3E%3E-for-HttpResponse%3CB%3E"],[187,"impl-From%3CServiceResponse%3CB%3E%3E-for-HttpResponse%3CB%3E"],[188,"impl-From%3CError%3E-for-HttpResponse"],[209,"impl-HttpMessage-for-HttpRequest"],[210,"impl-HttpRequest"],[418,"impl-Display-for-BodyLimitExceeded"],[419,"impl-Debug-for-BodyLimitExceeded"],[596,"impl-Display-for-ParseError"],[597,"impl-Debug-for-ParseError"],[599,"impl-Debug-for-SameSite"],[600,"impl-Display-for-SameSite"],[602,"impl-Debug-for-KeyError"],[603,"impl-Display-for-KeyError"],[604,"impl-Debug-for-Cookie%3C\'c%3E"],[605,"impl-Display-for-Cookie%3C\'c%3E"],[831,"impl-Add%3CDuration%3E-for-Date"],[832,"impl-Add%3CDuration%3E-for-Date"],[833,"impl-Add%3CDuration%3E-for-Duration"],[834,"impl-Add-for-Duration"],[835,"impl-Add%3CDuration%3E-for-Instant"],[836,"impl-Add%3CDuration%3E-for-Instant"],[837,"impl-Add%3CDuration%3E-for-OffsetDateTime"],[838,"impl-Add%3CDuration%3E-for-OffsetDateTime"],[839,"impl-Add%3CDuration%3E-for-PrimitiveDateTime"],[840,"impl-Add%3CDuration%3E-for-PrimitiveDateTime"],[841,"impl-Add%3CDuration%3E-for-Time"],[842,"impl-Add%3CDuration%3E-for-Time"],[843,"impl-AddAssign%3CDuration%3E-for-Date"],[844,"impl-AddAssign%3CDuration%3E-for-Date"],[845,"impl-AddAssign%3CDuration%3E-for-Duration"],[846,"impl-AddAssign-for-Duration"],[847,"impl-AddAssign%3CDuration%3E-for-Instant"],[848,"impl-AddAssign%3CDuration%3E-for-Instant"],[849,"impl-AddAssign%3CDuration%3E-for-OffsetDateTime"],[850,"impl-AddAssign%3CDuration%3E-for-OffsetDateTime"],[851,"impl-AddAssign%3CDuration%3E-for-PrimitiveDateTime"],[852,"impl-AddAssign%3CDuration%3E-for-PrimitiveDateTime"],[853,"impl-AddAssign%3CDuration%3E-for-Time"],[854,"impl-AddAssign%3CDuration%3E-for-Time"],[948,"impl-Div-for-Duration"],[949,"impl-Div%3Cu8%3E-for-Duration"],[950,"impl-Div%3Cu16%3E-for-Duration"],[951,"impl-Div%3CDuration%3E-for-Duration"],[952,"impl-Div%3Cf64%3E-for-Duration"],[953,"impl-Div%3Cu32%3E-for-Duration"],[954,"impl-Div%3Ci8%3E-for-Duration"],[955,"impl-Div%3Cf32%3E-for-Duration"],[956,"impl-Div%3Ci32%3E-for-Duration"],[957,"impl-Div%3Ci16%3E-for-Duration"],[958,"impl-DivAssign%3Ci8%3E-for-Duration"],[959,"impl-DivAssign%3Cu8%3E-for-Duration"],[960,"impl-DivAssign%3Cu32%3E-for-Duration"],[961,"impl-DivAssign%3Cf32%3E-for-Duration"],[962,"impl-DivAssign%3Cf64%3E-for-Duration"],[963,"impl-DivAssign%3Cu16%3E-for-Duration"],[964,"impl-DivAssign%3Ci32%3E-for-Duration"],[965,"impl-DivAssign%3Ci16%3E-for-Duration"],[968,"impl-PartialEq%3CDuration%3E-for-Duration"],[969,"impl-PartialEq-for-Duration"],[970,"impl-PartialEq%3CInstant%3E-for-Instant"],[971,"impl-PartialEq-for-Instant"],[973,"impl-PartialEq-for-OffsetDateTime"],[974,"impl-PartialEq%3CSystemTime%3E-for-OffsetDateTime"],[1008,"impl-Debug-for-Date"],[1009,"impl-Display-for-Date"],[1010,"impl-Debug-for-Duration"],[1011,"impl-Display-for-Duration"],[1012,"impl-Debug-for-Error"],[1013,"impl-Display-for-Error"],[1015,"impl-SmartDisplay-for-Month"],[1016,"impl-Debug-for-Month"],[1017,"impl-Display-for-Month"],[1018,"impl-Display-for-OffsetDateTime"],[1019,"impl-Debug-for-OffsetDateTime"],[1020,"impl-Display-for-PrimitiveDateTime"],[1021,"impl-Debug-for-PrimitiveDateTime"],[1022,"impl-Display-for-Time"],[1023,"impl-Debug-for-Time"],[1024,"impl-Debug-for-UtcOffset"],[1025,"impl-Display-for-UtcOffset"],[1026,"impl-SmartDisplay-for-Weekday"],[1027,"impl-Debug-for-Weekday"],[1028,"impl-Display-for-Weekday"],[1048,"impl-From%3CParse%3E-for-Error"],[1049,"impl-From%3CConversionRange%3E-for-Error"],[1050,"impl-From%3CComponentRange%3E-for-Error"],[1051,"impl-From%3CFormat%3E-for-Error"],[1052,"impl-From%3CInvalidFormatDescription%3E-for-Error"],[1054,"impl-From%3CTryFromParsed%3E-for-Error"],[1055,"impl-From%3CParseFromDescription%3E-for-Error"],[1056,"impl-From%3CInvalidVariant%3E-for-Error"],[1057,"impl-From%3CDifferentVariant%3E-for-Error"],[1142,"impl-Mul%3Cf32%3E-for-Duration"],[1143,"impl-Mul%3Ci16%3E-for-Duration"],[1144,"impl-Mul%3Cf64%3E-for-Duration"],[1145,"impl-Mul%3Cu8%3E-for-Duration"],[1146,"impl-Mul%3Ci8%3E-for-Duration"],[1147,"impl-Mul%3Cu32%3E-for-Duration"],[1148,"impl-Mul%3Ci32%3E-for-Duration"],[1149,"impl-Mul%3Cu16%3E-for-Duration"],[1150,"impl-MulAssign%3Ci16%3E-for-Duration"],[1151,"impl-MulAssign%3Ci32%3E-for-Duration"],[1152,"impl-MulAssign%3Cu32%3E-for-Duration"],[1153,"impl-MulAssign%3Cu16%3E-for-Duration"],[1154,"impl-MulAssign%3Cu8%3E-for-Duration"],[1155,"impl-MulAssign%3Cf64%3E-for-Duration"],[1156,"impl-MulAssign%3Ci8%3E-for-Duration"],[1157,"impl-MulAssign%3Cf32%3E-for-Duration"],[1195,"impl-PartialOrd-for-Duration"],[1196,"impl-PartialOrd%3CDuration%3E-for-Duration"],[1197,"impl-PartialOrd%3CInstant%3E-for-Instant"],[1198,"impl-PartialOrd-for-Instant"],[1199,"impl-PartialOrd-for-OffsetDateTime"],[1200,"impl-PartialOrd%3CSystemTime%3E-for-OffsetDateTime"],[1263,"impl-Sub%3CDuration%3E-for-Date"],[1264,"impl-Sub-for-Date"],[1265,"impl-Sub%3CDuration%3E-for-Date"],[1266,"impl-Sub-for-Duration"],[1267,"impl-Sub%3CDuration%3E-for-Duration"],[1268,"impl-Sub%3CDuration%3E-for-Instant"],[1269,"impl-Sub%3CInstant%3E-for-Instant"],[1270,"impl-Sub-for-Instant"],[1271,"impl-Sub%3CDuration%3E-for-Instant"],[1272,"impl-Sub%3CSystemTime%3E-for-OffsetDateTime"],[1273,"impl-Sub%3CDuration%3E-for-OffsetDateTime"],[1274,"impl-Sub%3CDuration%3E-for-OffsetDateTime"],[1275,"impl-Sub-for-OffsetDateTime"],[1276,"impl-Sub-for-PrimitiveDateTime"],[1277,"impl-Sub%3CDuration%3E-for-PrimitiveDateTime"],[1278,"impl-Sub%3CDuration%3E-for-PrimitiveDateTime"],[1279,"impl-Sub-for-Time"],[1280,"impl-Sub%3CDuration%3E-for-Time"],[1281,"impl-Sub%3CDuration%3E-for-Time"],[1282,"impl-SubAssign%3CDuration%3E-for-Date"],[1283,"impl-SubAssign%3CDuration%3E-for-Date"],[1284,"impl-SubAssign%3CDuration%3E-for-Duration"],[1285,"impl-SubAssign-for-Duration"],[1286,"impl-SubAssign%3CDuration%3E-for-Instant"],[1287,"impl-SubAssign%3CDuration%3E-for-Instant"],[1288,"impl-SubAssign%3CDuration%3E-for-OffsetDateTime"],[1289,"impl-SubAssign%3CDuration%3E-for-OffsetDateTime"],[1290,"impl-SubAssign%3CDuration%3E-for-PrimitiveDateTime"],[1291,"impl-SubAssign%3CDuration%3E-for-PrimitiveDateTime"],[1292,"impl-SubAssign%3CDuration%3E-for-Time"],[1293,"impl-SubAssign%3CDuration%3E-for-Time"],[1297,"impl-Sum-for-Duration"],[1298,"impl-Sum%3C%26Duration%3E-for-Duration"],[1629,"impl-Display-for-ComponentRange"],[1630,"impl-Debug-for-ComponentRange"],[1631,"impl-Debug-for-ConversionRange"],[1632,"impl-Display-for-ConversionRange"],[1633,"impl-Display-for-DifferentVariant"],[1634,"impl-Debug-for-DifferentVariant"],[1635,"impl-Debug-for-Format"],[1636,"impl-Display-for-Format"],[1637,"impl-Display-for-InvalidFormatDescription"],[1638,"impl-Debug-for-InvalidFormatDescription"],[1639,"impl-Debug-for-InvalidVariant"],[1640,"impl-Display-for-InvalidVariant"],[1641,"impl-Debug-for-Parse"],[1642,"impl-Display-for-Parse"],[1643,"impl-Display-for-ParseFromDescription"],[1644,"impl-Debug-for-ParseFromDescription"],[1645,"impl-Display-for-TryFromParsed"],[1646,"impl-Debug-for-TryFromParsed"],[1655,"impl-From%3CTryFromParsed%3E-for-Parse"],[1656,"impl-From%3CParseFromDescription%3E-for-Parse"],[1694,"impl-TryFrom%3CTryFromParsed%3E-for-ComponentRange"],[1695,"impl-TryFrom%3CError%3E-for-ComponentRange"],[1708,"impl-TryFrom%3CError%3E-for-ParseFromDescription"],[1710,"impl-TryFrom%3CParse%3E-for-ParseFromDescription"],[1711,"impl-TryFrom%3CParse%3E-for-TryFromParsed"],[1713,"impl-TryFrom%3CError%3E-for-TryFromParsed"],[1826,"impl-PartialEq-for-BorrowedFormatItem%3C\'a%3E"],[1827,"impl-PartialEq%3CComponent%3E-for-BorrowedFormatItem%3C\'_%3E"],[1828,"impl-PartialEq%3C%26%5BBorrowedFormatItem%3C\'_%3E%5D%3E-for-BorrowedFormatItem%3C\'_%3E"],[1829,"impl-PartialEq-for-Component"],[1830,"impl-PartialEq%3CBorrowedFormatItem%3C\'_%3E%3E-for-Component"],[1831,"impl-PartialEq%3COwnedFormatItem%3E-for-Component"],[1832,"impl-PartialEq%3C%26%5BOwnedFormatItem%5D%3E-for-OwnedFormatItem"],[1833,"impl-PartialEq-for-OwnedFormatItem"],[1834,"impl-PartialEq%3CComponent%3E-for-OwnedFormatItem"],[1847,"impl-From%3CComponent%3E-for-BorrowedFormatItem%3C\'_%3E"],[1849,"impl-From%3C%26%5BBorrowedFormatItem%3C\'_%3E%5D%3E-for-BorrowedFormatItem%3C\'a%3E"],[1853,"impl-From%3CBorrowedFormatItem%3C\'_%3E%3E-for-OwnedFormatItem"],[1854,"impl-From%3C%26BorrowedFormatItem%3C\'_%3E%3E-for-OwnedFormatItem"],[1855,"impl-From%3CComponent%3E-for-OwnedFormatItem"],[1856,"impl-From%3C%26T%3E-for-OwnedFormatItem"],[1857,"impl-From%3CVec%3CBorrowedFormatItem%3C\'_%3E%3E%3E-for-OwnedFormatItem"],[1858,"impl-From%3CBox%3C%5BItem%3C\'a%3E%5D%3E%3E-for-OwnedFormatItem"],[1859,"impl-From%3CItem%3C\'_%3E%3E-for-OwnedFormatItem"],[1860,"impl-From%3CVec%3COwnedFormatItem%3E%3E-for-OwnedFormatItem"],[1874,"impl-TryFrom%3COwnedFormatItem%3E-for-Component"],[1875,"impl-TryFrom%3CBorrowedFormatItem%3C\'_%3E%3E-for-Component"],[2041,"impl-Day"],[2042,"impl-Default-for-Day"],[2044,"impl-Default-for-Month"],[2045,"impl-Month"],[2046,"impl-Ordinal"],[2047,"impl-Default-for-Ordinal"],[2049,"impl-Weekday"],[2050,"impl-Default-for-Weekday"],[2052,"impl-WeekNumber"],[2053,"impl-Default-for-WeekNumber"],[2055,"impl-Year"],[2056,"impl-Default-for-Year"],[2057,"impl-Hour"],[2058,"impl-Default-for-Hour"],[2059,"impl-Minute"],[2060,"impl-Default-for-Minute"],[2061,"impl-Period"],[2062,"impl-Default-for-Period"],[2063,"impl-Second"],[2064,"impl-Default-for-Second"],[2066,"impl-Default-for-Subsecond"],[2067,"impl-Subsecond"],[2068,"impl-OffsetHour"],[2069,"impl-Default-for-OffsetHour"],[2070,"impl-Default-for-OffsetMinute"],[2071,"impl-OffsetMinute"],[2072,"impl-Default-for-OffsetSecond"],[2073,"impl-OffsetSecond"],[2076,"impl-Default-for-UnixTimestamp"],[2077,"impl-UnixTimestamp"],[2078,"impl-End"],[2079,"impl-Default-for-End"],[2836,"impl-Debug-for-PeerAddr"],[2837,"impl-Display-for-PeerAddr"],[2845,"impl-From%3C%26str%3E-for-ResourceDef"],[2846,"impl-From%3CString%3E-for-ResourceDef"],[2850,"impl-From%3C%26String%3E-for-Response%3CString%3E"],[2851,"impl-From%3CResponseBuilder%3E-for-Response%3CEitherBody%3C()%3E%3E"],[2852,"impl-From%3C%26Vec%3Cu8%3E%3E-for-Response%3CVec%3Cu8%3E%3E"],[2853,"impl-From%3CParseError%3E-for-Response%3CBoxBody%3E"],[2854,"impl-From%3C%26%5Bu8%5D%3E-for-Response%3C%26%5Bu8%5D%3E"],[2855,"impl-From%3CHandshakeError%3E-for-Response%3CBoxBody%3E"],[2856,"impl-From%3CDispatcherError%3CE,+U,+I%3E%3E-for-Response%3CBoxBody%3E"],[2857,"impl-From%3CServiceResponse%3CB%3E%3E-for-Response%3CB%3E"],[2858,"impl-From%3CString%3E-for-Response%3CString%3E"],[2859,"impl-From%3CByteString%3E-for-Response%3CByteString%3E"],[2860,"impl-From%3C%26str%3E-for-Response%3C%26str%3E"],[2861,"impl-From%3C%26HandshakeError%3E-for-Response%3CBoxBody%3E"],[2862,"impl-From%3CError%3E-for-Response%3CBoxBody%3E"],[2863,"impl-From%3CHttpResponseBuilder%3E-for-Response%3CBoxBody%3E"],[2864,"impl-From%3CVec%3Cu8%3E%3E-for-Response%3CVec%3Cu8%3E%3E"],[2866,"impl-From%3CHttpResponse%3CB%3E%3E-for-Response%3CB%3E"],[2867,"impl-From%3CBytes%3E-for-Response%3CBytes%3E"],[2868,"impl-From%3CResult%3CI,+E%3E%3E-for-Response%3CBoxBody%3E"],[2869,"impl-From%3CInfallible%3E-for-Response%3CBoxBody%3E"],[2870,"impl-From%3CError%3E-for-Response%3CBoxBody%3E"],[2871,"impl-From%3CBytesMut%3E-for-Response%3CBytesMut%3E"],[2881,"impl-From%3CRecvStream%3E-for-Payload%3CS%3E"],[2882,"impl-From%3CPayload%3E-for-Payload%3CS%3E"],[2884,"impl-From%3CPin%3CBox%3Cdyn+Stream%3CItem+=+Result%3CBytes,+PayloadError%3E%3E%3E%3E%3E-for-Payload"],[2885,"impl-From%3CPayload%3E-for-Payload%3CS%3E"],[2913,"impl-ServiceRequest"],[2914,"impl-HttpMessage-for-ServiceRequest"],[2928,"impl-Index%3Cusize%3E-for-Path%3CT%3E"],[2929,"impl-Index%3C%26str%3E-for-Path%3CT%3E"],[3018,"impl-Url"],[3019,"impl-ResourcePath-for-Url"],[3351,"impl-Display-for-Error"],[3352,"impl-Debug-for-Error"],[3353,"impl-Debug-for-InternalError%3CT%3E"],[3354,"impl-Display-for-InternalError%3CT%3E"],[3355,"impl-Debug-for-HttpError"],[3356,"impl-Display-for-HttpError"],[3357,"impl-Debug-for-BlockingError"],[3358,"impl-Display-for-BlockingError"],[3359,"impl-Display-for-UrlGenerationError"],[3360,"impl-Debug-for-UrlGenerationError"],[3361,"impl-Debug-for-UrlencodedError"],[3362,"impl-Display-for-UrlencodedError"],[3363,"impl-Debug-for-ParseError"],[3364,"impl-Display-for-ParseError"],[3365,"impl-Display-for-JsonPayloadError"],[3366,"impl-Debug-for-JsonPayloadError"],[3367,"impl-Display-for-PayloadError"],[3368,"impl-Debug-for-PayloadError"],[3369,"impl-Display-for-DispatchError"],[3370,"impl-Debug-for-DispatchError"],[3371,"impl-Display-for-PathError"],[3372,"impl-Debug-for-PathError"],[3373,"impl-Display-for-QueryPayloadError"],[3374,"impl-Debug-for-QueryPayloadError"],[3375,"impl-Display-for-ReadlinesError"],[3376,"impl-Debug-for-ReadlinesError"],[3377,"impl-Display-for-ContentTypeError"],[3378,"impl-Debug-for-ContentTypeError"],[3382,"impl-From%3CMaxSizeReached%3E-for-HttpError"],[3383,"impl-From%3CInvalidStatusCode%3E-for-HttpError"],[3384,"impl-From%3CInvalidHeaderName%3E-for-HttpError"],[3385,"impl-From%3CInvalidMethod%3E-for-HttpError"],[3386,"impl-From%3CInvalidHeaderPart%3E-for-HttpError"],[3388,"impl-From%3CInvalidUri%3E-for-HttpError"],[3389,"impl-From%3CInvalidUriParts%3E-for-HttpError"],[3390,"impl-From%3CInvalidHeaderValue%3E-for-HttpError"],[3391,"impl-From%3CInfallible%3E-for-HttpError"],[3395,"impl-From%3CError%3E-for-UrlencodedError"],[3396,"impl-From%3CPayloadError%3E-for-UrlencodedError"],[3397,"impl-From%3CError%3E-for-UrlencodedError"],[3398,"impl-From%3C(usize,+usize)%3E-for-UrlencodedError"],[3401,"impl-From%3CFromUtf8Error%3E-for-ParseError"],[3402,"impl-From%3CError%3E-for-ParseError"],[3403,"impl-From%3CUtf8Error%3E-for-ParseError"],[3404,"impl-From%3CError%3E-for-ParseError"],[3405,"impl-From%3CInvalidUri%3E-for-ParseError"],[3408,"impl-From%3CError%3E-for-PayloadError"],[3409,"impl-From%3COption%3CError%3E%3E-for-PayloadError"],[3411,"impl-From%3CError%3E-for-PayloadError"],[3412,"impl-From%3CError%3E-for-DispatchError"],[3413,"impl-From%3CError%3E-for-DispatchError"],[3415,"impl-From%3CResponse%3CBoxBody%3E%3E-for-DispatchError"],[3416,"impl-From%3CBox%3Cdyn+Error%3E%3E-for-DispatchError"],[3417,"impl-From%3CParseError%3E-for-DispatchError"],[3421,"impl-From%3CContentTypeError%3E-for-ReadlinesError"],[3423,"impl-From%3CPayloadError%3E-for-ReadlinesError"],[3750,"impl-PartialEq-for-Method"],[3751,"impl-PartialEq%3C%26Method%3E-for-Method"],[3752,"impl-PartialEq%3C%26str%3E-for-Method"],[3753,"impl-PartialEq%3CMethod%3E-for-%26Method"],[3754,"impl-PartialEq%3Cstr%3E-for-Method"],[3755,"impl-PartialEq%3Cu16%3E-for-StatusCode"],[3756,"impl-PartialEq-for-StatusCode"],[3757,"impl-PartialEq%3Cstr%3E-for-Uri"],[3758,"impl-PartialEq%3C%26str%3E-for-Uri"],[3759,"impl-PartialEq-for-Uri"],[3782,"impl-Display-for-Error"],[3783,"impl-Debug-for-Error"],[3784,"impl-Display-for-Method"],[3785,"impl-Debug-for-Method"],[3786,"impl-Debug-for-StatusCode"],[3787,"impl-Display-for-StatusCode"],[3788,"impl-Display-for-Uri"],[3789,"impl-Debug-for-Uri"],[3793,"impl-From%3CEncoderError%3E-for-Error"],[3794,"impl-From%3CHttpError%3E-for-Error"],[3795,"impl-From%3CHandshakeError%3E-for-Error"],[3796,"impl-From%3CInfallible%3E-for-Error"],[3797,"impl-From%3CParseError%3E-for-Error"],[3798,"impl-From%3CProtocolError%3E-for-Error"],[3799,"impl-From%3CPayloadError%3E-for-Error"],[3805,"impl-From%3CPathAndQuery%3E-for-Uri"],[3807,"impl-From%3CAuthority%3E-for-Uri"],[3809,"impl-From%3COption%3CDuration%3E%3E-for-KeepAlive"],[3811,"impl-From%3CDuration%3E-for-KeepAlive"],[3848,"impl-ResourcePath-for-Uri"],[3849,"impl-Uri"],[3851,"impl-Host-for-Uri"],[3852,"impl-Uri"],[3870,"impl-TryFrom%3C%26str%3E-for-Method"],[3871,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-Method"],[3873,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-StatusCode"],[3874,"impl-TryFrom%3C%26str%3E-for-StatusCode"],[3875,"impl-TryFrom%3Cu16%3E-for-StatusCode"],[3877,"impl-TryFrom%3CParts%3E-for-Uri"],[3878,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-Uri"],[3880,"impl-TryFrom%3CVec%3Cu8%3E%3E-for-Uri"],[3881,"impl-TryFrom%3CString%3E-for-Uri"],[3882,"impl-TryFrom%3C%26String%3E-for-Uri"],[3883,"impl-TryFrom%3C%26Uri%3E-for-Uri"],[3884,"impl-TryFrom%3C%26str%3E-for-Uri"],[4123,"impl-AsRef%3C%5Bu8%5D%3E-for-HeaderName"],[4124,"impl-AsRef%3Cstr%3E-for-HeaderName"],[4350,"impl-PartialEq%3CHeaderName%3E-for-%26HeaderName"],[4351,"impl-PartialEq%3C%26HeaderName%3E-for-HeaderName"],[4352,"impl-PartialEq%3C%26str%3E-for-HeaderName"],[4353,"impl-PartialEq-for-HeaderName"],[4354,"impl-PartialEq%3Cstr%3E-for-HeaderName"],[4355,"impl-PartialEq%3CHeaderValue%3E-for-%26HeaderValue"],[4356,"impl-PartialEq-for-HeaderValue"],[4357,"impl-PartialEq%3C%26T%3E-for-HeaderValue"],[4358,"impl-PartialEq%3Cstr%3E-for-HeaderValue"],[4359,"impl-PartialEq%3CString%3E-for-HeaderValue"],[4360,"impl-PartialEq%3C%5Bu8%5D%3E-for-HeaderValue"],[4378,"impl-PartialEq%3Cusize%3E-for-ContentLength"],[4379,"impl-PartialEq-for-ContentLength"],[4515,"impl-Debug-for-LanguageTag"],[4516,"impl-Display-for-LanguageTag"],[4517,"impl-Display-for-InvalidHeaderName"],[4518,"impl-Debug-for-InvalidHeaderName"],[4519,"impl-Debug-for-InvalidHeaderValue"],[4520,"impl-Display-for-InvalidHeaderValue"],[4521,"impl-Debug-for-HeaderName"],[4522,"impl-Display-for-HeaderName"],[4524,"impl-Debug-for-ToStrError"],[4525,"impl-Display-for-ToStrError"],[4527,"impl-Debug-for-Charset"],[4528,"impl-Display-for-Charset"],[4530,"impl-Display-for-ExtendedValue"],[4531,"impl-Debug-for-ExtendedValue"],[4532,"impl-Debug-for-HttpDate"],[4533,"impl-Display-for-HttpDate"],[4534,"impl-Display-for-Quality"],[4535,"impl-Debug-for-Quality"],[4536,"impl-Debug-for-QualityItem%3CT%3E"],[4537,"impl-Display-for-QualityItem%3CT%3E"],[4538,"impl-Debug-for-Accept"],[4539,"impl-Display-for-Accept"],[4540,"impl-Debug-for-AcceptCharset"],[4541,"impl-Display-for-AcceptCharset"],[4542,"impl-Display-for-AcceptEncoding"],[4543,"impl-Debug-for-AcceptEncoding"],[4544,"impl-Display-for-AcceptLanguage"],[4545,"impl-Debug-for-AcceptLanguage"],[4546,"impl-Display-for-Allow"],[4547,"impl-Debug-for-Allow"],[4548,"impl-Debug-for-CacheControl"],[4549,"impl-Display-for-CacheControl"],[4550,"impl-Debug-for-CacheDirective"],[4551,"impl-Display-for-CacheDirective"],[4552,"impl-Debug-for-DispositionType"],[4553,"impl-Display-for-DispositionType"],[4554,"impl-Debug-for-DispositionParam"],[4555,"impl-Display-for-DispositionParam"],[4556,"impl-Display-for-ContentDisposition"],[4557,"impl-Debug-for-ContentDisposition"],[4558,"impl-Display-for-ContentLanguage"],[4559,"impl-Debug-for-ContentLanguage"],[4561,"impl-Display-for-ContentRange"],[4562,"impl-Debug-for-ContentRange"],[4563,"impl-Debug-for-ContentRangeSpec"],[4564,"impl-Display-for-ContentRangeSpec"],[4565,"impl-Display-for-ContentType"],[4566,"impl-Debug-for-ContentType"],[4567,"impl-Display-for-Date"],[4568,"impl-Debug-for-Date"],[4569,"impl-Debug-for-Encoding"],[4570,"impl-Display-for-Encoding"],[4571,"impl-Display-for-EntityTag"],[4572,"impl-Debug-for-EntityTag"],[4573,"impl-Display-for-ETag"],[4574,"impl-Debug-for-ETag"],[4575,"impl-Debug-for-Expires"],[4576,"impl-Display-for-Expires"],[4577,"impl-Display-for-IfMatch"],[4578,"impl-Debug-for-IfMatch"],[4579,"impl-Debug-for-IfModifiedSince"],[4580,"impl-Display-for-IfModifiedSince"],[4581,"impl-Debug-for-IfNoneMatch"],[4582,"impl-Display-for-IfNoneMatch"],[4583,"impl-Debug-for-IfRange"],[4584,"impl-Display-for-IfRange"],[4585,"impl-Display-for-IfUnmodifiedSince"],[4586,"impl-Debug-for-IfUnmodifiedSince"],[4587,"impl-Display-for-LastModified"],[4588,"impl-Debug-for-LastModified"],[4589,"impl-Debug-for-Preference%3CT%3E"],[4590,"impl-Display-for-Preference%3CT%3E"],[4591,"impl-Debug-for-Range"],[4592,"impl-Display-for-Range"],[4593,"impl-Display-for-ByteRangeSpec"],[4594,"impl-Debug-for-ByteRangeSpec"],[4602,"impl-From%3Cu32%3E-for-HeaderValue"],[4603,"impl-From%3CHeaderName%3E-for-HeaderValue"],[4604,"impl-From%3Cisize%3E-for-HeaderValue"],[4605,"impl-From%3Ci64%3E-for-HeaderValue"],[4606,"impl-From%3Cusize%3E-for-HeaderValue"],[4608,"impl-From%3C%26HeaderValue%3E-for-HeaderValue"],[4609,"impl-From%3Cu64%3E-for-HeaderValue"],[4610,"impl-From%3Ci16%3E-for-HeaderValue"],[4611,"impl-From%3Cu16%3E-for-HeaderValue"],[4612,"impl-From%3Ci32%3E-for-HeaderValue"],[4667,"impl-FromStr-for-HeaderValue"],[4668,"impl-HeaderValue"],[4747,"impl-IntoIterator-for-HeaderMap"],[4748,"impl-IntoIterator-for-%26HeaderMap"],[4838,"impl-PartialOrd-for-HeaderValue"],[4839,"impl-PartialOrd%3Cstr%3E-for-HeaderValue"],[4840,"impl-PartialOrd%3C%26T%3E-for-HeaderValue"],[4841,"impl-PartialOrd%3CString%3E-for-HeaderValue"],[4842,"impl-PartialOrd%3CHeaderValue%3E-for-%26HeaderValue"],[4843,"impl-PartialOrd%3C%5Bu8%5D%3E-for-HeaderValue"],[4847,"impl-PartialOrd-for-ContentLength"],[4848,"impl-PartialOrd%3Cusize%3E-for-ContentLength"],[4961,"impl-TryFrom%3C%26str%3E-for-HeaderName"],[4962,"impl-TryFrom%3C%26String%3E-for-HeaderName"],[4963,"impl-TryFrom%3CVec%3Cu8%3E%3E-for-HeaderName"],[4964,"impl-TryFrom%3CString%3E-for-HeaderName"],[4965,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-HeaderName"],[4966,"impl-TryFrom%3CString%3E-for-HeaderValue"],[4967,"impl-TryFrom%3C%26str%3E-for-HeaderValue"],[4969,"impl-TryFrom%3CVec%3Cu8%3E%3E-for-HeaderValue"],[4970,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-HeaderValue"],[4971,"impl-TryFrom%3C%26String%3E-for-HeaderValue"],[5077,"impl-TryIntoHeaderValue-for-HeaderValue"],[5078,"impl-TryIntoHeaderValue-for-%26HeaderValue"],[5317,"impl-PartialEq%3CPort%3CU%3E%3E-for-Port%3CT%3E"],[5318,"impl-PartialEq%3Cu16%3E-for-Port%3CT%3E"],[5319,"impl-PartialEq-for-Authority"],[5320,"impl-PartialEq%3CString%3E-for-Authority"],[5321,"impl-PartialEq%3C%26str%3E-for-Authority"],[5322,"impl-PartialEq%3Cstr%3E-for-Authority"],[5323,"impl-PartialEq%3CString%3E-for-PathAndQuery"],[5324,"impl-PartialEq-for-PathAndQuery"],[5325,"impl-PartialEq%3Cstr%3E-for-PathAndQuery"],[5326,"impl-PartialEq%3C%26str%3E-for-PathAndQuery"],[5327,"impl-PartialEq-for-Scheme"],[5328,"impl-PartialEq%3Cstr%3E-for-Scheme"],[5338,"impl-Debug-for-Port%3CT%3E"],[5339,"impl-Display-for-Port%3CT%3E"],[5340,"impl-Debug-for-Authority"],[5341,"impl-Display-for-Authority"],[5343,"impl-Display-for-PathAndQuery"],[5344,"impl-Debug-for-PathAndQuery"],[5345,"impl-Debug-for-Scheme"],[5346,"impl-Display-for-Scheme"],[5348,"impl-Display-for-InvalidUri"],[5349,"impl-Debug-for-InvalidUri"],[5350,"impl-Debug-for-InvalidUriParts"],[5351,"impl-Display-for-InvalidUriParts"],[5383,"impl-PartialOrd%3Cstr%3E-for-Authority"],[5384,"impl-PartialOrd%3CString%3E-for-Authority"],[5385,"impl-PartialOrd%3C%26str%3E-for-Authority"],[5386,"impl-PartialOrd-for-Authority"],[5387,"impl-PartialOrd%3Cstr%3E-for-PathAndQuery"],[5388,"impl-PartialOrd%3C%26str%3E-for-PathAndQuery"],[5389,"impl-PartialOrd-for-PathAndQuery"],[5390,"impl-PartialOrd%3CString%3E-for-PathAndQuery"],[5409,"impl-TryFrom%3CString%3E-for-Authority"],[5411,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-Authority"],[5412,"impl-TryFrom%3C%26str%3E-for-Authority"],[5413,"impl-TryFrom%3CVec%3Cu8%3E%3E-for-Authority"],[5416,"impl-TryFrom%3C%26String%3E-for-PathAndQuery"],[5417,"impl-TryFrom%3CVec%3Cu8%3E%3E-for-PathAndQuery"],[5418,"impl-TryFrom%3C%26str%3E-for-PathAndQuery"],[5419,"impl-TryFrom%3CString%3E-for-PathAndQuery"],[5420,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-PathAndQuery"],[5422,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-Scheme"],[5423,"impl-TryFrom%3C%26str%3E-for-Scheme"],[6019,"impl-Debug-for-JoinError"],[6020,"impl-Display-for-JoinError"],[6113,"impl-Sub%3CDuration%3E-for-Instant"],[6114,"impl-Sub-for-Instant"],[6374,"impl-PartialEq%3CVec%3Cu8%3E%3E-for-Bytes"],[6375,"impl-PartialEq-for-Bytes"],[6376,"impl-PartialEq%3Cstr%3E-for-Bytes"],[6377,"impl-PartialEq%3C%26T%3E-for-Bytes"],[6378,"impl-PartialEq%3CString%3E-for-Bytes"],[6379,"impl-PartialEq%3CBytesMut%3E-for-Bytes"],[6380,"impl-PartialEq%3C%5Bu8%5D%3E-for-Bytes"],[6381,"impl-PartialEq%3Cstr%3E-for-BytesMut"],[6382,"impl-PartialEq%3CBytes%3E-for-BytesMut"],[6383,"impl-PartialEq%3CString%3E-for-BytesMut"],[6384,"impl-PartialEq-for-BytesMut"],[6385,"impl-PartialEq%3CVec%3Cu8%3E%3E-for-BytesMut"],[6386,"impl-PartialEq%3C%5Bu8%5D%3E-for-BytesMut"],[6387,"impl-PartialEq%3C%26T%3E-for-BytesMut"],[6418,"impl-Extend%3Cu8%3E-for-BytesMut"],[6419,"impl-Extend%3CBytes%3E-for-BytesMut"],[6420,"impl-Extend%3C%26u8%3E-for-BytesMut"],[6423,"impl-UpperHex-for-Bytes"],[6424,"impl-LowerHex-for-Bytes"],[6425,"impl-Debug-for-Bytes"],[6426,"impl-UpperHex-for-BytesMut"],[6427,"impl-LowerHex-for-BytesMut"],[6428,"impl-Debug-for-BytesMut"],[6433,"impl-Display-for-Form%3CT%3E"],[6434,"impl-Debug-for-Form%3CT%3E"],[6435,"impl-Display-for-Header%3CT%3E"],[6436,"impl-Debug-for-Header%3CT%3E"],[6437,"impl-Display-for-Json%3CT%3E"],[6438,"impl-Debug-for-Json%3CT%3E"],[6439,"impl-Debug-for-Path%3CT%3E"],[6440,"impl-Display-for-Path%3CT%3E"],[6441,"impl-Display-for-Query%3CT%3E"],[6442,"impl-Debug-for-Query%3CT%3E"],[6445,"impl-From%3CCustom%3E-for-Bytes"],[6447,"impl-From%3CVec%3Cu8%3E%3E-for-Bytes"],[6448,"impl-From%3C%26str%3E-for-Bytes"],[6449,"impl-From%3CBox%3C%5Bu8%5D%3E%3E-for-Bytes"],[6450,"impl-From%3CBytesMut%3E-for-Bytes"],[6451,"impl-From%3C%26%5Bu8%5D%3E-for-Bytes"],[6452,"impl-From%3CString%3E-for-Bytes"],[6453,"impl-From%3CCustom%3E-for-Bytes"],[6454,"impl-From%3CByteStr%3E-for-Bytes"],[6455,"impl-From%3CByteStr%3E-for-Bytes"],[6456,"impl-From%3C%26str%3E-for-BytesMut"],[6457,"impl-From%3C%26%5Bu8%5D%3E-for-BytesMut"],[6478,"impl-FromIterator%3C%26u8%3E-for-BytesMut"],[6479,"impl-FromIterator%3Cu8%3E-for-BytesMut"],[6558,"impl-Either%3CJson%3CT%3E,+Form%3CT%3E%3E"],[6559,"impl-Either%3CForm%3CT%3E,+Json%3CT%3E%3E"],[6565,"impl-IntoIterator-for-%26Bytes"],[6566,"impl-IntoIterator-for-Bytes"],[6567,"impl-IntoIterator-for-%26BytesMut"],[6568,"impl-IntoIterator-for-BytesMut"],[6585,"impl-PartialOrd%3C%26T%3E-for-Bytes"],[6586,"impl-PartialOrd%3C%5Bu8%5D%3E-for-Bytes"],[6587,"impl-PartialOrd%3CString%3E-for-Bytes"],[6588,"impl-PartialOrd-for-Bytes"],[6589,"impl-PartialOrd%3Cstr%3E-for-Bytes"],[6590,"impl-PartialOrd%3CVec%3Cu8%3E%3E-for-Bytes"],[6591,"impl-PartialOrd%3C%5Bu8%5D%3E-for-BytesMut"],[6592,"impl-PartialOrd%3C%26T%3E-for-BytesMut"],[6593,"impl-PartialOrd%3CString%3E-for-BytesMut"],[6594,"impl-PartialOrd%3Cstr%3E-for-BytesMut"],[6595,"impl-PartialOrd%3CVec%3Cu8%3E%3E-for-BytesMut"],[6596,"impl-PartialOrd-for-BytesMut"]],"c":"OjAAAAEAAAAAAAoAEAAAAJUAlgCXABMDOQMZBRkGGwYJE0kUyhg=","e":"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","a":{"encodedconfig":[2460],"extract":[18],"extractor":[18],"from_julian_date":[1074],"iso_weekday_number":[1182],"manage":[92,93,94],"middleware":[363,364,365,366,367,368,369],"parseable":[2571],"state":[95,6214],"use":[363,364,365,366,367,368,369]}}],\ +["actix_web_actors",{"t":"FNNNNNNNNNNNNNNNNNNNNNNCPPPPPPPPPGFPPPPPPPGPGPPPPPGPPPPPPPPPPPPGPPPPPPPFFNNNNNNNNNNNNNNNNNNNNNNNNNNONNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHHNNNNNNNNNNNNNNNNNHNHNHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN","n":["HttpContext","address","borrow","borrow_mut","cancel_future","create","from","handle","into","pack","parts","spawn","state","stop","terminate","try_from","try_into","type_id","vzip","wait","with_factory","write","write_eof","ws","Abnormal","Again","Away","BadOpCode","BadWebsocketKey","Binary","Binary","Close","Close","CloseCode","CloseReason","Continuation","Continuation","ContinuationFragment","ContinuationNotStarted","ContinuationStarted","Error","Extension","Frame","GetMethodRequired","HandshakeError","Invalid","InvalidLength","InvalidOpcode","Io","MaskedFrame","Message","NoConnectionUpgrade","NoVersionHeader","NoWebsocketUpgrade","Nop","Normal","Overflow","Ping","Ping","Policy","Pong","Pong","Protocol","ProtocolError","Restart","Size","Text","Text","UnmaskedFrame","Unsupported","UnsupportedVersion","WebsocketContext","WsResponseBuilder","address","binary","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","cancel_future","clone","clone","clone","clone_into","clone_into","clone_into","close","code","codec","create","create_with_addr","description","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","error_response","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","frame_size","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","handle","handshake","handshake_with_protocols","into","into","into","into","into","into","into","into","new","pack","parts","ping","pong","protocols","set_mailbox_capacity","source","spawn","start","start","start_with_addr","start_with_addr","start_with_protocols","state","stop","terminate","text","to_owned","to_owned","to_owned","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","wait","with_codec","with_factory","write_raw"],"q":[[0,"actix_web_actors"],[24,"actix_web_actors::ws"],[219,"actix_web_actors::context"],[220,"actix::address"],[221,"actix::actor"],[222,"bytes::bytes"],[223,"actix_web::error::error"],[224,"core::result"],[225,"futures_core::stream"],[226,"tokio::sync::oneshot"],[227,"core::option"],[228,"actix::address::envelope"],[229,"actix::handler"],[230,"core::marker"],[231,"actix::context_impl"],[232,"actix::fut::future"],[233,"core::any"],[234,"core::ops::function"],[235,"core::convert"],[236,"actix_http::ws::proto"],[237,"actix_http::ws"],[238,"actix_http::ws::codec"],[239,"actix_http::error"],[240,"actix::stream"],[241,"actix_web::response::response"],[242,"core::fmt"],[243,"alloc::string"],[244,"std::io::error"],[245,"actix_web::request"],[246,"actix_web::response::builder"],[247,"core::error"],[248,"bytestring"]],"i":[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,28,28,28,41,30,36,37,36,37,0,0,36,37,41,41,41,28,28,0,30,0,28,41,41,41,41,0,30,30,30,36,28,41,36,37,28,36,37,28,0,28,28,36,37,41,28,30,0,0,26,26,31,26,36,37,28,29,41,30,31,26,36,37,28,29,41,30,26,28,29,30,28,29,30,26,29,31,26,26,29,36,37,28,29,30,36,36,36,37,37,37,28,28,28,29,29,29,30,30,30,30,36,37,28,29,41,41,30,30,31,31,26,36,37,28,28,29,29,29,41,41,41,41,41,30,26,0,0,31,26,36,37,28,29,41,30,31,26,26,26,26,31,26,41,26,0,31,0,31,0,26,26,26,26,28,29,30,41,30,31,26,36,37,28,29,41,30,31,26,36,37,28,29,41,30,31,26,36,37,28,29,41,30,31,26,36,37,28,29,41,30,26,26,26,26],"f":"`{{{d{{b{c}}}}}{{f{c}}}{{j{}{{h{b}}}}}}{{{d{c}}}{{d{e}}}{}{}}{{{d{lc}}}{{d{le}}}{}{}}{{{d{l{b{c}}}}n}A`{{j{}{{h{b}}}}}}{c{{`{{Aj{}{{Ab{{Ah{AdAf}}}}}}}}}{{j{}{{h{}}}}}}{cc{}}{{{d{{b{c}}}}}n{{j{}{{h{b}}}}}}{ce{}{}}{{c{An{Al}}}{{B`{e}}}{BbBd}{}}{{{d{l{b{c}}}}}{{d{l{Bf{c}}}}}{{j{}{{h{b}}}}}}{{{d{l{b{c}}}}e}n{{j{}{{h{b}}}}}{{Bl{c}{{Bh{Bj}}}}}}{{{d{{b{c}}}}}Bn{{j{}{{h{b}}}}}}{{{d{l{b{c}}}}}Bj{{j{}{{h{b}}}}}}0{c{{Ah{e}}}{}{}}0{{{d{c}}}C`{}}7{{{d{l{b{c}}}}e}Bj{{j{}{{h{b}}}}}{{Bl{c}{{Bh{Bj}}}}}}{e{{`{{Aj{}{{Ab{{Ah{AdAf}}}}}}}}}{{j{}{{h{}}}}}{{Cb{{d{l{b{c}}}}}{{Bh{c}}}}}}{{{d{l{b{c}}}}Ad}Bj{{j{}{{h{b}}}}}}5``````````````````````````````````````````````````{{{d{{Cd{c}}}}}{{f{c}}}{{j{}{{h{Cd}}}}}}{{{d{l{Cd{c}}}}e}Bj{{j{}{{h{Cd}}}}}{{Cf{Ad}}}}{{{d{c}}}{{d{e}}}{}{}}0000000{{{d{lc}}}{{d{le}}}{}{}}0000000{{{d{l{Cd{c}}}}n}A`{{j{}{{h{Cd}}}}}}{{{d{Ch}}}Ch}{{{d{Cj}}}Cj}{{{d{Cl}}}Cl}{{{d{c}}{d{le}}}Bj{}{}}00{{{d{l{Cd{c}}}}{An{Cj}}}Bj{{j{}{{h{Cd}}}}}}`{{{Cn{ce}}D`}{{Cn{ce}}}{}{{Aj{}{{Ab{{Ah{AdDb}}}}}}}}{{ce}{{`{{Aj{}{{Ab{{Ah{AdAf}}}}}}}}}{Dd{j{}{{h{}}}}}{{Aj{}{{Ab{{Ah{AdDb}}}}}}}}{{ce}{{Df{{f{c}}{`{{Aj{}{{Ab{{Ah{AdAf}}}}}}}}}}}{Dd{j{}{{h{}}}}}{{Aj{}{{Ab{{Ah{AdDb}}}}}}}}`{{{d{Dh}}{d{Dh}}}A`}{{{d{Dj}}{d{Dj}}}A`}{{{d{Ch}}{d{Ch}}}A`}{{{d{Cj}}{d{Cj}}}A`}{{{d{Cl}}{d{Cl}}}A`}{{{d{c}}{d{e}}}A`{}{}}00000000000000{{{d{Cl}}}Dl}{{{d{Dh}}{d{lDn}}}{{Ah{BjE`}}}}{{{d{Dj}}{d{lDn}}}{{Ah{BjE`}}}}{{{d{Ch}}{d{lDn}}}{{Ah{BjE`}}}}{{{d{Cj}}{d{lDn}}}{{Ah{BjE`}}}}{{{d{Eb}}{d{lDn}}}{{Ah{BjE`}}}}0{{{d{Cl}}{d{lDn}}}{{Ah{BjE`}}}}0{{{Cn{ce}}Ed}{{Cn{ce}}}{}{{Aj{}{{Ab{{Ah{AdDb}}}}}}}}{cc{}}000{EfCh}1{{{Df{Chc}}}Cj{{Cf{Eh}}}}{ChCj}3{EjEb}{ElEb}{EnEb}6{EdEb}7{{{d{{Cd{c}}}}}n{{j{}{{h{Cd}}}}}}{{{d{F`}}}{{Ah{FbCl}}}}{{{d{F`}}{d{{Ff{{d{Fd}}}}}}}{{Ah{FbCl}}}}{ce{}{}}0000000{{c{d{F`}}e}{{Cn{ce}}}{{j{}{{h{}}}}Dd}{{Aj{}{{Ab{{Ah{AdDb}}}}}}}}{{c{An{Al}}}{{B`{e}}}{BbBd}{}}{{{d{l{Cd{c}}}}}{{d{l{Bf{c}}}}}{{j{}{{h{Cd}}}}}}{{{d{l{Cd{c}}}}{d{{Ff{En}}}}}Bj{{j{}{{h{Cd}}}}}}0{{{Cn{ce}}{d{{Ff{{d{Fd}}}}}}}{{Cn{ce}}}{}{{Aj{}{{Ab{{Ah{AdDb}}}}}}}}{{{d{l{Cd{c}}}}Ed}Bj{{j{}{{h{Cd}}}}}}{{{d{Eb}}}{{An{{d{Fh}}}}}}{{{d{l{Cd{c}}}}e}n{{j{}{{h{Cd}}}}}{{Bl{c}{{Bh{Bj}}}}}}{{c{d{F`}}e}{{Ah{DlAf}}}{{j{}{{h{}}}}Dd}{{Aj{}{{Ab{{Ah{AdDb}}}}}}}}{{{Cn{ce}}}{{Ah{DlAf}}}{}{{Aj{}{{Ab{{Ah{AdDb}}}}}}}}{{c{d{F`}}e}{{Ah{{Df{{f{c}}Dl}}Af}}}{{j{}{{h{}}}}Dd}{{Aj{}{{Ab{{Ah{AdDb}}}}}}}}{{{Cn{ce}}}{{Ah{{Df{{f{c}}Dl}}Af}}}{}{{Aj{}{{Ab{{Ah{AdDb}}}}}}}}{{c{d{{Ff{{d{Fd}}}}}}{d{F`}}e}{{Ah{DlAf}}}{{j{}{{h{}}}}Dd}{{Aj{}{{Ab{{Ah{AdDb}}}}}}}}{{{d{{Cd{c}}}}}Bn{{j{}{{h{Cd}}}}}}{{{d{l{Cd{c}}}}}Bj{{j{}{{h{Cd}}}}}}0{{{d{l{Cd{c}}}}e}Bj{{j{}{{h{Cd}}}}}{{Cf{Fj}}}}{{{d{c}}}e{}{}}00{{{d{c}}}Eh{}}0{c{{Ah{e}}}{}{}}000000000000000{{{d{c}}}C`{}}0000000{ce{}{}}0000000{{{d{l{Cd{c}}}}e}Bj{{j{}{{h{Cd}}}}}{{Bl{c}{{Bh{Bj}}}}}}{{ceD`}{{`{{Aj{}{{Ab{{Ah{AdAf}}}}}}}}}{Dd{j{}{{h{}}}}}{{Aj{}{{Ab{{Ah{AdDb}}}}}}}}{{cg}{{`{{Aj{}{{Ab{{Ah{AdAf}}}}}}}}}{{Aj{}{{Ab{{Ah{AdDb}}}}}}}{Dd{j{}{{h{}}}}}{{Cb{{d{l{Cd{e}}}}}{{Bh{e}}}}}}{{{d{l{Cd{c}}}}Dh}Bj{{j{}{{h{Cd}}}}}}","D":"Lh","p":[[5,"HttpContext",0,219],[1,"reference"],[5,"Addr",220],[17,"Context"],[10,"Actor",221],[0,"mut"],[5,"SpawnHandle",221],[1,"bool"],[17,"Item"],[5,"Bytes",222],[5,"Error",223],[6,"Result",224],[10,"Stream",225],[5,"Sender",226],[6,"Option",227],[5,"Envelope",228],[10,"Message",229],[10,"Send",230],[5,"ContextParts",231],[17,"Output"],[1,"unit"],[10,"ActorFuture",232],[6,"ActorState",221],[5,"TypeId",233],[10,"FnOnce",234],[5,"WebsocketContext",24],[10,"Into",235],[6,"CloseCode",24,236],[5,"CloseReason",24,236],[6,"HandshakeError",24,237],[5,"WsResponseBuilder",24],[5,"Codec",238],[6,"PayloadError",239],[10,"StreamHandler",240],[1,"tuple"],[6,"Message",24,238],[6,"Frame",24,238],[5,"HttpResponse",241],[5,"Formatter",242],[5,"Error",242],[6,"ProtocolError",24,237],[1,"usize"],[1,"u16"],[5,"String",243],[5,"Error",244],[6,"OpCode",236],[1,"u8"],[5,"HttpRequest",245],[5,"HttpResponseBuilder",246],[1,"str"],[1,"slice"],[10,"Error",247],[5,"ByteString",248]],"r":[[0,219],[33,236],[34,236],[42,238],[44,237],[50,238],[63,237]],"b":[[129,"impl-Display-for-ProtocolError"],[130,"impl-Debug-for-ProtocolError"],[131,"impl-Display-for-HandshakeError"],[132,"impl-Debug-for-HandshakeError"],[140,"impl-From%3C(CloseCode,+T)%3E-for-CloseReason"],[141,"impl-From%3CCloseCode%3E-for-CloseReason"],[143,"impl-From%3CError%3E-for-ProtocolError"],[144,"impl-From%3COpCode%3E-for-ProtocolError"],[145,"impl-From%3Cu8%3E-for-ProtocolError"],[147,"impl-From%3Cusize%3E-for-ProtocolError"]],"c":"OjAAAAEAAAAAAAEAEAAAAKwArgA=","e":"OzAAAAEAAHcADQACAAMACgAKAEoAAABMABYAaQAcAIsAAACNAAEAkAACAJQAAACiAAEAqAABAK8AAgCzACUA"}],\ +["actix_web_codegen",{"t":"XXXXXXXXXXXXX","n":["connect","delete","get","head","main","options","patch","post","put","route","routes","test","trace"],"q":[[0,"actix_web_codegen"]],"i":[0,0,0,0,0,0,0,0,0,0,0,0,0],"f":"`````````````","D":"Al","p":[],"r":[],"b":[],"c":"OjAAAAAAAAA=","e":"OjAAAAAAAAA="}],\ +["awc",{"t":"IIFPPFFFFGGFPFFPFIFGPPNONNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNENNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNCNFGFFGRPKFPPPFPTNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNNNNNNMNNNNNHHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOPPPPGPPPPPPPPPGPPPFPPPFPPPPPPPPGPPPGPPPPPPPPPPPPGPPPPPGPPFPPPPPPPPPPGGGNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNTTTTTTTTPGTTFTTTTTTTTTTTTTTTTTPTTTTTTTTFTTTTTTTTTTTTTTTTTTTTTTTTTTTTFTTTTTTTTTTPFTFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNCNNNNNNSSSSSSSSSSSSSSSSSKPPSSSSSSSSSSSSSSSSSGGSSPSSSRRPPPFSSPPSKFFFFSSSSSPFFPPPPPPPPPPPPPPPPPPSSSFTSTSSSSSSSFFSSSSSSSSSSSSSPSSSFKKSSSPSSSSSSSSSSSTPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNNNNNNNNNNNNHNNNNHNNNNNNNNNNNNNNNNNNHNNNNNNNNNNNNNNNNNNNNNNONNONNNCNNNMNNNMNNHNNNNNNNNNNNNHONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNMNMNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNFFFFFFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNFFTTFFFFFFFNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNFKRNNNNNNNMNNNNNFNNNNNNNNNNNNNNNNPPPPPPPGFFPPPPGPGPPPPPPPPPPPPPFNNNNNNNNNNNNNNNNNNNNNNONNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN","n":["BoxConnectorService","BoxedSocket","Client","Client","Client","ClientBuilder","ClientRequest","ClientResponse","Connect","ConnectRequest","ConnectResponse","Connector","Err","FrozenClientRequest","FrozenSendBuilder","Fut","JsonBody","MessageBody","ResponseBody","SendClientRequest","Tunnel","Tunnel","add_default_header","addr","address","append_header","basic_auth","basic_auth","bearer_auth","bearer_auth","body","body","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","builder","camel_case","clone","clone","clone","clone_into","clone_into","clone_into","conn_keep_alive","conn_lifetime","connector","connector","content_length","content_type","cookie","cookie","cookie","cookies","default","delete","disable_redirects","disable_timeout","disconnect_timeout","error","extensions","extensions_mut","extra_header","extra_header","extra_headers","finish","finish","fmt","fmt","force_close","freeze","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","get","get_method","get_method","get_peer_addr","get_uri","get_uri","get_version","handshake_timeout","head","headers","headers","headers","headers","headers","headers_mut","http","initial_connection_window_size","initial_connection_window_size","initial_window_size","initial_window_size","insert_header","insert_header_if_none","into","into","into","into","into","into","into","into","into","into","into","into","into","into_client_response","into_future","into_future","into_future","into_tunnel_response","json","limit","limit","limit","local_address","local_address","map_body","max_http_version","max_http_version","max_redirects","method","middleware","new","new","new","new","new","no_decompress","no_default_headers","openssl","options","patch","poll","poll","poll","poll_next","post","put","query","request","request_from","rustls","rustls_021","rustls_0_22","rustls_0_23","send","send","send","send_body","send_body","send_body","send_form","send_form","send_form","send_json","send_json","send_json","send_stream","send_stream","send_stream","status","take_payload","test","timeout","timeout","timeout","timeout","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_poll","try_poll","try_poll","try_poll_next","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","uri","uri","version","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","wrap","ws","ws","BodyLimitExceeded","BodySize","BodyStream","BoxBody","EitherBody","Error","Left","MessageBody","None","None","Right","Sized","SizedStream","Stream","ZERO","as_pin_mut","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","boxed","boxed","boxed","clone","clone","clone","clone_into","clone_into","clone_into","default","eq","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","into","into","into","into","into","into","into","is_eof","left","new","new","new","new","new","poll_next","poll_next","poll_next","poll_next","poll_next","poll_next","right","size","size","size","size","size","size","to_bytes","to_bytes_limited","to_owned","to_owned","to_owned","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into_bytes","try_into_bytes","try_into_bytes","try_into_bytes","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","body","body","BadOpCode","BadWebsocketKey","Body","Connect","ConnectError","ContentType","ContinuationFragment","ContinuationNotStarted","ContinuationStarted","Custom","Custom","Deserialize","Disconnected","EncodingCorrupted","FreezeRequestError","GetMethodRequired","H2","H2","HeaderValue","Http","Http","Http2Payload","HttpError","HttpError","Incomplete","InvalidChallengeResponse","InvalidConnectionHeader","InvalidLength","InvalidOpcode","InvalidResponseStatus","InvalidUpgradeHeader","InvalidUrl","Io","Io","Io","JsonPayloadError","MaskedFrame","MissingConnectionHeader","MissingHost","MissingScheme","MissingWebSocketAcceptHeader","NoConnectionUpgrade","NoRecords","NoVersionHeader","NoWebsocketUpgrade","Overflow","Overflow","Payload","PayloadError","Protocol","Resolver","Response","Send","SendRequest","SendRequestError","SslError","SslIsNotSupported","StatusCode","Timeout","Timeout","TunnelNotSupported","UnknownLength","UnknownScheme","UnmaskedFrame","Unresolved","UnsupportedVersion","Url","Url","WsClientError","WsHandshakeError","WsProtocolError","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone_into","eq","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","get_ref","into","into","into","into","into","into","into","into","into","into","is","source","source","source","to_owned","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","ACCEPTED","ALREADY_REPORTED","BAD_GATEWAY","BAD_REQUEST","CONFLICT","CONNECT","CONTINUE","CREATED","Close","ConnectionType","DELETE","EXPECTATION_FAILED","Error","FAILED_DEPENDENCY","FORBIDDEN","FOUND","GATEWAY_TIMEOUT","GET","GONE","HEAD","HTTP_09","HTTP_10","HTTP_11","HTTP_2","HTTP_3","HTTP_VERSION_NOT_SUPPORTED","IM_A_TEAPOT","IM_USED","INSUFFICIENT_STORAGE","INTERNAL_SERVER_ERROR","KeepAlive","LENGTH_REQUIRED","LOCKED","LOOP_DETECTED","METHOD_NOT_ALLOWED","MISDIRECTED_REQUEST","MOVED_PERMANENTLY","MULTIPLE_CHOICES","MULTI_STATUS","Method","NETWORK_AUTHENTICATION_REQUIRED","NON_AUTHORITATIVE_INFORMATION","NOT_ACCEPTABLE","NOT_EXTENDED","NOT_FOUND","NOT_IMPLEMENTED","NOT_MODIFIED","NO_CONTENT","OK","OPTIONS","PARTIAL_CONTENT","PATCH","PAYLOAD_TOO_LARGE","PAYMENT_REQUIRED","PERMANENT_REDIRECT","POST","PRECONDITION_FAILED","PRECONDITION_REQUIRED","PROCESSING","PROXY_AUTHENTICATION_REQUIRED","PUT","RANGE_NOT_SATISFIABLE","REQUEST_HEADER_FIELDS_TOO_LARGE","REQUEST_TIMEOUT","RESET_CONTENT","SEE_OTHER","SERVICE_UNAVAILABLE","SWITCHING_PROTOCOLS","StatusCode","TEMPORARY_REDIRECT","TOO_MANY_REQUESTS","TRACE","UNAUTHORIZED","UNAVAILABLE_FOR_LEGAL_REASONS","UNPROCESSABLE_ENTITY","UNSUPPORTED_MEDIA_TYPE","UPGRADE_REQUIRED","URI_TOO_LONG","USE_PROXY","Upgrade","Uri","VARIANT_ALSO_NEGOTIATES","Version","as_ref","as_str","as_str","as_u16","authority","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","builder","canonical_reason","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","compare","compare","default","default","default","default","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_bytes","from_bytes","from_maybe_shared","from_parts","from_static","from_str","from_str","from_str","from_u16","hash","hash","hash","hash","header","host","hostname","into","into","into","into","into","into","into_parts","is_client_error","is_idempotent","is_informational","is_redirection","is_safe","is_server_error","is_success","partial_cmp","partial_cmp","path","path_and_query","port","port","port_u16","query","scheme","scheme_str","source","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","uri","vzip","vzip","vzip","vzip","vzip","vzip","ACCEPT","ACCEPT_CHARSET","ACCEPT_ENCODING","ACCEPT_LANGUAGE","ACCEPT_RANGES","ACCESS_CONTROL_ALLOW_CREDENTIALS","ACCESS_CONTROL_ALLOW_HEADERS","ACCESS_CONTROL_ALLOW_METHODS","ACCESS_CONTROL_ALLOW_ORIGIN","ACCESS_CONTROL_EXPOSE_HEADERS","ACCESS_CONTROL_MAX_AGE","ACCESS_CONTROL_REQUEST_HEADERS","ACCESS_CONTROL_REQUEST_METHOD","AGE","ALLOW","ALT_SVC","AUTHORIZATION","AsHeaderName","Big5","Brotli","CACHE_CONTROL","CACHE_STATUS","CDN_CACHE_CONTROL","CONNECTION","CONTENT_DISPOSITION","CONTENT_ENCODING","CONTENT_LANGUAGE","CONTENT_LENGTH","CONTENT_LOCATION","CONTENT_RANGE","CONTENT_SECURITY_POLICY","CONTENT_SECURITY_POLICY_REPORT_ONLY","CONTENT_TYPE","COOKIE","CROSS_ORIGIN_EMBEDDER_POLICY","CROSS_ORIGIN_OPENER_POLICY","CROSS_ORIGIN_RESOURCE_POLICY","Charset","ContentEncoding","DATE","DNT","Deflate","ETAG","EXPECT","EXPIRES","Error","Error","Euc_Jp","Euc_Kr","Ext","ExtendedValue","FORWARDED","FROM","Gb2312","Gzip","HOST","Header","HeaderMap","HeaderName","HeaderValue","HttpDate","IF_MATCH","IF_MODIFIED_SINCE","IF_NONE_MATCH","IF_RANGE","IF_UNMODIFIED_SINCE","Identity","InvalidHeaderName","InvalidHeaderValue","Iso_2022_Jp","Iso_2022_Jp_2","Iso_2022_Kr","Iso_8859_1","Iso_8859_10","Iso_8859_2","Iso_8859_3","Iso_8859_4","Iso_8859_5","Iso_8859_6","Iso_8859_6_E","Iso_8859_6_I","Iso_8859_7","Iso_8859_8","Iso_8859_8_E","Iso_8859_8_I","Iso_8859_9","Koi8_R","LAST_MODIFIED","LINK","LOCATION","LanguageTag","MAX","MAX_FORWARDS","MIN","ORIGIN","PERMISSIONS_POLICY","PRAGMA","PROXY_AUTHENTICATE","PROXY_AUTHORIZATION","PUBLIC_KEY_PINS","PUBLIC_KEY_PINS_REPORT_ONLY","Quality","QualityItem","RANGE","REFERER","REFERRER_POLICY","REFRESH","RETRY_AFTER","SEC_WEBSOCKET_ACCEPT","SEC_WEBSOCKET_EXTENSIONS","SEC_WEBSOCKET_KEY","SEC_WEBSOCKET_PROTOCOL","SEC_WEBSOCKET_VERSION","SERVER","SET_COOKIE","STRICT_TRANSPORT_SECURITY","Shift_Jis","TE","TRAILER","TRANSFER_ENCODING","ToStrError","TryIntoHeaderPair","TryIntoHeaderValue","UPGRADE","UPGRADE_INSECURE_REQUESTS","USER_AGENT","Us_Ascii","VARY","VIA","WARNING","WWW_AUTHENTICATE","X_CONTENT_TYPE_OPTIONS","X_DNS_PREFETCH_CONTROL","X_FORWARDED_FOR","X_FORWARDED_HOST","X_FORWARDED_PROTO","X_FRAME_OPTIONS","X_XSS_PROTECTION","ZERO","Zstd","append","as_bytes","as_ref","as_ref","as_ref","as_str","as_str","as_str","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","canonicalize","capacity","charset","clear","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","cmp","cmp","compare","compare","compare","contains_key","default","default","default","drain","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","extended_language","extended_language_subtags","extension","extension_subtags","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt_comma_delimited","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from_bytes","from_bytes","from_comma_delimited","from_lowercase","from_maybe_shared","from_maybe_shared_unchecked","from_name","from_one_raw_str","from_static","from_static","from_str","from_str","from_str","from_str","from_str","from_str","from_str","from_str","full_language","get","get_all","get_mut","hash","hash","hash","hash","http_percent_encode","insert","into","into","into","into","into","into","into","into","into","into","into","into","into","into_iter","into_iter","into_string","is_empty","is_empty","is_language_range","is_sensitive","is_valid","item","iter","keys","language_tag","len","len","len_keys","map","matches","max","min","name","name","new","new","parse","parse","parse","parse_extended_value","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","primary_language","private_use","private_use_subtags","q","quality","region","remove","reserve","retain","script","set_sensitive","to_header_value","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_str","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into_pair","try_into_pair","try_into_value","try_into_value","try_into_value","try_into_value","try_into_value","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","validate","value","variant","variant_subtags","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","with_capacity","zero","Drain","HeaderMap","IntoIter","Iter","Keys","Removed","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","into","into","into","into","into","into_iter","into_iter","into_iter","into_iter","into_iter","is_empty","next","next","next","next","next","size_hint","size_hint","size_hint","size_hint","size_hint","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","Authority","Builder","HTTP","HTTPS","InvalidUri","InvalidUriParts","Parts","PathAndQuery","Port","Scheme","Uri","as_ref","as_ref","as_ref","as_str","as_str","as_str","as_str","as_u16","authority","authority","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","build","clone","clone","clone","clone_into","clone_into","clone_into","default","default","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from_maybe_shared","from_maybe_shared","from_static","from_static","from_str","from_str","from_str","hash","hash","hash","host","into","into","into","into","into","into","into","into","new","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","partial_cmp","path","path_and_query","path_and_query","port","port_u16","query","scheme","scheme","to_owned","to_owned","to_owned","to_string","to_string","to_string","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","Redirect","Transform","Transform","borrow","borrow_mut","default","from","into","max_redirect_times","new","new_transform","new_transform","try_from","try_into","type_id","vzip","TestResponse","append_header","borrow","borrow_mut","cookie","default","finish","from","insert_header","into","set_payload","try_from","try_into","type_id","version","vzip","with_header","Abnormal","Again","Away","Binary","Binary","Close","Close","CloseCode","CloseReason","Codec","Continuation","Continuation","Error","Extension","Frame","Invalid","Message","Nop","Normal","Ping","Ping","Policy","Pong","Pong","Protocol","Restart","Size","Text","Text","Unsupported","WebsocketsRequest","address","basic_auth","bearer_auth","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","client_mode","clone","clone","clone","clone_into","clone_into","clone_into","code","connect","cookie","decode","default","description","encode","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","header","into","into","into","into","into","into","max_frame_size","max_size","new","origin","protocols","server_mode","set_header","set_header_if_none","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip"],"q":[[0,"awc"],[270,"awc::body"],[392,"awc::body::EitherBody"],[394,"awc::error"],[631,"awc::http"],[892,"awc::http::header"],[1388,"awc::http::header::map"],[1455,"awc::http::uri"],[1635,"awc::middleware"],[1651,"awc::test"],[1668,"awc::ws"],[1801,"awc::builder"],[1802,"actix_rt::net"],[1803,"core::fmt"],[1804,"http::uri"],[1805,"actix_tls::connect::info"],[1806,"actix_tls::connect::connection"],[1807,"actix_tls::connect::error"],[1808,"actix_service"],[1809,"core::clone"],[1810,"actix_http::header::into_pair"],[1811,"awc::request"],[1812,"core::net::socket_addr"],[1813,"core::option"],[1814,"awc::responses::response"],[1815,"awc::responses::response_body"],[1816,"bytes::bytes"],[1817,"actix_http::error"],[1818,"core::result"],[1819,"futures_core::stream"],[1820,"tokio::net::tcp::stream"],[1821,"awc::client"],[1822,"awc::frozen"],[1823,"awc::client::connector"],[1824,"core::time"],[1825,"cookie"],[1826,"alloc::vec"],[1827,"core::cell"],[1828,"cookie::parse"],[1829,"actix_http::extensions"],[1830,"actix_http::header::map"],[1831,"alloc::rc"],[1832,"alloc::boxed"],[1833,"awc::connect"],[1834,"awc::client::error"],[1835,"awc::sender"],[1836,"http::method"],[1837,"http::version"],[1838,"actix_http::responses::head"],[1839,"actix_http::h1::client"],[1840,"actix_codec::framed"],[1841,"awc::responses::json_body"],[1842,"serde::de"],[1843,"core::net::ip_addr"],[1844,"actix_http::payload"],[1845,"core::ops::function"],[1846,"openssl::ssl::connector"],[1847,"core::pin"],[1848,"core::task::wake"],[1849,"core::task::poll"],[1850,"core::marker"],[1851,"serde_urlencoded::ser"],[1852,"serde::ser"],[1853,"actix_http::requests::head"],[1854,"rustls::client::client_conn"],[1855,"alloc::sync"],[1856,"actix_http::body::message_body"],[1857,"core::error"],[1858,"core::convert"],[1859,"http::status"],[1860,"core::any"],[1861,"actix_http::body::boxed"],[1862,"actix_http::body::either"],[1863,"actix_http::body::none"],[1864,"actix_http::body::size"],[1865,"actix_http::body::utils"],[1866,"actix_http::body::body_stream"],[1867,"actix_http::body::sized_stream"],[1868,"alloc::string"],[1869,"http::header::value"],[1870,"http::header::map"],[1871,"http::header::name"],[1872,"std::io::error"],[1873,"openssl::ssl::error"],[1874,"h2::error"],[1875,"serde_json::error"],[1876,"actix_http::ws::proto"],[1877,"http::uri::authority"],[1878,"http::uri::builder"],[1879,"actix_http::message"],[1880,"core::cmp"],[1881,"actix_http::encoding::encoder"],[1882,"http::uri::path"],[1883,"core::hash"],[1884,"http::uri::port"],[1885,"http::uri::scheme"],[1886,"language_tags"],[1887,"actix_http::header::shared::content_encoding"],[1888,"actix_http::header::shared::charset"],[1889,"actix_http::header::shared::extended"],[1890,"actix_http::header::shared::http_date"],[1891,"actix_http::header::shared::quality"],[1892,"actix_http::header::shared::quality_item"],[1893,"actix_http::header::as_name"],[1894,"core::iter::traits::iterator"],[1895,"std::time"],[1896,"core::str::traits"],[1897,"core::slice::iter"],[1898,"actix_http::header"],[1899,"actix_http::http_message"],[1900,"actix_http::header::into_value"],[1901,"awc::middleware::redirect"],[1902,"actix_http::ws::codec"],[1903,"bytes::bytes_mut"],[1904,"core::iter::traits::collect"],[1905,"actix_http"],[1906,"http"],[1907,"actix_http::header::common"],[1908,"actix_http::header::utils"]],"i":[0,0,0,45,56,0,0,0,0,0,0,0,51,0,0,51,0,0,0,0,45,56,1,28,13,13,1,13,1,13,0,20,1,32,45,56,41,13,51,28,29,30,62,20,21,1,32,45,56,41,13,51,28,29,30,62,20,21,29,13,28,29,30,28,29,30,32,32,1,32,13,13,0,13,20,20,29,29,1,1,32,0,20,20,41,30,30,1,32,13,20,13,13,1,32,45,56,41,13,51,51,51,28,29,30,62,20,21,29,13,30,13,13,30,13,32,29,13,29,30,20,20,13,0,1,32,1,32,13,13,1,32,45,56,41,13,51,28,29,30,62,20,21,56,51,62,21,56,20,32,62,21,1,32,20,1,32,1,13,0,1,32,29,62,21,13,1,32,29,29,51,62,21,20,29,29,13,29,29,32,32,32,32,41,13,30,41,13,30,41,13,30,41,13,30,41,13,30,20,20,0,1,32,13,20,28,29,30,1,32,45,56,41,13,51,28,29,30,62,20,21,1,32,45,56,41,13,51,28,29,30,62,20,21,51,62,21,20,1,32,45,56,41,13,51,28,29,30,62,20,21,13,28,20,1,32,45,56,41,13,51,28,29,30,62,20,21,1,0,29,0,0,0,0,0,83,90,0,0,92,90,92,0,92,92,89,96,89,90,91,92,97,95,96,89,90,91,92,97,95,83,89,90,90,91,92,90,91,92,91,92,92,92,92,89,90,91,92,95,95,96,89,90,91,92,97,95,96,89,90,91,92,97,95,92,90,96,89,90,91,97,83,96,89,90,91,97,90,83,96,89,90,91,97,0,0,90,91,92,95,96,89,90,91,92,97,95,96,89,90,91,92,97,95,83,89,90,91,96,89,90,91,92,97,95,96,89,90,91,92,97,95,182,183,104,99,50,50,0,103,104,104,104,50,49,103,100,24,0,99,100,50,0,50,49,24,0,101,24,102,102,104,104,102,102,0,100,24,104,0,104,102,101,101,102,99,100,99,99,24,104,103,0,102,100,50,50,102,0,100,100,0,100,50,50,24,101,104,100,99,50,49,0,0,0,52,100,101,50,49,102,103,24,104,99,52,100,101,50,49,102,103,24,104,99,99,99,99,99,99,99,52,52,100,100,101,101,50,50,49,49,102,102,103,103,24,24,104,104,99,99,52,52,52,52,52,52,52,52,52,52,100,100,100,100,100,100,101,101,50,50,50,50,50,50,50,50,50,50,49,49,49,49,102,102,102,102,102,102,102,102,103,103,103,103,24,24,24,24,104,104,104,104,104,99,52,52,100,101,50,49,102,103,24,104,99,52,52,24,104,99,52,100,101,50,49,102,103,24,104,99,52,100,101,50,49,102,103,24,104,99,52,100,101,50,49,102,103,24,104,99,52,100,101,50,49,102,103,24,104,99,52,100,101,50,49,102,103,24,104,99,86,86,86,86,86,53,86,86,125,0,53,86,0,86,86,86,86,53,86,53,54,54,54,54,54,86,86,86,86,86,125,86,86,86,86,86,86,86,86,0,86,86,86,86,86,86,86,86,86,53,86,53,86,86,86,53,86,86,86,86,53,86,86,86,86,86,86,86,0,86,86,53,86,86,86,86,86,86,86,125,0,86,0,53,53,86,86,4,127,53,86,4,54,125,127,53,86,4,54,125,4,86,53,86,4,54,125,53,86,4,54,125,86,54,86,54,53,86,4,54,53,53,53,53,53,86,86,4,4,4,54,125,53,53,53,86,86,86,4,4,4,54,54,54,125,125,125,127,127,53,53,86,86,4,4,54,125,127,127,127,127,127,127,127,127,53,53,86,86,4,4,4,54,125,53,86,4,4,4,53,86,4,86,53,86,4,54,0,4,4,127,53,86,4,54,125,4,86,53,86,86,53,86,86,86,54,4,4,4,4,4,4,4,4,127,53,86,4,54,125,127,53,86,4,127,53,53,53,86,86,86,86,4,4,4,4,4,4,4,4,54,125,127,53,86,4,54,125,127,53,86,4,54,125,0,127,53,86,4,54,125,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,140,138,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,0,0,0,12,169,140,140,140,0,0,0,140,138,0,0,0,0,0,0,0,0,0,0,0,138,0,0,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,140,0,0,0,0,143,0,143,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,140,0,0,0,0,0,0,0,0,0,140,0,0,0,0,0,0,0,0,0,0,0,143,138,42,119,136,136,119,137,136,138,137,113,106,136,136,119,151,42,140,138,141,142,143,144,137,113,106,136,119,151,42,140,138,141,142,143,144,137,42,141,42,137,136,119,42,140,138,141,142,143,144,137,136,119,42,140,138,141,142,143,144,119,142,143,119,142,143,42,42,138,143,42,137,136,136,136,136,136,119,119,119,119,119,119,140,138,141,142,143,144,137,137,137,136,136,136,119,119,119,140,140,140,138,138,138,141,141,141,142,142,142,143,143,143,144,144,144,137,137,137,137,137,137,113,113,106,106,136,136,119,151,151,42,140,140,138,141,141,142,142,143,143,144,144,0,137,113,106,136,136,119,119,119,119,119,119,119,119,119,119,119,151,42,42,140,138,141,142,142,143,144,136,119,0,136,119,119,119,0,136,119,137,136,119,119,140,138,142,144,137,42,42,42,137,136,119,138,0,42,137,113,106,136,119,151,42,140,138,141,142,143,144,42,42,137,119,42,137,119,137,144,42,42,141,119,42,42,0,137,144,144,164,138,42,144,164,137,138,0,119,119,119,119,119,119,142,143,144,137,137,137,0,144,137,42,42,42,137,119,138,137,136,119,42,140,138,141,142,143,144,119,137,113,106,136,151,140,141,142,143,144,137,113,106,136,136,136,136,136,136,119,119,119,119,119,119,151,42,140,138,138,141,142,143,143,144,137,113,106,136,119,151,42,140,138,141,142,143,144,12,138,169,119,119,138,142,137,113,106,136,119,151,42,140,138,141,142,143,144,137,141,137,137,137,113,106,136,119,151,42,140,138,141,142,143,144,42,144,0,0,0,0,0,0,161,163,162,146,170,161,163,162,146,170,161,163,162,146,170,161,163,162,146,170,161,163,162,146,170,161,163,162,146,170,161,161,163,162,146,170,161,163,162,146,170,161,163,162,146,170,161,163,162,146,170,161,163,162,146,170,161,163,162,146,170,0,0,135,135,0,0,0,0,0,0,0,134,123,135,134,123,129,135,134,124,132,134,123,124,129,135,132,109,105,134,123,124,129,135,132,109,105,124,123,129,135,123,129,135,124,132,134,134,123,123,123,123,129,129,129,129,135,135,123,123,123,129,129,129,135,135,135,134,134,123,123,124,129,129,135,135,132,109,109,105,105,134,123,124,129,135,132,132,109,109,105,105,123,129,123,129,123,129,135,123,129,135,123,134,123,124,129,135,132,109,105,124,123,123,123,123,129,129,129,129,129,124,132,123,123,129,124,132,123,129,135,134,123,129,135,109,105,134,123,123,123,123,123,124,129,129,129,129,129,129,135,135,135,132,109,105,134,123,124,129,135,132,109,105,134,123,124,129,135,132,109,105,134,123,124,129,135,132,109,105,0,0,46,172,172,172,172,172,172,172,46,172,172,172,172,172,0,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,174,176,176,176,179,180,179,180,0,0,0,179,180,176,176,0,176,0,179,176,179,180,176,179,180,176,176,176,179,180,176,0,88,88,88,88,179,180,175,176,177,88,179,180,175,176,177,175,175,176,177,175,176,177,177,88,88,175,175,177,175,179,180,176,177,179,179,179,180,180,180,176,176,176,177,177,177,88,179,180,175,176,177,88,179,180,175,176,176,177,177,177,88,88,179,180,175,176,177,88,175,175,88,88,88,88,88,175,176,177,88,179,180,175,176,177,88,179,180,175,176,177,88,179,180,175,176,177,88,179,180,175,176,177],"f":"``````````````````````{{{b{eg}}i}{{b{eg}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}{}Ah}`{{AjAl}Aj}{{Ajc}AjAh}{{{b{eg}}i{Bb{{B`{An}}}}}{{b{eg}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}{}Bd}{{Ajce}AjBdBd}{{{b{eg}}i}{{b{eg}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}{}Bd}{{Ajc}AjBd}`{{{B`{Bf{Bh{c}}}}}{{Bj{c}}}{{Cd{}{{Bl{{Cb{BnC`}}}}}}}}{{{B`{c}}}{{B`{e}}}{}{}}000000000000{{{B`{Bfc}}}{{B`{Bfe}}}{}{}}000000000000{{}{{b{{`{{Ad{{j{h}}}{{l{{n{hCf}}}}{A`{Ab}}}}Af}}}}}}{AjAj}{{{B`{Ch}}}Ch}{{{B`{Cj}}}Cj}{{{B`{Cl}}}Cl}{{{B`{c}}{B`{Bfe}}}Cn{}{}}00{{{D`{e}}Db}{{D`{e}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}}0{{{b{eg}}{D`{k}}}{{b{kg}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}{}{df}{{Ad{{j{h}}}{{l{{n{hi}}}}{A`{Ab}}}}Af}}{{{D`{c}}g}{{D`{g}}}{}{df}{{Ad{{j{h}}}{{l{{n{he}}}}{A`{Ab}}}}Af}}{{AjDd}Aj}{{Ajc}Aj{}}`{{AjDf}Aj}{{{B`{{Bh{c}}}}{B`{An}}}{{Bb{Df}}}{}}{{{B`{{Bh{c}}}}}{{Cb{{Dj{{Dh{Df}}}}Dl}}}{}}{{}Cj}{{{B`{Cj}}c}Aj{}}{{{b{eg}}}{{b{eg}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}{}}0:`{{{B`{{Bh{c}}}}}{{Dj{Dn}}}{}}{{{B`{{Bh{c}}}}}{{E`{Dn}}}{}}{{Ebc}EbAh}{{{B`{Cl}}c}EbAh}{{{B`{Cl}}Ed}Eb}{{{b{eg}}}Cj{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}{{El{{`{{`{{`{{`{e}}}}{Ef{Ad}}c{Eh{`}}}}}}Ej}}}}{{{D`{e}}}{{`{{`{{`{e}}}}{Ef{Ad}}c{Eh{`}}}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}}{{{B`{Aj}}{B`{BfEn}}}F`}{{{B`{{Bh{c}}}}{B`{BfEn}}}F`{}}{AjAj}{Aj{{Cb{ClFb}}}}{cc{}}000000{FdFf}{FhFf}222222?{{{B`{Aj}}}{{B`{Fj}}}}{{{B`{Cl}}}{{B`{Fj}}}}{{{B`{Aj}}}{{B`{{Bb{Al}}}}}}{{{B`{Aj}}}{{B`{h}}}}{{{B`{Cl}}}{{B`{h}}}}{{{B`{Aj}}}{{B`{Fl}}}}{{{D`{e}}Db}{{D`{e}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}}{{{B`{Cj}}c}Aj{}}{{{B`{Aj}}}{{B`{Ed}}}}{{{B`{BfCj}}}{{Bb{{B`{BfEd}}}}}}{{{B`{Cl}}}{{B`{Ed}}}}{{{B`{{Bh{c}}}}}{{B`{Ed}}}{}}0{{{B`{BfAj}}}{{B`{BfEd}}}}`{{{b{eg}}Fn}{{b{eg}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}{}}{{{D`{e}}Fn}{{D`{e}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}}10{{Ajc}AjAh}0{ce{}{}}000000000000{G`Bh}{c{}{}}00{G`{{Gj{Gb{Gh{GdGf}}}}}}{{{B`{Bf{Bh{c}}}}}{{Gl{ce}}}{{Cd{}{{Bl{{Cb{BnC`}}}}}}}Gn}{{{D`{e}}H`}{{D`{e}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}}{{{Gl{ce}}H`}{{Gl{ce}}}{{Cd{}{{Bl{{Cb{BnC`}}}}}}}Gn}{{{Bj{c}}H`}{{Bj{c}}}{{Cd{}{{Bl{{Cb{BnC`}}}}}}}}{{{b{eg}}Hb}{{b{eg}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}{}}{{{D`{e}}Hb}{{D`{e}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}}{{{Bh{c}}g}{{Bh{e}}}{}{}{{Hh{{B`{BfGb}}{Hd{c}}}{{Hf{{Hd{e}}}}}}}}{{{b{eg}}Fl}{{b{eg}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}{}}{{{D`{e}}Fl}{{D`{e}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}}{{{b{eg}}Hj}{{b{eg}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}{}}{{AjFj}Aj}`{{}{{b{{`{{Ad{{j{h}}}{{l{{n{hCf}}}}{A`{Ab}}}}Af}}Cn}}}}{{}{{D`{{`{{Ad{{j{h}}}{{l{{n{hCf}}}}{A`{Ab}}}}Af}}}}}}{{}Cj}={{{B`{Bf{Bh{c}}}}}{{Bj{c}}}{{Cd{}{{Bl{{Cb{BnC`}}}}}}}}{AjAj}{{{b{eg}}}{{b{eg}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}{}}{{{D`{e}}Hl}{{D`{e}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}}{{{B`{Cj}}c}Aj{}}0{{{Hn{{B`{BfFf}}}}{B`{BfI`}}}{{Ib{c}}}{}}{{{Hn{{B`{Bf{Gl{ce}}}}}}{B`{BfI`}}}{{Ib{g}}}{{Cd{}{{Bl{{Cb{BnC`}}}}}}}Gn{}}{{{Hn{{B`{Bf{Bj{c}}}}}}{B`{BfI`}}}{{Ib{e}}}{{Cd{}{{Bl{{Cb{BnC`}}}}}}}{}}{{{Hn{{B`{Bf{Bh{c}}}}}}{B`{BfI`}}}{{Ib{{Bb{e}}}}}{{Cd{}{{Bl{{Cb{BnC`}}}}}}Id}{}}44{{Aj{B`{c}}}{{Cb{AjIf}}}Ih}{{{B`{Cj}}Fjc}Aj{}}{{{B`{Cj}}c{B`{Ij}}}Aj{}}{{{D`{e}}{In{Il}}}{{D`{e}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}}{{{D`{e}}{In{J`}}}{{D`{e}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}}{{{D`{e}}{In{Jb}}}{{D`{e}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}}{{{D`{e}}{In{Jd}}}{{D`{e}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}}{EbFf}{AjFf}{{{B`{Cl}}}Ff}{{Ebc}FfJf}{{Ajc}FfJf}{{{B`{Cl}}c}FfJf}{{Ebc}FfIh}{{Aj{B`{c}}}FfIh}{{{B`{Cl}}{B`{c}}}FfIh}210{{Ebe}Ff{{Jj{{Eh{Jh}}}}}{{Cd{}{{Bl{{Cb{Bnc}}}}}}}}{{Aje}Ff{{Jj{{Eh{Jh}}}}}{{Cd{}{{Bl{{Cb{Bnc}}}}}}}}{{{B`{Cl}}e}Ff{{Jj{{Eh{Jh}}}}}{{Cd{}{{Bl{{Cb{Bnc}}}}}}}}{{{B`{{Bh{c}}}}}Jl{}}{{{B`{Bf{Bh{c}}}}}{{Hd{c}}}{}}`{{{b{eg}}Db}{{b{eg}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}{}}{{{D`{e}}Db}{{D`{e}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}}{{AjDb}Aj}{{{Bh{c}}Db}{{Bh{c}}}{}}{{{B`{c}}}e{}{}}00{c{{Cb{e}}}{}{}}0000000000000000000000000{{{Hn{{B`{Bfc}}}}{B`{BfI`}}}Ib{}}00{{{Hn{{B`{Bfc}}}}{B`{BfI`}}}{{Ib{{Bb{Cb}}}}}{}}{{{B`{c}}}Jn{}}000000000000{{Ajc}Aj{}}`{{{B`{{Bh{c}}}}}Fl{}}{ce{}{}}000000000000{{{b{ei}}k}{{b{e{`{ikgEj}}}}}{df}{{Ad{{j{h}}}{{l{{n{hc}}}}{A`{Ab}}}}Af}{}{{El{gEj}}}{{El{Ej}}}}`{{{B`{Cj}}c}K`{}}```````````````{{{B`{BfKb}}}{{Hn{{B`{BfKb}}}}}}{{{B`{c}}}{{B`{e}}}{}{}}000000{{{B`{Bfc}}}{{B`{Bfe}}}{}{}}000000{{{Jf{}{{A`{c}}}}}Kb{{Jj{{Eh{Jh}}}}}}{KbKb}{{{Kd{ce}}}KbJfJf}{{{B`{{Kd{ce}}}}}{{Kd{ce}}}AfAf}{{{B`{Kf}}}Kf}{{{B`{Kh}}}Kh}{{{B`{c}}{B`{Bfe}}}Cn{}{}}00{{}Kf}{{{B`{Kh}}{B`{Kh}}}Kj}{{{B`{c}}{B`{e}}}Kj{}{}}00{{{B`{Kb}}{B`{BfEn}}}{{Cb{CnKl}}}}{{{B`{{Kd{ce}}}}{B`{BfEn}}}{{Cb{CnKl}}}ff}{{{B`{Kf}}{B`{BfEn}}}{{Cb{CnKl}}}}{{{B`{Kh}}{B`{BfEn}}}{{Cb{CnKl}}}}{{{B`{Kn}}{B`{BfEn}}}{{Cb{CnKl}}}}0{cc{}}000000{ce{}{}}000000{{{B`{Kh}}}Kj}{c{{Kd{ce}}}{}{}}{e{{L`{e}}}{{Jj{{Eh{Jh}}}}}{{Cd{}{{Bl{{Cb{Bnc}}}}}}}}{cKbJf}{c{{Kd{c}}}{}}>{{Dde}{{Lb{e}}}{{Jj{{Eh{Jh}}}}}{{Cd{}{{Bl{{Cb{Bnc}}}}}}}}{{{Hn{{B`{Bf{Jf{}{{A`{c}}}}}}}}{B`{BfI`}}}{{Ib{{Bb{{Cb{Bnc}}}}}}}{{Jj{{Eh{Jh}}}}}}{{{Hn{{B`{Bf{L`{e}}}}}}{B`{BfI`}}}{{Ib{{Bb{{Cb{Bn}}}}}}}{{Jj{Eh}}}{{Cd{}{{Bl{{Cb{Bnc}}}}}}}}{{{Hn{{B`{BfKb}}}}{B`{BfI`}}}{{Ib{{Bb{{Cb{Bn}}}}}}}}{{{Hn{{B`{Bf{Kd{ce}}}}}}{B`{BfI`}}}{{Ib{{Bb{{Cb{Bn}}}}}}}JfJf}{{{Hn{{B`{BfKf}}}}{B`{BfI`}}}{{Ib{{Bb{{Cb{Bn}}}}}}}}{{{Hn{{B`{Bf{Lb{e}}}}}}{B`{BfI`}}}{{Ib{{Bb{{Cb{Bn}}}}}}}{{Jj{Eh}}}{{Cd{}{{Bl{{Cb{Bnc}}}}}}}}{c{{Kd{ec}}}{}{}}{{{B`{{Jf{}{{A`{c}}}}}}}Kh{{Jj{{Eh{Jh}}}}}}{{{B`{{L`{e}}}}}Kh{{Jj{{Eh{Jh}}}}}{{Cd{}{{Bl{{Cb{Bnc}}}}}}}}{{{B`{Kb}}}Kh}{{{B`{{Kd{ce}}}}}KhJfJf}{{{B`{Kf}}}Kh}{{{B`{{Lb{e}}}}}Kh{{Jj{{Eh{Jh}}}}}{{Cd{}{{Bl{{Cb{Bnc}}}}}}}}{c{{Cb{Bn}}}Jf}{{cH`}{{Cb{{Cb{Bn}}Kn}}}Jf}{{{B`{c}}}e{}{}}00{{{B`{c}}}Ld{}}{c{{Cb{e}}}{}{}}0000000000000{{{Jf{}{{A`{c}}}}}{{Cb{Bn{Jf{}{{A`{c}}}}}}}{{Jj{{Eh{Jh}}}}}}{Kb{{Cb{BnKb}}}}{{{Kd{ce}}}{{Cb{Bn{Kd{ce}}}}}JfJf}{Kf{{Cb{BnKf}}}}{{{B`{c}}}Jn{}}000000{ce{}{}}000000`````````````````````````````````````````````````````````````````````````{{{B`{c}}}{{B`{e}}}{}{}}000000000{{{B`{Bfc}}}{{B`{Bfe}}}{}{}}000000000{{{B`{Lf}}}Lf}{{{B`{c}}{B`{Bfe}}}Cn{}{}}{{{B`{Lf}}{B`{Lf}}}Kj}{{{B`{c}}{B`{e}}}Kj{}{}}00{{{B`{Fh}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{Lh}}{B`{BfEn}}}F`}0{{{B`{Lj}}{B`{BfEn}}}F`}0{{{B`{Fd}}{B`{BfEn}}}F`}0{{{B`{Fb}}{B`{BfEn}}}F`}0{{{B`{Ll}}{B`{BfEn}}}F`}0{{{B`{Ln}}{B`{BfEn}}}F`}0{{{B`{C`}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{M`}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{Lf}}{B`{BfEn}}}{{Cb{CnKl}}}}0{cc{}}{MbFh}{MdFh}{MfFh}{MhFh}{MjFh}{MlFh}{MnFh}{N`Fh}{NbFh}{AbLh}{{{Eh{Jh}}}Lh};{NdLh}{NfLh}{NhLh}{FhLj}?{NhFd}{NdFd}{FbFd}{FhFd}{LjFd}{LhFd}{{{Eh{Jh}}}Fd}{cc{}}{{{Gj{{Eh{Jh}}{Eh{f}}}}}Fd}{NjFd}{{{Gj{{Eh{Jh}}{Eh{f}}}}}Fb}{FhFb}{LjFb}5{LjLl}{FdLl}{{{Gj{{Nl{Hj}}Nn}}}Ll}{M`Ll}{FhLl}{JlLl};{NnLl}{CnLn}{O`Ln}{C`Ln}??{NdC`}{NhC`}{{{Bb{Nd}}}C`}{cc{}}{ObM`}{H`M`}{HjM`}{NdM`}4{{{B`{Fh}}}{{B`{Jh}}}}{ce{}{}}000000000{{{B`{Fh}}}Kj}{{{B`{Fh}}}{{Bb{{B`{Jh}}}}}}{{{B`{C`}}}{{Bb{{B`{Jh}}}}}}{{{B`{M`}}}{{Bb{{B`{Jh}}}}}}{{{B`{c}}}e{}{}}{{{B`{c}}}Ld{}}000000000{c{{Cb{e}}}{}{}}0000000000000000000{{{B`{c}}}Jn{}}0000000008888888888```````````````````````````````````````````````````````````````````````````````````{{{B`{Fj}}}{{B`{An}}}}0{{{B`{Jl}}}{{B`{An}}}}{{{B`{Jl}}}Od}{{{B`{h}}}{{Bb{{B`{Of}}}}}}{{{B`{c}}}{{B`{e}}}{}{}}00000{{{B`{Bfc}}}{{B`{Bfe}}}{}{}}00000{{}Oh}{{{B`{Jl}}}{{Bb{{B`{An}}}}}}{{{B`{Fj}}}Fj}{{{B`{Jl}}}Jl}{{{B`{h}}}h}{{{B`{Fl}}}Fl}{{{B`{Oj}}}Oj}{{{B`{c}}{B`{Bfe}}}Cn{}{}}0000{{{B`{Jl}}{B`{Jl}}}Ol}{{{B`{Fl}}{B`{Fl}}}Ol}{{{B`{c}}{B`{e}}}Ol{}{}}0{{}Fj}{{}Jl}{{}h}{{}Fl}{{{B`{Fj}}{B`{An}}}Kj}{{{B`{Fj}}{B`{Fj}}}Kj}{{{B`{Fj}}{B`{{B`{Fj}}}}}Kj}{{{B`{{B`{Fj}}}}{B`{Fj}}}Kj}{{{B`{Fj}}{B`{{B`{An}}}}}Kj}{{{B`{Jl}}{B`{Od}}}Kj}{{{B`{Jl}}{B`{Jl}}}Kj}{{{B`{h}}{B`{{B`{An}}}}}Kj}{{{B`{h}}{B`{An}}}Kj}{{{B`{h}}{B`{h}}}Kj}{{{B`{Fl}}{B`{Fl}}}Kj}{{{B`{Oj}}{B`{Oj}}}Kj}{{{B`{c}}{B`{e}}}Kj{}{}}00000000000000{{{B`{On}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{Fj}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{Jl}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{h}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{Fl}}{B`{BfEn}}}{{Cb{CnKl}}}}{{{B`{Oj}}{B`{BfEn}}}{{Cb{CnKl}}}}{NjOn}{cc{}}{C`On}{MnOn}{A@`On}{LfOn}{FhOn}{M`On}6{{{B`{Fj}}}Fj}7{{{B`{Jl}}}Jl}{A@bh}9{Ofh}::{{{B`{{A@d{Hj}}}}}{{Cb{FjMf}}}}{{{B`{{A@d{Hj}}}}}{{Cb{JlMl}}}}{c{{Cb{hMj}}}{{A@f{{A@d{Hj}}}}}}{A@h{{Cb{hMb}}}}{{{B`{An}}}h}{{{B`{An}}}{{Cb{Fj}}}}{{{B`{An}}}{{Cb{JlMl}}}}{{{B`{An}}}{{Cb{hMj}}}}{Od{{Cb{JlMl}}}}{{{B`{Fj}}{B`{Bfc}}}CnA@j}{{{B`{Jl}}{B`{Bfc}}}CnA@j}{{{B`{h}}{B`{Bfc}}}CnA@j}{{{B`{Fl}}{B`{Bfc}}}CnA@j}`{{{B`{h}}}{{Bb{{B`{An}}}}}}{{{B`{h}}}{{B`{An}}}}{ce{}{}}00000{hA@h}{{{B`{Jl}}}Kj}{{{B`{Fj}}}Kj}11011{{{B`{Jl}}{B`{Jl}}}{{Bb{Ol}}}}{{{B`{Fl}}{B`{Fl}}}{{Bb{Ol}}}}6{{{B`{h}}}{{Bb{{B`{A@b}}}}}}{{{B`{h}}}{{Bb{Od}}}}{{{B`{h}}}{{Bb{{A@l{{B`{An}}}}}}}}1:{{{B`{h}}}{{Bb{{B`{A@n}}}}}};{{{B`{On}}}{{Bb{{B`{Jh}}}}}}{{{B`{c}}}e{}{}}0000{{{B`{c}}}Ld{}}000{c{{Cb{e}}}{}{}}{{{B`{{A@d{Hj}}}}}{{Cb{Fj}}}}{{{B`{An}}}{{Cb{Fj}}}}2{{{B`{An}}}{{Cb{Jl}}}}{{{B`{{A@d{Hj}}}}}{{Cb{Jl}}}}{Od{{Cb{Jl}}}}5{{{B`{An}}}{{Cb{h}}}}{A@h{{Cb{h}}}}{{{B`{{A@d{Hj}}}}}{{Cb{h}}}}{Ld{{Cb{h}}}}9{{{B`{Ld}}}{{Cb{h}}}}{{{Dh{Hj}}}{{Cb{h}}}}{{{B`{h}}}{{Cb{h}}}}<<<<<<<<{{{B`{c}}}Jn{}}00000`{ce{}{}}00000````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````{{{B`{BfEd}}AA`Nn}Cn}{{{B`{Nn}}}{{B`{{A@d{Hj}}}}}}{{{B`{AA`}}}{{B`{{A@d{Hj}}}}}}{{{B`{AA`}}}{{B`{An}}}}2{{{B`{AAb}}}{{B`{An}}}}1{AAd{{B`{An}}}}{{{B`{c}}}{{B`{e}}}{}{}}0003000000000{{{B`{Bfc}}}{{B`{Bfe}}}{}{}}000000000000{{{B`{AAb}}}{{Cb{AAbAAf}}}}{{{B`{Ed}}}H`}`{{{B`{BfEd}}}Cn}{{{B`{AAb}}}AAb}{{{B`{AA`}}}AA`}{{{B`{Nn}}}Nn}{{{B`{Ed}}}Ed}{{{B`{AAh}}}AAh}{{{B`{AAd}}}AAd}{{{B`{AAj}}}AAj}{{{B`{AAl}}}AAl}{{{B`{AAn}}}AAn}{{{B`{{AB`{c}}}}}{{AB`{c}}}Af}{{{B`{c}}{B`{Bfe}}}Cn{}{}}000000000{{{B`{Nn}}{B`{Nn}}}Ol}{{{B`{AAl}}{B`{AAl}}}Ol}{{{B`{AAn}}{B`{AAn}}}Ol}{{{B`{c}}{B`{e}}}Ol{}{}}00{{{B`{Ed}}c}KjABb}{{}Ed}{{}AAd}{{}AAn}{{{B`{BfEd}}}ABd}{{{B`{AAb}}{B`{AAb}}}Kj}{{{B`{AA`}}{B`{AA`}}}Kj}{{{B`{{B`{AA`}}}}{B`{AA`}}}Kj}{{{B`{AA`}}{B`{{B`{AA`}}}}}Kj}{{{B`{AA`}}{B`{{B`{An}}}}}Kj}{{{B`{AA`}}{B`{An}}}Kj}{{{B`{{B`{Nn}}}}{B`{Nn}}}Kj}{{{B`{Nn}}{B`{An}}}Kj}{{{B`{Nn}}{B`{Ld}}}Kj}{{{B`{Nn}}{B`{{B`{c}}}}}KjABf}{{{B`{Nn}}{B`{Nn}}}Kj}{{{B`{Nn}}{B`{{A@d{Hj}}}}}Kj}{{{B`{AAh}}{B`{AAh}}}Kj}{{{B`{AAd}}{B`{AAd}}}Kj}{{{B`{AAj}}{B`{AAj}}}Kj}{{{B`{AAl}}{B`{AAl}}}Kj}{{{B`{AAn}}{B`{AAn}}}Kj}{{{B`{{AB`{c}}}}{B`{{AB`{c}}}}}KjABh}{{{B`{c}}{B`{e}}}Kj{}{}}00000000000000000000000000{{{B`{AAb}}}{{Bb{{B`{An}}}}}}{{{B`{AAb}}}{{`{{ABj{}{{Bl{{B`{An}}}}}}}}}}1{{{B`{AAb}}}{{`{{ABj{}{{Bl{{Gj{ABl{B`{An}}}}}}}}}}}}{{{B`{AAb}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{Nb}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{Md}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{AA`}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{Nn}}{B`{BfEn}}}{{Cb{CnKl}}}}{{{B`{ABn}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{Ed}}{B`{BfEn}}}{{Cb{CnKl}}}}{{{B`{AAh}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{AAd}}{B`{BfEn}}}{{Cb{CnKl}}}}{{{B`{AAj}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{AAl}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{AAn}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{{AB`{c}}}}{B`{BfEn}}}{{Cb{CnKl}}}f}{{{B`{{AB`{c}}}}{B`{BfEn}}}{{Cb{CnKl}}}Bd}{{{B`{BfEn}}{B`{{A@d{c}}}}}{{Cb{CnKl}}}Bd}{cc{}}00{{{B`{AA`}}}AA`}1{AC`Nn}{DdNn}{OdNn}{ACbNn}{{{B`{Nn}}}Nn}{AA`Nn}{ACdNn}{FnNn}{H`Nn}{ACfNn};;;{AChEd}<<<{ACjAAl}==={{{B`{{A@d{Hj}}}}}{{Cb{AA`Nb}}}}{{{B`{{A@d{Hj}}}}}{{Cb{NnMd}}}}{c{{Cb{{Dh{e}}Nj}}}{{ABj{}{{Bl{{B`{Nn}}}}}}}ACl}2{c{{Cb{NnMd}}}{{A@f{{A@d{Hj}}}}}}{cNn{{A@f{{A@d{Hj}}}}}};{{{Bb{{B`{Nn}}}}}{{Cb{cNj}}}ACl}{{{B`{An}}}AA`}{{{B`{An}}}Nn}{{{B`{An}}}{{Cb{AAbACn}}}}{{{B`{An}}}{{Cb{AA`Nb}}}}{{{B`{An}}}{{Cb{Nn}}}}{{{B`{An}}}{{Cb{NnMd}}}}{{{B`{An}}}{{Cb{AAhOn}}}}{{{B`{An}}}{{Cb{AAd}}}}{{{B`{An}}}{{Cb{AAlNj}}}}{{{B`{An}}}{{Cb{{AB`{c}}}}}ACl}{{{B`{AAb}}}{{B`{An}}}}{{{B`{Ed}}c}{{Bb{{B`{Nn}}}}}ABb}{{{B`{Ed}}c}{{AD`{Nn}}}ABb}{{{B`{BfEd}}c}{{Bb{{B`{BfNn}}}}}ABb}{{{B`{AAb}}{B`{Bfc}}}CnA@j}{{{B`{AA`}}{B`{Bfc}}}CnA@j}{{{B`{Nn}}{B`{Bfc}}}CnA@j}{{{B`{AAd}}{B`{Bfc}}}CnA@j}{{{B`{BfEn}}{B`{{A@d{Hj}}}}}{{Cb{CnKl}}}}{{{B`{BfEd}}AA`Nn}ADb}{ce{}{}}000000000000{Ed}{{{B`{Ed}}}}{AAbLd}{{{B`{Nn}}}Kj}{{{B`{Ed}}}Kj}{{{B`{AAb}}}Kj}20`{{{B`{Ed}}}ADd}{{{B`{Ed}}}ADf}`{{{B`{Nn}}}H`}{{{B`{Ed}}}H`}0`{{{B`{AAb}}{B`{AAb}}}Kj}{c{{AB`{c}}}{}}0{{}AA`}0{{}Ed}{{cAAn}{{AB`{c}}}{}}{{{B`{c}}}{{Cb{ADhNj}}}ADj}{{{B`{An}}}{{Cb{AAbACn}}}}{{{B`{c}}}{{Cb{AAdNj}}}ADj}{{{B`{An}}}{{Cb{AAjNj}}}}{{{B`{Nn}}{B`{Nn}}}{{Bb{Ol}}}}{{{B`{{B`{Nn}}}}{B`{Nn}}}{{Bb{Ol}}}}{{{B`{Nn}}{B`{Ld}}}{{Bb{Ol}}}}{{{B`{Nn}}{B`{{B`{c}}}}}{{Bb{Ol}}}ABf}{{{B`{Nn}}{B`{{A@d{Hj}}}}}{{Bb{Ol}}}}{{{B`{Nn}}{B`{An}}}{{Bb{Ol}}}}{{{B`{AAl}}{B`{AAl}}}{{Bb{Ol}}}}{{{B`{AAn}}{B`{AAn}}}{{Bb{Ol}}}}{{{B`{{AB`{c}}}}{B`{{AB`{c}}}}}{{Bb{Ol}}}ABh}{{{B`{AAb}}}{{B`{An}}}}{{{B`{AAb}}}{{Bb{{B`{An}}}}}}{{{B`{AAb}}}{{`{{ABj{}{{Bl{{B`{An}}}}}}}}}}{cAAn{{ADl{AAn}}}}`2{{{B`{BfEd}}c}ADbABb}{{{B`{BfEd}}H`}Cn}{{{B`{BfEd}}c}Cn{{ADn{{B`{AA`}}{B`{BfNn}}}{{Hf{Kj}}}}}}5{{{B`{BfNn}}Kj}Cn}{AAdNn}{{{B`{c}}}e{}{}}000000000{{{B`{Nn}}}{{Cb{{B`{An}}ABn}}}}{{{B`{c}}}Ld{}}000000000{c{{Cb{e}}}{}{}}00{Ld{{Cb{AA`}}}}{{{B`{Ld}}}{{Cb{AA`}}}}2{{{B`{{A@d{Hj}}}}}{{Cb{AA`}}}}{{{Dh{Hj}}}{{Cb{AA`}}}}{{{B`{An}}}{{Cb{AA`}}}}{Ld{{Cb{Nn}}}}{{{B`{Ld}}}{{Cb{Nn}}}}7{{{Dh{Hj}}}{{Cb{Nn}}}}{{{B`{An}}}{{Cb{Nn}}}}{{{B`{{A@d{Hj}}}}}{{Cb{Nn}}}}:::{{{B`{An}}}{{Cb{AAd}}}};;;;{AE`{{Cb{AAn}}}}<<<<<<<<<<<<<<{{{Ah{}{{A`{c}}}}}{{Cb{{Gj{AA`Nn}}c}}}{{Jj{Fh}}}}{c{{Cb{{Gj{AA`Nn}}}}}{}}{{{AEb{}{{A`{c}}}}}{{Cb{Nnc}}}{{Jj{Fh}}}}{{{B`{Nn}}}{{Cb{Nn}}}}{Nn{{Cb{Nn}}}}{AAd{{Cb{Nn}}}}{AAl{{Cb{Nn}}}}{{{B`{c}}}Jn{}}000000000000{{{B`{AAb}}}{{Cb{CnAAf}}}}`{{{B`{AAb}}}{{Bb{{B`{An}}}}}}{{{B`{AAb}}}{{`{{ABj{}{{Bl{{B`{An}}}}}}}}}}{ce{}{}}000000000000{H`Ed}{c{{AB`{c}}}{}}``````{{{B`{c}}}{{B`{e}}}{}{}}0000{{{B`{Bfc}}}{{B`{Bfe}}}{}{}}0000{{{B`{ADb}}{B`{BfEn}}}{{Cb{CnKl}}}}{{{B`{ADf}}{B`{BfEn}}}{{Cb{CnKl}}}}{{{B`{ADd}}{B`{BfEn}}}{{Cb{CnKl}}}}{{{B`{ABd}}{B`{BfEn}}}{{Cb{CnKl}}}}{{{B`{AEd}}{B`{BfEn}}}{{Cb{CnKl}}}}{cc{}}0000::::::::::{{{B`{ADb}}}Kj}{{{B`{BfADb}}}Bb}{{{B`{BfADf}}}Bb}{{{B`{BfADd}}}Bb}{{{B`{BfABd}}}Bb}{{{B`{BfAEd}}}Bb}{{{B`{ADb}}}{{Gj{H`{Bb{H`}}}}}}{{{B`{ADf}}}{{Gj{H`{Bb{H`}}}}}}{{{B`{ADd}}}{{Gj{H`{Bb{H`}}}}}}{{{B`{ABd}}}{{Gj{H`{Bb{H`}}}}}}{{{B`{AEd}}}{{Gj{H`{Bb{H`}}}}}}{c{{Cb{e}}}{}{}}000000000{{{B`{c}}}Jn{}}0000{ce{}{}}0000```````````{{{B`{{A@l{c}}}}}{{B`{An}}}{{A@f{An}}}}{{{B`{Of}}}{{B`{An}}}}{{{B`{A@n}}}{{B`{An}}}}21{{{B`{A@b}}}{{B`{An}}}}1{{{B`{{A@l{c}}}}}Od{}}{{Ohc}Oh{}}`{{{B`{c}}}{{B`{e}}}{}{}}0000000{{{B`{Bfc}}}{{B`{Bfe}}}{}{}}0000000{Oh{{Cb{hFh}}}}{{{B`{Of}}}Of}{{{B`{A@b}}}A@b}{{{B`{A@n}}}A@n}{{{B`{c}}{B`{Bfe}}}Cn{}{}}00{{}Oh}{{}A@h}{{{B`{{A@l{c}}}}{B`{Od}}}Kj{}}{{{B`{{A@l{c}}}}{B`{{A@l{e}}}}}Kj{}{}}{{{B`{Of}}{B`{Ld}}}Kj}{{{B`{Of}}{B`{{B`{An}}}}}Kj}{{{B`{Of}}{B`{An}}}Kj}{{{B`{Of}}{B`{Of}}}Kj}{{{B`{A@b}}{B`{{B`{An}}}}}Kj}{{{B`{A@b}}{B`{Ld}}}Kj}{{{B`{A@b}}{B`{A@b}}}Kj}{{{B`{A@b}}{B`{An}}}Kj}{{{B`{A@n}}{B`{A@n}}}Kj}{{{B`{A@n}}{B`{An}}}Kj}{{{B`{c}}{B`{e}}}Kj{}{}}00000000{{{B`{{A@l{c}}}}{B`{BfEn}}}{{Cb{CnKl}}}{}}{{{B`{{A@l{c}}}}{B`{BfEn}}}{{Cb{CnKl}}}f}{{{B`{Of}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{Oh}}{B`{BfEn}}}{{Cb{CnKl}}}}{{{B`{A@b}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{A@n}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{A@h}}{B`{BfEn}}}{{Cb{CnKl}}}}{{{B`{Mj}}{B`{BfEn}}}{{Cb{CnKl}}}}0{{{B`{Mb}}{B`{BfEn}}}{{Cb{CnKl}}}}0{cc{}}0000{hA@h}11{AEfMj}2{AEfMb}{c{{Cb{OfMj}}}{{A@f{{A@d{Hj}}}}}}{c{{Cb{A@bMj}}}{{A@f{{A@d{Hj}}}}}}{{{B`{An}}}Of}{{{B`{An}}}A@b}{{{B`{An}}}{{Cb{OfMj}}}}{{{B`{An}}}{{Cb{A@bMj}}}}{{{B`{An}}}{{Cb{A@n}}}}{{{B`{Of}}{B`{Bfc}}}CnA@j}{{{B`{A@b}}{B`{Bfc}}}CnA@j}{{{B`{A@n}}{B`{Bfc}}}CnA@j}{{{B`{Of}}}{{B`{An}}}}{ce{}{}}0000000{{}Oh}{{{B`{Of}}{B`{Ld}}}{{Bb{Ol}}}}{{{B`{Of}}{B`{{B`{An}}}}}{{Bb{Ol}}}}{{{B`{Of}}{B`{Of}}}{{Bb{Ol}}}}{{{B`{Of}}{B`{An}}}{{Bb{Ol}}}}{{{B`{A@b}}{B`{{B`{An}}}}}{{Bb{Ol}}}}{{{B`{A@b}}{B`{A@b}}}{{Bb{Ol}}}}{{{B`{A@b}}{B`{Ld}}}{{Bb{Ol}}}}{{{B`{A@b}}{B`{An}}}{{Bb{Ol}}}}{{{B`{A@b}}}{{B`{An}}}}{{Ohc}Oh{}}`{{{B`{Of}}}{{Bb{{A@l{{B`{An}}}}}}}}{{{B`{Of}}}{{Bb{Od}}}}{{{B`{A@b}}}{{Bb{{B`{An}}}}}}3`{{{B`{c}}}e{}{}}00{{{B`{c}}}Ld{}}00000{c{{Cb{e}}}{}{}}{{{B`{An}}}{{Cb{Of}}}}1{{{Dh{Hj}}}{{Cb{Of}}}}{{{B`{{A@d{Hj}}}}}{{Cb{Of}}}}{Ld{{Cb{Of}}}}44{{{Dh{Hj}}}{{Cb{A@b}}}}{{{B`{An}}}{{Cb{A@b}}}}{Ld{{Cb{A@b}}}}{{{B`{{A@d{Hj}}}}}{{Cb{A@b}}}}{{{B`{Ld}}}{{Cb{A@b}}}}{{{B`{An}}}{{Cb{A@n}}}}:{{{B`{{A@d{Hj}}}}}{{Cb{A@n}}}};;;;;;;;;;;{{{B`{c}}}Jn{}}0000000{ce{}{}}0000000```{{{B`{c}}}{{B`{e}}}{}{}}{{{B`{Bfc}}}{{B`{Bfe}}}{}{}}{{}AEh}{cc{}}4{{AEhHj}AEh}2{{{El{}{{AEj{c}}}}g}c{{Ad{e}}}{}{}}{{AEhc}e{{Ad{Ej}{{l{G`}}{A`{Fd}}}}}{}}{c{{Cb{e}}}{}{}}098`{{AElc}AElAh}87{{AElDf}AEl}{{}AEl}{AElBh}83<{{AElc}AEl{{Jj{Bn}}}}55>{{AElFl}AEl}>{cAElAh}```````````````````````````````{{K`Al}K`}{{K`c{Bb{{B`{An}}}}}K`Bd}{{K`c}K`Bd}{{{B`{c}}}{{B`{e}}}{}{}}00000{{{B`{Bfc}}}{{B`{Bfe}}}{}{}}00000{AEnAEn}{{{B`{AEn}}}AEn}{{{B`{AF`}}}AF`}{{{B`{AFb}}}AFb}{{{B`{c}}{B`{Bfe}}}Cn{}{}}00`{K`{{Cb{{Gj{Bh{Gh{GdAEn}}}}Ll}}}}{{K`Df}K`}{{{B`{BfAEn}}{B`{BfAFd}}}{{Cb{Bb}}}}{{}AEn}`{{{B`{BfAEn}}AFf{B`{BfAFd}}}{{Cb{Cn}}}}{{{B`{AFf}}{B`{AFf}}}Kj}{{{B`{AFh}}{B`{AFh}}}Kj}{{{B`{AF`}}{B`{AF`}}}Kj}{{{B`{AFb}}{B`{AFb}}}Kj}{{{B`{c}}{B`{e}}}Kj{}{}}00000000000{{{B`{K`}}{B`{BfEn}}}F`}{{{B`{AFf}}{B`{BfEn}}}{{Cb{CnKl}}}}{{{B`{AFh}}{B`{BfEn}}}{{Cb{CnKl}}}}{{{B`{AEn}}{B`{BfEn}}}{{Cb{CnKl}}}}{{{B`{AF`}}{B`{BfEn}}}{{Cb{CnKl}}}}{{{B`{AFb}}{B`{BfEn}}}{{Cb{CnKl}}}}{cc{}}000{OdAF`}11{AF`AFb}{{{Gj{AF`c}}}AFb{{Jj{Ld}}}}{{K`ce}K`{}AEb}{ce{}{}}00000{{K`H`}K`}{{AEnH`}AEn}{{}AEn}{{K`c}K`{}}{{K`e}K`{{A@f{An}}}{{AFj{}{{Bl{c}}}}}}{K`K`}77{{{B`{c}}}e{}{}}00{c{{Cb{e}}}{}{}}00000000000{{{B`{c}}}Jn{}}00000999999","D":"FCb","p":[[5,"ClientBuilder",0,1801],[10,"ActixStream",1802],[10,"Debug",1803],[5,"Uri",631,1804],[5,"ConnectInfo",1805],[17,"Response"],[5,"Connection",1806],[17,"Error"],[6,"ConnectError",1807],[10,"Service",1808],[10,"Clone",1809],[10,"TryIntoHeaderPair",892,1810],[5,"ClientRequest",0,1811],[6,"SocketAddr",1812],[1,"str"],[1,"reference"],[6,"Option",1813],[10,"Display",1803],[0,"mut"],[5,"ClientResponse",0,1814],[5,"ResponseBody",0,1815],[17,"Item"],[5,"Bytes",1816],[6,"PayloadError",394,1817],[6,"Result",1818],[10,"Stream",1819],[5,"TcpStream",1820],[5,"Connect",0,1821],[5,"Client",0,1821],[5,"FrozenClientRequest",0,1822],[1,"unit"],[5,"Connector",0,1823],[5,"Duration",1824],[1,"u64"],[5,"Cookie",1825],[5,"Vec",1826],[5,"Ref",1827],[6,"ParseError",1828],[5,"Extensions",1829],[5,"RefMut",1827],[5,"FrozenSendBuilder",0,1822],[5,"HeaderMap",892,1830],[5,"Rc",1831],[5,"Box",1832],[6,"ConnectRequest",0,1833],[10,"Transform",1635],[5,"Formatter",1803],[8,"Result",1803],[6,"FreezeRequestError",394,1834],[6,"SendRequestError",394,1834],[6,"SendClientRequest",0,1835],[5,"HttpError",394],[5,"Method",631,1836],[5,"Version",631,1837],[1,"u32"],[6,"ConnectResponse",0,1833],[5,"ResponseHead",1838],[8,"BoxedSocket",0,1833],[5,"ClientCodec",1839],[5,"Framed",1840],[1,"tuple"],[5,"JsonBody",0,1841],[10,"DeserializeOwned",1842],[1,"usize"],[6,"IpAddr",1843],[6,"Payload",1844],[17,"Output"],[10,"FnOnce",1845],[1,"u8"],[5,"SslConnector",1846],[5,"Pin",1847],[5,"Context",1848],[6,"Poll",1849],[10,"Unpin",1850],[6,"Error",1851],[10,"Serialize",1852],[5,"RequestHead",1853],[5,"ClientConfig",1854],[5,"Arc",1855],[5,"ClientConfig",1854],[5,"ClientConfig",1854],[5,"ClientConfig",1854],[10,"MessageBody",270,1856],[10,"Error",1857],[10,"Into",1858],[5,"StatusCode",631,1859],[5,"TypeId",1860],[5,"WebsocketsRequest",1668],[5,"BoxBody",270,1861],[6,"EitherBody",270,1862],[5,"None",270,1863],[6,"BodySize",270,1864],[1,"bool"],[5,"Error",1803],[5,"BodyLimitExceeded",270,1865],[5,"BodyStream",270,1866],[5,"SizedStream",270,1867],[5,"String",1868],[6,"WsHandshakeError",394],[6,"ConnectError",394,1834],[6,"InvalidUrl",394,1834],[6,"WsClientError",394],[6,"JsonPayloadError",394],[6,"WsProtocolError",394],[5,"InvalidUriParts",1455,1804],[5,"InvalidHeaderValue",892,1869],[5,"InvalidMethod",1836],[5,"MaxSizeReached",1870],[5,"InvalidUri",1455,1804],[5,"InvalidStatusCode",1859],[6,"Infallible",1858],[6,"InvalidHeaderPart",1810],[5,"InvalidHeaderName",892,1871],[5,"Error",1872],[5,"Error",1873],[5,"Error",1874],[6,"ParseError",1817],[1,"array"],[5,"HeaderValue",892,1869],[5,"Error",1875],[6,"OpCode",1876],[1,"u16"],[5,"Authority",1455,1877],[5,"Builder",1455,1878],[6,"ConnectionType",631,1879],[6,"Ordering",1880],[5,"Error",631,1817],[6,"EncoderError",1881],[5,"PathAndQuery",1455,1882],[1,"slice"],[10,"AsRef",1858],[5,"Parts",1455,1804],[10,"Hasher",1883],[5,"Port",1455,1884],[5,"Scheme",1455,1885],[5,"HeaderName",892,1871],[5,"LanguageTag",892,1886],[6,"ContentEncoding",892,1887],[6,"ValidationError",1886],[6,"Charset",892,1888],[5,"ExtendedValue",892,1889],[5,"HttpDate",892,1890],[5,"Quality",892,1891],[5,"QualityItem",892,1892],[10,"AsHeaderName",892,1893],[5,"Drain",1388,1830],[10,"Sized",1850],[10,"PartialEq",1880],[10,"Iterator",1894],[1,"char"],[5,"ToStrError",892,1869],[1,"i32"],[1,"isize"],[1,"i64"],[1,"i16"],[5,"HeaderMap",1870],[5,"SystemTime",1895],[10,"FromStr",1896],[6,"ParseError",1886],[5,"Iter",1897],[5,"Removed",1388,1830],[5,"Iter",1388,1830],[5,"Keys",1388,1830],[10,"Header",892,1898],[10,"HttpMessage",1899],[10,"TryInto",1858],[10,"FnMut",1845],[1,"f32"],[10,"TryIntoHeaderValue",892,1900],[5,"IntoIter",1388,1830],[6,"ErrorKind",1804],[5,"Redirect",1635,1901],[17,"Transform"],[5,"TestResponse",1651],[5,"Codec",1668,1902],[6,"CloseCode",1668,1876],[5,"CloseReason",1668,1876],[5,"BytesMut",1903],[6,"Message",1668,1902],[6,"Frame",1668,1902],[10,"IntoIterator",1904],[15,"Left",392],[15,"Right",392]],"r":[[0,1833],[1,1833],[2,1821],[5,1801],[6,1811],[7,1814],[8,1821],[9,1833],[10,1833],[11,1823],[13,1822],[14,1822],[16,1841],[17,1815],[18,1815],[19,1835],[30,1905],[270,1865],[271,1864],[272,1866],[273,1861],[274,1862],[277,1856],[278,1863],[282,1867],[354,1865],[355,1865],[398,1834],[408,1834],[412,1869],[425,1834],[442,1817],[448,1834],[451,1859],[640,1879],[643,1817],[670,1836],[699,1859],[711,1804],[713,1837],[818,1905],[885,1906],[892,1871],[893,1871],[894,1871],[895,1871],[896,1871],[897,1871],[898,1871],[899,1871],[900,1871],[901,1871],[902,1871],[903,1871],[904,1871],[905,1871],[906,1871],[907,1871],[908,1871],[909,1893],[912,1871],[913,1907],[914,1907],[915,1871],[916,1871],[917,1871],[918,1871],[919,1871],[920,1871],[921,1871],[922,1871],[923,1871],[924,1871],[925,1871],[926,1907],[927,1907],[928,1907],[929,1888],[930,1887],[931,1871],[932,1871],[934,1871],[935,1871],[936,1871],[942,1889],[943,1871],[944,1871],[947,1871],[948,1898],[949,1830],[950,1871],[951,1869],[952,1890],[953,1871],[954,1871],[955,1871],[956,1871],[957,1871],[959,1871],[960,1869],[979,1871],[980,1871],[981,1871],[982,1886],[984,1871],[986,1871],[987,1907],[988,1871],[989,1871],[990,1871],[991,1871],[992,1871],[993,1891],[994,1892],[995,1871],[996,1871],[997,1871],[998,1871],[999,1871],[1000,1871],[1001,1871],[1002,1871],[1003,1871],[1004,1871],[1005,1871],[1006,1871],[1007,1871],[1009,1871],[1010,1871],[1011,1871],[1012,1869],[1013,1810],[1014,1900],[1015,1871],[1016,1871],[1017,1871],[1019,1871],[1020,1871],[1021,1871],[1022,1871],[1023,1871],[1024,1871],[1025,1907],[1026,1907],[1027,1907],[1028,1871],[1029,1871],[1174,1908],[1203,1908],[1208,1908],[1227,1908],[1257,1898],[1268,1889],[1281,1891],[1388,1830],[1389,1830],[1390,1830],[1391,1830],[1392,1830],[1393,1830],[1455,1877],[1456,1878],[1459,1804],[1460,1804],[1461,1804],[1462,1882],[1463,1884],[1464,1885],[1465,1804],[1635,1901],[1675,1876],[1676,1876],[1677,1902],[1682,1902],[1684,1902]],"b":[[100,"impl-From%3CSendRequestError%3E-for-SendClientRequest"],[101,"impl-From%3CError%3E-for-SendClientRequest"],[120,"impl-ClientResponse%3CS%3E"],[121,"impl-HttpMessage-for-ClientResponse%3CS%3E"],[318,"impl-Display-for-BodyLimitExceeded"],[319,"impl-Debug-for-BodyLimitExceeded"],[491,"impl-Display-for-Error"],[492,"impl-Debug-for-Error"],[493,"impl-Display-for-ConnectError"],[494,"impl-Debug-for-ConnectError"],[495,"impl-Debug-for-InvalidUrl"],[496,"impl-Display-for-InvalidUrl"],[497,"impl-Debug-for-SendRequestError"],[498,"impl-Display-for-SendRequestError"],[499,"impl-Debug-for-FreezeRequestError"],[500,"impl-Display-for-FreezeRequestError"],[501,"impl-Display-for-WsClientError"],[502,"impl-Debug-for-WsClientError"],[503,"impl-Debug-for-JsonPayloadError"],[504,"impl-Display-for-JsonPayloadError"],[505,"impl-Debug-for-PayloadError"],[506,"impl-Display-for-PayloadError"],[507,"impl-Debug-for-ProtocolError"],[508,"impl-Display-for-ProtocolError"],[509,"impl-Debug-for-HandshakeError"],[510,"impl-Display-for-HandshakeError"],[512,"impl-From%3CInvalidUriParts%3E-for-Error"],[513,"impl-From%3CInvalidHeaderValue%3E-for-Error"],[514,"impl-From%3CInvalidMethod%3E-for-Error"],[515,"impl-From%3CMaxSizeReached%3E-for-Error"],[516,"impl-From%3CInvalidUri%3E-for-Error"],[517,"impl-From%3CInvalidStatusCode%3E-for-Error"],[518,"impl-From%3CInfallible%3E-for-Error"],[519,"impl-From%3CInvalidHeaderPart%3E-for-Error"],[520,"impl-From%3CInvalidHeaderName%3E-for-Error"],[521,"impl-From%3CConnectError%3E-for-ConnectError"],[522,"impl-From%3CBox%3Cdyn+Error%3E%3E-for-ConnectError"],[524,"impl-From%3CError%3E-for-ConnectError"],[525,"impl-From%3CError%3E-for-ConnectError"],[526,"impl-From%3CError%3E-for-ConnectError"],[529,"impl-From%3CError%3E-for-SendRequestError"],[530,"impl-From%3CError%3E-for-SendRequestError"],[531,"impl-From%3CFreezeRequestError%3E-for-SendRequestError"],[532,"impl-From%3CError%3E-for-SendRequestError"],[533,"impl-From%3CInvalidUrl%3E-for-SendRequestError"],[534,"impl-From%3CConnectError%3E-for-SendRequestError"],[535,"impl-From%3CBox%3Cdyn+Error%3E%3E-for-SendRequestError"],[537,"impl-From%3C(Box%3Cdyn+Error%3E,+Box%3Cdyn+Debug%3E)%3E-for-SendRequestError"],[538,"impl-From%3CParseError%3E-for-SendRequestError"],[539,"impl-From%3C(Box%3Cdyn+Error%3E,+Box%3Cdyn+Debug%3E)%3E-for-FreezeRequestError"],[540,"impl-From%3CError%3E-for-FreezeRequestError"],[541,"impl-From%3CInvalidUrl%3E-for-FreezeRequestError"],[543,"impl-From%3CInvalidUrl%3E-for-WsClientError"],[544,"impl-From%3CSendRequestError%3E-for-WsClientError"],[545,"impl-From%3C(%5Bu8;+28%5D,+HeaderValue)%3E-for-WsClientError"],[546,"impl-From%3CProtocolError%3E-for-WsClientError"],[547,"impl-From%3CError%3E-for-WsClientError"],[548,"impl-From%3CStatusCode%3E-for-WsClientError"],[550,"impl-From%3CHeaderValue%3E-for-WsClientError"],[551,"impl-From%3C()%3E-for-JsonPayloadError"],[552,"impl-From%3CError%3E-for-JsonPayloadError"],[553,"impl-From%3CPayloadError%3E-for-JsonPayloadError"],[556,"impl-From%3CError%3E-for-PayloadError"],[557,"impl-From%3CError%3E-for-PayloadError"],[558,"impl-From%3COption%3CError%3E%3E-for-PayloadError"],[560,"impl-From%3COpCode%3E-for-ProtocolError"],[561,"impl-From%3Cusize%3E-for-ProtocolError"],[562,"impl-From%3Cu8%3E-for-ProtocolError"],[563,"impl-From%3CError%3E-for-ProtocolError"],[751,"impl-PartialEq%3Cstr%3E-for-Method"],[752,"impl-PartialEq-for-Method"],[753,"impl-PartialEq%3C%26Method%3E-for-Method"],[754,"impl-PartialEq%3CMethod%3E-for-%26Method"],[755,"impl-PartialEq%3C%26str%3E-for-Method"],[756,"impl-PartialEq%3Cu16%3E-for-StatusCode"],[757,"impl-PartialEq-for-StatusCode"],[758,"impl-PartialEq%3C%26str%3E-for-Uri"],[759,"impl-PartialEq%3Cstr%3E-for-Uri"],[760,"impl-PartialEq-for-Uri"],[778,"impl-Display-for-Error"],[779,"impl-Debug-for-Error"],[780,"impl-Display-for-Method"],[781,"impl-Debug-for-Method"],[782,"impl-Debug-for-StatusCode"],[783,"impl-Display-for-StatusCode"],[784,"impl-Debug-for-Uri"],[785,"impl-Display-for-Uri"],[788,"impl-From%3CParseError%3E-for-Error"],[790,"impl-From%3CPayloadError%3E-for-Error"],[791,"impl-From%3CInfallible%3E-for-Error"],[792,"impl-From%3CEncoderError%3E-for-Error"],[793,"impl-From%3CHandshakeError%3E-for-Error"],[794,"impl-From%3CError%3E-for-Error"],[795,"impl-From%3CProtocolError%3E-for-Error"],[800,"impl-From%3CPathAndQuery%3E-for-Uri"],[802,"impl-From%3CAuthority%3E-for-Uri"],[839,"impl-Host-for-Uri"],[840,"impl-Uri"],[856,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-Method"],[857,"impl-TryFrom%3C%26str%3E-for-Method"],[859,"impl-TryFrom%3C%26str%3E-for-StatusCode"],[860,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-StatusCode"],[861,"impl-TryFrom%3Cu16%3E-for-StatusCode"],[863,"impl-TryFrom%3C%26str%3E-for-Uri"],[864,"impl-TryFrom%3CParts%3E-for-Uri"],[865,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-Uri"],[866,"impl-TryFrom%3CString%3E-for-Uri"],[868,"impl-TryFrom%3C%26String%3E-for-Uri"],[869,"impl-TryFrom%3CVec%3Cu8%3E%3E-for-Uri"],[870,"impl-TryFrom%3C%26Uri%3E-for-Uri"],[1034,"impl-AsRef%3C%5Bu8%5D%3E-for-HeaderName"],[1035,"impl-AsRef%3Cstr%3E-for-HeaderName"],[1103,"impl-PartialEq-for-HeaderName"],[1104,"impl-PartialEq%3CHeaderName%3E-for-%26HeaderName"],[1105,"impl-PartialEq%3C%26HeaderName%3E-for-HeaderName"],[1106,"impl-PartialEq%3C%26str%3E-for-HeaderName"],[1107,"impl-PartialEq%3Cstr%3E-for-HeaderName"],[1108,"impl-PartialEq%3CHeaderValue%3E-for-%26HeaderValue"],[1109,"impl-PartialEq%3Cstr%3E-for-HeaderValue"],[1110,"impl-PartialEq%3CString%3E-for-HeaderValue"],[1111,"impl-PartialEq%3C%26T%3E-for-HeaderValue"],[1112,"impl-PartialEq-for-HeaderValue"],[1113,"impl-PartialEq%3C%5Bu8%5D%3E-for-HeaderValue"],[1151,"impl-Display-for-LanguageTag"],[1152,"impl-Debug-for-LanguageTag"],[1153,"impl-Debug-for-InvalidHeaderName"],[1154,"impl-Display-for-InvalidHeaderName"],[1155,"impl-Debug-for-InvalidHeaderValue"],[1156,"impl-Display-for-InvalidHeaderValue"],[1157,"impl-Display-for-HeaderName"],[1158,"impl-Debug-for-HeaderName"],[1160,"impl-Display-for-ToStrError"],[1161,"impl-Debug-for-ToStrError"],[1163,"impl-Display-for-Charset"],[1164,"impl-Debug-for-Charset"],[1166,"impl-Debug-for-ExtendedValue"],[1167,"impl-Display-for-ExtendedValue"],[1168,"impl-Display-for-HttpDate"],[1169,"impl-Debug-for-HttpDate"],[1170,"impl-Debug-for-Quality"],[1171,"impl-Display-for-Quality"],[1172,"impl-Debug-for-QualityItem%3CT%3E"],[1173,"impl-Display-for-QualityItem%3CT%3E"],[1180,"impl-From%3Ci32%3E-for-HeaderValue"],[1181,"impl-From%3Cu64%3E-for-HeaderValue"],[1182,"impl-From%3Cu16%3E-for-HeaderValue"],[1183,"impl-From%3Cisize%3E-for-HeaderValue"],[1184,"impl-From%3C%26HeaderValue%3E-for-HeaderValue"],[1185,"impl-From%3CHeaderName%3E-for-HeaderValue"],[1186,"impl-From%3Ci64%3E-for-HeaderValue"],[1187,"impl-From%3Cu32%3E-for-HeaderValue"],[1188,"impl-From%3Cusize%3E-for-HeaderValue"],[1189,"impl-From%3Ci16%3E-for-HeaderValue"],[1213,"impl-FromStr-for-HeaderValue"],[1214,"impl-HeaderValue"],[1242,"impl-IntoIterator-for-HeaderMap"],[1243,"impl-IntoIterator-for-%26HeaderMap"],[1269,"impl-PartialOrd-for-HeaderValue"],[1270,"impl-PartialOrd%3CHeaderValue%3E-for-%26HeaderValue"],[1271,"impl-PartialOrd%3CString%3E-for-HeaderValue"],[1272,"impl-PartialOrd%3C%26T%3E-for-HeaderValue"],[1273,"impl-PartialOrd%3C%5Bu8%5D%3E-for-HeaderValue"],[1274,"impl-PartialOrd%3Cstr%3E-for-HeaderValue"],[1314,"impl-TryFrom%3CString%3E-for-HeaderName"],[1315,"impl-TryFrom%3C%26String%3E-for-HeaderName"],[1317,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-HeaderName"],[1318,"impl-TryFrom%3CVec%3Cu8%3E%3E-for-HeaderName"],[1319,"impl-TryFrom%3C%26str%3E-for-HeaderName"],[1320,"impl-TryFrom%3CString%3E-for-HeaderValue"],[1321,"impl-TryFrom%3C%26String%3E-for-HeaderValue"],[1323,"impl-TryFrom%3CVec%3Cu8%3E%3E-for-HeaderValue"],[1324,"impl-TryFrom%3C%26str%3E-for-HeaderValue"],[1325,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-HeaderValue"],[1352,"impl-TryIntoHeaderValue-for-%26HeaderValue"],[1353,"impl-TryIntoHeaderValue-for-HeaderValue"],[1501,"impl-PartialEq%3Cu16%3E-for-Port%3CT%3E"],[1502,"impl-PartialEq%3CPort%3CU%3E%3E-for-Port%3CT%3E"],[1503,"impl-PartialEq%3CString%3E-for-Authority"],[1504,"impl-PartialEq%3C%26str%3E-for-Authority"],[1505,"impl-PartialEq%3Cstr%3E-for-Authority"],[1506,"impl-PartialEq-for-Authority"],[1507,"impl-PartialEq%3C%26str%3E-for-PathAndQuery"],[1508,"impl-PartialEq%3CString%3E-for-PathAndQuery"],[1509,"impl-PartialEq-for-PathAndQuery"],[1510,"impl-PartialEq%3Cstr%3E-for-PathAndQuery"],[1511,"impl-PartialEq-for-Scheme"],[1512,"impl-PartialEq%3Cstr%3E-for-Scheme"],[1522,"impl-Display-for-Port%3CT%3E"],[1523,"impl-Debug-for-Port%3CT%3E"],[1524,"impl-Debug-for-Authority"],[1525,"impl-Display-for-Authority"],[1527,"impl-Display-for-PathAndQuery"],[1528,"impl-Debug-for-PathAndQuery"],[1529,"impl-Debug-for-Scheme"],[1530,"impl-Display-for-Scheme"],[1532,"impl-Display-for-InvalidUri"],[1533,"impl-Debug-for-InvalidUri"],[1534,"impl-Debug-for-InvalidUriParts"],[1535,"impl-Display-for-InvalidUriParts"],[1567,"impl-PartialOrd%3CString%3E-for-Authority"],[1568,"impl-PartialOrd%3C%26str%3E-for-Authority"],[1569,"impl-PartialOrd-for-Authority"],[1570,"impl-PartialOrd%3Cstr%3E-for-Authority"],[1571,"impl-PartialOrd%3C%26str%3E-for-PathAndQuery"],[1572,"impl-PartialOrd-for-PathAndQuery"],[1573,"impl-PartialOrd%3CString%3E-for-PathAndQuery"],[1574,"impl-PartialOrd%3Cstr%3E-for-PathAndQuery"],[1593,"impl-TryFrom%3C%26str%3E-for-Authority"],[1595,"impl-TryFrom%3CVec%3Cu8%3E%3E-for-Authority"],[1596,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-Authority"],[1597,"impl-TryFrom%3CString%3E-for-Authority"],[1600,"impl-TryFrom%3CVec%3Cu8%3E%3E-for-PathAndQuery"],[1601,"impl-TryFrom%3C%26str%3E-for-PathAndQuery"],[1602,"impl-TryFrom%3CString%3E-for-PathAndQuery"],[1603,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-PathAndQuery"],[1604,"impl-TryFrom%3C%26String%3E-for-PathAndQuery"],[1605,"impl-TryFrom%3C%26str%3E-for-Scheme"],[1607,"impl-TryFrom%3C%26%5Bu8%5D%3E-for-Scheme"],[1757,"impl-From%3CCloseCode%3E-for-CloseReason"],[1758,"impl-From%3C(CloseCode,+T)%3E-for-CloseReason"]],"c":"OjAAAAEAAAAAAAAAEAAAABIA","e":"OzAAAAEAAPADawABAAEACQAAAA0AAAAQAAAAEgAAABgAAAAhABkAPQAFAEkAAABNAAAAUwABAFoAAQBlAAEAegAAAJEAAgCgAAAAqwADAMgAAADOAC0A/QAAAP8ADAAfAQ0ALgESAFEBAABVAQAAWAECAF4BBABlAREAeAESAKIBAACqAQAAsQEBAMkBAADSAS0AAQIKAA0CAwASAgYAGgIEACACBQAnAgMALQICADECAwBCAjUAhAIAAMsCAADQAgsA3gI3ABcDBQAeAwAAIAMBACMDAAArAwIALwMDADUDAABEAwEASAMAAE4DJwB3AwUAqgMAAAsEAgARBBoAMAQZAEsEAgBPBAMAVQQmAIAEFgCbBAAAnQQJAKoEAACuBAAAvAQCAMAEAwDIBAMA2wQBAO8EAAD0BAAA9gQIAAsFCQAWBTEASQUQAF4FDABzBQ4AjAUEAJIFHQC7BQIAxQUPANYFKgAGBgAACQYAAAsGAAAQBgUAIAYHADAGNABmBgMAbAYBAG8GBAB2BgEAeQYAAH8GAgCDBgAApwYLALQGBQC9BgEAwAYWANsGAADeBgEA7wYaAA=="}]\ +]')); +if (typeof exports !== 'undefined') exports.searchIndex = searchIndex; +else if (window.initSearch) window.initSearch(searchIndex); diff --git a/search.desc/actix_files/actix_files-desc-0-.js b/search.desc/actix_files/actix_files-desc-0-.js new file mode 100644 index 000000000..3a6811291 --- /dev/null +++ b/search.desc/actix_files/actix_files-desc-0-.js @@ -0,0 +1 @@ +searchState.loadedDescShard("actix_files", 0, "Static file serving for Actix Web.\nA directory; responds with the generated directory listing.\nStatic files handling service.\nAssembled file serving service.\nHTTP Range header representation.\nA file with an associated name.\nBase directory.\nReturns the Content-Disposition that will be used when …\nReturns the Content-Encoding that will be used when …\nReturns the Content-Type header that will be used when …\nSets default handler which is used when no matched file …\nDisable Content-Disposition header.\nDisables Content-Disposition header.\nReturns reference to the underlying file object.\nReturn the MIME type associated with a filename extension …\nSet custom directory renderer.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCreates an instance from a previously opened file.\nAdds a routing guard.\nSet index file\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCreates an HttpResponse with file as a streaming body.\nIs this entry visible from this directory?\nLength of range.\nReturns the filesystem metadata associated with this file.\nSpecifies guard to check before fetching directory …\nSpecifies MIME override callback.\nReturns the time the file was last modified.\nCreate new Files instance for a specified base directory.\nCreate a new directory\nAttempts to open a file asynchronously in read-only mode.\nParses Range HTTP header string as per RFC 2616.\nReturns the filesystem path to this file.\nPath of subdirectory to generate listing for.\nSets path filtering closure.\nSpecifies whether text responses should signal a UTF-8 …\nSpecifies whether text responses should signal a UTF-8 …\nRedirects to a slash-ended path when browsing a directory.\nSet the Content-Disposition for serving this file. This …\nSets content encoding for this file.\nSets the Content-Type header that will be used when …\nSet response status code.\nShow files listing for directories.\nStart of range.\nSpecifies whether to use ETag or not.\nSpecifies whether to return ETag header in response.\nEnables serving hidden files and directories, allowing a …\nSpecifies whether to use Last-Modified or not.\nSpecifies whether to return Last-Modified header in …") \ No newline at end of file diff --git a/search.desc/actix_http/actix_http-desc-0-.js b/search.desc/actix_http/actix_http-desc-0-.js new file mode 100644 index 000000000..7897cb27c --- /dev/null +++ b/search.desc/actix_http/actix_http-desc-0-.js @@ -0,0 +1 @@ +searchState.loadedDescShard("actix_http", 0, "HTTP types and services for the Actix ecosystem.\n202 Accepted [RFC7231, Section 6.3.3]\n208 Already Reported [RFC5842]\n502 Bad Gateway [RFC7231, Section 6.6.3]\n400 Bad Request [RFC7231, Section 6.5.1]\nA boxed payload stream.\n409 Conflict [RFC7231, Section 6.5.8]\nCONNECT\n100 Continue [RFC7231, Section 6.2.1]\n201 Created [RFC7231, Section 6.3.2]\nClose connection after response.\nRepresents various types of connection\nDELETE\nKeep-alive is disabled.\n417 Expectation Failed [RFC7231, Section 6.5.14]\nA type map for request extensions.\n424 Failed Dependency [RFC4918]\n403 Forbidden [RFC7231, Section 6.5.3]\n302 Found [RFC7231, Section 6.4.3]\n504 Gateway Timeout [RFC7231, Section 6.6.5]\nGET\n410 Gone [RFC7231, Section 6.5.9]\nHEAD\nHTTP/0.9\nHTTP/1.0\nHTTP/1.1\nHTTP/2.0\nHTTP/3.0\n505 HTTP Version Not Supported [RFC7231, Section 6.6.6]\nTrait that implements general purpose operations on HTTP …\nA ServiceFactory for HTTP/1.1 and HTTP/2 connections.\nAn HTTP service builder.\n418 I’m a teapot [curiously not registered by IANA but …\n226 IM Used [RFC3229]\n507 Insufficient Storage [RFC4918]\n500 Internal Server Error [RFC7231, Section 6.6.1]\nConnection keep-alive config.\nKeep connection alive after response.\n411 Length Required [RFC7231, Section 6.5.10]\n423 Locked [RFC4918]\n508 Loop Detected [RFC5842]\n405 Method Not Allowed [RFC7231, Section 6.5.5]\n421 Misdirected Request RFC7540, Section 9.1.2\n301 Moved Permanently [RFC7231, Section 6.4.2]\n300 Multiple Choices [RFC7231, Section 6.4.1]\n207 Multi-Status [RFC4918]\nThe Request Method (VERB)\n511 Network Authentication Required [RFC6585]\n203 Non-Authoritative Information [RFC7231, Section 6.3.4]\n406 Not Acceptable [RFC7231, Section 6.5.6]\n510 Not Extended [RFC2774]\n404 Not Found [RFC7231, Section 6.5.4]\n501 Not Implemented [RFC7231, Section 6.6.2]\n304 Not Modified [RFC7232, Section 4.1]\n204 No Content [RFC7231, Section 6.3.5]\n200 OK [RFC7231, Section 6.3.1]\nOPTIONS\nRely on OS to shutdown TCP connection.\n206 Partial Content [RFC7233, Section 4.1]\nPATCH\n413 Payload Too Large [RFC7231, Section 6.5.11]\n402 Payment Required [RFC7231, Section 6.5.2]\n308 Permanent Redirect [RFC7238]\nPOST\n412 Precondition Failed [RFC7232, Section 4.2]\n428 Precondition Required [RFC6585]\n102 Processing [RFC2518]\n407 Proxy Authentication Required [RFC7235, Section 3.2]\nPUT\nA streaming payload.\nA major HTTP protocol version.\n416 Range Not Satisfiable [RFC7233, Section 4.4]\n431 Request Header Fields Too Large [RFC6585]\n408 Request Timeout [RFC7231, Section 6.5.7]\n205 Reset Content [RFC7231, Section 6.3.6]\nAn HTTP request.\nAn HTTP response.\nAn HTTP response builder.\n303 See Other [RFC7231, Section 6.4.4]\n503 Service Unavailable [RFC7231, Section 6.6.4]\n101 Switching Protocols [RFC7231, Section 6.2.2]\nHTTP service configuration.\nAn HTTP status code (status-code in RFC 7230 et al.).\nType of message payload stream\n307 Temporary Redirect [RFC7231, Section 6.4.7]\n429 Too Many Requests [RFC6585]\nTRACE\nKeep-alive duration.\nConfiguration options used when accepting TLS connection.\n401 Unauthorized [RFC7235, Section 3.1]\n451 Unavailable For Legal Reasons [RFC7725]\n422 Unprocessable Entity [RFC4918]\n415 Unsupported Media Type [RFC7231, Section 6.5.13]\n426 Upgrade Required [RFC7231, Section 6.5.15]\n414 URI Too Long [RFC7231, Section 6.5.12]\n305 Use Proxy [RFC7231, Section 6.4.5]\nConnection is upgraded to different type.\nThe URI component of a request.\n506 Variant Also Negotiates [RFC2295]\nRepresents a version of the HTTP spec.\nAppend a header, keeping any that were set with an …\nReturn a &str representation of the HTTP method\nReturns a &str representation of the StatusCode\nReturns the u16 corresponding to this StatusCode.\nGet the authority of this Uri.\nConstructs a new response with status 400 Bad Request.\nTraits and structures to aid consuming and writing HTTP …\nGenerate response with a wrapped body.\nReturns a reference to the body of this response.\nConstructs a new response builder.\nConstructs builder for HttpService instance.\nCreates a new builder-style object to manufacture a Uri.\nIs to uppercase headers with Camel-Case. Default is false\nGet the standardised reason-phrase for this status code.\nCheck if request has chunked transfer encoding.\nCheck if request has chunked transfer encoding.\nGet response body chunking state\nGet response body chunking state\nClear the Extensions of all inserted extensions.\nCreates a time object representing the deadline for the …\nSet client connection disconnect timeout.\nCreates a time object representing the deadline for the …\nSet client request timeout (for first request).\nReturns a reference a piece of connection data set in an …\nConnection type\nCheck if map contains an item of a given type.\nRead the request content type. If request did not contain …\nRead the request content type. If request did not contain …\nSet response content type.\nDrops body and returns new response.\nContent-Encoding support.\nGet content type encoding.\nGet content type encoding.\nError and Result module\nProvide service for EXPECT: 100-Continue support.\nSets service for Expect: 100-Continue handling.\nRequest contains EXPECT header.\nExtends self with the items from another Extensions.\nReturns a reference to the request-local data/extensions …\nReturns a reference to the request-local data/extensions …\nReturns a mutable reference to the request-local …\nReturns a mutable reference to the request-local …\nFinish service configuration and create HttpService …\nGenerate response with an empty body.\nForce-close connection, even if it is marked as keep-alive.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nConverts a slice of bytes to an HTTP method.\nConverts a &u8 to a status code\nAttempt to convert a Bytes buffer to a Uri.\nAttempt to convert a Parts into a Uri.\nConvert a Uri from a static string.\nConverts a u16 to a status code.\nGet a reference to an item of a given type.\nGet a mutable reference to an item of a given type.\nHTTP/1 protocol implementation.\nFinish service configuration and create a service for the …\nHTTP/2 protocol.\nFinish service configuration and create a service for the …\nSet TLS handshake timeout duration.\nHttp message part of the request\nReturns a reference to the head of this response.\nReturns a mutable reference to the head of this response.\nPre-defined HeaderNames, traits for parsing and …\nRead the message headers.\nReturns a reference to response headers.\nRead the message headers.\nRead the message headers.\nMutable reference to the message’s headers.\nReturns a mutable reference to response headers.\nMutable reference to the message headers.\nMutable reference to the message headers.\nGet the host of this Uri.\nInsert an item into the map.\nInsert a header, replacing any that were set with an …\nConstructs a new response with status 500 Internal Server …\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturns the response body, dropping all other parts.\nSplit request into request head and payload\nConvert a Uri into Parts.\nReturns split head and body.\nCheck if status is within 400-499.\nWhether a method is considered “idempotent”, meaning …\nCheck if status is within 100-199.\nCheck if status is within 300-399.\nWhether a method is considered “safe”, meaning the …\nCheck if status is within 500-599.\nCheck if status is within 200-299.\nSet connection keep-alive setting.\nSet connection type to KeepAlive\nReturns true if keep-alive is enabled.\nConnection keep-alive setting.\nCheck if keep-alive is enabled\nCreates a time object representing the deadline for this …\nSet the local address that this service is bound to.\nReturns the local address that this server is bound to.\nMap the current body type to another using a closure, …\nMap the current body to a type-erased BoxBody.\nGenerate response with a body.\nRead the Request method.\nConvert the request content type to a known mime type.\nConvert the request content type to a known mime type.\nGet new message from the pool of objects\nCreate new Request instance\nCreate response builder\nConstructs a new response with default body.\nConstructs new HttpService instance from service with …\nCreate instance of ServiceConfig.\nCreates an empty Extensions.\nCreate new instance of ResponseHead type\nDisable chunked transfer encoding for HTTP/1.1 streaming …\nSet no chunking for payload\nConstructs a new response with status 404 Not Found.\nConstructs a new response with status 200 OK.\nSets the callback to be run on connection establishment.\nCreate OpenSSL based service.\nCreate OpenSSL based service with custom TLS acceptor …\nThe target path of this Request.\nGet the path of this Uri.\nReturns the path & query components of the Uri\nGet request’s payload\nPeer socket address.\nWill only be None when called in unit tests unless set …\nGet the port part of this Uri.\nGet the port of this Uri as a u16.\nGet the query string of this Uri, starting after the ?.\nSet the custom reason for the response.\nGet custom reason for the response\nRemove an item from the map of a given type.\nCreate new Request instance\nCreate Rustls v0.20 based service.\nCreate Rustls v0.21 based service.\nCreate Rustls v0.21 based service with custom TLS acceptor …\nCreate Rustls v0.22 based service.\nCreate Rustls v0.22 based service with custom TLS acceptor …\nCreate Rustls v0.23 based service.\nCreate Rustls v0.23 based service with custom TLS acceptor …\nCreate Rustls v0.20 based service with custom TLS acceptor …\nGet the scheme of this Uri.\nGet the scheme of this Uri as a &str.\nSet connection secure state\nReturns true if connection is secure (i.e., using TLS / …\nSets new body.\nSet true to send headers which are formatted as Camel-Case.\nSets the flag that controls whether to send headers …\nSet connection type of the message\nSet connection type of the message\nSet HTTP status code of this response.\nReturns the status code of this response.\nReturns a mutable reference the status code of this …\nCreate an owned ResponseBuilder, leaving the original in a …\nTakes current payload and replaces it with None value\nReturns the connection-level data/extensions container if …\nMessage payload stream\nGet request’s payload\nReturns the request-local data/extensions container, …\nCreates TCP stream service from HTTP service.\nCreates TCP stream service from HTTP service that …\nVarious testing helpers for use in internal and app tests.\nProvide service for custom Connection: UPGRADE support.\nCheck if request requires connection upgrade\nSet connection type to Upgrade.\nReturns true if connection upgrade is enabled.\nSets service for custom Connection: Upgrade handling.\nConnection upgrade status\nCheck upgrade status of this message\nURI component of request and response lines\nRequest’s uri.\nMutable reference to the request’s uri.\nRead the Request Version.\nConstructs a new response with given body.\nCreate new Request instance\nWebSocket protocol implementation.\nError type returned from to_bytes_limited when body …\nBody size hint.\nStreaming response wrapper.\nA boxed message body with boxed errors.\nAn “either” type specialized for body types.\nThe type of error that will be returned if streaming body …\nA body of type L.\nAn interface for types that can be used as a response body.\nBody type for responses that forbid payloads.\nImplicitly empty body.\nA body of type R.\nKnown size body.\nKnown sized streaming response wrapper.\nUnknown size body.\nEquivalent to BodySize::Sized(0);\nReturns a mutable pinned reference to the inner message …\nWraps this body into a BoxBody.\nWraps this body into a BoxBody.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturns true if size hint indicates omitted or empty body.\nCreates new EitherBody using left variant.\nBoxes body type, erasing type information.\nCreates new EitherBody left variant with a boxed right …\nConstructs new “none” body.\nAttempt to pull out the next chunk of body bytes.\nAttempts to pull out the next value of the underlying …\nAttempts to pull out the next value of the underlying …\nCreates new EitherBody using right variant.\nBody size hint.\nCollects all the bytes produced by body.\nCollects the bytes produced by body, up to limit bytes.\nTry to convert into the complete chunk of body bytes.\nTry to convert into the complete chunk of body bytes.\nReturns the argument unchanged.\nReturns the argument unchanged.\nConstruct decoder based on headers.\nCalls U::from(self).\nCalls U::from(self).\nConstruct a decoder.\nBody streaming error.\nA set of error that can occur during parsing content type.\nDisconnect timeout. Makes sense for TLS streams.\nA set of errors that can occur during dispatching HTTP …\nContent encoding stream corruption.\nHTTP/2 error.\nHandler dropped payload before reading EOF.\nAn invalid Header.\nHTTP/2 payload error.\nA generic “error” for HTTP connections\nA message reached EOF, but is not complete.\nA payload reached EOF, but is not complete.\nInternal error.\nAn I/O error that occurred while trying to read or write …\nGeneric I/O error.\nAn io::Error that occurred while trying to read or write …\nAn invalid Method, such as GE.T.\nPayload reached size limit.\nRequest parse error.\nA set of errors that can occur during parsing HTTP streams.\nCan not parse content type.\nA set of errors that can occur during payload parsing.\nService error.\nThe first request did not complete within the specified …\nAn invalid Status, such as 1337 ELITE.\nA timeout occurred waiting for an IO event.\nA message head is too large to be reasonable.\nUnknown content encoding.\nPayload length is unknown.\nUpgrade service error.\nAn invalid Uri, such as exam ple.domain.\nParsing a field as string failed.\nAn invalid HttpVersion, such as HTP/1.1\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturn a reference to the lower level, inner error.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturn true if the underlying error has the same type as T.\nPayload chunk.\nHTTP/1 Codec\nHTTP/1 Payload Codec\nHTTP/1 Codec\nDispatcher for HTTP/1.1 protocol\nServiceFactory implementation for HTTP1 transport\nService implementation for HTTP/1 transport\nHTTP message.\nCodec message\nIncoming request type\nBuffered stream of bytes chunks\nSend HTTP/1 response\nCreates a payload stream.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nTransform payload codec to a message codec\nConvert message codec to a payload codec\nCheck if last response is keep-alive\nCheck if last response is keep-alive\nCheck if last response is keep-alive.\nCheck if keep-alive enabled on server level.\nCheck last request’s message type\nCheck last request’s message type.\nCreate HTTP/1 codec.\nCreate HTTP/1 codec.\nCreate OpenSSL based service.\nCreate Rustls v0.20 based service.\nCreate Rustls v0.21 based service.\nCreate Rustls v0.22 based service.\nCreate Rustls v0.23 based service.\nCreate simple tcp stream service\nPut unused data back to payload\nCheck if request is upgrade\nCheck if request is upgrade.\nDispatcher for HTTP/2 protocol.\nServiceFactory implementation for HTTP/2 transport\nHTTP/2 peer stream.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCreate OpenSSL based service.\nCreate Rustls v0.20 based service.\nCreate Rustls v0.21 based service.\nCreate Rustls v0.22 based service.\nCreate Rustls v0.23 based service.\nCreate plain TCP based service\nAdvertises which content types the client is able to …\nAdvertises which character set the client is able to …\nAdvertises which content encoding the client is able to …\nAdvertises which languages the client is able to …\nMarker used by the server to advertise partial request …\nPreflight response indicating if the response to the …\nPreflight response indicating permitted HTTP headers.\nPreflight header response indicating permitted access …\nIndicates whether the response can be shared with …\nIndicates which headers can be exposed as part of the …\nIndicates how long the results of a preflight request can …\nInforms the server which HTTP headers will be used when an …\nInforms the server know which HTTP method will be used …\nIndicates the time in seconds the object has been in a …\nLists the set of methods support by a resource.\nAdvertises the availability of alternate services to …\nContains the credentials to authenticate a user agent with …\nSealed trait implemented for types that can be effectively …\nBig5\nA format using the Brotli algorithm.\nSpecifies directives for caching mechanisms in both …\nResponse header field that indicates how caches have …\nResponse header field that allows origin servers to …\nControls whether or not the network connection stays open …\nIndicates if the content is expected to be displayed …\nUsed to compress the media-type.\nUsed to describe the languages intended for the audience.\nIndicates the size of the entity-body.\nIndicates an alternate location for the returned data.\nIndicates where in a full body message a partial message …\nAllows controlling resources the user agent is allowed to …\nAllows experimenting with policies by monitoring their …\nUsed to indicate the media type of the resource.\nContains stored HTTP cookies previously sent by the server …\nResponse header that prevents a document from loading any …\nResponse header that allows you to ensure a top-level …\nResponse header that conveys a desire that the browser …\nA MIME character set.\nRepresents a supported content encoding.\nContains the date and time at which the message was …\nIndicates the client’s tracking preference.\nA format using the zlib structure with deflate algorithm.\nIdentifier for a specific version of a resource.\nIndicates expectations that need to be fulfilled by the …\nContains the date/time after which the response is …\nThe type returned in the event of a conversion error.\nEUC-JP\nEUC-KR\nAn arbitrary charset specified as a string\nThe value part of an extended parameter consisting of …\nContains information from the client-facing side of proxy …\nContains an Internet email address for a human user who …\nGB2312\nGzip algorithm.\nSpecifies the domain name of the server and (optionally) …\nAn interface for types that already represent a valid …\nRepresents an HTTP header field name\nRepresents an HTTP header field value.\nA timestamp with HTTP-style formatting and parsing.\nMakes a request conditional based on the E-Tag.\nMakes a request conditional based on the modification date.\nMakes a request conditional based on the E-Tag.\nMakes a request conditional based on range.\nMakes the request conditional based on the last …\nIndicates the no-op identity encoding.\nA possible error when converting a HeaderName from another …\nA possible error when converting a HeaderValue from a …\nISO-2022-JP\nISO-2022-JP-2\nISO-2022-KR\nISO-8859-1\nISO-8859-10\nISO-8859-2\nISO-8859-3\nISO-8859-4\nISO-8859-5\nISO-8859-6\nISO-8859-6-E\nISO-8859-6-I\nISO-8859-7\nISO-8859-8\nISO-8859-8-E\nISO-8859-8-I\nISO-8859-9\nKOI8-R\nContent-Types that are acceptable for the response.\nAllows the server to point an interested client to another …\nIndicates the URL to redirect a page to.\nA language tag as described in RFC 5646.\nThe maximum quality value, equivalent to q=1.0.\nIndicates the max number of intermediaries the request …\nThe minimum, non-zero quality value, equivalent to q=0.001.\nIndicates where a fetch originates from.\nResponse header that provides a mechanism to allow and …\nHTTP/1.0 header usually used for backwards compatibility.\nDefines the authentication method that should be used to …\nContains the credentials to authenticate a user agent to a …\nAssociates a specific cryptographic public key with a …\nSends reports of pinning violation to the report-uri …\nRepresents a quality used in q-factor values.\nRepresents an item with a quality value as defined in RFC …\nIndicates the part of a document that the server should …\nContains the address of the previous web page from which a …\nGoverns which referrer information should be included with …\nInforms the web browser that the current page or frame …\nThe Retry-After response HTTP header indicates how long …\nThe |Sec-WebSocket-Accept| header field is used in the …\nThe |Sec-WebSocket-Extensions| header field is used in the …\nThe |Sec-WebSocket-Key| header field is used in the …\nThe |Sec-WebSocket-Protocol| header field is used in the …\nThe |Sec-WebSocket-Version| header field is used in the …\nContains information about the software used by the origin …\nUsed to send cookies from the server to the user agent.\nTells the client to communicate with HTTPS instead of …\nShift_JIS\nInforms the server of transfer encodings willing to be …\nAllows the sender to include additional fields at the end …\nSpecifies the form of encoding used to safely transfer the …\nA possible error when converting a HeaderValue to a string …\nAn interface for types that can be converted into a …\nAn interface for types that can be converted into a …\nUsed as part of the exchange to upgrade the protocol.\nSends a signal to the server expressing the client’s …\nContains a string that allows identifying the requesting …\nUS ASCII\nDetermines how to match future requests with cached …\nAdded by proxies to track routing.\nGeneral HTTP header contains information about possible …\nDefines the authentication method that should be used to …\nMarker used by the server to indicate that the MIME types …\nControls DNS prefetching.\nRequest header (de-facto standard) for identifying the …\nRequest header (de-facto standard) for identifying the …\nRequest header (de-facto standard) for identifying the …\nIndicates whether or not a browser should be allowed to …\nStop pages from loading when an XSS attack is detected.\nThe zero quality value, equivalent to q=0.0.\nZstd algorithm.\nConverts a HeaderValue to a byte slice.\nReturn the serialization of this language tag.\nReturns a str representation of the header.\nConvert content encoding to string.\nReturns the canonical version of the language tag following\nThe character set that is used to encode the value to a …\nPerforms a case-insensitive comparison of the string …\nPerforms a case-insensitive comparison of the string …\nReturn the extended language subtags.\nIterate on the extended language subtags.\nReturn the extension subtags.\nIterate on the extension subtags.\nFormat an array into a comma-delimited string.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nConverts a slice of bytes to an HTTP header name.\nAttempt to convert a byte slice to a HeaderValue.\nReads a comma-delimited raw header into a Vec.\nConverts a slice of bytes to an HTTP header name.\nAttempt to convert a Bytes buffer to a HeaderValue.\nConvert a Bytes directly into a HeaderValue without …\nConverts a HeaderName into a HeaderValue\nReads a single string when parsing a header.\nConverts a static string to a HTTP header name.\nConvert a static string to a HeaderValue.\nAttempt to convert a string to a HeaderValue.\nReturn the primary language subtag and its extended …\nPercent encode a sequence of bytes with a character set …\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturn the serialization of this language tag.\nReturns true if the HeaderValue has a length of zero bytes.\nChecks if it is a language range, meaning that there are …\nReturns true if the value represents sensitive data.\nCheck if the language tag is valid according to RFC 5646.\nThe wrapped contents of the field.\nThe human language details of the value, if available.\nReturns the length of self.\nA multi-value HeaderMap and its iterators.\nMatches language tags. The first language acts as a …\nConstructs a new QualityItem from an item, using the …\nConstructs a new QualityItem from an item, using the …\nReturns the name of the header field.\nConstructs a new QualityItem from an item and a quality …\nParse the header from a HTTP message.\nCreate a LanguageTag from its serialization.\nParses extended header parameter values (ext-value), as …\nReturn the primary language subtag.\nReturn the private use subtags.\nIterate on the private use subtags.\nConvenience function to create a Quality from an f32 …\nThe quality (client or server preference) for the value.\nReturn the region subtag.\nReturn the script subtag.\nMark that the header value represents sensitive …\nConvert content encoding to header value.\nYields a &str slice if the HeaderValue only contains …\nTry to convert value to a HeaderValue.\nCheck if the language tag is “valid” according to RFC …\nThe parameter value, as expressed in octets.\nReturn the variant subtags.\nIterate on the variant subtags.\nConstructs a new QualityItem from an item, using zero …\nIterator over drained name-value pairs.\nA multi-map of HTTP headers.\nIterator over owned name-value pairs.\nIterator over borrowed name-value pairs.\nIterator over all names in the map.\nIterator over removed, owned values with the same …\nAppends a name-value pair to the map.\nReturns the number of single-value headers the map can …\nClears the map, removing all name-value pairs.\nReturns true if the map contains a value for the specified …\nClears the map, returning all name-value sets as an …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns a reference to the first value associated with a …\nReturns an iterator over all values associated with a …\nReturns a mutable reference to the first value associated …\nInserts (overrides) a name-value pair in the map.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturns true if the map contains no elements.\nReturns true if iterator contains no elements, without …\nAn iterator over all name-value pairs.\nAn iterator over all contained header names.\nReturns the number of values stored in the map.\nReturns the number of keys stored in the map.\nCreate an empty HeaderMap.\nRemoves all headers for a particular header name from the …\nReserves capacity for at least additional more headers to …\nRetains only the headers specified by the predicate.\nCreate an empty HeaderMap with the specified capacity.\nAsync I/O test buffer.\nTest Request builder.\nAsync I/O test buffer with ability to incrementally add to …\nAppend a header, keeping any that were set with an …\nCreate new empty TestBuffer instance.\nCreate new empty TestBuffer instance.\nAdd data to read buffer.\nAdd data to read buffer.\nComplete request creation and generate Request instance.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nInsert a header, replacing any that were set with an …\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nSet HTTP method of this request.\nCreate new TestBuffer instance with initial read buffer.\nCreate new TestBuffer instance with initial read buffer.\nSet request payload.\nSet URI of this request.\nSet HTTP version of this request.\nCreate a default TestRequest and then set its URI.\nRepresents the authority component of a URI.\nA builder for Uris.\nHTTP protocol scheme\nHTTP protocol over TLS.\nAn error resulting from a failed attempt to construct a …\nAn error resulting from a failed attempt to construct a …\nThe various parts of a URI.\nRepresents the path component of a URI\nThe port component of a URI.\nRepresents the scheme component of a URI\nThe URI component of a request.\nReturns the port number as a str.\nReturn a str representation of the authority\nReturns the path and query as a string component.\nReturn a str representation of the scheme\nReturns the port number as a u16.\nSet the Authority for this URI.\nThe authority component of a URI\nConsumes this builder, and tries to construct a valid Uri …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nAttempt to convert a Bytes buffer to a Authority.\nAttempt to convert a Bytes buffer to a PathAndQuery.\nAttempt to convert an Authority from a static string.\nConvert a PathAndQuery from a static string.\nGet the host of this Authority.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCreates a new default instance of Builder to construct a …\nReturns the path component\nSet the PathAndQuery for this URI.\nThe origin-form component of a URI\nGet the port part of this Authority.\nGet the port of this Authority as a u16.\nReturns the query string component\nSet the Scheme for this URI.\nThe scheme component of a URI\nIndicates an abnormal closure. If the abnormal closure was …\nIndicates that the server is overloaded and the client …\nIndicates that an endpoint is “going away”, such as a …\nIndicates an invalid opcode was received.\nBad opcode.\nWebSocket key is not set or wrong.\nBinary message.\nBinary frame.\nIndicates a binary data frame.\nClose message with optional reason.\nClose message with optional reason.\nIndicates a close control frame.\nStatus code used to indicate why an endpoint is closing …\nReason for closing the connection\nWebSocket protocol codec.\nContinuation.\nContinuation.\nUnknown continuation fragment.\nContinuation has not started.\nReceived new continuation but it is already started.\nIndicates a continuation frame of a fragmented message.\nIndicates that a server is terminating the connection …\nIndicates that an endpoint (client) is terminating the …\nA WebSocket frame.\nOnly get method is allowed.\nWebSocket handshake errors\nIndicates that an endpoint is terminating the connection …\nInvalid control frame length\nEncountered invalid opcode.\nI/O error.\nA WebSocket continuation item.\nReceived a masked frame from server.\nA WebSocket message.\nConnection header is not set to upgrade.\nWebSocket version header is not set.\nUpgrade header if not set to WebSocket.\nNo-op. Useful for low-level services.\nIndicates a normal closure, meaning that the purpose for …\nOperation codes defined in [RFC 6455 §11.8].\nA payload reached size limit.\nA struct representing a WebSocket frame.\nPing message.\nPing message.\nIndicates a ping control frame.\nIndicates that an endpoint is terminating the connection …\nPong message.\nPong message.\nIndicates a pong control frame.\nIndicates that an endpoint is terminating the connection …\nWebSocket protocol errors.\nIndicates that the server is restarting. A client may …\nIndicates that an endpoint is terminating the connection …\nText message.\nText frame. Note that the codec does not validate UTF-8 …\nIndicates a text data frame.\nReceived an unmasked frame from client.\nIndicates that an endpoint is terminating the connection …\nUnsupported WebSocket version.\nSet decoder to client mode.\nExit code\nOptional description of the exit code\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nVerify WebSocket handshake request and create handshake …\nCreate WebSocket handshake response.\nHashes the Sec-WebSocket-Key header according to the …\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nSet max frame size.\nCreate new WebSocket frames decoder.\nParse the input stream into a frame.\nParse the payload of a close frame.\nVerify WebSocket handshake request.\nCreate a new Close control frame.\nGenerate binary representation") \ No newline at end of file diff --git a/search.desc/actix_http_test/actix_http_test-desc-0-.js b/search.desc/actix_http_test/actix_http_test-desc-0-.js new file mode 100644 index 000000000..7e30bbde8 --- /dev/null +++ b/search.desc/actix_http_test/actix_http_test-desc-0-.js @@ -0,0 +1 @@ +searchState.loadedDescShard("actix_http_test", 0, "Various helpers for Actix applications to use during …\nTest server controller\nConstruct test server url\nGet default HeaderMap of Client.\nCreate DELETE request\nReturns the argument unchanged.\nCreate GET request\nCreate HEAD request\nCalls U::from(self).\nCreate OPTIONS request\nCreate PATCH request\nCreate POST request\nCreate PUT request\nConnect to test HTTP server\nCreate HTTPS DELETE request\nCreate HTTPS GET request\nCreate HTTPS HEAD request\nCreate HTTPS OPTIONS request\nCreate HTTPS PATCH request\nCreate HTTPS POST request\nCreate HTTPS PUT request\nStop HTTP server.\nConstruct test HTTPS server URL.\nStart test server.\nStart test server on an existing address binding.\nGet a localhost socket address with random, unused port.\nConstruct test server url\nConnect to a WebSocket server.\nConnect to WebSocket server at a given path.") \ No newline at end of file diff --git a/search.desc/actix_multipart/actix_multipart-desc-0-.js b/search.desc/actix_multipart/actix_multipart-desc-0-.js new file mode 100644 index 000000000..610eb9bdd --- /dev/null +++ b/search.desc/actix_multipart/actix_multipart-desc-0-.js @@ -0,0 +1 @@ +searchState.loadedDescShard("actix_multipart", 0, "Multipart form support for Actix Web.\nMultipart boundary is not found\nDuplicate field\nA single field in a multipart stream\nAn error from a field handler in a form\nMultipart stream is incomplete\nMissing field\nThe server-side implementation of multipart/form-data …\nA set of errors that can occur during parsing multipart …\nNested multipart is not supported\nContent-Disposition header is not found or is not equal to …\nContent-Type header is not found\nNot consumed\nError during field parsing\nCan not parse Content-Type header\nPayload error\nUnknown field\nReturns the field’s Content-Disposition.\nReturns a reference to the field’s content (mime) type, …\nProcess and extract typed data from a multipart stream.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns a reference to the field’s header map.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturns the field’s name.\nCreate multipart instance for boundary.\nTrait that data types to be used in a multipart form …\nFuture that resolves to a Self.\nUsed to keep track of the remaining limits for the form …\nTrait that allows a type to be used in the MultipartForm …\nTyped multipart/form-data extractor.\nImplements MultipartCollect for a struct so that it can be …\nMultipartForm extractor configuration.\nReads a field into memory.\nSets custom error handler.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nOnce all the fields have been processed and stored in the …\nThe extractor will call this function for each incoming …\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nUnwrap into inner T value.\nDeserializes a field as JSON.\nAn optional limit in bytes to be applied a given field …\nSets maximum accepted data that will be read into memory. …\nThe form will call this function to handle the field.\nWrites a field to a temporary file on disk.\nDeserializes a field from plain text.\nSets maximum accepted payload size for the entire form. By …\nThis function should be called within a FieldReader when …\nRead the field into memory.\nThe value of the Content-Type header.\nThe data.\nThe filename value in the Content-Disposition header.\nReturns the argument unchanged.\nCalls U::from(self).\nContent type error.\nDeserialize error.\nDeserialize from JSON.\nConfiguration for the Json field reader.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nSets whether or not the field must have a valid …\nFile I/O Error\nWrite the field to a temporary file on disk.\nConfiguration for the TempFile field reader.\nThe value of the content-type header.\nSets the directory that temp files will be created in.\nSets custom error handler.\nThe temporary file on disk.\nThe filename value in the content-disposition header.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nThe size in bytes of the file.\nContent type error.\nDeserialize error.\nDeserialize from plain text.\nConfiguration for the Text field reader.\nUTF-8 decoding error.\nSets custom error handler.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nUnwraps into inner value.\nSets whether or not the field must have a valid …\nConstructs a multipart/form-data payload from bytes and …\nConstructs a multipart/form-data payload from bytes and …") \ No newline at end of file diff --git a/search.desc/actix_multipart_derive/actix_multipart_derive-desc-0-.js b/search.desc/actix_multipart_derive/actix_multipart_derive-desc-0-.js new file mode 100644 index 000000000..0b901c1a0 --- /dev/null +++ b/search.desc/actix_multipart_derive/actix_multipart_derive-desc-0-.js @@ -0,0 +1 @@ +searchState.loadedDescShard("actix_multipart_derive", 0, "Multipart form derive macro for Actix Web.\nImplements MultipartCollect for a struct so that it can be …") \ No newline at end of file diff --git a/search.desc/actix_router/actix_router-desc-0-.js b/search.desc/actix_router/actix_router-desc-0-.js new file mode 100644 index 000000000..37f3be9a7 --- /dev/null +++ b/search.desc/actix_router/actix_router-desc-0-.js @@ -0,0 +1 @@ +searchState.loadedDescShard("actix_router", 0, "Resource path matching and router.\nHelper trait for type that could be converted to one or …\nResource path match information.\nType of resource’s path returned in resource_path.\nOne or many patterns.\nPartial percent-decoding.\nDescribes the set of paths that match to a resource.\nResource router.\nBuilder for an ordered routing list.\nReturns full path as a string.\nConstructs new RouterBuilder with empty route list.\nCollects dynamic segment values into resource.\nCollects dynamic segment values into resource after …\nTries to match path to this resource, returning the …\nFinish configuration and create router instance.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nGet matched parameter by name without type conversion\nReturns mutable reference to inner path instance.\nReturns reference to inner path instance.\nReturns a numeric resource ID.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCheck if there are any matched patterns.\nReturns true if path matches this resource.\nReturns true if pattern type is prefix.\nReturn iterator to items in parameter container.\nJoins two resources.\nDeserializes matching parameters to a specified type U.\nReturns resource definition name, if set.\nConstructs a new Quoter instance given a set of protected …\nConstructs a new resource definition from patterns.\nRegisters resource for specified path.\nReturns path.\nReturns the pattern string that generated the resource …\nReturns iterator of pattern strings that generated the …\nRegisters resource for specified path prefix.\nConstructs a new resource definition using a pattern that …\nAdds a new route to the end of the routing list.\nReturns matched parameter by name.\nRegisters resource for ResourceDef.\nFinds the value in the router that matches a given routing …\nFinds the value in the router that matches a given routing …\nSame as recognize but returns a mutable reference to the …\nSame as recognize_fn but returns a mutable reference to …\nPartially percent-decodes the given bytes.\nReset state.\nAssembles full resource path from iterator of dynamic …\nAssembles resource path from map of dynamic segment values.\nConstructs a new resource definition using a string …\nReturns number of interpolated segments.\nSet new path.\nSet numeric resource ID.\nAssigns a new name to the resource.\nSkip first n chars in path.\nReturns unprocessed part of the path.\nReturns URI.") \ No newline at end of file diff --git a/search.desc/actix_test/actix_test-desc-0-.js b/search.desc/actix_test/actix_test-desc-0-.js new file mode 100644 index 000000000..58568f429 --- /dev/null +++ b/search.desc/actix_test/actix_test-desc-0-.js @@ -0,0 +1 @@ +searchState.loadedDescShard("actix_test", 0, "Integration testing tools for Actix Web applications.\nAn asynchronous HTTP and WebSocket client.\nAn HTTP Client request builder\nClient Response\nManages HTTP client network connectivity.\nContent encoding stream corruption.\nHTTP/2 payload error.\nA payload reached EOF, but is not complete.\nGeneric I/O error.\nPayload reached size limit.\nA set of errors that can occur during payload parsing.\nAsync I/O test buffer.\nTest Request builder.\nA basic HTTP server controller that simplifies the process …\nPayload length is unknown.\nConstruct test server url\nSet socket address of the server.\nInserts application data.\nAppend a header, keeping any that were set with an …\nAppends a header, keeping any that were set with an …\nSet HTTP basic authorization header.\nSet HTTP bearer authentication header\nReturns a Future that consumes the body stream and …\nConstructs new Client builder.\nHelper function that returns a response body of a …\nHelper function that returns a deserialized response body …\nCalls service and waits for response future completion.\nSend headers in Camel-Case form.\nGet default HeaderMap of Client.\nSets client timeout for first request.\nCreate default test server config.\nSet keep-alive period for opened connection.\nSet max lifetime period for connection.\nSets custom connector.\nSet content length\nSet request’s content type\nSet a cookie\nReturn request cookie.\nSets cookie for this request.\nLoad request cookies.\nCreate DELETE request.\nConstruct HTTP DELETE request.\nConstructs test request with DELETE method.\nSet server connection disconnect timeout in milliseconds.\nCreate new empty TestBuffer instance.\nAdd data to read buffer.\nFinish configuration process and create connector service.\nForce close connection instead of returning it back to …\nFreeze request builder and construct FrozenClientRequest, …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCreate GET request.\nConstruct HTTP GET request.\nConstructs test request with GET method.\nGet HTTP method of this request\nGet peer address of this request.\nGet HTTP URI of request.\nGet HTTP version of this request.\nAccepts HTTP/1.1 only.\nAccepts HTTP/2 only.\nSets TLS handshake timeout.\nCreate HEAD request.\nConstruct HTTP HEAD request.\nReturns request’s headers.\nGet default HeaderMap of Client.\nReturns request’s headers.\nReturns request’s mutable headers.\nInitialize service from application builder instance.\nSets the initial window size (in bytes) for HTTP/2 …\nSets the initial window size (in bytes) for HTTP/2 …\nInsert a header, replacing any that were set with an …\nInserts a header, replacing any that were set with an …\nInsert a header only if it is not yet set.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturns a Future consumes the body stream, parses JSON, …\nSet total number of simultaneous connections per type of …\nSet local IP Address the connector would use for …\nMap the current body type to another using a closure. …\nSets maximum supported HTTP major version.\nSet HTTP method of this request.\nSets method of this request.\nCreate a new connector with default TLS settings\nConstructs new client instance with default settings.\nCreate new TestBuffer instance with initial read buffer.\nDisable automatic decompress of response’s body\nCreates service that always responds with 200 OK and no …\nAccepts secure connections via OpenSSL.\nSets custom OpenSSL SslConnector instance.\nCreate OPTIONS request.\nConstruct HTTP OPTIONS request.\nSets request path pattern parameter.\nCreate PATCH request.\nConstruct HTTP PATCH request.\nConstructs test request with PATCH method.\nSets peer address.\nSets test server port.\nCreate POST request.\nConstruct HTTP POST request.\nConstructs test request with POST method.\nCreate PUT request.\nConstruct HTTP PUT request.\nConstructs test request with PUT method.\nSets the query part of the request\nHelper function that returns a response body of a …\nHelper function that returns a deserialized response body …\nConnect request with given method and path.\nConstruct HTTP request.\nCreate ClientRequest from RequestHead\nSets custom Rustls v0.20 ClientConfig instance.\nSets custom Rustls v0.21 ClientConfig instance.\nAccepts secure connections via Rustls v0.20.\nAccepts secure connections via Rustls v0.21.\nAccepts secure connections via Rustls v0.22.\nSets custom Rustls v0.22 ClientConfig instance.\nAccepts secure connections via Rustls v0.23.\nSets custom Rustls v0.23 ClientConfig instance.\nSet an empty body and generate ClientRequest.\nComplete request construction and send body.\nSet a urlencoded body and generate ClientRequest\nSet a JSON body and generate ClientRequest\nFinalizes request creation, calls service, and waits for …\nSet an streaming body and generate ClientRequest.\nSerializes data to a URL encoded form and set it as the …\nSerializes data to JSON and set it as the request payload.\nSets request payload.\nStart default TestServer.\nStart test server with custom configuration\nGet the status from the server.\nCreates service that always responds with given status …\nStop HTTP server.\nSets TCP connection timeout.\nSet request timeout. Overrides client wide timeout setting.\nSet a timeout duration for ClientResponse.\nCollects all the bytes produced by body.\nFinalizes request creation and returns HttpRequest and …\nFinalizes request creation and returns HttpRequest …\nFinalizes request creation and returns Request instance.\nFinalizes request creation and returns ServiceRequest …\nFinalizes request creation and returns ServiceResponse …\nGet a localhost socket address with random, unused port.\nSet HTTP URI of request.\nSets URI of this request.\nConstruct test server url\nRead the Request Version.\nSets HTTP version of this request.\nConstructs test request and sets request URI.\nSets number of workers for the test server.\nConnect to a WebSocket server.\nInitialize a WebSocket connection. Returns a WebSocket …\nConnect to WebSocket server at a given path.") \ No newline at end of file diff --git a/search.desc/actix_web/actix_web-desc-0-.js b/search.desc/actix_web/actix_web-desc-0-.js new file mode 100644 index 000000000..148a2cc50 --- /dev/null +++ b/search.desc/actix_web/actix_web-desc-0-.js @@ -0,0 +1 @@ +searchState.loadedDescShard("actix_web", 0, "Actix Web is a powerful, pragmatic, and extremely fast web …\nThe top-level builder for an Actix Web application.\nAllows overriding status code and headers for a Responder.\nCombines two extractor or responder types into a single …\nContains the error value\nThe associated error which can be returned.\nA type that implements FromRequest is called an extractor …\nFuture that resolves to a Self.\nThe interface for request handlers.\nTrait that implements general purpose operations on HTTP …\nAn incoming request.\nAn outgoing response.\nAn HTTP response builder.\nAn HTTP Server.\nA value of type L.\nContains the success value\nA collection of Routes that respond to the same path …\nTrait implemented by types that can be converted to an …\nA convenience Result for Actix Web operations.\nA value of type R.\nA request handler with guards.\nA collection of Routes, Resources, or other services that …\nType of message payload stream\nAdd a cookie to this response.\nAdd a “removal” cookie to the response that matches …\nReturns addresses of bound sockets.\nReturns addresses of bound sockets and the scheme for it.\nReturns a reference to the application’s connection …\nSet application (root level) data.\nAdd resource data.\nAdd scope data.\nRetrieves a piece of application state.\nAppend a header, keeping any that were set with an …\nAppend header to the final response.\nSets the maximum number of pending connections.\nResolves socket address(es) and binds server to created …\nResolves socket address(es) and binds server to created …\nResolves socket address(es) and binds server to created …\nResolves socket address(es) and binds server to created …\nResolves socket address(es) and binds server to created …\nResolves socket address(es) and binds server to created …\nResolves socket address(es) and binds server to created …\nOpens Unix Domain Socket (UDS) from uds path and binds …\nTraits and structures to aid consuming and writing HTTP …\nSet a body and build the HttpResponse.\nReturns a reference to this response’s body.\nConstructs a response builder with specific HTTP status.\nCheck if request has chunked transfer encoding.\nSets server connection shutdown timeout.\nSets server client timeout for first request.\nRun external configuration as part of the application …\nRun external configuration as part of the scope building …\nReturns a reference a piece of connection data set in an …\nCreates route handler with actix_web::guard::Connect.\nReturns connection info for the current request.\nSet response content type.\nRead the request content type. If request did not contain …\nAdd a cookie to the response.\nReturn request cookie.\nGet an iterator for the cookies set by this response.\nLoad request cookies.\nWraps responder to allow alteration of its response.\nWraps responder to allow alteration of its response.\nAdd application (root) data after wrapping in Data<T>.\nAdd resource data after wrapping in Data<T>.\nAdd scope data after wrapping in Data<T>.\nAdd application data factory that resolves asynchronously.\nDefault service that is invoked when no matching resource …\nSets the default service to be used if no matching route …\nDefault service to be used if no matching resource could …\nRemove all cookies with the given name from this response.\nAdds a DELETE route.\nCreates route handler with actix_web::guard::Delete.\nLower-level types and re-exports.\nDisables signal handling.\nDrops body and returns new response.\nGet content type encoding.\nError and Result module\nThe source error for this response\nReturns a reference to the request-local data/extensions …\nReturns a reference to the response-local data/extensions …\nReturns reference to the response-local data/extensions …\nReturns a mutable reference to the request-local …\nReturns a mutable reference to the response-local …\nReturns reference to the response-local data/extensions …\nRegister an external resource.\nCreate a Self from request head asynchronously.\nCreate a Self from request head asynchronously.\nSet an empty body and build the HttpResponse.\nForce close connection, even if it is marked as keep-alive\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCreate an error response.\nCreate a Self from request parts asynchronously.\nAdds a GET route.\nCreates route handler with actix_web::guard::Get.\nRoute guards.\nAdd match guard to a resource.\nAdd guard to the route.\nAdd match guard to a scope.\nAdds a HEAD route.\nReturns a reference to response head.\nThis method returns reference to the request head\nCreates route handler with actix_web::guard::Head.\nReturns a mutable reference to response head.\nRead the message headers.\nGet the headers from the response\nReturns request’s headers.\nGet a mutable reference to the headers\nVarious HTTP related types.\nInsert a header, replacing any that were set with an …\nInsert (override) header in the final response.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturns the response body, dropping all other parts.\nReturns split head and body.\nSet a JSON body and build the HttpResponse.\nSet connection type to KeepAlive\nKeep-alive status for this connection\nSets server keep-alive preference.\nBinds to existing listener for accepting incoming …\nBinds to existing listener for accepting incoming …\nBinds to existing listener for accepting incoming TLS …\nBinds to existing listener for accepting incoming TLS …\nBinds to existing listener for accepting incoming TLS …\nBinds to existing listener for accepting incoming TLS …\nBinds to existing listener for accepting incoming TLS …\nBinds to existing Unix Domain Socket (UDS) listener.\nMarks async main function as the Actix Web system …\nMap the current body type to another using a closure, …\nMap the current body to a type-erased BoxBody.\nMap the current body type B to EitherBody::Left(B).\nMap the current body type B to EitherBody::Right(B).\nReturns a reference to the URL parameters container.\nThe resource name that matched the path. Useful for …\nThe resource definition pattern that matched the path. …\nSets the per-worker maximum concurrent TLS connection …\nSets the per-worker maximum number of concurrent …\nSet a body and build the HttpResponse.\nAdd method guard to the route.\nRead the Request method.\nA collection of common middleware.\nConvert the request content type to a known mime type.\nSet resource name.\nCreate application builder. Application can be configured …\nConstructs new resource that matches a path pattern.\nCreate response builder\nConstructs a response.\nCreate new route which matches any request.\nCreate a new scope\nCreate new HTTP server with application factory\nDisable chunked transfer encoding for HTTP/1.1 streaming …\nSets function that will be called once before each …\nCreates route handler with actix_web::guard::Options.\nAdds a PATCH route.\nCreates route handler with actix_web::guard::Patch.\nThe target path of this request.\nReturns peer socket address.\nAdds a POST route.\nCreates route handler with actix_web::guard::Post.\nAdds a PUT route.\nCreates route handler with actix_web::guard::Put.\nThe query string in the URL.\nSet the custom reason for the response.\nGet a reference to a ResourceMap of current application.\nConvert self to HttpResponse.\nConfigure route for a specific path.\nRegister a new route.\nConfigure route for a specific path.\nCreates resource handler, allowing multiple HTTP method …\nCreates resource handler, allowing multiple HTTP methods …\nA selection of re-exports from tokio and actix-rt.\nStart listening for incoming connections.\nSets server host name.\nRegister HTTP service.\nSet raw service to be constructed and called as the …\nRegister HTTP service.\nMacro to help register different types of services at the …\nSets new body.\nSets timeout for graceful worker shutdown of workers.\nSet HTTP status code of this response.\nGet the response status code\nSet the StatusCode for this response\nSet a streaming body and build the HttpResponse.\nFlags the System to exit after server shutdown.\nThis method construct new HttpResponseBuilder\nMessage payload stream\nVarious helpers for Actix applications to use during …\nMarks async test functions to use the Actix Web system …\nSets TLS handshake timeout.\nRegister a new route and add handler. This route matches …\nSet handler function, use request extractors for …\nAdds a TRACE route.\nCreates route handler with actix_web::guard::Trace.\nSet connection type to Upgrade\nConnection upgrade status\nRequest’s uri.\nGenerates URL for a named resource.\nGenerate URL for named resource\nRead the Request Version.\nEssentials helper functions and types for application …\nConstructs a response with body\nOverride a status code for the Responder’s response.\nSets max number of threads for each worker’s blocking …\nSets number of workers to start (per bind address).\nRegisters an app-wide middleware.\nRegisters a resource middleware.\nRegisters a route middleware.\nRegisters a scope-wide middleware.\nRegisters an app-wide function middleware.\nRegisters a resource function middleware.\nRegisters a scope-wide function middleware.\nError type returned from to_bytes_limited when body …\nBody size hint.\nStreaming response wrapper.\nA boxed message body with boxed errors.\nAn “either” type specialized for body types.\nThe type of error that will be returned if streaming body …\nA body of type L.\nAn interface for types that can be used as a response body.\nBody type for responses that forbid payloads.\nImplicitly empty body.\nA body of type R.\nKnown size body.\nKnown sized streaming response wrapper.\nUnknown size body.\nEquivalent to BodySize::Sized(0);\nReturns a mutable pinned reference to the inner message …\nWraps this body into a BoxBody.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturns true if size hint indicates omitted or empty body.\nCreates new EitherBody using left variant.\nBoxes body type, erasing type information.\nCreates new EitherBody left variant with a boxed right …\nConstructs new “none” body.\nAttempt to pull out the next chunk of body bytes.\nAttempts to pull out the next value of the underlying …\nAttempts to pull out the next value of the underlying …\nCreates new EitherBody using right variant.\nBody size hint.\nCollects all the bytes produced by body.\nCollects the bytes produced by body, up to limit bytes.\nTry to convert into the complete chunk of body bytes.\nRepresentation of an HTTP cookie.\nStructure that follows the builder pattern for building …\nA collection of cookies that tracks its modifications.\nExpiration for a “permanent” cookie at a specific …\nIterator over the changes to a cookie jar.\nWrapper around Cookie whose Display implementation either …\nThe cookie’s name was empty.\nA cookie’s expiration: either session or a date-time.\nIterator over all of the cookies in a jar.\nA cryptographic master key for use with Signed and/or …\nAn error indicating an issue with generating or …\nThe “Lax” SameSite attribute.\nThe cookie did not contain a name/value pair.\nThe “None” SameSite attribute.\nEnum corresponding to a parsing error.\nA child cookie jar that provides authenticated encryption …\nThe SameSite cookie attribute.\nExpiration for a “session” cookie. Browsers define the …\nA child cookie jar that authenticates its cookies.\nThe “Strict” SameSite attribute.\nToo few bytes (.0) were provided to generate a key.\nDecoding the cookie’s name or value resulted in invalid …\nAdds cookie to the parent jar. The cookie’s value is …\nAdds cookie to the parent jar. The cookie’s value is …\nAdds cookie to this jar. If a cookie with the same name …\nAdds an “original” cookie to parent jar. The cookie’…\nAdds an “original” cookie to this jar. The cookie’s …\nAdds an “original” cookie to this jar. If an original …\nReturns a description of this error as a string\nCreates a new CookieBuilder instance from the given key …\nReturns the inner OffsetDateTime if self is a DateTime.\nAuthenticates and decrypts cookie, returning the plaintext …\nReturns an iterator over cookies that represent the …\nDerives new signing/encryption keys from a master key.\nSets the domain field in the cookie being built.\nReturns the Domain of the cookie if one was specified.\nReturns the Domain of self as a string slice of the raw …\nPercent-encode the name and value pair.\nWraps self in an encoded Display: a cost-free wrapper …\nReturns the raw bytes of a key suitable for encrypting …\nSets the expires field in the cookie being built.\nReturns the Expiration of the cookie if one was specified.\nReturns the expiration date-time of the cookie if one was …\nFinishes building and returns the built Cookie.\nFormats the cookie self as a Set-Cookie header value.\nRemoves cookie from this jar completely. This method …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCreates a new Key from a 512-bit cryptographically random …\nReturns the argument unchanged.\nReturns the argument unchanged.\nGenerates signing/encryption keys from a secure, random …\nReturns a reference to the Cookie inside this jar with the …\nReturns a reference to the Cookie inside this jar with the …\nReturns a reference to the Cookie inside this jar with the …\nSets the http_only field in the cookie being built.\nReturns whether this cookie was marked HttpOnly or not. …\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nConverts self into a Cookie with a static lifetime with as …\nReturns true if self is an Expiration::DateTime.\nReturns true if self is SameSite::Lax and false otherwise.\nReturns true if self is SameSite::None and false otherwise.\nReturns true if self is an Expiration::Session.\nReturns true if self is SameSite::Strict and false …\nReturns an iterator over all of the cookies present in …\nMakes self a “permanent” cookie by extending its …\nMake self a “removal” cookie by clearing its value, …\nApplied f to the inner OffsetDateTime if self is a DateTime…\nReturns the raw bytes of the master key. Guaranteed to be …\nSets the max_age field in the cookie being built.\nReturns the specified max-age of the cookie if one was …\nReturns the name of self.\nReturns the name of self as a string slice of the raw …\nReturns the name and value of self as a tuple of …\nCreates a new Cookie with the given name and an empty …\nCreates a new CookieBuilder instance from the given name …\nCreates an empty cookie jar.\nCreates a new Cookie with the given name and value.\nParses a Cookie from the given HTTP cookie header value …\nParses a Cookie from the given HTTP cookie header value …\nSets the path field in the cookie being built.\nReturns the Path of the cookie if one was specified.\nReturns the Path of self as a string slice of the raw …\nMakes the cookie being built ‘permanent’ by extending …\nReturns a read-only PrivateJar with self as its parent jar …\nReturns a read/write PrivateJar with self as its parent …\nRemoves cookie from the parent jar.\nRemoves cookie from the parent jar.\nRemoves cookie from this jar. If an original cookie with …\nRemoves all delta cookies, i.e. all cookies not added via …\nSets the same_site field in the cookie being built.\nReturns the SameSite attribute of this cookie if one was …\nSets the secure field in the cookie being built.\nReturns whether this cookie was marked Secure or not. …\nSets the domain of self to domain.\nSets the expires field of self to time. If time is None, an\nSets the value of http_only in self to value. If value is …\nSets the value of max_age in self to value. If value is …\nSets the name of self to name.\nSets the path of self to path.\nSets the value of same_site in self to value. If value is …\nSets the value of secure in self to value. If value is None…\nSets the value of self to value.\nReturns a read-only SignedJar with self as its parent jar …\nReturns a read/write SignedJar with self as its parent jar …\nReturns the raw bytes of a key suitable for signing …\nOnly display the name and value.\nWraps self in a stripped Display]: a cost-free wrapper …\nA fallible version of Key::from().\nAttempts to generate signing/encryption keys from a …\nUnsets the domain of self.\nUnsets the expires of self.\nUnsets the path of self.\nReturns the value of self.\nReturns the value of self as a string slice of the raw …\nVerifies the authenticity and integrity of cookie, …\nEquivalent to 1.days().\nDate in the proleptic Gregorian calendar.\nA span of time with nanosecond precision.\nContains the error value\nA unified error type for anything returned by a method in …\nEquivalent to 1.hours().\nA measurement of a monotonically non-decreasing clock. …\nThe maximum valid Date.\nThe maximum possible duration. Adding any positive …\nThe largest value that can be represented by …\nEquivalent to 1.microseconds().\nCreate a Time that is exactly midnight.\nEquivalent to 1.milliseconds().\nThe minimum valid Date.\nThe minimum possible duration. Adding any negative …\nThe smallest value that can be represented by …\nEquivalent to 1.minutes().\nMonths of the year.\nEquivalent to 1.nanoseconds().\nA PrimitiveDateTime with a UtcOffset.\nContains the success value\nCombined date and time.\nAn alias for std::result::Result with a generic error from …\nEquivalent to 1.seconds().\nThe clock time within a given date. Nanosecond precision.\nMidnight, 1 January, 1970 (UTC).\nA UtcOffset that is UTC.\nAn offset from UTC.\nEquivalent to 1.weeks().\nDays of the week.\nEquivalent to 0.seconds().\nGet the absolute value of the duration.\nPanics\nPanics\nPanics\nPanics\nPanics\nPanics\nPanics\nPanics\nPanics\nAdd the sub-day time of the Duration to the Time. Wraps on …\nAdd the sub-day time of the std::time::Duration to the Time…\nPanics\nPanics\nPanics\nPanics\nGet the clock hour, minute, and second.\nGet the clock hour, minute, and second.\nObtain the UTC offset as its hours, minutes, and seconds. …\nGet the clock hour, minute, second, and microsecond.\nGet the clock hour, minute, second, and microsecond.\nGet the clock hour, minute, second, and millisecond.\nGet the clock hour, minute, second, and millisecond.\nGet the clock hour, minute, second, and nanosecond.\nGet the clock hour, minute, second, and nanosecond.\nGet the number of fractional seconds in the duration.\nGet the number of fractional seconds in the duration.\nAssuming that the existing PrimitiveDateTime represents a …\nAssuming that the existing PrimitiveDateTime represents a …\nComputes self + duration, returning None if an overflow …\nComputes self + rhs, returning None if an overflow …\nReturns Some(t) where t is the time self + duration if t …\nComputes self + duration, returning None if an overflow …\nComputes self + duration, returning None if an overflow …\nComputes self + duration, returning None if an overflow …\nComputes self / rhs, returning None if rhs == 0 or if the …\nComputes self * rhs, returning None if an overflow …\nComputes -self, returning None if the result would …\nCreates a new Duration from the specified number of seconds\nCreates a new Duration from the specified number of seconds\nComputes self - duration, returning None if an overflow …\nComputes self - rhs, returning None if an overflow …\nReturns Some(t) where t is the time self - duration if t …\nComputes self - duration, returning None if an overflow …\nComputes self - duration, returning None if an overflow …\nComputes self - duration, returning None if an overflow …\nConvert the OffsetDateTime from the current UtcOffset to …\nConversion between units of time.\nGet the Date in the stored offset.\nGet the Date component of the PrimitiveDateTime.\nGet the day of the month.\nGet the day of the date in the stored offset.\nGet the day of the date.\nCreate a new Duration with the given number of days. …\nReturns the amount of time elapsed since this instant was …\nVarious error types returned by methods in the time crate.\nExtension traits.\nFormat the Date using the provided format description.\nFormat the OffsetDateTime using the provided format …\nFormat the PrimitiveDateTime using the provided format …\nFormat the Time using the provided format description.\nFormat the UtcOffset using the provided format description.\nDescription of how types should be formatted and parsed.\nFormat the Date using the provided format description.\nFormat the OffsetDateTime using the provided format …\nFormat the PrimitiveDateTime using the provided format …\nFormat the Time using the provided format description.\nFormat the UtcOffset using the provided format description.\nFormatting for various types.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nAttempt to create a Date from the year, month, and day.\nAttempt to create a Time from the hour, minute, and second.\nCreate a UtcOffset representing an offset by the number of …\nAttempt to create a Time from the hour, minute, second, …\nAttempt to create a Time from the hour, minute, second, …\nAttempt to create a Time from the hour, minute, second, …\nAttempt to create a Date from the ISO year, week, and …\nCreate a Date from the Julian day.\nAttempt to create a Date from the year and ordinal day …\nCreate an OffsetDateTime from the provided Unix timestamp. …\nConstruct an OffsetDateTime from the provided Unix …\nCreate a UtcOffset representing an offset by the number of …\nGet the clock hour in the stored offset.\nGet the clock hour.\nGet the clock hour.\nCreate a new Duration with the given number of hours. …\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nObtain the inner std::time::Instant.\nCheck if a duration is negative.\nCheck if the offset is negative, or west of UTC.\nCheck if a duration is positive.\nCheck if the offset is positive, or east of UTC.\nCheck if the offset is exactly UTC.\nCheck if a duration is exactly zero.\nGet the ISO week number.\nGet the ISO week number of the date in the stored offset.\nGet the ISO week number.\nMacros to construct statically known values.\nGet the microseconds within the second in the stored …\nGet the microseconds within the second.\nGet the microseconds within the second.\nCreate a new Duration with the given number of …\nCreate a PrimitiveDateTime using the existing date. The …\nGet the milliseconds within the second in the stored …\nGet the milliseconds within the second.\nGet the milliseconds within the second.\nCreate a new Duration with the given number of …\nGet the minute within the hour in the stored offset.\nGet the minute within the hour.\nGet the minute within the hour.\nCreate a new Duration with the given number of minutes. …\nObtain the number of minutes past the hour the offset is …\nGet the week number where week 1 begins on the first …\nGet the week number where week 1 begins on the first …\nGet the week number where week 1 begins on the first …\nGet the month.\nGet the month of the date in the stored offset.\nGet the month of the date.\nGet the nanoseconds within the second in the stored offset.\nGet the nanoseconds within the second.\nGet the nanoseconds within the second.\nCreate a new Duration with the given number of nanoseconds.\nCreate a new Duration with the provided seconds and …\nCreate a new PrimitiveDateTime from the provided Date and …\nCreate a new OffsetDateTime with the given Date, Time, and …\nCreate a new OffsetDateTime with the given Date and Time …\nGet the next month.\nGet the next weekday.\nGet the next calendar date.\nCalculates the first occurrence of a weekday that is …\nReturns an Instant corresponding to “now”.\nCreate a new OffsetDateTime with the current date and time …\nGet n-th next month.\nGet n-th next day.\nCalculates the nth occurrence of a weekday that is …\nGet n-th previous month.\nGet n-th previous day.\nCalculates the nth occurrence of a weekday that is …\nGet the zero-indexed number of days from Monday.\nGet the zero-indexed number of days from Sunday.\nGet the one-indexed number of days from Monday.\nGet the one-indexed number of days from Sunday.\nGet the UtcOffset.\nGet the day of the year.\nGet the day of the year of the date in the stored offset.\nGet the day of the year.\nParse a Date from the input using the provided format …\nParse an OffsetDateTime from the input using the provided …\nParse a PrimitiveDateTime from the input using the …\nParse a Time from the input using the provided format …\nParse a UtcOffset from the input using the provided format …\nParsing for various types.\nCalculates the first occurrence of a weekday that is …\nGet the previous month.\nGet the previous weekday.\nGet the previous calendar date.\nReplace the date, which is assumed to be in the stored …\nReplace the date, preserving the time.\nReplace the date and time, which are assumed to be in the …\nReplace the day of the month.\nReplace the day of the month.\nReplace the day of the month.\nReplace the clock hour.\nReplace the clock hour.\nReplace the clock hour.\nReplace the microseconds within the second.\nReplace the microseconds within the second.\nReplace the microseconds within the second.\nReplace the milliseconds within the second.\nReplace the milliseconds within the second.\nReplace the milliseconds within the second.\nReplace the minutes within the hour.\nReplace the minutes within the hour.\nReplace the minutes within the hour.\nReplace the month of the year.\nReplace the month of the year.\nReplace the month of the year.\nReplace the nanoseconds within the second.\nReplace the nanoseconds within the second.\nReplace the nanoseconds within the second.\nReplace the offset. The date and time components remain …\nReplace the day of the year.\nReplace the day of the year.\nReplace the day of the year.\nReplace the seconds within the minute.\nReplace the seconds within the minute.\nReplace the seconds within the minute.\nReplace the time, which is assumed to be in the stored …\nReplace the time, preserving the date.\nReplace the year. The month and day will be unchanged.\nReplace the year. The month and day will be unchanged.\nReplace the year. The month and day will be unchanged.\nComputes self + duration, saturating value on overflow.\nComputes self + rhs, saturating if an overflow occurred.\nComputes self + duration, saturating value on overflow.\nComputes self + duration, saturating value on overflow.\nComputes self * rhs, saturating if an overflow occurred.\nCreates a new Duration from the specified number of seconds\nCreates a new Duration from the specified number of seconds\nComputes self - duration, saturating value on overflow.\nComputes self - rhs, saturating if an overflow occurred.\nComputes self - duration, saturating value on overflow.\nComputes self - duration, saturating value on overflow.\nGet the second within the minute in the stored offset.\nGet the second within the minute.\nGet the second within the minute.\nCreate a new Duration with the given number of seconds.\nCreates a new Duration from the specified number of …\nCreates a new Duration from the specified number of …\nObtain the number of seconds past the minute the offset is …\nPanics\nPanics\nPanics\nPanics\nPanics\nPanics\nPanics\nPanics\nPanics\nPanics\nPanics\nPanics\nPanics\nPanics\nSubtract two Times, returning the Duration between. This …\nSubtract the sub-day time of the std::time::Duration from …\nSubtract the sub-day time of the Duration from the Time. …\nPanics\nPanics\nPanics\nPanics\nGet the number of microseconds past the number of whole …\nGet the number of milliseconds past the number of whole …\nGet the number of nanoseconds past the number of whole …\nGet the week number where week 1 begins on the first …\nGet the week number where week 1 begins on the first …\nGet the week number where week 1 begins on the first …\nGet the Time in the stored offset.\nGet the Time component of the PrimitiveDateTime.\nRuns a closure, returning the duration of time it took to …\nGet the year, month, and day.\nGet the year, month, and day.\nGet the year, month, and day.\nGet the clock hour, minute, and second.\nGet the clock hour, minute, second, and microsecond.\nGet the clock hour, minute, second, and millisecond.\nGet the clock hour, minute, second, and nanosecond.\nGet the ISO 8601 year, week number, and weekday.\nGet the ISO 8601 year, week number, and weekday.\nGet the ISO 8601 year, week number, and weekday.\nGet the Julian day for the date.\nGet the Julian day for the date. The time is not taken …\nGet the Julian day for the date. The time is not taken …\nConvert the OffsetDateTime from the current UtcOffset to …\nGet the year and ordinal day number.\nGet the year and ordinal day number.\nGet the year and ordinal day number.\nGet the Unix timestamp.\nGet the Unix timestamp in nanoseconds.\nConvert the existing Duration to a std::time::Duration and …\nUtility functions.\nGet the weekday.\nGet the weekday of the date in the stored offset.\nGet the weekday.\nCreate a new Duration with the given number of weeks. …\nGet the number of whole days in the duration.\nGet the number of whole hours in the duration.\nObtain the number of whole hours the offset is from UTC. A …\nGet the number of whole microseconds in the duration.\nGet the number of whole milliseconds in the duration.\nGet the number of whole minutes in the duration.\nObtain the number of whole minutes the offset is from UTC. …\nGet the number of nanoseconds in the duration.\nGet the number of whole seconds in the duration.\nObtain the number of whole seconds the offset is from UTC. …\nGet the number of whole weeks in the duration.\nAttempt to create a PrimitiveDateTime using the existing …\nAttempt to create a PrimitiveDateTime using the existing …\nAttempt to create a PrimitiveDateTime using the existing …\nAttempt to create a PrimitiveDateTime using the existing …\nCreate a PrimitiveDateTime using the existing date and the …\nGet the year of the date.\nGet the year of the date in the stored offset.\nGet the year of the date.\nA unit of time representing exactly one day.\nA unit of time representing exactly one hour.\nA unit of time representing exactly one microsecond.\nA unit of time representing exactly one millisecond.\nA unit of time representing exactly one minute.\nA unit of time representing exactly one nanosecond.\nA unit of time representing exactly one second.\nA unit of time representing exactly one week.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nObtain the number of times Nanosecond can fit into T. If T …\nObtain the number of times Microsecond can fit into T. If T…\nObtain the number of times Millisecond can fit into T. If T…\nObtain the number of times Second can fit into T. If T is …\nObtain the number of times Minute can fit into T. If T is …\nObtain the number of times Hour can fit into T. If T is …\nObtain the number of times Day can fit into T. If T is …\nObtain the number of times Week can fit into T. If T is …\nAn error type indicating that a component provided to a …\nSome component contained an invalid value for the type.\nAn error type indicating that a conversion failed because …\nAn error type indicating that a TryFrom call failed …\nA unified error type for anything returned by a method in …\nSomething was expected, but not found.\nAn error occurred when formatting.\nThe Parsed did not include enough information to construct …\nThe type being formatted does not contain sufficient …\nThe component named has a value that cannot be formatted …\nA dynamic component was not valid.\nA component name is not valid.\nThe format description provided was not valid.\nA string literal was not what was expected.\nA modifier is not valid.\nAn error type indicating that a FromStr call failed …\nA component name is missing.\nA required modifier is missing.\nCertain behavior is not supported in the given context.\nAn error that occurred at some stage of parsing.\nAn error that occurred while parsing the input into a …\nA value of std::io::Error was returned internally.\nAn error that occurred when converting a Parsed to another …\nThere was a bracket pair that was opened but not closed.\nThe input should have ended, but there were characters …\nThe input was expected to have ended, but there are …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nWhether the value’s permitted range is conditional, i.e. …\nObtain the name of the component whose value was out of …\nThe context in which the behavior is not supported.\nThe zero-based index of the opening bracket.\nThe zero-based index the component name starts at.\nThe zero-based index the modifier starts at.\nThe zero-based index where the component name should start.\nThe zero-based index of the component.\nThe zero-based index the item was expected to be found at.\nThe zero-based index the error occurred at.\nThe name of the invalid component name.\nThe name of the modifier that is missing.\nThe value of the invalid modifier.\nWhat was expected to be present, but wasn’t.\nThe behavior that is not supported.\nAn extension trait for std::time::Instant that adds …\nCreate Durations from numeric literals.\nCreate std::time::Durations from numeric literals.\nPanics\nReturns Some(t) where t is the time …\nReturns Some(t) where t is the time …\nCreate a Duration from the number of days.\nCreate a Duration from the number of hours.\nCreate a Duration from the number of microseconds.\nCreate a Duration from the number of milliseconds.\nCreate a Duration from the number of minutes.\nCreate a Duration from the number of nanoseconds.\nCreate a Duration from the number of seconds.\nReturns the amount of time elapsed from another instant to …\nCreate a std::time::Duration from the number of days.\nCreate a std::time::Duration from the number of hours.\nCreate a std::time::Duration from the number of …\nCreate a std::time::Duration from the number of …\nCreate a std::time::Duration from the number of minutes.\nCreate a std::time::Duration from the number of …\nCreate a std::time::Duration from the number of seconds.\nCreate a std::time::Duration from the number of weeks.\nPanics\nCreate a Duration from the number of weeks.\nA complete description of how to format and parse a type.\nA component of a larger format description.\nA minimal representation of a single non-literal item.\nA minimal representation of a single non-literal item.\nA minimal representation of a single non-literal item.\nA series of literals or components that collectively form …\nA series of literals or components that collectively form …\nA series of literals or components that collectively form …\nDay of the month.\nThe end of input. Parsing this component will fail if …\nA series of FormatItems where, when parsing, the first …\nA series of FormatItems where, when parsing, the first …\nA series of FormatItems where, when parsing, the first …\nA complete description of how to format and parse a type.\nHour of the day.\nA number of bytes to ignore when parsing. This has no …\nBytes that are formatted as-is.\nBytes that are formatted as-is.\nBytes that are formatted as-is.\nMinute within the hour.\nMonth of the year.\nHour of the UTC offset.\nMinute within the hour of the UTC offset.\nSecond within the minute of the UTC offset.\nA FormatItem that may or may not be present when parsing. …\nA FormatItem that may or may not be present when parsing. …\nA FormatItem that may or may not be present when parsing. …\nOrdinal day of the year.\nA complete description of how to format and parse a type.\nAM/PM part of the time.\nSecond within the minute.\nSubsecond within the second.\nA Unix timestamp.\nWeek within the year.\nDay of the week.\nYear of the date.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nVarious modifiers for components.\nParse a sequence of items from the format description.\nParse a sequence of items from the format description.\nParse a sequence of items from the format description.\nWell-known formats, typically standards.\nDay of the month.\nExactly eight digits.\nThe end of input.\nExactly five digits.\nExactly four digits.\nThe full value of the year.\nHour of the day.\nIgnore some number of bytes.\nWeek 1 is the week that contains January 4.\nOnly the last two digits of the year.\nThe long form of the month name (e.g. “January”).\nThe long form of the weekday (e.g. “Monday”).\nMicroseconds since the Unix epoch.\nMilliseconds since the Unix epoch.\nMinute within the hour.\nA numerical representation using Monday as the first day …\nWeek 1 begins on the first Monday of the calendar year.\nMonth of the year.\nThe representation of a month.\nNanoseconds since the Unix epoch.\nExactly nine digits.\nThere is no padding. This can result in a width below the …\nThe number of the month (January is 1, December is 12).\nHour of the UTC offset.\nMinute within the hour of the UTC offset.\nSecond within the minute of the UTC offset.\nExactly one digit.\nAny number of digits (up to nine) that is at least one. …\nOrdinal day of the year.\nType of padding to ensure a minimum width.\nAM/PM part of the time.\nSecond within the minute.\nSeconds since the Unix epoch.\nExactly seven digits.\nThe short form of the month name (e.g. “Jan”).\nThe short form of the weekday (e.g. “Mon”).\nExactly six digits.\nA space character ( ) should be used as padding.\nSubsecond within the second.\nThe number of digits present in a subsecond representation.\nA numerical representation using Sunday as the first day …\nWeek 1 begins on the first Sunday of the calendar year.\nExactly three digits.\nExactly two digits.\nA Unix timestamp.\nThe precision of a Unix timestamp.\nWeek within the year.\nThe representation used for the week number.\nDay of the week.\nThe representation used for the day of the week.\nYear of the date.\nThe representation used for a year value.\nA zero character (0) should be used as padding.\nIs the value case sensitive when parsing?\nIs the value case sensitive when parsing?\nIs the value case sensitive when parsing?\nCreate an instance of Ignore with the provided number of …\nThe number of bytes to ignore.\nCreates a modifier that indicates the value is padded with …\nCreates an instance of this type that indicates the value …\nCreates a modifier that indicates the value is padded with …\nCreates a modifier that indicates the value uses the Long …\nCreates a modifier that indicates that the value is padded …\nCreates a modifier that indicates the value uses the Full …\nCreates a modifier that indicates the value is padded with …\nCreates a modifier that indicates the value is padded with …\nCreates a modifier that indicates the value uses the …\nCreates a modifier that indicates the value is padded with …\nCreates a modifier that indicates the stringified value …\nCreates a modifier that indicates the value only uses a …\nCreates a modifier that indicates the value is padded with …\nCreates a modifier that indicates the value is padded with …\nCreates a modifier that indicates the value represents the …\nCreates a modifier used to represent the end of input.\nHow many digits are present in the component?\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nIs the hour displayed using a 12 or 24-hour clock?\nIs the period uppercase or lowercase?\nWhether the value is based on the ISO week number or the …\nWhen using a numerical representation, should it be zero …\nThe padding to obtain the minimum width.\nThe padding to obtain the minimum width.\nThe padding to obtain the minimum width.\nThe padding to obtain the minimum width.\nThe padding to obtain the minimum width.\nThe padding to obtain the minimum width.\nThe padding to obtain the minimum width.\nThe padding to obtain the minimum width.\nThe padding to obtain the minimum width.\nThe padding to obtain the minimum width.\nThe padding to obtain the minimum width.\nThe precision of the timestamp.\nWhat form of representation should be used?\nWhat form of representation should be used?\nWhat kind of representation should be used?\nWhat kind of representation should be used?\nWhether the + sign is present when a positive year …\nWhether the + sign is present on positive values.\nWhether the + sign must be present for a non-negative …\nAn Iso8601 that handles only the date, but is otherwise …\nAn Iso8601 that handles the date and time, but is …\nAn Iso8601 that handles the date, time, and UTC offset. …\nAn Iso8601 with the default configuration.\nThe format described in ISO 8601.\nAn Iso8601 that handles only the UTC offset, but is …\nAn Iso8601 that can only be used for parsing. Using this …\nThe format described in RFC 2822.\nThe format described in RFC 3339.\nAn Iso8601 that handles only the time, but is otherwise …\nAn Iso8601 that handles the time and UTC offset, but is …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nThe format described in ISO 8601.\nUse the year-month-day format.\nConfiguration for Iso8601.\nA configuration for the Iso8601 format.\nFormat only the date.\nWhich format to use for the date.\nFormat the date and time.\nFormat the date, time, and UTC offset.\nAn encoded Config that can be used as a const parameter to …\nWhich components to format.\nFormat the hour only. Minutes, seconds, and nanoseconds …\nFormat only the offset hour. Requires the offset minute to …\nThe format described in ISO 8601.\nFormat the hour and minute. Seconds and nanoseconds will …\nFormat both the offset hour and minute.\nThe configuration can only be used for parsing. Using this …\nFormat only the UTC offset.\nThe precision for the UTC offset.\nUse the week-ordinal format.\nFormat the hour, minute, and second. Nanoseconds will be …\nFormat only the time.\nFormat the time and UTC offset.\nThe precision and number of decimal digits present for the …\nUse the year-week-weekday format.\nEncode the configuration, permitting it to be used as a …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nSet the format used for the date.\nSet whether the format the date, time, and/or UTC offset.\nSet the precision for the UTC offset.\nSet the precision and number of decimal digits present for …\nSet whether the format contains separators (such as - or :…\nSet whether the year is six digits.\nA type that describes a format.\nA type that can be parsed.\nAll information parsed.\nObtain the day component.\nReturns the argument unchanged.\nObtain the hour_12 component.\nObtain the hour_12_is_pm component.\nObtain the hour_24 component.\nCalls U::from(self).\nObtain the iso_week_number component.\nObtain the iso_year component.\nObtain the iso_year_last_two component.\nObtain the minute component.\nObtain the monday_week_number component.\nObtain the month component.\nCreate a new instance of Parsed with no information known.\nObtain the offset_hour component.\nObtain the offset_minute component.\nObtain the offset_second component.\nObtain the ordinal component.\nParse a single component, mutating the struct. The …\nParse a single BorrowedFormatItem or OwnedFormatItem, …\nParse a sequence of BorrowedFormatItems or OwnedFormatItem…\nParse a literal byte sequence. The remaining input is …\nObtain the second component.\nSet the set_day component.\nSet the set_hour_12 component.\nSet the set_hour_12_is_pm component.\nSet the set_hour_24 component.\nSet the set_iso_week_number component.\nSet the set_iso_year component.\nSet the set_iso_year_last_two component.\nSet the set_minute component.\nSet the set_monday_week_number component.\nSet the set_month component.\nSet the set_offset_hour component.\nSet the set_offset_minute_signed component.\nSet the set_offset_second_signed component.\nSet the set_ordinal component.\nSet the set_second component.\nSet the set_subsecond component.\nSet the set_sunday_week_number component.\nSet the set_unix_timestamp_nanos component.\nSet the set_weekday component.\nSet the set_year component.\nSet the set_year_last_two component.\nObtain the subsecond component.\nObtain the sunday_week_number component.\nObtain the unix_timestamp_nanos component.\nObtain the weekday component.\nSet the day component and return self.\nSet the hour_12 component and return self.\nSet the hour_12_is_pm component and return self.\nSet the hour_24 component and return self.\nSet the iso_week_number component and return self.\nSet the iso_year component and return self.\nSet the iso_year_last_two component and return self.\nSet the minute component and return self.\nSet the monday_week_number component and return self.\nSet the month component and return self.\nSet the offset_hour component and return self.\nSet the offset_minute component and return self.\nSet the offset_second component and return self.\nSet the ordinal component and return self.\nSet the second component and return self.\nSet the subsecond component and return self.\nSet the sunday_week_number component and return self.\nSet the unix_timestamp_nanos component and return self.\nSet the weekday component and return self.\nSet the year component and return self.\nSet the year_last_two component and return self.\nObtain the year component.\nObtain the year_last_two component.\nGet the number of calendar days in a given year.\nGet the number of days in the month of a given year.\nReturns if the provided year is a leap year in the …\nGet the number of weeks in the ISO year.\nApplication connection config.\nApplication configuration\nService factory configuration.\nHTTP connection information.\nErrors produced by the service.\nErrors produced by the service when polling readiness or …\nErrors produced by the created services.\nA type map for request extensions.\nThe future response value.\nThe future response value.\nThe future of the Service instance.g\nErrors produced while building a transform service.\nErrors potentially raised while building a service.\nFuture that resolves to some T when parsed from a JSON …\nResource path match information.\nA streaming payload.\nExtractor for peer’s socket address.\nStream that reads request line by line.\nDescribes the set of paths that match to a resource.\nAn HTTP response.\nResponses produced by the service.\nResponses given by the service.\nResponses given by the created services.\nGeneral purpose TCP server that runs services receiving …\nServer handle.\nAn asynchronous operation from Request to a Response.\nThe kind of Service created by this factory.\nFactory for creating Services.\nA service level request wrapper.\nA service level response wrapper.\nDefines the interface of a service factory that wraps …\nThe TransformService value created by this factory\nFuture that resolves to some T when parsed from a URL …\nAdds a (possibly nested) resource.\nAdd data container to request’s resolution set.\nAn implementation of poll_ready that always signals …\nCounterpart to HttpRequest::app_config.\nCounterpart to HttpRequest::app_data.\nReturns full path as a string.\nConstructs a new response with status 400 Bad Request.\nReturns a reference to the body of this response.\nCreate server build.\nConstructs a new response builder.\nProcess the request and return the response asynchronously.\nIs to uppercase headers with Camel-Case. Default is false\nCollects dynamic segment values into resource.\nCollects dynamic segment values into resource after …\nGet response body chunking state\nGet response body chunking state\nClear the Extensions of all inserted extensions.\nReturns reference to configuration.\nCounterpart to HttpRequest::conn_data.\nReturns a reference to connection info.\nConnection type\nCheck if map contains an item of a given type.\nReturn request cookie.\nReturn request cookies.\nReturns the default AppConfig. Note: The included socket …\nReturns default handler factory.\nDrops body and returns new response.\nCreate ServiceResponse from this request and given error.\nCreate service response for error\nRequest contains EXPECT header.\nExtends self with the items from another Extensions.\nReturns a reference to the request-local data/extensions …\nReturns a mutable reference to the request-local …\nDerives a type from this request using an extractor.\nTries to match path to this resource, returning the …\nSet a service factory implementation and generate web …\nCreate ServiceFactory for function that can produce …\nCreate ServiceFactory for function that can act as a …\nAn implementation of poll_ready that forwards readiness …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCreate service response from the error\nConstruct decoder based on headers.\nConstruct request from parts.\nConstruct ServiceRequest with no payload from given …\nGet matched parameter by name without type conversion\nGet a reference to an item of a given type.\nReturns mutable reference to inner path instance.\nGet a mutable reference to an item of a given type.\nReturns reference to inner path instance.\nAdd match guard to a web service.\nCreates a context object for use with a routing guard.\nGet a Server handle that can be used issue commands and …\nReturns true if there is a resource that would match path.\nReturns a reference to the head of this response.\nReturns a reference to the request head.\nReturns a mutable reference to the head of this response.\nReturns a mutable reference to the request head.\nReturns a reference to response headers.\nReturns a reference to request headers.\nReturns response’s headers.\nRead the message headers.\nRead the message headers.\nReturns a mutable reference to response headers.\nReturns a mutable reference to request headers.\nReturns mutable response’s headers.\nMutable reference to the message headers.\nMutable reference to the message headers.\nServer host name.\nHostname of the request.\nReturns a numeric resource ID.\nInsert an item into the map.\nConstructs a new response with status 500 Internal Server …\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturns the response body, dropping all other parts.\nConsumes the response and returns its body.\nUnwrap into inner SocketAddr value.\nReturns split head and body.\nDeconstruct ServiceRequest into inner parts.\nDestructures ServiceResponse into request and response …\nCreate ServiceResponse from this request and given …\nCreate service response\nCheck if there are any matched patterns.\nReturns true if path matches this resource.\nReturns true if pattern type is prefix.\nCheck if root is being configured\nReturn iterator to items in parameter container.\nJoins two resources.\nReturns true if keep-alive is enabled.\nCheck if keep-alive is enabled\nSet maximum accepted payload size. The default limit is …\nSet maximum accepted payload size. The default limit is …\nSet maximum accepted payload size. The default limit is …\nDeserializes matching parameters to a specified type U.\nReturns the socket address of the local half of this TCP …\nMap the current body type to another using a closure, …\nMap the current body type to another using a closure. …\nMap the current body to a type-erased BoxBody.\nCounterpart to HttpRequest::match_info.\nReturns a mutable reference to the path match information.\nCounterpart to HttpRequest::match_name.\nReturns the name of the route that matches the given path …\nCounterpart to HttpRequest::match_pattern.\nReturns the full resource pattern matched against a path …\nReturns the request method.\nReturns resource definition name, if set.\nSet service name.\nConstructs a new resource definition from patterns.\nConstructs a new response with default body.\nCreate service response instance\nCreate new WebService instance.\nCreate a new future to decode a URL encoded request …\nCreate a new future to decode a JSON request payload.\nCreate a new stream to read request line by line.\nConstruct a decoder.\nCreates an empty Extensions.\nCreate new instance of ResponseHead type\nCreates a container node in the ResourceMap tree.\nCreate and return a new service asynchronously.\nCreates and returns a new Transform component, …\nSet no chunking for payload\nConstructs a new response with status 404 Not Found.\nConstructs a new response with status 200 OK.\nReturns immutable accessors to inner parts.\nReturns mutable accessors to inner parts.\nReturns path.\nReturns request path.\nReturns the pattern string that generated the resource …\nReturns iterator of pattern strings that generated the …\nPause accepting incoming connections.\nReturns peer’s socket address.\nReturns serialized IP address of the peer connection.\nWill only be None when called in unit tests unless set …\nReturns Ready when the service is able to process requests.\nConstructs a new resource definition using a pattern that …\nReturns matched parameter by name.\nCounterpart to HttpRequest::query_string.\nReal IP (remote address) of client that initiated request.\nGet custom reason for the response\nRegister HTTP service.\nRemove an item from the map of a given type.\nReturns immutable accessor to inner HttpRequest.\nReturns reference to original request.\nReset state.\nReturns a reference to the application’s resource map. …\nAssembles full resource path from iterator of dynamic …\nAssembles resource path from map of dynamic segment values.\nReturns reference to response.\nReturns mutable reference to response.\nResume accepting incoming connections.\nConstructs a new resource definition using a string …\nScheme of the request.\nReturns true if connection is secure (i.e., running over …\nReturns number of interpolated segments.\nSet new path.\nSets new body.\nSet true to send headers which are formatted as Camel-Case.\nSets the flag that controls whether to send headers …\nSet connection type of the message\nSet connection type of the message\nSet numeric resource ID.\nAssigns a new name to the resource.\nSet request payload.\nSkip first n chars in path.\nReturns the status code of this response.\nReturns response status code.\nReturns a mutable reference the status code of this …\nStop incoming connection processing, stop all workers and …\nTakes current payload and replaces it with None value\nReturns unprocessed part of the path.\nReturns true if connection upgrade is enabled.\nConnection upgrade status\nCheck upgrade status of this message\nReturns URI.\nReturns the request URI.\nGenerate URL for named resource.\nReturns the request version.\nConstructs a new response with given body.\nLength as reported by Content-Length header, if present.\nAn error representing a problem running a blocking task on …\nBody streaming error.\nCan not decode chunked transfer encoding.\nContent type error.\nContent type error\nA set of error that can occur during parsing content type.\nContentType error.\nDeserialize error\nDeserialize error\nQuery deserialize error.\nDisconnect timeout. Makes sense for TLS streams.\nA set of errors that can occur during dispatching HTTP …\nEncoding error.\nContent encoding stream corruption.\nPayload size is bigger than allowed. (default: 256kB)\nContains the error value\nGeneral purpose Actix Web error.\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a GONE …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a LOCKED…\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHelper function that wraps any error and generates a …\nHTTP/2 error.\nHandler dropped payload before reading EOF.\nAn invalid Header.\nHTTP/2 payload error.\nA generic “error” for HTTP connections\nA message reached EOF, but is not complete.\nA payload reached EOF, but is not complete.\nWraps errors to alter the generated response status code.\nInternal error.\nAn I/O error that occurred while trying to read or write …\nGeneric I/O error.\nAn io::Error that occurred while trying to read or write …\nA set of errors that can occur during parsing json payloads\nLine limit exceeded.\nAn invalid Method, such as GE.T.\nNot all URL parameters covered.\nContains the success value\nPayload size is larger than allowed. (default limit: …\nPayload size is bigger than allowed but no content length …\nPayload reached size limit.\nPayload size is bigger than allowed & content length …\nParse error.\nRequest parse error.\nA set of errors that can occur during parsing HTTP streams.\nURL parse error.\nCan not parse content type.\nA set of errors that can occur during parsing request paths\nPayload error.\nPayload error\nPayload error.\nA set of errors that can occur during payload parsing.\nA set of errors that can occur during parsing query …\nError type returned when reading body as lines.\nResource not found.\nErrors that can generate responses.\nA convenience Result for Actix Web operations.\nSerialize error.\nSerialize error\nService error.\nThe first request did not complete within the specified …\nAn invalid Status, such as 1337 ELITE.\nA timeout occurred waiting for an IO event.\nA message head is too large to be reasonable.\nUnknown content encoding.\nPayload size is now known.\nPayload length is unknown.\nUpgrade service error.\nAn invalid Uri, such as exam ple.domain.\nErrors which can occur when attempting to generate …\nA set of errors that can occur during parsing urlencoded …\nParsing a field as string failed.\nAn invalid HttpVersion, such as HTP/1.1\nSimilar to as_response_error but downcasts.\nReturns the reference to the underlying ResponseError.\nDowncasts a generic body to a mutable specific type.\nDowncasts generic body to a specific type.\nShortcut for creating an HttpResponse.\nCreates full response for error.\nCreates full response for error.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nConstructs an InternalError with pre-defined response.\nReturn a reference to the lower level, inner error.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturn true if the underlying error has the same type as T.\nConstructs an InternalError with given status code.\nReturns appropriate status code for error.\nReturns appropriate status code for error.\nA guard that verifies that an Accept header is present and …\nCreates a guard that matches if all added guards match.\nA collection of guards that match if the conjunction of …\nCreates a guard that matches if any added guards match.\nA collection of guards that match if the disjunction of …\nCreates a guard that matches the CONNECT request method.\nCreates a guard that matches the DELETE request method.\nCreates a guard that matches the GET request method.\nInterface for routing guards.\nProvides access to request parts that are useful during …\nCreates a guard that matches the HEAD request method.\nCreates a guard that matches if request contains given …\nCreates a guard that matches requests targeting a specific …\nCreates a guard that matches a specified HTTP method.\nWraps a guard and inverts the outcome of its Guard …\nCreates a guard that matches the OPTIONS request method.\nCreates a guard that matches the PATCH request method.\nCreates a guard that matches the POST request method.\nCreates a guard that matches the PUT request method.\nCreates a guard that matches the TRACE request method.\nAdds new guard to the collection of guards to check.\nReturns true if predicate condition is met for a given …\nCreates a guard using the given function.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns reference to the request head.\nExtracts a typed header from the request.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nAllows */* in the Accept header to pass the guard check.\nConstructs new Acceptable guard with the given mime …\nAdds new guard to the collection of guards to check.\nReturns reference to the request-local data/extensions …\nReturns mutable reference to the request-local …\n202 Accepted [RFC7231, Section 6.3.3]\n208 Already Reported [RFC5842]\n502 Bad Gateway [RFC7231, Section 6.6.3]\n400 Bad Request [RFC7231, Section 6.5.1]\n409 Conflict [RFC7231, Section 6.5.8]\nCONNECT\n100 Continue [RFC7231, Section 6.2.1]\n201 Created [RFC7231, Section 6.3.2]\nClose connection after response.\nRepresents various types of connection\nDELETE\nKeep-alive is disabled.\n417 Expectation Failed [RFC7231, Section 6.5.14]\n424 Failed Dependency [RFC4918]\n403 Forbidden [RFC7231, Section 6.5.3]\n302 Found [RFC7231, Section 6.4.3]\n504 Gateway Timeout [RFC7231, Section 6.6.5]\nGET\n410 Gone [RFC7231, Section 6.5.9]\nHEAD\nHTTP/0.9\nHTTP/1.0\nHTTP/1.1\nHTTP/2.0\nHTTP/3.0\n505 HTTP Version Not Supported [RFC7231, Section 6.6.6]\n418 I’m a teapot [curiously not registered by IANA but …\n226 IM Used [RFC3229]\n507 Insufficient Storage [RFC4918]\n500 Internal Server Error [RFC7231, Section 6.6.1]\nConnection keep-alive config.\nKeep connection alive after response.\n411 Length Required [RFC7231, Section 6.5.10]\n423 Locked [RFC4918]\n508 Loop Detected [RFC5842]\n405 Method Not Allowed [RFC7231, Section 6.5.5]\n421 Misdirected Request RFC7540, Section 9.1.2\n301 Moved Permanently [RFC7231, Section 6.4.2]\n300 Multiple Choices [RFC7231, Section 6.4.1]\n207 Multi-Status [RFC4918]\nThe Request Method (VERB)\n511 Network Authentication Required [RFC6585]\n203 Non-Authoritative Information [RFC7231, Section 6.3.4]\n406 Not Acceptable [RFC7231, Section 6.5.6]\n510 Not Extended [RFC2774]\n404 Not Found [RFC7231, Section 6.5.4]\n501 Not Implemented [RFC7231, Section 6.6.2]\n304 Not Modified [RFC7232, Section 4.1]\n204 No Content [RFC7231, Section 6.3.5]\n200 OK [RFC7231, Section 6.3.1]\nOPTIONS\nRely on OS to shutdown TCP connection.\n206 Partial Content [RFC7233, Section 4.1]\nPATCH\n413 Payload Too Large [RFC7231, Section 6.5.11]\n402 Payment Required [RFC7231, Section 6.5.2]\n308 Permanent Redirect [RFC7238]\nPOST\n412 Precondition Failed [RFC7232, Section 4.2]\n428 Precondition Required [RFC6585]\n102 Processing [RFC2518]\n407 Proxy Authentication Required [RFC7235, Section 3.2]\nPUT\n416 Range Not Satisfiable [RFC7233, Section 4.4]\n431 Request Header Fields Too Large [RFC6585]\n408 Request Timeout [RFC7231, Section 6.5.7]\n205 Reset Content [RFC7231, Section 6.3.6]\n303 See Other [RFC7231, Section 6.4.4]\n503 Service Unavailable [RFC7231, Section 6.6.4]\n101 Switching Protocols [RFC7231, Section 6.2.2]\nAn HTTP status code (status-code in RFC 7230 et al.).\n307 Temporary Redirect [RFC7231, Section 6.4.7]\n429 Too Many Requests [RFC6585]\nTRACE\nKeep-alive duration.\n401 Unauthorized [RFC7235, Section 3.1]\n451 Unavailable For Legal Reasons [RFC7725]\n422 Unprocessable Entity [RFC4918]\n415 Unsupported Media Type [RFC7231, Section 6.5.13]\n426 Upgrade Required [RFC7231, Section 6.5.15]\n414 URI Too Long [RFC7231, Section 6.5.12]\n305 Use Proxy [RFC7231, Section 6.4.5]\nConnection is upgraded to different type.\nThe URI component of a request.\n506 Variant Also Negotiates [RFC2295]\nRepresents a version of the HTTP spec.\nReturn a &str representation of the HTTP method\nReturns a &str representation of the StatusCode\nReturns the u16 corresponding to this StatusCode.\nGet the authority of this Uri.\nCreates a new builder-style object to manufacture a Uri.\nGet the standardised reason-phrase for this status code.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nConverts a slice of bytes to an HTTP method.\nConverts a &u8 to a status code\nAttempt to convert a Bytes buffer to a Uri.\nAttempt to convert a Parts into a Uri.\nConvert a Uri from a static string.\nConverts a u16 to a status code.\nA Collection of Header implementations for common HTTP …\nGet the host of this Uri.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nConvert a Uri into Parts.\nCheck if status is within 400-499.\nWhether a method is considered “idempotent”, meaning …\nCheck if status is within 100-199.\nCheck if status is within 300-399.\nWhether a method is considered “safe”, meaning the …\nCheck if status is within 500-599.\nCheck if status is within 200-299.\nGet the path of this Uri.\nReturns the path & query components of the Uri\nGet the port part of this Uri.\nGet the port of this Uri as a u16.\nGet the query string of this Uri, starting after the ?.\nGet the scheme of this Uri.\nGet the scheme of this Uri as a &str.\nURI component of request and response lines\nAdvertises which content types the client is able to …\nAdvertises which character set the client is able to …\nAdvertises which content encoding the client is able to …\nAdvertises which languages the client is able to …\nMarker used by the server to advertise partial request …\nPreflight response indicating if the response to the …\nPreflight response indicating permitted HTTP headers.\nPreflight header response indicating permitted access …\nIndicates whether the response can be shared with …\nIndicates which headers can be exposed as part of the …\nIndicates how long the results of a preflight request can …\nInforms the server which HTTP headers will be used when an …\nInforms the server know which HTTP method will be used …\nIndicates the time in seconds the object has been in a …\nLists the set of methods support by a resource.\nAdvertises the availability of alternate services to …\nContains the credentials to authenticate a user agent with …\nAccept header, defined in RFC 7231 §5.3.2.\nAccept-Charset header, defined in RFC 7231 §5.3.3.\nAccept-Encoding header, defined in RFC 7231\nAccept-Language header, defined in RFC 7231 §5.3.5\nAllow header, defined in RFC 7231 §7.4.1\nAny value is a match\nAny value is a match\nA wildcard value.\nSealed trait implemented for types that can be effectively …\nAttachment implies that the recipient should prompt the …\nBig5\nA format using the Brotli algorithm.\nA range of bytes to fetch.\nByte range\nByte range.\nSpecifies directives for caching mechanisms in both …\nResponse header field that indicates how caches have …\nResponse header field that allows origin servers to …\nControls whether or not the network connection stays open …\nIndicates if the content is expected to be displayed …\nUsed to compress the media-type.\nUsed to describe the languages intended for the audience.\nIndicates the size of the entity-body.\nIndicates an alternate location for the returned data.\nIndicates where in a full body message a partial message …\nAllows controlling resources the user agent is allowed to …\nAllows experimenting with policies by monitoring their …\nUsed to indicate the media type of the resource.\nContains stored HTTP cookies previously sent by the server …\nResponse header that prevents a document from loading any …\nResponse header that allows you to ensure a top-level …\nResponse header that conveys a desire that the browser …\nCache-Control header, defined in RFC 7234 §5.2.\nCacheControl contains a list of these directives.\nA MIME character set.\nA Content-Disposition header. It is compatible to be used …\nRepresents a supported content encoding.\nContent-Language header, defined in RFC 7231 §3.1.3.2\nContent-Length header, defined in RFC 9110 §8.6.\nContent-Range header, defined in RFC 7233 §4.2\nContent-Range header, defined in RFC 7233 §4.2\nContent-Type header, defined in RFC 9110 §8.3.\nContains the date and time at which the message was …\nIndicates the client’s tracking preference.\nDate header, defined in RFC 7231 §7.1.1.2\nThe date when the client retrieved the resource.\nA format using the zlib structure with deflate algorithm.\nParameter in ContentDisposition.\nThe implied disposition of the content of the HTTP body.\nIdentifier for a specific version of a resource.\nETag header, defined in RFC 7232 §2.3\nIndicates expectations that need to be fulfilled by the …\nContains the date/time after which the response is …\nA value to represent an encoding used in the …\nAn entity tag, defined in [RFC 7232 §2.3].\nThe entity-tag the client has of the resource.\nThe type returned in the event of a conversion error.\nEUC-JP\nEUC-KR\nExpires header, defined in RFC 7234 §5.3\nAn arbitrary charset specified as a string\nExtension type. Should be handled by recipients the same …\nThe value part of an extended parameter consisting of …\nExtension directives. Optionally include an argument.\nContains information from the client-facing side of proxy …\nContains an Internet email address for a human user who …\nA plain file name.\nAn extended file name. It must not exist for …\nUsed in multipart/form-data as defined in RFC 7578 to …\nAll bytes starting from x, inclusive.\nAll bytes from x to y, inclusive.\nGB2312\nGzip algorithm.\nSpecifies the domain name of the server and (optionally) …\nAn interface for types that already represent a valid …\nA multi-map of HTTP headers.\nRepresents an HTTP header field name\nRepresents an HTTP header field value.\nA timestamp with HTTP-style formatting and parsing.\nMakes a request conditional based on the E-Tag.\nMakes a request conditional based on the modification date.\nMakes a request conditional based on the E-Tag.\nMakes a request conditional based on range.\nMakes the request conditional based on the last …\nIndicates the no-op identity encoding.\nIf-Match header, defined in RFC 7232 §3.1\nIf-Modified-Since header, defined in RFC 7232 §3.3\nIf-None-Match header, defined in RFC 7232 §3.2\nIf-Range header, defined in RFC 7233 §3.2\nIf-Unmodified-Since header, defined in RFC 7232 §3.4\nInline implies default processing.\nA possible error when converting a HeaderName from another …\nA possible error when converting a HeaderValue from a …\nISO-2022-JP\nISO-2022-JP-2\nISO-2022-KR\nISO-8859-1\nISO-8859-10\nISO-8859-2\nISO-8859-3\nISO-8859-4\nISO-8859-5\nISO-8859-6\nISO-8859-6-E\nISO-8859-6-I\nISO-8859-7\nISO-8859-8\nISO-8859-8-E\nISO-8859-8-I\nISO-8859-9\nOnly the listed items are a match\nOnly the listed items are a match\nA supported content encoding. See ContentEncoding for …\nKOI8-R\nContent-Types that are acceptable for the response.\nAllows the server to point an interested client to another …\nIndicates the URL to redirect a page to.\nA language tag as described in RFC 5646.\nThe last y bytes, inclusive.\nLast-Modified header, defined in RFC 7232 §2.2\nThe maximum quality value, equivalent to q=1.0.\nIndicates the max number of intermediaries the request …\nThe minimum, non-zero quality value, equivalent to q=0.001.\n“max-age=delta”\n“max-stale=delta”\n“min-fresh=delta”\n“must-revalidate”\nFor DispositionType::FormData (i.e. multipart/form-data), …\n“no-cache”\n“no-store”\n“no-transform”\nIndicates where a fetch originates from.\n“only-if-cached”\nResponse header that provides a mechanism to allow and …\nHTTP/1.0 header usually used for backwards compatibility.\nDefines the authentication method that should be used to …\nContains the credentials to authenticate a user agent to a …\nAssociates a specific cryptographic public key with a …\nSends reports of pinning violation to the report-uri …\nA wrapper for types used in header values where wildcard (*…\n“private”\n“proxy-revalidate”\n“public”\nRepresents a quality used in q-factor values.\nRepresents an item with a quality value as defined in RFC …\nIndicates the part of a document that the server should …\nContains the address of the previous web page from which a …\nGoverns which referrer information should be included with …\nInforms the web browser that the current page or frame …\nThe Retry-After response HTTP header indicates how long …\nRange header, defined in RFC 7233 §3.1\nThe |Sec-WebSocket-Accept| header field is used in the …\nThe |Sec-WebSocket-Extensions| header field is used in the …\nThe |Sec-WebSocket-Key| header field is used in the …\nThe |Sec-WebSocket-Protocol| header field is used in the …\nThe |Sec-WebSocket-Version| header field is used in the …\nContains information about the software used by the origin …\nUsed to send cookies from the server to the user agent.\n“s-maxage=delta”\nTells the client to communicate with HTTPS instead of …\nShift_JIS\nA valid T.\nInforms the server of transfer encodings willing to be …\nAllows the sender to include additional fields at the end …\nSpecifies the form of encoding used to safely transfer the …\nA possible error when converting a HeaderValue to a string …\nAn interface for types that can be converted into a …\nAn interface for types that can be converted into a …\nUsed as part of the exchange to upgrade the protocol.\nSends a signal to the server expressing the client’s …\nContains a string that allows identifying the requesting …\nAn unrecognized regular parameter as defined in RFC 5987 …\nSome other encoding that is less common, can be any string.\nAn unrecognized extended parameter as defined in RFC 5987 …\nCustom range, with unit not registered at IANA\nCustom range, with unit not registered at IANA.\nUS ASCII\nDetermines how to match future requests with cached …\nAdded by proxies to track routing.\nGeneral HTTP header contains information about possible …\nDefines the authentication method that should be used to …\nMarker used by the server to indicate that the MIME types …\nControls DNS prefetching.\nRequest header (de-facto standard) for identifying the …\nRequest header (de-facto standard) for identifying the …\nRequest header (de-facto standard) for identifying the …\nIndicates whether or not a browser should be allowed to …\nStop pages from loading when an XSS attack is detected.\nThe zero quality value, equivalent to q=0.0.\nZstd algorithm.\nAppends a name-value pair to the map.\nConverts a HeaderValue to a byte slice.\nReturns the filename if applicable.\nReturns the filename* if applicable.\nReturns the name if applicable.\nReturn the serialization of this language tag.\nReturns a str representation of the header.\nConvert content encoding to string.\nReturns the value of the unrecognized regular parameter if …\nReturns the value of the unrecognized extended parameter …\nConstructs a Content-Disposition header suitable for …\nConstructs a common byte range header.\nConstructs a byte range header with multiple subranges.\nReturns the canonical version of the language tag following\nReturns the number of single-value headers the map can …\nThe character set that is used to encode the value to a …\nClears the map, removing all name-value pairs.\nReturns true if the map contains a value for the specified …\nThe disposition type\nClears the map, returning all name-value sets as an …\nPerforms a case-insensitive comparison of the string …\nPerforms a case-insensitive comparison of the string …\nReturn the extended language subtags.\nIterate on the extended language subtags.\nReturn the extension subtags.\nIterate on the extension subtags.\nFormat an array into a comma-delimited string.\nConstructs a Content-Type: application/www-form-url-encoded…\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nConverts a slice of bytes to an HTTP header name.\nAttempt to convert a byte slice to a HeaderValue.\nReads a comma-delimited raw header into a Vec.\nConverts a slice of bytes to an HTTP header name.\nAttempt to convert a Bytes buffer to a HeaderValue.\nConvert a Bytes directly into a HeaderValue without …\nConverts a HeaderName into a HeaderValue\nReads a single string when parsing a header.\nParse a raw Content-Disposition header value.\nConverts a static string to a HTTP header name.\nConvert a static string to a HeaderValue.\nAttempt to convert a string to a HeaderValue.\nReturn the primary language subtag and its extended …\nReturns a reference to the first value associated with a …\nReturns an iterator over all values associated with a …\nReturn the value of filename if exists.\nReturn the value of filename* if exists.\nReturns a mutable reference to the first value associated …\nReturn the value of name if exists.\nReturn the value of the parameter which the name matches.\nReturn the value of the extended parameter which the name …\nConstruct Accept: text/html.\nConstructs a Content-Type: text/html; charset=utf-8 header.\nPercent encode a sequence of bytes with a character set …\nConstruct Accept: image/*.\nInserts (overrides) a name-value pair in the map.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturns Content-Length value.\nConsumes the container, returning the value in the Specific…\nReturn the serialization of this language tag.\nReturns true if preference is the any/wildcard (*) value.\nReturns true if type is Attachment.\nReturns true if the HeaderValue has a length of zero bytes.\nReturns true if the map contains no elements.\nReturns true if type is Ext and the disp_type matches.\nReturns true if the parameter is Filename.\nReturns true if the parameter is FilenameExt.\nReturns true if type is FormData.\nReturns true if type is Inline.\nChecks if it is a language range, meaning that there are …\nReturns true if the parameter is Name.\nReturns true if the value represents sensitive data.\nReturns true if preference is the specific item (T) …\nReturns true if the parameter is Unknown and the name …\nReturns true if the parameter is UnknownExt and the name …\nCheck if the language tag is valid according to RFC 5646.\nReturns reference to value in Specific variant, if it is …\nThe wrapped contents of the field.\nAn iterator over all name-value pairs.\nConstructs a Content-Type: image/jpeg header.\nConstruct Accept: application/json.\nConstructs a Content-Type: application/json header.\nAn iterator over all contained header names.\nThe human language details of the value, if available.\nReturns the length of self.\nReturns the number of values stored in the map.\nReturns the number of keys stored in the map.\nA multi-value HeaderMap and its iterators.\nMatches language tags. The first language acts as a …\nConstructs a new QualityItem from an item, using the …\nConstructs a new QualityItem from an item, using the …\nReturns the name of the header field.\nSelects the most acceptable encoding according to client …\nCreate an empty HeaderMap.\nConstructs a new QualityItem from an item and a quality …\nConstructs a new EntityTag.\nConstructs a new strong EntityTag.\nConstructs a new weak EntityTag.\nCreate a date instance set to the current system time\nConstructs a Content-Type: application/octet-stream header.\nDisposition parameters\nParse the header from a HTTP message.\nCreate a LanguageTag from its serialization.\nParses extended header parameter values (ext-value), as …\nConstructs a Content-Type: text/plain; charset=utf-8 …\nConstructs a Content-Type: image/png header.\nExtracts the most preferable mime type, accounting for …\nExtracts the most preferable encoding, accounting for …\nExtracts the most preferable language, accounting for …\nReturn the primary language subtag.\nReturn the private use subtags.\nIterate on the private use subtags.\nConvenience function to create a Quality from an f32 …\nThe quality (client or server preference) for the value.\nReturns a sorted list of mime types from highest to lowest …\nReturns a sorted list of encodings from highest to lowest …\nReturns a sorted list of languages from highest to lowest …\nReturn the region subtag.\nRemoves all headers for a particular header name from the …\nReserves capacity for at least additional more headers to …\nRetains only the headers specified by the predicate.\nReturn the script subtag.\nMark that the header value represents sensitive …\nSets tag.\nConstruct Accept: */*.\nFor strong comparison two entity-tags are equivalent if …\nReturns the inverse of strong_eq().\nReturns tag.\nConstruct Accept: text/*.\nConvert content encoding to header value.\nGiven the full length of the entity, attempt to normalize …\nYields a &str slice if the HeaderValue only contains …\nTry to convert value to a HeaderValue.\nCheck if the language tag is “valid” according to RFC …\nThe parameter value, as expressed in octets.\nReturn the variant subtags.\nIterate on the variant subtags.\nWeakness indicator for the tag\nFor weak comparison two entity-tags are equivalent if …\nReturns inverse of weak_eq().\nCreate an empty HeaderMap with the specified capacity.\nConstructs a Content-Type: text/xml header.\nConstructs a new QualityItem from an item, using zero …\nTotal length of the instance, can be omitted if unknown\nFirst and last bytes of the range, omitted if request …\nother-range-resp\nother-range-unit\nIterator over drained name-value pairs.\nA multi-map of HTTP headers.\nIterator over owned name-value pairs.\nIterator over borrowed name-value pairs.\nIterator over all names in the map.\nIterator over removed, owned values with the same …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturns true if iterator contains no elements, without …\nRepresents the authority component of a URI.\nA builder for Uris.\nHTTP protocol scheme\nHTTP protocol over TLS.\nAn error resulting from a failed attempt to construct a …\nAn error resulting from a failed attempt to construct a …\nThe various parts of a URI.\nRepresents the path component of a URI\nThe port component of a URI.\nRepresents the scheme component of a URI\nThe URI component of a request.\nReturns the port number as a str.\nReturn a str representation of the authority\nReturns the path and query as a string component.\nReturn a str representation of the scheme\nReturns the port number as a u16.\nSet the Authority for this URI.\nThe authority component of a URI\nConsumes this builder, and tries to construct a valid Uri …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nAttempt to convert a Bytes buffer to a Authority.\nAttempt to convert a Bytes buffer to a PathAndQuery.\nAttempt to convert an Authority from a static string.\nConvert a PathAndQuery from a static string.\nGet the host of this Authority.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCreates a new default instance of Builder to construct a …\nReturns the path component\nSet the PathAndQuery for this URI.\nThe origin-form component of a URI\nGet the port part of this Authority.\nGet the port of this Authority as a u16.\nReturns the query string component\nSet the Scheme for this URI.\nThe scheme component of a URI\nAlways add a trailing slash to the end of the path.\nMiddleware for enabling any middleware to be used in …\nMiddleware for compressing response payloads.\nMiddleware for conditionally enabling other middleware.\nMiddleware for setting default response headers.\nReturn type for ErrorHandlers custom handlers.\nMiddleware for registering custom status code based error …\nA future that resolves to an HTTP response.\nMiddleware for logging request and response summaries to …\nOnly merge any present multiple trailing slashes.\nMiddleware for normalizing a request’s path so that …\nImmediate HTTP response.\nDetermines the behavior of the NormalizePath middleware.\nTrim trailing slashes from the end of the path.\nAdds a header to the default set.\nAdds a default Content-Type header if response does not …\nRegister a function that receives a ServiceRequest and …\nRegister a function that receives a ServiceResponse and …\nCreate Logger middleware with format:\nRegister a default error handler.\nRegister a handler on which to fall back for client error …\nRegister a handler on which to fall back for server error …\nIgnore and do not log access info for specified path.\nIgnore and do not log access info for paths that match …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nRegister error handler for specified status code.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nSets the logging target to target.\nWrap a middleware to give it broader compatibility.\nConstruct new ErrorHandlers instance.\nConstructs an empty DefaultHeaders middleware.\nCreate Logger middleware with the specified format.\nCreate new NormalizePath middleware with the specified …\nConstructs a new NormalizePath middleware with trim …\nA Tokio-based runtime proxy.\nA manager for a per-thread distributed async runtime.\nRunner that keeps a System’s event loop alive until stop …\nGet handle to a the System’s initial Arbiter.\nRuns the provided future, blocking the current thread …\nRuns the provided future, blocking the current thread …\nGet current running system.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nNumeric system identifier.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCheck if there is a System registered on the current …\nTCP/UDP/Unix bindings (mostly Tokio re-exports).\nReturns a new runtime initialized with default …\nCreate a new system.\nPins a value on the stack.\nStarts event loop and will return once System is stopped.\nRuns the event loop until stopped, returning the exit code.\nAsynchronous signal handling (Tokio re-exports).\nSpawns a future on the current thread as a new task.\nOffload a future onto the single-threaded runtime.\nStop the system (with code 0).\nStop the system with a given exit code.\nTask management (Tokio re-exports).\nUtilities for tracking time (Tokio re-exports).\nRetrieves a reference to the underlying Tokio runtime …\nTry to get current running system.\nReturns a Ready representing readiness for all operations.\nReturns the empty Ready set.\nReturns a Ready representing error readiness.\nReturns a Ready representing priority readiness.\nReturns a Ready representing readable readiness.\nReturns a Ready representing read closed readiness.\nDescribes the readiness state of an I/O resources.\nA TCP socket server, listening for connections.\nA TCP socket that has not yet been converted to a TcpStream…\nA TCP stream between a local and a remote socket.\nA UDP socket.\nAn I/O object representing a Unix datagram socket.\nA Unix socket which can accept connections from other Unix …\nA structure representing a connected Unix socket.\nReturns a Ready representing writable readiness.\nReturns a Ready representing write closed readiness.\nAccepts a new incoming connection from this listener.\nAccepts a new incoming connection to this listener.\nReads or writes from the socket using a user-provided IO …\nReads or writes from the socket using a user-provided IO …\nReads or writes from the socket using a user-provided IO …\nReads or writes from the socket using a user-provided IO …\nCreates a new TcpListener, which will be bound to the …\nBinds the socket to the given address.\nThis function will create a new UDP socket and attempt to …\nCreates a new UnixDatagram bound to the specified path.\nCreates a new UnixListener bound to the specified path.\nSets the value for the SO_BINDTODEVICE option on this …\nSets the value for the SO_BINDTODEVICE option on this …\nGets the value of the SO_BROADCAST option for this socket.\nEstablishes a TCP connection with a peer at the specified …\nOpens a TCP connection to a remote host.\nConnects the UDP socket setting the default destination …\nConnects the socket to the specified address.\nConnects to the socket named by path.\nGets the value for the SO_BINDTODEVICE option on this …\nGets the value for the SO_BINDTODEVICE option on this …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nConverts a RawFd to a TcpSocket.\nCreates new TcpListener from a std::net::TcpListener.\nCreates new TcpStream from a std::net::TcpStream.\nCreates new UdpSocket from a previously bound …\nCreates new UnixDatagram from a …\nCreates new UnixListener from a …\nCreates new UnixStream from a …\nConverts a std::net::TcpStream into a TcpSocket. The …\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nSplits a TcpStream into a read half and a write half, …\nSplits a UnixStream into a read half and a write half, …\nTurns a tokio::net::TcpListener into a …\nTurns a tokio::net::TcpStream into a std::net::TcpStream.\nTurns a tokio::net::UdpSocket into a std::net::UdpSocket.\nTurns a tokio::net::UnixDatagram into a …\nTurns a tokio::net::UnixListener into a …\nTurns a tokio::net::UnixStream into a …\nReturns true if Ready is the empty set.\nReturns true if the value includes error readiness.\nReturns true if the value includes priority readiness.\nReturns true if the value includes read-closed readiness.\nReturns true if the value includes readable.\nReturns true if the value includes writable readiness.\nReturns true if the value includes write-closed readiness.\nExecutes an operation of the IP_ADD_MEMBERSHIP type.\nExecutes an operation of the IPV6_ADD_MEMBERSHIP type.\nGets the value of the SO_KEEPALIVE option on this socket.\nExecutes an operation of the IP_DROP_MEMBERSHIP type.\nExecutes an operation of the IPV6_DROP_MEMBERSHIP type.\nReads the linger duration for this socket by getting the …\nReads the linger duration for this socket by getting the …\nConverts the socket into a TcpListener.\nReturns the local address that this listener is bound to.\nGets the local address of this socket.\nReturns the local address that this stream is bound to.\nReturns the local address that this socket is bound to.\nReturns the local address that this socket is bound to.\nReturns the local socket address of this listener.\nReturns the socket address of the local half of this …\nGets the value of the IP_MULTICAST_LOOP option for this …\nGets the value of the IPV6_MULTICAST_LOOP option for this …\nGets the value of the IP_MULTICAST_TTL option for this …\nCreates a new socket configured for IPv4.\nCreates a new socket configured for IPv6.\nGets the value of the TCP_NODELAY option on this socket.\nGets the value of the TCP_NODELAY option on this socket.\nCreates an unnamed pair of connected sockets.\nCreates an unnamed pair of connected sockets.\nReceives data on the socket from the remote address to …\nReceives data from the socket, without removing it from …\nRetrieve the sender of the data at the head of the input …\nReturns the remote address that this stream is connected …\nReturns the socket address of the remote peer this socket …\nReturns the address of this socket’s peer.\nReturns the socket address of the remote half of this …\nReturns effective credentials of the process which called …\nPolls to accept a new incoming connection to this listener.\nPolls to accept a new incoming connection to this listener.\nAttempts to receive data on the socket, without removing …\nReceives data from the socket, without removing it from …\nRetrieve the sender of the data at the head of the input …\nPolls for read readiness.\nPolls for read readiness.\nAttempts to receive a single datagram message on the …\nAttempts to receive a single datagram message on the …\nAttempts to receive a single datagram on the socket.\nAttempts to receive a single datagram on the specified …\nPolls for read/receive readiness.\nPolls for read/receive readiness.\nAttempts to send data on the socket to the remote address …\nAttempts to send data on the socket to the remote address …\nPolls for write/send readiness.\nPolls for write/send readiness.\nAttempts to send data on the socket to a given address.\nAttempts to send data to the specified address.\nPolls for write readiness.\nPolls for write readiness.\nWaits for the socket to become readable.\nWaits for the socket to become readable.\nWaits for the socket to become readable.\nWaits for the socket to become readable.\nWaits for any of the requested ready states.\nWaits for any of the requested ready states.\nWaits for any of the requested ready states.\nWaits for any of the requested ready states.\nReceives a single datagram message on the socket from the …\nReceives data from the socket.\nReceives a single datagram message on the socket from the …\nReceives data from the socket from the address to which it …\nReceives a single datagram message on the socket, …\nReceives from the socket, advances the buffer’s internal …\nReturns the size of the TCP receive buffer for this socket.\nReceives a single datagram message on the socket. On …\nReceives data from the socket.\nRetrieves the value set for SO_REUSEADDR on this socket.\nAllows the socket to bind to an in-use port. Only …\nSends data on the socket to the remote address that the …\nSends data on the socket to the socket’s peer.\nReturns the size of the TCP send buffer for this socket.\nSends data on the socket to the given address. On success, …\nSends data on the socket to the specified address.\nSets the value of the SO_BROADCAST option for this socket.\nSets value for the SO_KEEPALIVE option on this socket.\nSets the linger duration of this socket by setting the …\nSets the linger duration of this socket by setting the …\nSets the value of the IP_MULTICAST_LOOP option for this …\nSets the value of the IPV6_MULTICAST_LOOP option for this …\nSets the value of the IP_MULTICAST_TTL option for this …\nSets the value of the TCP_NODELAY option on this socket.\nSets the value of the TCP_NODELAY option on this socket.\nSets the size of the TCP receive buffer on this socket.\nAllows the socket to bind to an in-use address.\nAllows the socket to bind to an in-use port. Only …\nSets the size of the TCP send buffer on this socket.\nSets the value for the IP_TOS option on this socket.\nSets the value for the IP_TOS option on this socket.\nSets the value for the IP_TTL option on this socket.\nSets the value for the IP_TTL option on this socket.\nSets the value for the IP_TTL option on this socket.\nShuts down the read, write, or both halves of this …\nSplits a TcpStream into a read half and a write half, …\nSplits a UnixStream into a read half and a write half, …\nReturns the value of the SO_ERROR option.\nReturns the value of the SO_ERROR option.\nReturns the value of the SO_ERROR option.\nReturns the value of the SO_ERROR option.\nReturns the value of the SO_ERROR option.\nReturns the value of the SO_ERROR option.\nGets the value of the IP_TOS option for this socket.\nGets the value of the IP_TOS option for this socket.\nConsumes stream, returning the tokio I/O object.\nConsumes stream, returning the tokio I/O object.\nConsumes stream, returning the tokio I/O object.\nConsumes stream, returning the Tokio I/O object.\nConsumes stream, returning the tokio I/O object.\nConsumes stream, returning the tokio I/O object.\nTries to read or write from the socket using a …\nTries to read or write from the socket using a …\nTries to read or write from the socket using a …\nTries to read or write from the socket using a …\nTries to receive data on the socket without removing it …\nTry to retrieve the sender of the data at the head of the …\nTries to read data from the stream into the provided …\nTry to read data from the stream into the provided buffer, …\nTries to read data from the stream into the provided …\nTries to read data from the stream into the provided …\nTries to read data from the stream into the provided …\nTries to read data from the stream into the provided …\nTries to receive a single datagram message on the socket …\nTries to receive a datagram from the peer without waiting.\nTries to receive data from the stream into the provided …\nTries to read data from the stream into the provided …\nTries to receive a single datagram message on the socket. …\nTries to receive data from the socket without waiting.\nTries to receive a single datagram message on the socket. …\nTries to receive data from the socket without waiting.\nTries to send data on the socket to the remote address to …\nTries to send a datagram to the peer without waiting.\nTries to send data on the socket to the given address, but …\nTries to send a datagram to the peer without waiting.\nTry to write a buffer to the stream, returning how many …\nTries to write a buffer to the stream, returning how many …\nTries to write several buffers to the stream, returning …\nTries to write several buffers to the stream, returning …\nGets the value of the IP_TTL option for this socket.\nGets the value of the IP_TTL option for this socket.\nGets the value of the IP_TTL option for this socket.\nCreates a new UnixDatagram which is not bound to any …\nWaits for the socket to become writable.\nWaits for the socket to become writable.\nWaits for the socket to become writable.\nWaits for the socket to become writable.\nCompletes when a “ctrl-c” notification is sent to the …\nUnix specific signals (Tokio re-exports).\nAn listener for receiving a particular type of OS signal.\nRepresents the specific kind of signal to listen for.\nRepresents the SIGALRM signal.\nGet the signal’s numeric value.\nRepresents the SIGCHLD signal.\nReturns the argument unchanged.\nReturns the argument unchanged.\nAllows for listening to any valid OS signal.\nRepresents the SIGHUP signal.\nRepresents the SIGINT signal.\nCalls U::from(self).\nCalls U::from(self).\nRepresents the SIGIO signal.\nRepresents the SIGPIPE signal.\nPolls to receive the next signal notification event, …\nRepresents the SIGQUIT signal.\nReceives the next signal notification event.\nCreates a new listener which will receive notifications …\nRepresents the SIGTERM signal.\nRepresents the SIGUSR1 signal.\nRepresents the SIGUSR2 signal.\nRepresents the SIGWINCH signal.\nTask failed to execute to completion.\nAn owned permission to join on a task (await its …\nAbort the task associated with the handle.\nReturns a new AbortHandle that can be used to remotely …\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nConsumes the join error, returning the object with which …\nReturns true if the error was caused by the task being …\nChecks if the task associated with this JoinHandle has …\nReturns true if the error was caused by the task panicking.\nRuns the provided closure on a thread where blocking is …\nConsumes the join error, returning the object with which …\nYields execution back to the Tokio runtime.\nA measurement of a monotonically nondecreasing clock. …\nInterval returned by interval and interval_at.\nFuture returned by sleep and sleep_until.\nFuture returned by timeout and timeout_at.\nReturns Some(t) where t is the time self + duration if t …\nReturns the amount of time elapsed from another instant to …\nReturns Some(t) where t is the time self - duration if t …\nReturns the instant at which the future will complete.\nReturns the amount of time elapsed from another instant to …\nReturns the amount of time elapsed since this instant was …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCreate a tokio::time::Instant from a std::time::Instant.\nGets a mutable reference to the underlying value in this …\nGets a reference to the underlying value in this timeout.\nCreates new Interval that yields with interval of period. …\nCreates new Interval that yields with interval of period …\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nConsumes this timeout, returning the underlying value.\nConvert the value into a std::time::Instant.\nReturns true if Sleep has elapsed.\nReturns the MissedTickBehavior strategy currently being …\nReturns an instant corresponding to “now”.\nReturns the period of the interval.\nPolls for the next instant in the interval to be reached.\nResets the interval to complete one period after the …\nResets the Sleep instance to a new deadline.\nResets the interval after the specified std::time::Duration…\nResets the interval to a crate::time::Instant deadline.\nResets the interval immediately.\nReturns the amount of time elapsed from another instant to …\nSets the MissedTickBehavior strategy that should be used.\nWaits until duration has elapsed.\nWaits until deadline is reached.\nCompletes when the next instant in the interval has been …\nRequires a Future to complete before the specified …\nAsync I/O test buffer.\nTest Request builder.\nInserts application data.\nAppends a header, keeping any that were set with an …\nHelper function that returns a response body of a …\nHelper function that returns a deserialized response body …\nCalls service and waits for response future completion.\nSets cookie for this request.\nConstructs test request with DELETE method.\nCreate new empty TestBuffer instance.\nAdd data to read buffer.\nReturns the argument unchanged.\nReturns the argument unchanged.\nConstructs test request with GET method.\nInitialize service from application builder instance.\nInserts a header, replacing any that were set with an …\nCalls U::from(self).\nCalls U::from(self).\nSets method of this request.\nCreate new TestBuffer instance with initial read buffer.\nCreates service that always responds with 200 OK and no …\nSets request path pattern parameter.\nConstructs test request with PATCH method.\nSets peer address.\nConstructs test request with POST method.\nConstructs test request with PUT method.\nHelper function that returns a response body of a …\nHelper function that returns a deserialized response body …\nFinalizes request creation, calls service, and waits for …\nSerializes data to a URL encoded form and set it as the …\nSerializes data to JSON and set it as the request payload.\nSets request payload.\nCreates service that always responds with given status …\nFinalizes request creation and returns HttpRequest and …\nFinalizes request creation and returns HttpRequest …\nFinalizes request creation and returns Request instance.\nFinalizes request creation and returns ServiceRequest …\nFinalizes request creation and returns ServiceResponse …\nFallible version of call_and_read_body_json that allows …\nFallible version of call_service that allows testing …\nFallible version of read_body that allows testing …\nFallible version of read_body_json that allows testing …\nSets URI of this request.\nSets HTTP version of this request.\nConstructs test request and sets request URI.\nRead bytes from a buffer.\nA trait for values that provide sequential write access to …\nA cheaply cloneable and sliceable chunk of contiguous …\nA unique reference to a contiguous slice of memory.\nApplication data wrapper and extractor.\nCombines two extractor or responder types into a single …\nURL encoded payload extractor and responder.\nForm extractor configuration.\nExtract typed headers from the request.\nJSON extractor and responder.\nFuture that resolves to some T when parsed from a JSON …\nJson extractor configuration.\nA value of type L.\nExtract typed data from request path segments.\nPath extractor configuration\nExtract a request’s raw payload stream.\nConfiguration for request payloads.\nExtract typed information from the request’s query.\nQuery extractor configuration.\nStream that reads request line by line.\nAn HTTP service for redirecting one path to another path …\nRequest-local data extractor.\nA value of type R.\nEnables parts of app configuration to be declared …\nFuture that resolves to some T when parsed from a URL …\nAdvance the internal cursor of the Buf\nAdvance the internal cursor of the BufMut\nAdd arbitrary app data item.\nExecutes blocking function on a thread pool, returns …\nReturns the number of bytes the BytesMut can hold without …\nCreates an adaptor which will chain this buffer with …\nCreates an adapter which will chain this buffer with …\nReturns a slice starting at the current position and of …\nReturns a mutable slice starting at the current BufMut …\nFills dst with potentially multiple slices starting at self…\nClears the buffer, removing all data.\nClears the buffer, removing all data. Existing capacity is …\nRun external configuration as part of the application …\nSet predicate for allowed content types.\nSets whether or not the request must have a Content-Type …\nCreates Bytes instance from slice, by copying it.\nConsumes len bytes inside self and returns new instance of …\nCopies bytes from self into dst.\nAdd shared app data item.\nDefault service to be used if no matching resource could …\nCreates a new route with DELETE method guard.\nSet custom error handler\nSet custom error handler.\nSet custom error handler.\nSet custom error handler\nAppends given bytes to this BytesMut.\nRegister an external resource.\nConverts self into an immutable Bytes.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nDeserialize a T from the URL encoded query parameter …\nCreates a new Bytes from a static slice.\nCreates a new route with GET method guard.\nGets an IEEE754 single-precision (4 bytes) floating point …\nGets an IEEE754 single-precision (4 bytes) floating point …\nGets an IEEE754 single-precision (4 bytes) floating point …\nGets an IEEE754 double-precision (8 bytes) floating point …\nGets an IEEE754 double-precision (8 bytes) floating point …\nGets an IEEE754 double-precision (8 bytes) floating point …\nGets a signed 128 bit integer from self in big-endian byte …\nGets a signed 128 bit integer from self in little-endian …\nGets a signed 128 bit integer from self in native-endian …\nGets a signed 16 bit integer from self in big-endian byte …\nGets a signed 16 bit integer from self in little-endian …\nGets a signed 16 bit integer from self in native-endian …\nGets a signed 32 bit integer from self in big-endian byte …") \ No newline at end of file diff --git a/search.desc/actix_web/actix_web-desc-1-.js b/search.desc/actix_web/actix_web-desc-1-.js new file mode 100644 index 000000000..6395e8cde --- /dev/null +++ b/search.desc/actix_web/actix_web-desc-1-.js @@ -0,0 +1 @@ +searchState.loadedDescShard("actix_web", 1, "Gets a signed 32 bit integer from self in little-endian …\nGets a signed 32 bit integer from self in native-endian …\nGets a signed 64 bit integer from self in big-endian byte …\nGets a signed 64 bit integer from self in little-endian …\nGets a signed 64 bit integer from self in native-endian …\nGets a signed 8 bit integer from self.\nGets a signed n-byte integer from self in big-endian byte …\nGets a signed n-byte integer from self in little-endian …\nGets a signed n-byte integer from self in native-endian …\nReturns reference to inner T.\nGets an unsigned 128 bit integer from self in big-endian …\nGets an unsigned 128 bit integer from self in …\nGets an unsigned 128 bit integer from self in …\nGets an unsigned 16 bit integer from self in big-endian …\nGets an unsigned 16 bit integer from self in little-endian …\nGets an unsigned 16 bit integer from self in native-endian …\nGets an unsigned 32 bit integer from self in the …\nGets an unsigned 32 bit integer from self in the …\nGets an unsigned 32 bit integer from self in native-endian …\nGets an unsigned 64 bit integer from self in big-endian …\nGets an unsigned 64 bit integer from self in little-endian …\nGets an unsigned 64 bit integer from self in native-endian …\nGets an unsigned 8 bit integer from self.\nGets an unsigned n-byte integer from self in big-endian …\nGets an unsigned n-byte integer from self in little-endian …\nGets an unsigned n-byte integer from self in native-endian …\nReturns true if there are any more bytes to consume\nReturns true if there is space in self for more bytes.\nCreates a new route with HEAD method guard.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nUnwrap to inner Payload type.\nUnwraps to the internal Arc<T>\nConsumes the ReqData, returning its wrapped data.\nUnwrap into inner T value.\nUnwrap into the inner T value.\nUnwrap into inner T value.\nUnwrap into inner T value.\nUnwrap into inner T value.\nReturns true if the Bytes has a length of 0.\nReturns true if the BytesMut has a length of 0.\nReturns true if this is the only reference to the data.\nReturns the number of bytes contained in this Bytes.\nReturns the number of bytes contained in this BytesMut.\nCreates an adaptor which can write at most limit bytes to …\nSet maximum accepted payload size. By default this limit …\nSet maximum accepted payload size. By default this limit …\nSet maximum accepted payload size in bytes. The default …\nCreates a new route with specified method guard.\nSet required mime type of the request. By default mime …\nCreates a new empty Bytes.\nCreates a new BytesMut with default capacity.\nCreate new Data instance.\nConstruct a new Redirect service that matches a path.\nCreate new instance with a size limit (in bytes) and no …\nCreates a new route with PATCH method guard.\nUse the “308 Permanent Redirect” status when …\nCreates a new route with POST method guard.\nCreates a new route with PUT method guard.\nTransfer bytes into self from src and advance the cursor …\nPut cnt bytes val into self.\nWrites an IEEE754 single-precision (4 bytes) floating …\nWrites an IEEE754 single-precision (4 bytes) floating …\nWrites an IEEE754 single-precision (4 bytes) floating …\nWrites an IEEE754 double-precision (8 bytes) floating …\nWrites an IEEE754 double-precision (8 bytes) floating …\nWrites an IEEE754 double-precision (8 bytes) floating …\nWrites a signed 128 bit integer to self in the big-endian …\nWrites a signed 128 bit integer to self in little-endian …\nWrites a signed 128 bit integer to self in native-endian …\nWrites a signed 16 bit integer to self in big-endian byte …\nWrites a signed 16 bit integer to self in little-endian …\nWrites a signed 16 bit integer to self in native-endian …\nWrites a signed 32 bit integer to self in big-endian byte …\nWrites a signed 32 bit integer to self in little-endian …\nWrites a signed 32 bit integer to self in native-endian …\nWrites a signed 64 bit integer to self in the big-endian …\nWrites a signed 64 bit integer to self in little-endian …\nWrites a signed 64 bit integer to self in native-endian …\nWrites a signed 8 bit integer to self.\nWrites low nbytes of a signed integer to self in …\nWrites low nbytes of a signed integer to self in …\nWrites low nbytes of a signed integer to self in …\nTransfer bytes into self from src and advance the cursor …\nWrites an unsigned 128 bit integer to self in the …\nWrites an unsigned 128 bit integer to self in …\nWrites an unsigned 128 bit integer to self in …\nWrites an unsigned 16 bit integer to self in big-endian …\nWrites an unsigned 16 bit integer to self in little-endian …\nWrites an unsigned 16 bit integer to self in native-endian …\nWrites an unsigned 32 bit integer to self in big-endian …\nWrites an unsigned 32 bit integer to self in little-endian …\nWrites an unsigned 32 bit integer to self in native-endian …\nWrites an unsigned 64 bit integer to self in the …\nWrites an unsigned 64 bit integer to self in little-endian …\nWrites an unsigned 64 bit integer to self in native-endian …\nWrites an unsigned 8 bit integer to self.\nWrites an unsigned n-byte integer to self in big-endian …\nWrites an unsigned n-byte integer to self in the …\nWrites an unsigned n-byte integer to self in the …\nCreates an adaptor which implements the Read trait for self…\nCreate a relative or absolute redirect.\nReturns the number of bytes between the current position …\nReturns the number of bytes that can be written from the …\nReserves capacity for at least additional more bytes to be …\nResizes the buffer so that len is equal to new_len.\nCreates a new resource for a specific path.\nCreates a new un-configured route.\nConfigure route for a specific path.\nCreates scope for common path prefix.\nUse the “303 See Other” status when responding.\nCreates a raw service for a specific path.\nRegister HTTP service factory.\nSets the length of the buffer.\nReturns a slice of self for the provided range.\nReturns a slice of self that is equivalent to the given …\nReturns the remaining spare capacity of the buffer as a …\nRemoves the bytes from the current view, returning them in …\nSplits the bytes into two at the given index.\nSplits the bytes into two at the given index.\nSplits the bytes into two at the given index.\nSplits the buffer into two at the given index.\nCreates an adaptor which will read at most limit bytes …\nUse the “307 Temporary Redirect” status when …\nCreates a new any-method route with handler.\nConstruct a new Redirect to use as a responder.\nBuffers entire payload from request.\nBuffers payload from request up to limit bytes.\nCreates a new route with TRACE method guard.\nShortens the buffer, keeping the first len bytes and …\nShortens the buffer, keeping the first len bytes and …\nAbsorbs a BytesMut that was previously split off.\nAllows the use of custom status codes for less common …\nCreates a new BytesMut with the specified capacity.\nCreates an adaptor which implements the Write trait for …\nCreates a new BytesMut, which is initialized with zero.\nLength as reported by Content-Length header, if present.") \ No newline at end of file diff --git a/search.desc/actix_web_actors/actix_web_actors-desc-0-.js b/search.desc/actix_web_actors/actix_web_actors-desc-0-.js new file mode 100644 index 000000000..70b960319 --- /dev/null +++ b/search.desc/actix_web_actors/actix_web_actors-desc-0-.js @@ -0,0 +1 @@ +searchState.loadedDescShard("actix_web_actors", 0, "Actix actors support for Actix Web.\nExecution context for HTTP actors\nCreate a new HTTP Context from a request and an actor\nReturns the argument unchanged.\nHandle of the running future\nCalls U::from(self).\nCreate a new HTTP Context\nWrite payload\nIndicate end of streaming payload. Also this method calls …\nWebsocket integration.\nIndicates an abnormal closure. If the abnormal closure was …\nIndicates that the server is overloaded and the client …\nIndicates that an endpoint is “going away”, such as a …\nBad opcode.\nWebSocket key is not set or wrong.\nBinary message.\nBinary frame.\nClose message with optional reason.\nClose message with optional reason.\nStatus code used to indicate why an endpoint is closing …\nReason for closing the connection\nContinuation.\nContinuation.\nUnknown continuation fragment.\nContinuation has not started.\nReceived new continuation but it is already started.\nIndicates that a server is terminating the connection …\nIndicates that an endpoint (client) is terminating the …\nA WebSocket frame.\nOnly get method is allowed.\nWebSocket handshake errors\nIndicates that an endpoint is terminating the connection …\nInvalid control frame length\nEncountered invalid opcode.\nI/O error.\nReceived a masked frame from server.\nA WebSocket message.\nConnection header is not set to upgrade.\nWebSocket version header is not set.\nUpgrade header if not set to WebSocket.\nNo-op. Useful for low-level services.\nIndicates a normal closure, meaning that the purpose for …\nA payload reached size limit.\nPing message.\nPing message.\nIndicates that an endpoint is terminating the connection …\nPong message.\nPong message.\nIndicates that an endpoint is terminating the connection …\nWebSocket protocol errors.\nIndicates that the server is restarting. A client may …\nIndicates that an endpoint is terminating the connection …\nText message.\nText frame. Note that the codec does not validate UTF-8 …\nReceived an unmasked frame from client.\nIndicates that an endpoint is terminating the connection …\nUnsupported WebSocket version.\nExecution context for WebSockets actors\nBuilder for Websocket session response.\nSend binary frame\nSend close frame\nExit code\nSet the Codec for the session. If Self::frame_size is also …\nCreate a new Websocket context from a request and an actor.\nCreate a new Websocket context from a request and an actor.\nOptional description of the exit code\nSet the max frame size for each message (in bytes).\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nHandle of the running future\nPrepare WebSocket handshake response.\nPrepare WebSocket handshake response.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nConstruct a new WsResponseBuilder with actor, request, and …\nSend ping frame\nSend pong frame\nSet the protocols for the session.\nSet mailbox capacity\nPerform WebSocket handshake and start actor.\nPerform WebSocket handshake and start actor.\nPerform WebSocket handshake and start actor.\nPerform WebSocket handshake and start actor.\nDo WebSocket handshake and start ws actor.\nSend text frame\nCreate a new Websocket context from a request, an actor, …\nCreate a new Websocket context\nWrite payload") \ No newline at end of file diff --git a/search.desc/actix_web_codegen/actix_web_codegen-desc-0-.js b/search.desc/actix_web_codegen/actix_web_codegen-desc-0-.js new file mode 100644 index 000000000..8470a5c77 --- /dev/null +++ b/search.desc/actix_web_codegen/actix_web_codegen-desc-0-.js @@ -0,0 +1 @@ +searchState.loadedDescShard("actix_web_codegen", 0, "Routing and runtime macros for Actix Web.\nCreates route handler with actix_web::guard::Connect.\nCreates route handler with actix_web::guard::Delete.\nCreates route handler with actix_web::guard::Get.\nCreates route handler with actix_web::guard::Head.\nMarks async main function as the Actix Web system …\nCreates route handler with actix_web::guard::Options.\nCreates route handler with actix_web::guard::Patch.\nCreates route handler with actix_web::guard::Post.\nCreates route handler with actix_web::guard::Put.\nCreates resource handler, allowing multiple HTTP method …\nCreates resource handler, allowing multiple HTTP methods …\nMarks async test functions to use the Actix Web system …\nCreates route handler with actix_web::guard::Trace.") \ No newline at end of file diff --git a/search.desc/awc/awc-desc-0-.js b/search.desc/awc/awc-desc-0-.js new file mode 100644 index 000000000..0ec7d9215 --- /dev/null +++ b/search.desc/awc/awc-desc-0-.js @@ -0,0 +1 @@ +searchState.loadedDescShard("awc", 0, "awc is an asynchronous HTTP and WebSocket client library.\nAn asynchronous HTTP and WebSocket client.\nStandard HTTP request.\nStandard HTTP response.\nAn HTTP Client builder\nAn HTTP Client request builder\nClient Response\nCombined HTTP and WebSocket request type received by …\nCombined HTTP response & WebSocket tunnel type returned …\nManages HTTP client network connectivity.\nFrozenClientRequest struct represents cloneable client …\nBuilder that allows to modify extra headers.\nA Future that reads a body stream, parses JSON, resolving …\nA Future that reads a body stream, resolving as Bytes.\nFuture that sends request’s payload and resolves to a …\nTunnel used by WebSocket connection requests.\nTunnel used for WebSocket communication.\nAdd default header.\nSet socket address of the server.\nAppend a header, keeping any that were set with an …\nSet client wide HTTP basic authorization header\nSet HTTP basic authorization header.\nSet client wide HTTP bearer authentication header\nSet HTTP bearer authentication header\nTraits and structures to aid consuming and writing HTTP …\nReturns a Future that consumes the body stream and …\nConstructs new Client builder.\nSend headers in Camel-Case form.\nSet keep-alive period for opened connection.\nSet max lifetime period for connection.\nUse custom connector service.\nSets custom connector.\nSet content length\nSet request’s content type\nSet a cookie\nReturn request cookie.\nLoad request cookies.\nConstruct HTTP DELETE request.\nDo not follow redirects.\nDisable request timeout.\nSet server connection disconnect timeout in milliseconds.\nHTTP client errors\nInsert a header, it overrides existing header in …\nClones this FrozenClientRequest, returning a new one with …\nClones this FrozenClientRequest, returning a new one with …\nFinish build process and create Client instance.\nFinish configuration process and create connector service.\nForce close connection instead of returning it back to …\nFreeze request builder and construct FrozenClientRequest, …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nConstruct HTTP GET request.\nGet HTTP method of this request\nGet HTTP method of this request\nGet peer address of this request.\nGet HTTP URI of request.\nGet HTTP URI of request\nGet HTTP version of this request.\nSets TLS handshake timeout.\nConstruct HTTP HEAD request.\nReturns request’s headers.\nGet default HeaderMap of Client.\nReturns request’s headers.\nReturns request’s headers.\nReturns request’s mutable headers.\nVarious HTTP related types.\nIndicates the initial window size (in octets) for HTTP2 …\nSets the initial window size (in bytes) for HTTP/2 …\nIndicates the initial window size (in octets) for HTTP2 …\nSets the initial window size (in bytes) for HTTP/2 …\nInsert a header, replacing any that were set with an …\nInsert a header only if it is not yet set.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nUnwraps type into HTTP response.\nUnwraps type into WebSocket tunnel response.\nReturns a Future consumes the body stream, parses JSON, …\nSet total number of simultaneous connections per type of …\nChange max size of payload. Default limit is 2 MiB.\nChange max size limit of payload.\nSet local IP Address the connector would use for …\nSet local IP Address the connector would use for …\nMap the current body type to another using a closure. …\nMaximum supported HTTP major version.\nSets maximum supported HTTP major version.\nSet max number of redirects.\nSet HTTP method of this request.\nCreate a new ClientBuilder with default settings\nCreate a new connector with default TLS settings\nConstructs new client instance with default settings.\nCreates a JSON body stream reader from a response by …\nCreates a body stream reader from a response by taking its …\nDisable automatic decompress of response’s body\nDo not add fundamental default request headers.\nSets custom OpenSSL SslConnector instance.\nConstruct HTTP OPTIONS request.\nConstruct HTTP PATCH request.\nConstruct HTTP POST request.\nConstruct HTTP PUT request.\nSets the query part of the request\nConstruct HTTP request.\nCreate ClientRequest from RequestHead\nSets custom Rustls v0.20 ClientConfig instance.\nSets custom Rustls v0.21 ClientConfig instance.\nSets custom Rustls v0.22 ClientConfig instance.\nSets custom Rustls v0.23 ClientConfig instance.\nComplete request construction and send an empty body.\nSet an empty body and generate ClientRequest.\nSend an empty body.\nComplete request construction and send a body.\nComplete request construction and send body.\nSend a body.\nComplete request construction and send an urlencoded body.\nSet a urlencoded body and generate ClientRequest\nSend an urlencoded body.\nComplete request construction and send a json body.\nSet a JSON body and generate ClientRequest\nSend a json body.\nComplete request construction and send a streaming body.\nSet an streaming body and generate ClientRequest.\nSend a streaming body.\nGet the status from the server.\nTest helpers for actix http client to use during testing.\nSet request timeout\nSets TCP connection timeout.\nSet request timeout. Overrides client wide timeout setting.\nSet a timeout duration for ClientResponse.\nSet HTTP URI of request.\nRead the Request Version.\nRegisters middleware, in the form of a middleware …\nWebsockets client\nInitialize a WebSocket connection. Returns a WebSocket …\nError type returned from to_bytes_limited when body …\nBody size hint.\nStreaming response wrapper.\nA boxed message body with boxed errors.\nAn “either” type specialized for body types.\nThe type of error that will be returned if streaming body …\nA body of type L.\nAn interface for types that can be used as a response body.\nBody type for responses that forbid payloads.\nImplicitly empty body.\nA body of type R.\nKnown size body.\nKnown sized streaming response wrapper.\nUnknown size body.\nEquivalent to BodySize::Sized(0);\nReturns a mutable pinned reference to the inner message …\nWraps this body into a BoxBody.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturns true if size hint indicates omitted or empty body.\nCreates new EitherBody using left variant.\nBoxes body type, erasing type information.\nCreates new EitherBody left variant with a boxed right …\nConstructs new “none” body.\nAttempt to pull out the next chunk of body bytes.\nAttempts to pull out the next value of the underlying …\nAttempts to pull out the next value of the underlying …\nCreates new EitherBody using right variant.\nBody size hint.\nCollects all the bytes produced by body.\nCollects the bytes produced by body, up to limit bytes.\nTry to convert into the complete chunk of body bytes.\nBad opcode.\nWebSocket key is not set or wrong.\nError sending request body\nFailed to connect to host\nA set of errors that can occur while connecting to an HTTP …\nContent type error\nUnknown continuation fragment.\nContinuation has not started.\nReceived new continuation but it is already started.\nOther errors that can occur after submitting a request.\nOther errors that can occur after submitting a request.\nDeserialize error\nConnector has been disconnected\nContent encoding stream corruption.\nA set of errors that can occur during freezing a request\nOnly get method is allowed.\nHttp2 error\nHttp2 error\nRepresents an HTTP header field value.\nHttp error\nHTTP error\nHTTP/2 payload error.\nA generic “error” for HTTP connections\nA payload reached EOF, but is not complete.\nInvalid challenge response\nInvalid connection header\nInvalid control frame length\nEncountered invalid opcode.\nInvalid response status\nInvalid upgrade header\nConnection io error\nGeneric I/O error.\nI/O error.\nA set of errors that can occur during parsing json payloads\nReceived a masked frame from server.\nMissing Connection header\nMissing Sec-Websocket-Accept header\nConnection header is not set to upgrade.\nNo dns records\nWebSocket version header is not set.\nUpgrade header if not set to WebSocket.\nPayload reached size limit.\nA payload reached size limit.\nPayload error\nA set of errors that can occur during payload parsing.\nProtocol error\nFailed to resolve the hostname\nError parsing response\nError sending request\nSend request error\nA set of errors that can occur during request sending and …\nSSL error\nSSL feature is not enabled\nAn HTTP status code (status-code in RFC 7230 et al.).\nConnecting took too long\nResponse took too long\nTunnels are not supported for HTTP/2 connection\nPayload length is unknown.\nReceived an unmasked frame from client.\nUnresolved host name\nUnsupported WebSocket version.\nInvalid URL\nInvalid URL\nWebsocket client error\nWebSocket handshake errors\nWebSocket protocol errors.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturn a reference to the lower level, inner error.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturn true if the underlying error has the same type as T.\n202 Accepted [RFC7231, Section 6.3.3]\n208 Already Reported [RFC5842]\n502 Bad Gateway [RFC7231, Section 6.6.3]\n400 Bad Request [RFC7231, Section 6.5.1]\n409 Conflict [RFC7231, Section 6.5.8]\nCONNECT\n100 Continue [RFC7231, Section 6.2.1]\n201 Created [RFC7231, Section 6.3.2]\nClose connection after response.\nRepresents various types of connection\nDELETE\n417 Expectation Failed [RFC7231, Section 6.5.14]\n424 Failed Dependency [RFC4918]\n403 Forbidden [RFC7231, Section 6.5.3]\n302 Found [RFC7231, Section 6.4.3]\n504 Gateway Timeout [RFC7231, Section 6.6.5]\nGET\n410 Gone [RFC7231, Section 6.5.9]\nHEAD\nHTTP/0.9\nHTTP/1.0\nHTTP/1.1\nHTTP/2.0\nHTTP/3.0\n505 HTTP Version Not Supported [RFC7231, Section 6.6.6]\n418 I’m a teapot [curiously not registered by IANA but …\n226 IM Used [RFC3229]\n507 Insufficient Storage [RFC4918]\n500 Internal Server Error [RFC7231, Section 6.6.1]\nKeep connection alive after response.\n411 Length Required [RFC7231, Section 6.5.10]\n423 Locked [RFC4918]\n508 Loop Detected [RFC5842]\n405 Method Not Allowed [RFC7231, Section 6.5.5]\n421 Misdirected Request RFC7540, Section 9.1.2\n301 Moved Permanently [RFC7231, Section 6.4.2]\n300 Multiple Choices [RFC7231, Section 6.4.1]\n207 Multi-Status [RFC4918]\nThe Request Method (VERB)\n511 Network Authentication Required [RFC6585]\n203 Non-Authoritative Information [RFC7231, Section 6.3.4]\n406 Not Acceptable [RFC7231, Section 6.5.6]\n510 Not Extended [RFC2774]\n404 Not Found [RFC7231, Section 6.5.4]\n501 Not Implemented [RFC7231, Section 6.6.2]\n304 Not Modified [RFC7232, Section 4.1]\n204 No Content [RFC7231, Section 6.3.5]\n200 OK [RFC7231, Section 6.3.1]\nOPTIONS\n206 Partial Content [RFC7233, Section 4.1]\nPATCH\n413 Payload Too Large [RFC7231, Section 6.5.11]\n402 Payment Required [RFC7231, Section 6.5.2]\n308 Permanent Redirect [RFC7238]\nPOST\n412 Precondition Failed [RFC7232, Section 4.2]\n428 Precondition Required [RFC6585]\n102 Processing [RFC2518]\n407 Proxy Authentication Required [RFC7235, Section 3.2]\nPUT\n416 Range Not Satisfiable [RFC7233, Section 4.4]\n431 Request Header Fields Too Large [RFC6585]\n408 Request Timeout [RFC7231, Section 6.5.7]\n205 Reset Content [RFC7231, Section 6.3.6]\n303 See Other [RFC7231, Section 6.4.4]\n503 Service Unavailable [RFC7231, Section 6.6.4]\n101 Switching Protocols [RFC7231, Section 6.2.2]\nAn HTTP status code (status-code in RFC 7230 et al.).\n307 Temporary Redirect [RFC7231, Section 6.4.7]\n429 Too Many Requests [RFC6585]\nTRACE\n401 Unauthorized [RFC7235, Section 3.1]\n451 Unavailable For Legal Reasons [RFC7725]\n422 Unprocessable Entity [RFC4918]\n415 Unsupported Media Type [RFC7231, Section 6.5.13]\n426 Upgrade Required [RFC7231, Section 6.5.15]\n414 URI Too Long [RFC7231, Section 6.5.12]\n305 Use Proxy [RFC7231, Section 6.4.5]\nConnection is upgraded to different type.\nThe URI component of a request.\n506 Variant Also Negotiates [RFC2295]\nRepresents a version of the HTTP spec.\nReturn a &str representation of the HTTP method\nReturns a &str representation of the StatusCode\nReturns the u16 corresponding to this StatusCode.\nGet the authority of this Uri.\nCreates a new builder-style object to manufacture a Uri.\nGet the standardised reason-phrase for this status code.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nConverts a slice of bytes to an HTTP method.\nConverts a &u8 to a status code\nAttempt to convert a Bytes buffer to a Uri.\nAttempt to convert a Parts into a Uri.\nConvert a Uri from a static string.\nConverts a u16 to a status code.\nPre-defined HeaderNames, traits for parsing and …\nGet the host of this Uri.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nConvert a Uri into Parts.\nCheck if status is within 400-499.\nWhether a method is considered “idempotent”, meaning …\nCheck if status is within 100-199.\nCheck if status is within 300-399.\nWhether a method is considered “safe”, meaning the …\nCheck if status is within 500-599.\nCheck if status is within 200-299.\nGet the path of this Uri.\nReturns the path & query components of the Uri\nGet the port part of this Uri.\nGet the port of this Uri as a u16.\nGet the query string of this Uri, starting after the ?.\nGet the scheme of this Uri.\nGet the scheme of this Uri as a &str.\nURI component of request and response lines\nAdvertises which content types the client is able to …\nAdvertises which character set the client is able to …\nAdvertises which content encoding the client is able to …\nAdvertises which languages the client is able to …\nMarker used by the server to advertise partial request …\nPreflight response indicating if the response to the …\nPreflight response indicating permitted HTTP headers.\nPreflight header response indicating permitted access …\nIndicates whether the response can be shared with …\nIndicates which headers can be exposed as part of the …\nIndicates how long the results of a preflight request can …\nInforms the server which HTTP headers will be used when an …\nInforms the server know which HTTP method will be used …\nIndicates the time in seconds the object has been in a …\nLists the set of methods support by a resource.\nAdvertises the availability of alternate services to …\nContains the credentials to authenticate a user agent with …\nSealed trait implemented for types that can be effectively …\nBig5\nA format using the Brotli algorithm.\nSpecifies directives for caching mechanisms in both …\nResponse header field that indicates how caches have …\nResponse header field that allows origin servers to …\nControls whether or not the network connection stays open …\nIndicates if the content is expected to be displayed …\nUsed to compress the media-type.\nUsed to describe the languages intended for the audience.\nIndicates the size of the entity-body.\nIndicates an alternate location for the returned data.\nIndicates where in a full body message a partial message …\nAllows controlling resources the user agent is allowed to …\nAllows experimenting with policies by monitoring their …\nUsed to indicate the media type of the resource.\nContains stored HTTP cookies previously sent by the server …\nResponse header that prevents a document from loading any …\nResponse header that allows you to ensure a top-level …\nResponse header that conveys a desire that the browser …\nA MIME character set.\nRepresents a supported content encoding.\nContains the date and time at which the message was …\nIndicates the client’s tracking preference.\nA format using the zlib structure with deflate algorithm.\nIdentifier for a specific version of a resource.\nIndicates expectations that need to be fulfilled by the …\nContains the date/time after which the response is …\nThe type returned in the event of a conversion error.\nEUC-JP\nEUC-KR\nAn arbitrary charset specified as a string\nThe value part of an extended parameter consisting of …\nContains information from the client-facing side of proxy …\nContains an Internet email address for a human user who …\nGB2312\nGzip algorithm.\nSpecifies the domain name of the server and (optionally) …\nAn interface for types that already represent a valid …\nA multi-map of HTTP headers.\nRepresents an HTTP header field name\nRepresents an HTTP header field value.\nA timestamp with HTTP-style formatting and parsing.\nMakes a request conditional based on the E-Tag.\nMakes a request conditional based on the modification date.\nMakes a request conditional based on the E-Tag.\nMakes a request conditional based on range.\nMakes the request conditional based on the last …\nIndicates the no-op identity encoding.\nA possible error when converting a HeaderName from another …\nA possible error when converting a HeaderValue from a …\nISO-2022-JP\nISO-2022-JP-2\nISO-2022-KR\nISO-8859-1\nISO-8859-10\nISO-8859-2\nISO-8859-3\nISO-8859-4\nISO-8859-5\nISO-8859-6\nISO-8859-6-E\nISO-8859-6-I\nISO-8859-7\nISO-8859-8\nISO-8859-8-E\nISO-8859-8-I\nISO-8859-9\nKOI8-R\nContent-Types that are acceptable for the response.\nAllows the server to point an interested client to another …\nIndicates the URL to redirect a page to.\nA language tag as described in RFC 5646.\nThe maximum quality value, equivalent to q=1.0.\nIndicates the max number of intermediaries the request …\nThe minimum, non-zero quality value, equivalent to q=0.001.\nIndicates where a fetch originates from.\nResponse header that provides a mechanism to allow and …\nHTTP/1.0 header usually used for backwards compatibility.\nDefines the authentication method that should be used to …\nContains the credentials to authenticate a user agent to a …\nAssociates a specific cryptographic public key with a …\nSends reports of pinning violation to the report-uri …\nRepresents a quality used in q-factor values.\nRepresents an item with a quality value as defined in RFC …\nIndicates the part of a document that the server should …\nContains the address of the previous web page from which a …\nGoverns which referrer information should be included with …\nInforms the web browser that the current page or frame …\nThe Retry-After response HTTP header indicates how long …\nThe |Sec-WebSocket-Accept| header field is used in the …\nThe |Sec-WebSocket-Extensions| header field is used in the …\nThe |Sec-WebSocket-Key| header field is used in the …\nThe |Sec-WebSocket-Protocol| header field is used in the …\nThe |Sec-WebSocket-Version| header field is used in the …\nContains information about the software used by the origin …\nUsed to send cookies from the server to the user agent.\nTells the client to communicate with HTTPS instead of …\nShift_JIS\nInforms the server of transfer encodings willing to be …\nAllows the sender to include additional fields at the end …\nSpecifies the form of encoding used to safely transfer the …\nA possible error when converting a HeaderValue to a string …\nAn interface for types that can be converted into a …\nAn interface for types that can be converted into a …\nUsed as part of the exchange to upgrade the protocol.\nSends a signal to the server expressing the client’s …\nContains a string that allows identifying the requesting …\nUS ASCII\nDetermines how to match future requests with cached …\nAdded by proxies to track routing.\nGeneral HTTP header contains information about possible …\nDefines the authentication method that should be used to …\nMarker used by the server to indicate that the MIME types …\nControls DNS prefetching.\nRequest header (de-facto standard) for identifying the …\nRequest header (de-facto standard) for identifying the …\nRequest header (de-facto standard) for identifying the …\nIndicates whether or not a browser should be allowed to …\nStop pages from loading when an XSS attack is detected.\nThe zero quality value, equivalent to q=0.0.\nZstd algorithm.\nAppends a name-value pair to the map.\nConverts a HeaderValue to a byte slice.\nReturn the serialization of this language tag.\nReturns a str representation of the header.\nConvert content encoding to string.\nReturns the canonical version of the language tag following\nReturns the number of single-value headers the map can …\nThe character set that is used to encode the value to a …\nClears the map, removing all name-value pairs.\nReturns true if the map contains a value for the specified …\nClears the map, returning all name-value sets as an …\nPerforms a case-insensitive comparison of the string …\nPerforms a case-insensitive comparison of the string …\nReturn the extended language subtags.\nIterate on the extended language subtags.\nReturn the extension subtags.\nIterate on the extension subtags.\nFormat an array into a comma-delimited string.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nConverts a slice of bytes to an HTTP header name.\nAttempt to convert a byte slice to a HeaderValue.\nReads a comma-delimited raw header into a Vec.\nConverts a slice of bytes to an HTTP header name.\nAttempt to convert a Bytes buffer to a HeaderValue.\nConvert a Bytes directly into a HeaderValue without …\nConverts a HeaderName into a HeaderValue\nReads a single string when parsing a header.\nConverts a static string to a HTTP header name.\nConvert a static string to a HeaderValue.\nAttempt to convert a string to a HeaderValue.\nReturn the primary language subtag and its extended …\nReturns a reference to the first value associated with a …\nReturns an iterator over all values associated with a …\nReturns a mutable reference to the first value associated …\nPercent encode a sequence of bytes with a character set …\nInserts (overrides) a name-value pair in the map.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturn the serialization of this language tag.\nReturns true if the HeaderValue has a length of zero bytes.\nReturns true if the map contains no elements.\nChecks if it is a language range, meaning that there are …\nReturns true if the value represents sensitive data.\nCheck if the language tag is valid according to RFC 5646.\nThe wrapped contents of the field.\nAn iterator over all name-value pairs.\nAn iterator over all contained header names.\nThe human language details of the value, if available.\nReturns the length of self.\nReturns the number of values stored in the map.\nReturns the number of keys stored in the map.\nA multi-value HeaderMap and its iterators.\nMatches language tags. The first language acts as a …\nConstructs a new QualityItem from an item, using the …\nConstructs a new QualityItem from an item, using the …\nReturns the name of the header field.\nCreate an empty HeaderMap.\nConstructs a new QualityItem from an item and a quality …\nParse the header from a HTTP message.\nCreate a LanguageTag from its serialization.\nParses extended header parameter values (ext-value), as …\nReturn the primary language subtag.\nReturn the private use subtags.\nIterate on the private use subtags.\nConvenience function to create a Quality from an f32 …\nThe quality (client or server preference) for the value.\nReturn the region subtag.\nRemoves all headers for a particular header name from the …\nReserves capacity for at least additional more headers to …\nRetains only the headers specified by the predicate.\nReturn the script subtag.\nMark that the header value represents sensitive …\nConvert content encoding to header value.\nYields a &str slice if the HeaderValue only contains …\nTry to convert value to a HeaderValue.\nCheck if the language tag is “valid” according to RFC …\nThe parameter value, as expressed in octets.\nReturn the variant subtags.\nIterate on the variant subtags.\nCreate an empty HeaderMap with the specified capacity.\nConstructs a new QualityItem from an item, using zero …\nIterator over drained name-value pairs.\nA multi-map of HTTP headers.\nIterator over owned name-value pairs.\nIterator over borrowed name-value pairs.\nIterator over all names in the map.\nIterator over removed, owned values with the same …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nReturns true if iterator contains no elements, without …\nRepresents the authority component of a URI.\nA builder for Uris.\nHTTP protocol scheme\nHTTP protocol over TLS.\nAn error resulting from a failed attempt to construct a …\nAn error resulting from a failed attempt to construct a …\nThe various parts of a URI.\nRepresents the path component of a URI\nThe port component of a URI.\nRepresents the scheme component of a URI\nThe URI component of a request.\nReturns the port number as a str.\nReturn a str representation of the authority\nReturns the path and query as a string component.\nReturn a str representation of the scheme\nReturns the port number as a u16.\nSet the Authority for this URI.\nThe authority component of a URI\nConsumes this builder, and tries to construct a valid Uri …\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nAttempt to convert a Bytes buffer to a Authority.\nAttempt to convert a Bytes buffer to a PathAndQuery.\nAttempt to convert an Authority from a static string.\nConvert a PathAndQuery from a static string.\nGet the host of this Authority.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCreates a new default instance of Builder to construct a …\nReturns the path component\nSet the PathAndQuery for this URI.\nThe origin-form component of a URI\nGet the port part of this Authority.\nGet the port of this Authority as a u16.\nReturns the query string component\nSet the Scheme for this URI.\nThe scheme component of a URI\nTrait for transform a type to another one. Both the input …\nReturns the argument unchanged.\nCalls U::from(self).\nCreates and returns a new Transform component.\nTest ClientResponse builder\nAppend a header\nSet cookie for this response\nComplete response creation and generate ClientResponse …\nReturns the argument unchanged.\nInsert a header\nCalls U::from(self).\nSet response’s payload\nSet HTTP version of this response\nCreate TestResponse and set header\nIndicates an abnormal closure. If the abnormal closure was …\nIndicates that the server is overloaded and the client …\nIndicates that an endpoint is “going away”, such as a …\nBinary message.\nBinary frame.\nClose message with optional reason.\nClose message with optional reason.\nStatus code used to indicate why an endpoint is closing …\nReason for closing the connection\nWebSocket protocol codec.\nContinuation.\nContinuation.\nIndicates that a server is terminating the connection …\nIndicates that an endpoint (client) is terminating the …\nA WebSocket frame.\nIndicates that an endpoint is terminating the connection …\nA WebSocket message.\nNo-op. Useful for low-level services.\nIndicates a normal closure, meaning that the purpose for …\nPing message.\nPing message.\nIndicates that an endpoint is terminating the connection …\nPong message.\nPong message.\nIndicates that an endpoint is terminating the connection …\nIndicates that the server is restarting. A client may …\nIndicates that an endpoint is terminating the connection …\nText message.\nText frame. Note that the codec does not validate UTF-8 …\nIndicates that an endpoint is terminating the connection …\nWebSocket connection.\nSet socket address of the server.\nSet HTTP basic authorization header\nSet HTTP bearer authentication header\nSet decoder to client mode.\nExit code\nComplete request construction and connect to a WebSocket …\nSet a cookie\nOptional description of the exit code\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nReturns the argument unchanged.\nAppend a header.\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nCalls U::from(self).\nSet max frame size\nSet max frame size.\nCreate new WebSocket frames decoder.\nSet request Origin\nSet supported WebSocket protocols\nDisable payload masking. By default ws client masks frame …\nInsert a header, replaces existing header.\nInsert a header only if it is not yet set.") \ No newline at end of file diff --git a/settings.html b/settings.html new file mode 100644 index 000000000..c7f3e00c7 --- /dev/null +++ b/settings.html @@ -0,0 +1 @@ +Settings

Rustdoc settings

Back
\ No newline at end of file diff --git a/src-files.js b/src-files.js new file mode 100644 index 000000000..e574be95f --- /dev/null +++ b/src-files.js @@ -0,0 +1,14 @@ +var srcIndex = new Map(JSON.parse('[\ +["actix_files",["",[],["chunked.rs","directory.rs","encoding.rs","error.rs","files.rs","lib.rs","named.rs","path_buf.rs","range.rs","service.rs"]]],\ +["actix_http",["",[["body",[],["body_stream.rs","boxed.rs","either.rs","message_body.rs","mod.rs","none.rs","size.rs","sized_stream.rs","utils.rs"]],["encoding",[],["decoder.rs","encoder.rs","mod.rs"]],["h1",[],["chunked.rs","client.rs","codec.rs","decoder.rs","dispatcher.rs","encoder.rs","expect.rs","mod.rs","payload.rs","service.rs","timer.rs","upgrade.rs","utils.rs"]],["h2",[],["dispatcher.rs","mod.rs","service.rs"]],["header",[["shared",[],["charset.rs","content_encoding.rs","extended.rs","http_date.rs","mod.rs","quality.rs","quality_item.rs"]]],["as_name.rs","common.rs","into_pair.rs","into_value.rs","map.rs","mod.rs","utils.rs"]],["requests",[],["head.rs","mod.rs","request.rs"]],["responses",[],["builder.rs","head.rs","mod.rs","response.rs"]],["ws",[],["codec.rs","dispatcher.rs","frame.rs","mask.rs","mod.rs","proto.rs"]]],["builder.rs","config.rs","date.rs","error.rs","extensions.rs","helpers.rs","http_message.rs","keep_alive.rs","lib.rs","message.rs","payload.rs","service.rs","test.rs"]]],\ +["actix_http_test",["",[],["lib.rs"]]],\ +["actix_multipart",["",[["form",[],["bytes.rs","json.rs","mod.rs","tempfile.rs","text.rs"]]],["error.rs","extractor.rs","lib.rs","server.rs","test.rs"]]],\ +["actix_multipart_derive",["",[],["lib.rs"]]],\ +["actix_router",["",[],["de.rs","lib.rs","path.rs","pattern.rs","quoter.rs","regex_set.rs","resource.rs","resource_path.rs","router.rs","url.rs"]]],\ +["actix_test",["",[],["lib.rs"]]],\ +["actix_web",["",[["error",[],["error.rs","internal.rs","macros.rs","mod.rs","response_error.rs"]],["guard",[],["acceptable.rs","host.rs","mod.rs"]],["http",[["header",[],["accept.rs","accept_charset.rs","accept_encoding.rs","accept_language.rs","allow.rs","cache_control.rs","content_disposition.rs","content_language.rs","content_length.rs","content_range.rs","content_type.rs","date.rs","encoding.rs","entity.rs","etag.rs","expires.rs","if_match.rs","if_modified_since.rs","if_none_match.rs","if_range.rs","if_unmodified_since.rs","last_modified.rs","macros.rs","mod.rs","preference.rs","range.rs"]]],["mod.rs"]],["middleware",[],["compat.rs","compress.rs","condition.rs","default_headers.rs","err_handlers.rs","logger.rs","mod.rs","normalize.rs"]],["response",[],["builder.rs","customize_responder.rs","http_codes.rs","mod.rs","responder.rs","response.rs"]],["test",[],["mod.rs","test_request.rs","test_services.rs","test_utils.rs"]],["types",[],["either.rs","form.rs","header.rs","json.rs","mod.rs","path.rs","payload.rs","query.rs","readlines.rs"]]],["app.rs","app_service.rs","config.rs","data.rs","dev.rs","extract.rs","handler.rs","helpers.rs","info.rs","lib.rs","redirect.rs","request.rs","request_data.rs","resource.rs","rmap.rs","route.rs","rt.rs","scope.rs","server.rs","service.rs","web.rs"]]],\ +["actix_web_actors",["",[],["context.rs","lib.rs","ws.rs"]]],\ +["actix_web_codegen",["",[],["lib.rs","route.rs"]]],\ +["awc",["",[["client",[],["config.rs","connection.rs","connector.rs","error.rs","h1proto.rs","h2proto.rs","mod.rs","pool.rs"]],["middleware",[],["mod.rs","redirect.rs"]],["responses",[],["json_body.rs","mod.rs","read_body.rs","response.rs","response_body.rs"]]],["any_body.rs","builder.rs","connect.rs","error.rs","frozen.rs","lib.rs","request.rs","sender.rs","test.rs","ws.rs"]]]\ +]')); +createSrcSidebar(); diff --git a/src/actix_files/chunked.rs.html b/src/actix_files/chunked.rs.html new file mode 100644 index 000000000..62baabf23 --- /dev/null +++ b/src/actix_files/chunked.rs.html @@ -0,0 +1,435 @@ +chunked.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::{
+    cmp, fmt,
+    future::Future,
+    io,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use actix_web::{error::Error, web::Bytes};
+#[cfg(feature = "experimental-io-uring")]
+use bytes::BytesMut;
+use futures_core::{ready, Stream};
+use pin_project_lite::pin_project;
+
+use super::named::File;
+
+pin_project! {
+    /// Adapter to read a `std::file::File` in chunks.
+    #[doc(hidden)]
+    pub struct ChunkedReadFile<F, Fut> {
+        size: u64,
+        offset: u64,
+        #[pin]
+        state: ChunkedReadFileState<Fut>,
+        counter: u64,
+        callback: F,
+    }
+}
+
+#[cfg(not(feature = "experimental-io-uring"))]
+pin_project! {
+    #[project = ChunkedReadFileStateProj]
+    #[project_replace = ChunkedReadFileStateProjReplace]
+    enum ChunkedReadFileState<Fut> {
+        File { file: Option<File>, },
+        Future { #[pin] fut: Fut },
+    }
+}
+
+#[cfg(feature = "experimental-io-uring")]
+pin_project! {
+    #[project = ChunkedReadFileStateProj]
+    #[project_replace = ChunkedReadFileStateProjReplace]
+    enum ChunkedReadFileState<Fut> {
+        File { file: Option<(File, BytesMut)> },
+        Future { #[pin] fut: Fut },
+    }
+}
+
+impl<F, Fut> fmt::Debug for ChunkedReadFile<F, Fut> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("ChunkedReadFile")
+    }
+}
+
+pub(crate) fn new_chunked_read(
+    size: u64,
+    offset: u64,
+    file: File,
+) -> impl Stream<Item = Result<Bytes, Error>> {
+    ChunkedReadFile {
+        size,
+        offset,
+        #[cfg(not(feature = "experimental-io-uring"))]
+        state: ChunkedReadFileState::File { file: Some(file) },
+        #[cfg(feature = "experimental-io-uring")]
+        state: ChunkedReadFileState::File {
+            file: Some((file, BytesMut::new())),
+        },
+        counter: 0,
+        callback: chunked_read_file_callback,
+    }
+}
+
+#[cfg(not(feature = "experimental-io-uring"))]
+async fn chunked_read_file_callback(
+    mut file: File,
+    offset: u64,
+    max_bytes: usize,
+) -> Result<(File, Bytes), Error> {
+    use io::{Read as _, Seek as _};
+
+    let res = actix_web::web::block(move || {
+        let mut buf = Vec::with_capacity(max_bytes);
+
+        file.seek(io::SeekFrom::Start(offset))?;
+
+        let n_bytes = file.by_ref().take(max_bytes as u64).read_to_end(&mut buf)?;
+
+        if n_bytes == 0 {
+            Err(io::Error::from(io::ErrorKind::UnexpectedEof))
+        } else {
+            Ok((file, Bytes::from(buf)))
+        }
+    })
+    .await??;
+
+    Ok(res)
+}
+
+#[cfg(feature = "experimental-io-uring")]
+async fn chunked_read_file_callback(
+    file: File,
+    offset: u64,
+    max_bytes: usize,
+    mut bytes_mut: BytesMut,
+) -> io::Result<(File, Bytes, BytesMut)> {
+    bytes_mut.reserve(max_bytes);
+
+    let (res, mut bytes_mut) = file.read_at(bytes_mut, offset).await;
+    let n_bytes = res?;
+
+    if n_bytes == 0 {
+        return Err(io::ErrorKind::UnexpectedEof.into());
+    }
+
+    let bytes = bytes_mut.split_to(n_bytes).freeze();
+
+    Ok((file, bytes, bytes_mut))
+}
+
+#[cfg(feature = "experimental-io-uring")]
+impl<F, Fut> Stream for ChunkedReadFile<F, Fut>
+where
+    F: Fn(File, u64, usize, BytesMut) -> Fut,
+    Fut: Future<Output = io::Result<(File, Bytes, BytesMut)>>,
+{
+    type Item = Result<Bytes, Error>;
+
+    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        let mut this = self.as_mut().project();
+        match this.state.as_mut().project() {
+            ChunkedReadFileStateProj::File { file } => {
+                let size = *this.size;
+                let offset = *this.offset;
+                let counter = *this.counter;
+
+                if size == counter {
+                    Poll::Ready(None)
+                } else {
+                    let max_bytes = cmp::min(size.saturating_sub(counter), 65_536) as usize;
+
+                    let (file, bytes_mut) = file
+                        .take()
+                        .expect("ChunkedReadFile polled after completion");
+
+                    let fut = (this.callback)(file, offset, max_bytes, bytes_mut);
+
+                    this.state
+                        .project_replace(ChunkedReadFileState::Future { fut });
+
+                    self.poll_next(cx)
+                }
+            }
+            ChunkedReadFileStateProj::Future { fut } => {
+                let (file, bytes, bytes_mut) = ready!(fut.poll(cx))?;
+
+                this.state.project_replace(ChunkedReadFileState::File {
+                    file: Some((file, bytes_mut)),
+                });
+
+                *this.offset += bytes.len() as u64;
+                *this.counter += bytes.len() as u64;
+
+                Poll::Ready(Some(Ok(bytes)))
+            }
+        }
+    }
+}
+
+#[cfg(not(feature = "experimental-io-uring"))]
+impl<F, Fut> Stream for ChunkedReadFile<F, Fut>
+where
+    F: Fn(File, u64, usize) -> Fut,
+    Fut: Future<Output = Result<(File, Bytes), Error>>,
+{
+    type Item = Result<Bytes, Error>;
+
+    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        let mut this = self.as_mut().project();
+        match this.state.as_mut().project() {
+            ChunkedReadFileStateProj::File { file } => {
+                let size = *this.size;
+                let offset = *this.offset;
+                let counter = *this.counter;
+
+                if size == counter {
+                    Poll::Ready(None)
+                } else {
+                    let max_bytes = cmp::min(size.saturating_sub(counter), 65_536) as usize;
+
+                    let file = file
+                        .take()
+                        .expect("ChunkedReadFile polled after completion");
+
+                    let fut = (this.callback)(file, offset, max_bytes);
+
+                    this.state
+                        .project_replace(ChunkedReadFileState::Future { fut });
+
+                    self.poll_next(cx)
+                }
+            }
+            ChunkedReadFileStateProj::Future { fut } => {
+                let (file, bytes) = ready!(fut.poll(cx))?;
+
+                this.state
+                    .project_replace(ChunkedReadFileState::File { file: Some(file) });
+
+                *this.offset += bytes.len() as u64;
+                *this.counter += bytes.len() as u64;
+
+                Poll::Ready(Some(Ok(bytes)))
+            }
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_files/directory.rs.html b/src/actix_files/directory.rs.html new file mode 100644 index 000000000..06209ff13 --- /dev/null +++ b/src/actix_files/directory.rs.html @@ -0,0 +1,253 @@ +directory.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
+
use std::{
+    fmt::Write,
+    fs::DirEntry,
+    io,
+    path::{Path, PathBuf},
+};
+
+use actix_web::{dev::ServiceResponse, HttpRequest, HttpResponse};
+use percent_encoding::{utf8_percent_encode, CONTROLS};
+use v_htmlescape::escape as escape_html_entity;
+
+/// A directory; responds with the generated directory listing.
+#[derive(Debug)]
+pub struct Directory {
+    /// Base directory.
+    pub base: PathBuf,
+
+    /// Path of subdirectory to generate listing for.
+    pub path: PathBuf,
+}
+
+impl Directory {
+    /// Create a new directory
+    pub fn new(base: PathBuf, path: PathBuf) -> Directory {
+        Directory { base, path }
+    }
+
+    /// Is this entry visible from this directory?
+    pub fn is_visible(&self, entry: &io::Result<DirEntry>) -> bool {
+        if let Ok(ref entry) = *entry {
+            if let Some(name) = entry.file_name().to_str() {
+                if name.starts_with('.') {
+                    return false;
+                }
+            }
+            if let Ok(ref md) = entry.metadata() {
+                let ft = md.file_type();
+                return ft.is_dir() || ft.is_file() || ft.is_symlink();
+            }
+        }
+        false
+    }
+}
+
+pub(crate) type DirectoryRenderer =
+    dyn Fn(&Directory, &HttpRequest) -> Result<ServiceResponse, io::Error>;
+
+/// Returns percent encoded file URL path.
+macro_rules! encode_file_url {
+    ($path:ident) => {
+        utf8_percent_encode(&$path, CONTROLS)
+    };
+}
+
+/// Returns HTML entity encoded formatter.
+///
+/// ```plain
+/// " => &quot;
+/// & => &amp;
+/// ' => &#x27;
+/// < => &lt;
+/// > => &gt;
+/// / => &#x2f;
+/// ```
+macro_rules! encode_file_name {
+    ($entry:ident) => {
+        escape_html_entity(&$entry.file_name().to_string_lossy())
+    };
+}
+
+pub(crate) fn directory_listing(
+    dir: &Directory,
+    req: &HttpRequest,
+) -> Result<ServiceResponse, io::Error> {
+    let index_of = format!("Index of {}", req.path());
+    let mut body = String::new();
+    let base = Path::new(req.path());
+
+    for entry in dir.path.read_dir()? {
+        if dir.is_visible(&entry) {
+            let entry = entry.unwrap();
+            let p = match entry.path().strip_prefix(&dir.path) {
+                Ok(p) if cfg!(windows) => base.join(p).to_string_lossy().replace('\\', "/"),
+                Ok(p) => base.join(p).to_string_lossy().into_owned(),
+                Err(_) => continue,
+            };
+
+            // if file is a directory, add '/' to the end of the name
+            if let Ok(metadata) = entry.metadata() {
+                if metadata.is_dir() {
+                    let _ = write!(
+                        body,
+                        "<li><a href=\"{}\">{}/</a></li>",
+                        encode_file_url!(p),
+                        encode_file_name!(entry),
+                    );
+                } else {
+                    let _ = write!(
+                        body,
+                        "<li><a href=\"{}\">{}</a></li>",
+                        encode_file_url!(p),
+                        encode_file_name!(entry),
+                    );
+                }
+            } else {
+                continue;
+            }
+        }
+    }
+
+    let html = format!(
+        "<html>\
+         <head><title>{}</title></head>\
+         <body><h1>{}</h1>\
+         <ul>\
+         {}\
+         </ul></body>\n</html>",
+        index_of, index_of, body
+    );
+    Ok(ServiceResponse::new(
+        req.clone(),
+        HttpResponse::Ok()
+            .content_type("text/html; charset=utf-8")
+            .body(html),
+    ))
+}
+
\ No newline at end of file diff --git a/src/actix_files/encoding.rs.html b/src/actix_files/encoding.rs.html new file mode 100644 index 000000000..a51f73856 --- /dev/null +++ b/src/actix_files/encoding.rs.html @@ -0,0 +1,105 @@ +encoding.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
+
use mime::Mime;
+
+/// Transforms MIME `text/*` types into their UTF-8 equivalent, if supported.
+///
+/// MIME types that are converted
+/// - application/javascript
+/// - text/html
+/// - text/css
+/// - text/plain
+/// - text/csv
+/// - text/tab-separated-values
+pub(crate) fn equiv_utf8_text(ct: Mime) -> Mime {
+    // use (roughly) order of file-type popularity for a web server
+
+    if ct == mime::APPLICATION_JAVASCRIPT {
+        return mime::APPLICATION_JAVASCRIPT_UTF_8;
+    }
+
+    if ct == mime::TEXT_HTML {
+        return mime::TEXT_HTML_UTF_8;
+    }
+
+    if ct == mime::TEXT_CSS {
+        return mime::TEXT_CSS_UTF_8;
+    }
+
+    if ct == mime::TEXT_PLAIN {
+        return mime::TEXT_PLAIN_UTF_8;
+    }
+
+    if ct == mime::TEXT_CSV {
+        return mime::TEXT_CSV_UTF_8;
+    }
+
+    if ct == mime::TEXT_TAB_SEPARATED_VALUES {
+        return mime::TEXT_TAB_SEPARATED_VALUES_UTF_8;
+    }
+
+    ct
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_equiv_utf8_text() {
+        assert_eq!(equiv_utf8_text(mime::TEXT_PLAIN), mime::TEXT_PLAIN_UTF_8);
+        assert_eq!(equiv_utf8_text(mime::TEXT_XML), mime::TEXT_XML);
+        assert_eq!(equiv_utf8_text(mime::IMAGE_PNG), mime::IMAGE_PNG);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_files/error.rs.html b/src/actix_files/error.rs.html new file mode 100644 index 000000000..2dc96dab3 --- /dev/null +++ b/src/actix_files/error.rs.html @@ -0,0 +1,99 @@ +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
+
use actix_web::{http::StatusCode, ResponseError};
+use derive_more::Display;
+
+/// Errors which can occur when serving static files.
+#[derive(Debug, PartialEq, Eq, Display)]
+pub enum FilesError {
+    /// Path is not a directory.
+    #[allow(dead_code)]
+    #[display(fmt = "path is not a directory. Unable to serve static files")]
+    IsNotDirectory,
+
+    /// Cannot render directory.
+    #[display(fmt = "unable to render directory without index file")]
+    IsDirectory,
+}
+
+impl ResponseError for FilesError {
+    /// Returns `404 Not Found`.
+    fn status_code(&self) -> StatusCode {
+        StatusCode::NOT_FOUND
+    }
+}
+
+#[derive(Debug, PartialEq, Eq, Display)]
+#[non_exhaustive]
+pub enum UriSegmentError {
+    /// Segment started with the wrapped invalid character.
+    #[display(fmt = "segment started with invalid character: ('{_0}')")]
+    BadStart(char),
+
+    /// Segment contained the wrapped invalid character.
+    #[display(fmt = "segment contained invalid character ('{_0}')")]
+    BadChar(char),
+
+    /// Segment ended with the wrapped invalid character.
+    #[display(fmt = "segment ended with invalid character: ('{_0}')")]
+    BadEnd(char),
+
+    /// Path is not a valid UTF-8 string after percent-decoding.
+    #[display(fmt = "path is not a valid UTF-8 string after percent-decoding")]
+    NotValidUtf8,
+}
+
+impl ResponseError for UriSegmentError {
+    /// Returns `400 Bad Request`.
+    fn status_code(&self) -> StatusCode {
+        StatusCode::BAD_REQUEST
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_files/files.rs.html b/src/actix_files/files.rs.html new file mode 100644 index 000000000..db8a7eade --- /dev/null +++ b/src/actix_files/files.rs.html @@ -0,0 +1,861 @@ +files.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
+
use std::{
+    cell::RefCell,
+    fmt, io,
+    path::{Path, PathBuf},
+    rc::Rc,
+};
+
+use actix_service::{boxed, IntoServiceFactory, ServiceFactory, ServiceFactoryExt};
+use actix_web::{
+    dev::{
+        AppService, HttpServiceFactory, RequestHead, ResourceDef, ServiceRequest, ServiceResponse,
+    },
+    error::Error,
+    guard::Guard,
+    http::header::DispositionType,
+    HttpRequest,
+};
+use futures_core::future::LocalBoxFuture;
+
+use crate::{
+    directory_listing, named,
+    service::{FilesService, FilesServiceInner},
+    Directory, DirectoryRenderer, HttpNewService, MimeOverride, PathFilter,
+};
+
+/// Static files handling service.
+///
+/// `Files` service must be registered with `App::service()` method.
+///
+/// # Examples
+/// ```
+/// use actix_web::App;
+/// use actix_files::Files;
+///
+/// let app = App::new()
+///     .service(Files::new("/static", "."));
+/// ```
+pub struct Files {
+    mount_path: String,
+    directory: PathBuf,
+    index: Option<String>,
+    show_index: bool,
+    redirect_to_slash: bool,
+    default: Rc<RefCell<Option<Rc<HttpNewService>>>>,
+    renderer: Rc<DirectoryRenderer>,
+    mime_override: Option<Rc<MimeOverride>>,
+    path_filter: Option<Rc<PathFilter>>,
+    file_flags: named::Flags,
+    use_guards: Option<Rc<dyn Guard>>,
+    guards: Vec<Rc<dyn Guard>>,
+    hidden_files: bool,
+}
+
+impl fmt::Debug for Files {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("Files")
+    }
+}
+
+impl Clone for Files {
+    fn clone(&self) -> Self {
+        Self {
+            directory: self.directory.clone(),
+            index: self.index.clone(),
+            show_index: self.show_index,
+            redirect_to_slash: self.redirect_to_slash,
+            default: self.default.clone(),
+            renderer: self.renderer.clone(),
+            file_flags: self.file_flags,
+            mount_path: self.mount_path.clone(),
+            mime_override: self.mime_override.clone(),
+            path_filter: self.path_filter.clone(),
+            use_guards: self.use_guards.clone(),
+            guards: self.guards.clone(),
+            hidden_files: self.hidden_files,
+        }
+    }
+}
+
+impl Files {
+    /// Create new `Files` instance for a specified base directory.
+    ///
+    /// # Argument Order
+    /// The first argument (`mount_path`) is the root URL at which the static files are served.
+    /// For example, `/assets` will serve files at `example.com/assets/...`.
+    ///
+    /// The second argument (`serve_from`) is the location on disk at which files are loaded.
+    /// This can be a relative path. For example, `./` would serve files from the current
+    /// working directory.
+    ///
+    /// # Implementation Notes
+    /// If the mount path is set as the root path `/`, services registered after this one will
+    /// be inaccessible. Register more specific handlers and services first.
+    ///
+    /// `Files` utilizes the existing Tokio thread-pool for blocking filesystem operations.
+    /// The number of running threads is adjusted over time as needed, up to a maximum of 512 times
+    /// the number of server [workers](actix_web::HttpServer::workers), by default.
+    pub fn new<T: Into<PathBuf>>(mount_path: &str, serve_from: T) -> Files {
+        let orig_dir = serve_from.into();
+        let dir = match orig_dir.canonicalize() {
+            Ok(canon_dir) => canon_dir,
+            Err(_) => {
+                log::error!("Specified path is not a directory: {:?}", orig_dir);
+                PathBuf::new()
+            }
+        };
+
+        Files {
+            mount_path: mount_path.trim_end_matches('/').to_owned(),
+            directory: dir,
+            index: None,
+            show_index: false,
+            redirect_to_slash: false,
+            default: Rc::new(RefCell::new(None)),
+            renderer: Rc::new(directory_listing),
+            mime_override: None,
+            path_filter: None,
+            file_flags: named::Flags::default(),
+            use_guards: None,
+            guards: Vec::new(),
+            hidden_files: false,
+        }
+    }
+
+    /// Show files listing for directories.
+    ///
+    /// By default show files listing is disabled.
+    ///
+    /// When used with [`Files::index_file()`], files listing is shown as a fallback
+    /// when the index file is not found.
+    pub fn show_files_listing(mut self) -> Self {
+        self.show_index = true;
+        self
+    }
+
+    /// Redirects to a slash-ended path when browsing a directory.
+    ///
+    /// By default never redirect.
+    pub fn redirect_to_slash_directory(mut self) -> Self {
+        self.redirect_to_slash = true;
+        self
+    }
+
+    /// Set custom directory renderer.
+    pub fn files_listing_renderer<F>(mut self, f: F) -> Self
+    where
+        for<'r, 's> F:
+            Fn(&'r Directory, &'s HttpRequest) -> Result<ServiceResponse, io::Error> + 'static,
+    {
+        self.renderer = Rc::new(f);
+        self
+    }
+
+    /// Specifies MIME override callback.
+    pub fn mime_override<F>(mut self, f: F) -> Self
+    where
+        F: Fn(&mime::Name<'_>) -> DispositionType + 'static,
+    {
+        self.mime_override = Some(Rc::new(f));
+        self
+    }
+
+    /// Sets path filtering closure.
+    ///
+    /// The path provided to the closure is relative to `serve_from` path.
+    /// You can safely join this path with the `serve_from` path to get the real path.
+    /// However, the real path may not exist since the filter is called before checking path existence.
+    ///
+    /// When a path doesn't pass the filter, [`Files::default_handler`] is called if set, otherwise,
+    /// `404 Not Found` is returned.
+    ///
+    /// # Examples
+    /// ```
+    /// use std::path::Path;
+    /// use actix_files::Files;
+    ///
+    /// // prevent searching subdirectories and following symlinks
+    /// let files_service = Files::new("/", "./static").path_filter(|path, _| {
+    ///     path.components().count() == 1
+    ///         && Path::new("./static")
+    ///             .join(path)
+    ///             .symlink_metadata()
+    ///             .map(|m| !m.file_type().is_symlink())
+    ///             .unwrap_or(false)
+    /// });
+    /// ```
+    pub fn path_filter<F>(mut self, f: F) -> Self
+    where
+        F: Fn(&Path, &RequestHead) -> bool + 'static,
+    {
+        self.path_filter = Some(Rc::new(f));
+        self
+    }
+
+    /// Set index file
+    ///
+    /// Shows specific index file for directories instead of
+    /// showing files listing.
+    ///
+    /// If the index file is not found, files listing is shown as a fallback if
+    /// [`Files::show_files_listing()`] is set.
+    pub fn index_file<T: Into<String>>(mut self, index: T) -> Self {
+        self.index = Some(index.into());
+        self
+    }
+
+    /// Specifies whether to use ETag or not.
+    ///
+    /// Default is true.
+    pub fn use_etag(mut self, value: bool) -> Self {
+        self.file_flags.set(named::Flags::ETAG, value);
+        self
+    }
+
+    /// Specifies whether to use Last-Modified or not.
+    ///
+    /// Default is true.
+    pub fn use_last_modified(mut self, value: bool) -> Self {
+        self.file_flags.set(named::Flags::LAST_MD, value);
+        self
+    }
+
+    /// Specifies whether text responses should signal a UTF-8 encoding.
+    ///
+    /// Default is false (but will default to true in a future version).
+    pub fn prefer_utf8(mut self, value: bool) -> Self {
+        self.file_flags.set(named::Flags::PREFER_UTF8, value);
+        self
+    }
+
+    /// Adds a routing guard.
+    ///
+    /// Use this to allow multiple chained file services that respond to strictly different
+    /// properties of a request. Due to the way routing works, if a guard check returns true and the
+    /// request starts being handled by the file service, it will not be able to back-out and try
+    /// the next service, you will simply get a 404 (or 405) error response.
+    ///
+    /// To allow `POST` requests to retrieve files, see [`Files::method_guard()`].
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::{guard::Header, App};
+    /// use actix_files::Files;
+    ///
+    /// App::new().service(
+    ///     Files::new("/","/my/site/files")
+    ///         .guard(Header("Host", "example.com"))
+    /// );
+    /// ```
+    pub fn guard<G: Guard + 'static>(mut self, guard: G) -> Self {
+        self.guards.push(Rc::new(guard));
+        self
+    }
+
+    /// Specifies guard to check before fetching directory listings or files.
+    ///
+    /// Note that this guard has no effect on routing; it's main use is to guard on the request's
+    /// method just before serving the file, only allowing `GET` and `HEAD` requests by default.
+    /// See [`Files::guard`] for routing guards.
+    pub fn method_guard<G: Guard + 'static>(mut self, guard: G) -> Self {
+        self.use_guards = Some(Rc::new(guard));
+        self
+    }
+
+    /// See [`Files::method_guard`].
+    #[doc(hidden)]
+    #[deprecated(since = "0.6.0", note = "Renamed to `method_guard`.")]
+    pub fn use_guards<G: Guard + 'static>(self, guard: G) -> Self {
+        self.method_guard(guard)
+    }
+
+    /// Disable `Content-Disposition` header.
+    ///
+    /// By default Content-Disposition` header is enabled.
+    pub fn disable_content_disposition(mut self) -> Self {
+        self.file_flags.remove(named::Flags::CONTENT_DISPOSITION);
+        self
+    }
+
+    /// Sets default handler which is used when no matched file could be found.
+    ///
+    /// # Examples
+    /// Setting a fallback static file handler:
+    /// ```
+    /// use actix_files::{Files, NamedFile};
+    /// use actix_web::dev::{ServiceRequest, ServiceResponse, fn_service};
+    ///
+    /// # fn run() -> Result<(), actix_web::Error> {
+    /// let files = Files::new("/", "./static")
+    ///     .index_file("index.html")
+    ///     .default_handler(fn_service(|req: ServiceRequest| async {
+    ///         let (req, _) = req.into_parts();
+    ///         let file = NamedFile::open_async("./static/404.html").await?;
+    ///         let res = file.into_response(&req);
+    ///         Ok(ServiceResponse::new(req, res))
+    ///     }));
+    /// # Ok(())
+    /// # }
+    /// ```
+    pub fn default_handler<F, U>(mut self, f: F) -> Self
+    where
+        F: IntoServiceFactory<U, ServiceRequest>,
+        U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error>
+            + 'static,
+    {
+        // create and configure default resource
+        self.default = Rc::new(RefCell::new(Some(Rc::new(boxed::factory(
+            f.into_factory().map_init_err(|_| ()),
+        )))));
+
+        self
+    }
+
+    /// Enables serving hidden files and directories, allowing a leading dots in url fragments.
+    pub fn use_hidden_files(mut self) -> Self {
+        self.hidden_files = true;
+        self
+    }
+}
+
+impl HttpServiceFactory for Files {
+    fn register(mut self, config: &mut AppService) {
+        let guards = if self.guards.is_empty() {
+            None
+        } else {
+            let guards = std::mem::take(&mut self.guards);
+            Some(
+                guards
+                    .into_iter()
+                    .map(|guard| -> Box<dyn Guard> { Box::new(guard) })
+                    .collect::<Vec<_>>(),
+            )
+        };
+
+        if self.default.borrow().is_none() {
+            *self.default.borrow_mut() = Some(config.default_service());
+        }
+
+        let rdef = if config.is_root() {
+            ResourceDef::root_prefix(&self.mount_path)
+        } else {
+            ResourceDef::prefix(&self.mount_path)
+        };
+
+        config.register_service(rdef, guards, self, None)
+    }
+}
+
+impl ServiceFactory<ServiceRequest> for Files {
+    type Response = ServiceResponse;
+    type Error = Error;
+    type Config = ();
+    type Service = FilesService;
+    type InitError = ();
+    type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
+
+    fn new_service(&self, _: ()) -> Self::Future {
+        let mut inner = FilesServiceInner {
+            directory: self.directory.clone(),
+            index: self.index.clone(),
+            show_index: self.show_index,
+            redirect_to_slash: self.redirect_to_slash,
+            default: None,
+            renderer: self.renderer.clone(),
+            mime_override: self.mime_override.clone(),
+            path_filter: self.path_filter.clone(),
+            file_flags: self.file_flags,
+            guards: self.use_guards.clone(),
+            hidden_files: self.hidden_files,
+        };
+
+        if let Some(ref default) = *self.default.borrow() {
+            let fut = default.new_service(());
+            Box::pin(async {
+                match fut.await {
+                    Ok(default) => {
+                        inner.default = Some(default);
+                        Ok(FilesService(Rc::new(inner)))
+                    }
+                    Err(_) => Err(()),
+                }
+            })
+        } else {
+            Box::pin(async move { Ok(FilesService(Rc::new(inner))) })
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_web::{
+        http::StatusCode,
+        test::{self, TestRequest},
+        App, HttpResponse,
+    };
+
+    use super::*;
+
+    #[actix_web::test]
+    async fn custom_files_listing_renderer() {
+        let srv = test::init_service(
+            App::new().service(
+                Files::new("/", "./tests")
+                    .show_files_listing()
+                    .files_listing_renderer(|dir, req| {
+                        Ok(ServiceResponse::new(
+                            req.clone(),
+                            HttpResponse::Ok().body(dir.path.to_str().unwrap().to_owned()),
+                        ))
+                    }),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/").to_request();
+        let res = test::call_service(&srv, req).await;
+
+        assert_eq!(res.status(), StatusCode::OK);
+        let body = test::read_body(res).await;
+        let body_str = std::str::from_utf8(&body).unwrap();
+        let actual_path = Path::new(&body_str);
+        let expected_path = Path::new("actix-files/tests");
+        assert!(
+            actual_path.ends_with(expected_path),
+            "body {:?} does not end with {:?}",
+            actual_path,
+            expected_path
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_files/lib.rs.html b/src/actix_files/lib.rs.html new file mode 100644 index 000000000..724277809 --- /dev/null +++ b/src/actix_files/lib.rs.html @@ -0,0 +1,2079 @@ +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
+
//! Static file serving for Actix Web.
+//!
+//! Provides a non-blocking service for serving static files from disk.
+//!
+//! # Examples
+//! ```
+//! use actix_web::App;
+//! use actix_files::Files;
+//!
+//! let app = App::new()
+//!     .service(Files::new("/static", ".").prefer_utf8(true));
+//! ```
+
+#![deny(rust_2018_idioms, nonstandard_style)]
+#![warn(future_incompatible, missing_docs, missing_debug_implementations)]
+#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
+#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+
+use std::path::Path;
+
+use actix_service::boxed::{BoxService, BoxServiceFactory};
+use actix_web::{
+    dev::{RequestHead, ServiceRequest, ServiceResponse},
+    error::Error,
+    http::header::DispositionType,
+};
+use mime_guess::from_ext;
+
+mod chunked;
+mod directory;
+mod encoding;
+mod error;
+mod files;
+mod named;
+mod path_buf;
+mod range;
+mod service;
+
+pub use self::{
+    chunked::ChunkedReadFile, directory::Directory, files::Files, named::NamedFile,
+    range::HttpRange, service::FilesService,
+};
+use self::{
+    directory::{directory_listing, DirectoryRenderer},
+    error::FilesError,
+    path_buf::PathBufWrap,
+};
+
+type HttpService = BoxService<ServiceRequest, ServiceResponse, Error>;
+type HttpNewService = BoxServiceFactory<(), ServiceRequest, ServiceResponse, Error, ()>;
+
+/// Return the MIME type associated with a filename extension (case-insensitive).
+/// If `ext` is empty or no associated type for the extension was found, returns
+/// the type `application/octet-stream`.
+#[inline]
+pub fn file_extension_to_mime(ext: &str) -> mime::Mime {
+    from_ext(ext).first_or_octet_stream()
+}
+
+type MimeOverride = dyn Fn(&mime::Name<'_>) -> DispositionType;
+
+type PathFilter = dyn Fn(&Path, &RequestHead) -> bool;
+
+#[cfg(test)]
+mod tests {
+    use std::{
+        fmt::Write as _,
+        fs::{self},
+        ops::Add,
+        time::{Duration, SystemTime},
+    };
+
+    use actix_web::{
+        dev::ServiceFactory,
+        guard,
+        http::{
+            header::{self, ContentDisposition, DispositionParam},
+            Method, StatusCode,
+        },
+        middleware::Compress,
+        test::{self, TestRequest},
+        web::{self, Bytes},
+        App, HttpResponse, Responder,
+    };
+
+    use super::*;
+    use crate::named::File;
+
+    #[actix_web::test]
+    async fn test_file_extension_to_mime() {
+        let m = file_extension_to_mime("");
+        assert_eq!(m, mime::APPLICATION_OCTET_STREAM);
+
+        let m = file_extension_to_mime("jpg");
+        assert_eq!(m, mime::IMAGE_JPEG);
+
+        let m = file_extension_to_mime("invalid extension!!");
+        assert_eq!(m, mime::APPLICATION_OCTET_STREAM);
+
+        let m = file_extension_to_mime("");
+        assert_eq!(m, mime::APPLICATION_OCTET_STREAM);
+    }
+
+    #[actix_rt::test]
+    async fn test_if_modified_since_without_if_none_match() {
+        let file = NamedFile::open_async("Cargo.toml").await.unwrap();
+        let since = header::HttpDate::from(SystemTime::now().add(Duration::from_secs(60)));
+
+        let req = TestRequest::default()
+            .insert_header((header::IF_MODIFIED_SINCE, since))
+            .to_http_request();
+        let resp = file.respond_to(&req);
+        assert_eq!(resp.status(), StatusCode::NOT_MODIFIED);
+    }
+
+    #[actix_rt::test]
+    async fn test_if_modified_since_without_if_none_match_same() {
+        let file = NamedFile::open_async("Cargo.toml").await.unwrap();
+        let since = file.last_modified().unwrap();
+
+        let req = TestRequest::default()
+            .insert_header((header::IF_MODIFIED_SINCE, since))
+            .to_http_request();
+        let resp = file.respond_to(&req);
+        assert_eq!(resp.status(), StatusCode::NOT_MODIFIED);
+    }
+
+    #[actix_rt::test]
+    async fn test_if_modified_since_with_if_none_match() {
+        let file = NamedFile::open_async("Cargo.toml").await.unwrap();
+        let since = header::HttpDate::from(SystemTime::now().add(Duration::from_secs(60)));
+
+        let req = TestRequest::default()
+            .insert_header((header::IF_NONE_MATCH, "miss_etag"))
+            .insert_header((header::IF_MODIFIED_SINCE, since))
+            .to_http_request();
+        let resp = file.respond_to(&req);
+        assert_ne!(resp.status(), StatusCode::NOT_MODIFIED);
+    }
+
+    #[actix_rt::test]
+    async fn test_if_unmodified_since() {
+        let file = NamedFile::open_async("Cargo.toml").await.unwrap();
+        let since = file.last_modified().unwrap();
+
+        let req = TestRequest::default()
+            .insert_header((header::IF_UNMODIFIED_SINCE, since))
+            .to_http_request();
+        let resp = file.respond_to(&req);
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_if_unmodified_since_failed() {
+        let file = NamedFile::open_async("Cargo.toml").await.unwrap();
+        let since = header::HttpDate::from(SystemTime::UNIX_EPOCH);
+
+        let req = TestRequest::default()
+            .insert_header((header::IF_UNMODIFIED_SINCE, since))
+            .to_http_request();
+        let resp = file.respond_to(&req);
+        assert_eq!(resp.status(), StatusCode::PRECONDITION_FAILED);
+    }
+
+    #[actix_rt::test]
+    async fn test_named_file_text() {
+        assert!(NamedFile::open_async("test--").await.is_err());
+        let mut file = NamedFile::open_async("Cargo.toml").await.unwrap();
+        {
+            file.file();
+            let _f: &File = &file;
+        }
+        {
+            let _f: &mut File = &mut file;
+        }
+
+        let req = TestRequest::default().to_http_request();
+        let resp = file.respond_to(&req);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            "text/x-toml"
+        );
+        assert_eq!(
+            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+            "inline; filename=\"Cargo.toml\""
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_named_file_content_disposition() {
+        assert!(NamedFile::open_async("test--").await.is_err());
+        let mut file = NamedFile::open_async("Cargo.toml").await.unwrap();
+        {
+            file.file();
+            let _f: &File = &file;
+        }
+        {
+            let _f: &mut File = &mut file;
+        }
+
+        let req = TestRequest::default().to_http_request();
+        let resp = file.respond_to(&req);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+            "inline; filename=\"Cargo.toml\""
+        );
+
+        let file = NamedFile::open_async("Cargo.toml")
+            .await
+            .unwrap()
+            .disable_content_disposition();
+        let req = TestRequest::default().to_http_request();
+        let resp = file.respond_to(&req);
+        assert!(resp.headers().get(header::CONTENT_DISPOSITION).is_none());
+    }
+
+    #[actix_rt::test]
+    async fn test_named_file_non_ascii_file_name() {
+        let file = {
+            #[cfg(feature = "experimental-io-uring")]
+            {
+                crate::named::File::open("Cargo.toml").await.unwrap()
+            }
+
+            #[cfg(not(feature = "experimental-io-uring"))]
+            {
+                crate::named::File::open("Cargo.toml").unwrap()
+            }
+        };
+
+        let mut file = NamedFile::from_file(file, "貨物.toml").unwrap();
+        {
+            file.file();
+            let _f: &File = &file;
+        }
+        {
+            let _f: &mut File = &mut file;
+        }
+
+        let req = TestRequest::default().to_http_request();
+        let resp = file.respond_to(&req);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            "text/x-toml"
+        );
+        assert_eq!(
+            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+            "inline; filename=\"貨物.toml\"; filename*=UTF-8''%E8%B2%A8%E7%89%A9.toml"
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_named_file_set_content_type() {
+        let mut file = NamedFile::open_async("Cargo.toml")
+            .await
+            .unwrap()
+            .set_content_type(mime::TEXT_XML);
+        {
+            file.file();
+            let _f: &File = &file;
+        }
+        {
+            let _f: &mut File = &mut file;
+        }
+
+        let req = TestRequest::default().to_http_request();
+        let resp = file.respond_to(&req);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            "text/xml"
+        );
+        assert_eq!(
+            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+            "inline; filename=\"Cargo.toml\""
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_named_file_image() {
+        let mut file = NamedFile::open_async("tests/test.png").await.unwrap();
+        {
+            file.file();
+            let _f: &File = &file;
+        }
+        {
+            let _f: &mut File = &mut file;
+        }
+
+        let req = TestRequest::default().to_http_request();
+        let resp = file.respond_to(&req);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            "image/png"
+        );
+        assert_eq!(
+            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+            "inline; filename=\"test.png\""
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_named_file_javascript() {
+        let file = NamedFile::open_async("tests/test.js").await.unwrap();
+
+        let req = TestRequest::default().to_http_request();
+        let resp = file.respond_to(&req);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            "application/javascript; charset=utf-8"
+        );
+        assert_eq!(
+            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+            "inline; filename=\"test.js\""
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_named_file_image_attachment() {
+        let cd = ContentDisposition {
+            disposition: DispositionType::Attachment,
+            parameters: vec![DispositionParam::Filename(String::from("test.png"))],
+        };
+        let mut file = NamedFile::open_async("tests/test.png")
+            .await
+            .unwrap()
+            .set_content_disposition(cd);
+        {
+            file.file();
+            let _f: &File = &file;
+        }
+        {
+            let _f: &mut File = &mut file;
+        }
+
+        let req = TestRequest::default().to_http_request();
+        let resp = file.respond_to(&req);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            "image/png"
+        );
+        assert_eq!(
+            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+            "attachment; filename=\"test.png\""
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_named_file_binary() {
+        let mut file = NamedFile::open_async("tests/test.binary").await.unwrap();
+        {
+            file.file();
+            let _f: &File = &file;
+        }
+        {
+            let _f: &mut File = &mut file;
+        }
+
+        let req = TestRequest::default().to_http_request();
+        let resp = file.respond_to(&req);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            "application/octet-stream"
+        );
+        assert_eq!(
+            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+            "attachment; filename=\"test.binary\""
+        );
+    }
+
+    #[allow(deprecated)]
+    #[actix_rt::test]
+    async fn status_code_customize_same_output() {
+        let file1 = NamedFile::open_async("Cargo.toml")
+            .await
+            .unwrap()
+            .set_status_code(StatusCode::NOT_FOUND);
+
+        let file2 = NamedFile::open_async("Cargo.toml")
+            .await
+            .unwrap()
+            .customize()
+            .with_status(StatusCode::NOT_FOUND);
+
+        let req = TestRequest::default().to_http_request();
+        let res1 = file1.respond_to(&req);
+        let res2 = file2.respond_to(&req);
+
+        assert_eq!(res1.status(), StatusCode::NOT_FOUND);
+        assert_eq!(res2.status(), StatusCode::NOT_FOUND);
+    }
+
+    #[actix_rt::test]
+    async fn test_named_file_status_code_text() {
+        let mut file = NamedFile::open_async("Cargo.toml").await.unwrap();
+
+        {
+            file.file();
+            let _f: &File = &file;
+        }
+
+        {
+            let _f: &mut File = &mut file;
+        }
+
+        let file = file.customize().with_status(StatusCode::NOT_FOUND);
+
+        let req = TestRequest::default().to_http_request();
+        let resp = file.respond_to(&req);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            "text/x-toml"
+        );
+        assert_eq!(
+            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+            "inline; filename=\"Cargo.toml\""
+        );
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+    }
+
+    #[actix_rt::test]
+    async fn test_mime_override() {
+        fn all_attachment(_: &mime::Name<'_>) -> DispositionType {
+            DispositionType::Attachment
+        }
+
+        let srv = test::init_service(
+            App::new().service(
+                Files::new("/", ".")
+                    .mime_override(all_attachment)
+                    .index_file("Cargo.toml"),
+            ),
+        )
+        .await;
+
+        let request = TestRequest::get().uri("/").to_request();
+        let response = test::call_service(&srv, request).await;
+        assert_eq!(response.status(), StatusCode::OK);
+
+        let content_disposition = response
+            .headers()
+            .get(header::CONTENT_DISPOSITION)
+            .expect("To have CONTENT_DISPOSITION");
+        let content_disposition = content_disposition
+            .to_str()
+            .expect("Convert CONTENT_DISPOSITION to str");
+        assert_eq!(content_disposition, "attachment; filename=\"Cargo.toml\"");
+    }
+
+    #[actix_rt::test]
+    async fn test_named_file_ranges_status_code() {
+        let srv = test::init_service(
+            App::new().service(Files::new("/test", ".").index_file("Cargo.toml")),
+        )
+        .await;
+
+        // Valid range header
+        let request = TestRequest::get()
+            .uri("/t%65st/Cargo.toml")
+            .insert_header((header::RANGE, "bytes=10-20"))
+            .to_request();
+        let response = test::call_service(&srv, request).await;
+        assert_eq!(response.status(), StatusCode::PARTIAL_CONTENT);
+
+        // Invalid range header
+        let request = TestRequest::get()
+            .uri("/t%65st/Cargo.toml")
+            .insert_header((header::RANGE, "bytes=1-0"))
+            .to_request();
+        let response = test::call_service(&srv, request).await;
+
+        assert_eq!(response.status(), StatusCode::RANGE_NOT_SATISFIABLE);
+    }
+
+    #[actix_rt::test]
+    async fn test_named_file_content_range_headers() {
+        let srv = actix_test::start(|| App::new().service(Files::new("/", ".")));
+
+        // Valid range header
+        let response = srv
+            .get("/tests/test.binary")
+            .insert_header((header::RANGE, "bytes=10-20"))
+            .send()
+            .await
+            .unwrap();
+        let content_range = response.headers().get(header::CONTENT_RANGE).unwrap();
+        assert_eq!(content_range.to_str().unwrap(), "bytes 10-20/100");
+
+        // Invalid range header
+        let response = srv
+            .get("/tests/test.binary")
+            .insert_header((header::RANGE, "bytes=10-5"))
+            .send()
+            .await
+            .unwrap();
+        let content_range = response.headers().get(header::CONTENT_RANGE).unwrap();
+        assert_eq!(content_range.to_str().unwrap(), "bytes */100");
+    }
+
+    #[actix_rt::test]
+    async fn test_named_file_content_length_headers() {
+        let srv = actix_test::start(|| App::new().service(Files::new("/", ".")));
+
+        // Valid range header
+        let response = srv
+            .get("/tests/test.binary")
+            .insert_header((header::RANGE, "bytes=10-20"))
+            .send()
+            .await
+            .unwrap();
+        let content_length = response.headers().get(header::CONTENT_LENGTH).unwrap();
+        assert_eq!(content_length.to_str().unwrap(), "11");
+
+        // Valid range header, starting from 0
+        let response = srv
+            .get("/tests/test.binary")
+            .insert_header((header::RANGE, "bytes=0-20"))
+            .send()
+            .await
+            .unwrap();
+        let content_length = response.headers().get(header::CONTENT_LENGTH).unwrap();
+        assert_eq!(content_length.to_str().unwrap(), "21");
+
+        // Without range header
+        let mut response = srv.get("/tests/test.binary").send().await.unwrap();
+        let content_length = response.headers().get(header::CONTENT_LENGTH).unwrap();
+        assert_eq!(content_length.to_str().unwrap(), "100");
+
+        // Should be no transfer-encoding
+        let transfer_encoding = response.headers().get(header::TRANSFER_ENCODING);
+        assert!(transfer_encoding.is_none());
+
+        // Check file contents
+        let bytes = response.body().await.unwrap();
+        let data = web::Bytes::from(fs::read("tests/test.binary").unwrap());
+        assert_eq!(bytes, data);
+    }
+
+    #[actix_rt::test]
+    async fn test_head_content_length_headers() {
+        let srv = actix_test::start(|| App::new().service(Files::new("/", ".")));
+
+        let response = srv.head("/tests/test.binary").send().await.unwrap();
+
+        let content_length = response
+            .headers()
+            .get(header::CONTENT_LENGTH)
+            .unwrap()
+            .to_str()
+            .unwrap();
+
+        assert_eq!(content_length, "100");
+    }
+
+    #[actix_rt::test]
+    async fn test_static_files_with_spaces() {
+        let srv =
+            test::init_service(App::new().service(Files::new("/", ".").index_file("Cargo.toml")))
+                .await;
+        let request = TestRequest::get()
+            .uri("/tests/test%20space.binary")
+            .to_request();
+        let response = test::call_service(&srv, request).await;
+        assert_eq!(response.status(), StatusCode::OK);
+
+        let bytes = test::read_body(response).await;
+        let data = web::Bytes::from(fs::read("tests/test space.binary").unwrap());
+        assert_eq!(bytes, data);
+    }
+
+    #[cfg(not(target_os = "windows"))]
+    #[actix_rt::test]
+    async fn test_static_files_with_special_characters() {
+        // Create the file we want to test against ad-hoc. We can't check it in as otherwise
+        // Windows can't even checkout this repository.
+        let temp_dir = tempfile::tempdir().unwrap();
+        let file_with_newlines = temp_dir.path().join("test\n\x0B\x0C\rnewline.text");
+        fs::write(&file_with_newlines, "Look at my newlines").unwrap();
+
+        let srv = test::init_service(
+            App::new().service(Files::new("/", temp_dir.path()).index_file("Cargo.toml")),
+        )
+        .await;
+        let request = TestRequest::get()
+            .uri("/test%0A%0B%0C%0Dnewline.text")
+            .to_request();
+        let response = test::call_service(&srv, request).await;
+        assert_eq!(response.status(), StatusCode::OK);
+
+        let bytes = test::read_body(response).await;
+        let data = web::Bytes::from(fs::read(file_with_newlines).unwrap());
+        assert_eq!(bytes, data);
+    }
+
+    #[actix_rt::test]
+    async fn test_files_not_allowed() {
+        let srv = test::init_service(App::new().service(Files::new("/", "."))).await;
+
+        let req = TestRequest::default()
+            .uri("/Cargo.toml")
+            .method(Method::POST)
+            .to_request();
+
+        let resp = test::call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
+
+        let srv = test::init_service(App::new().service(Files::new("/", "."))).await;
+        let req = TestRequest::default()
+            .method(Method::PUT)
+            .uri("/Cargo.toml")
+            .to_request();
+        let resp = test::call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
+    }
+
+    #[actix_rt::test]
+    async fn test_files_guards() {
+        let srv = test::init_service(
+            App::new().service(Files::new("/", ".").method_guard(guard::Post())),
+        )
+        .await;
+
+        let req = TestRequest::default()
+            .uri("/Cargo.toml")
+            .method(Method::POST)
+            .to_request();
+
+        let resp = test::call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_named_file_content_encoding() {
+        let srv = test::init_service(App::new().wrap(Compress::default()).service(
+            web::resource("/").to(|| async {
+                NamedFile::open_async("Cargo.toml")
+                    .await
+                    .unwrap()
+                    .set_content_encoding(header::ContentEncoding::Identity)
+            }),
+        ))
+        .await;
+
+        let request = TestRequest::get()
+            .uri("/")
+            .insert_header((header::ACCEPT_ENCODING, "gzip"))
+            .to_request();
+        let res = test::call_service(&srv, request).await;
+        assert_eq!(res.status(), StatusCode::OK);
+        assert!(res.headers().contains_key(header::CONTENT_ENCODING));
+        assert!(!test::read_body(res).await.is_empty());
+    }
+
+    #[actix_rt::test]
+    async fn test_named_file_content_encoding_gzip() {
+        let srv = test::init_service(App::new().wrap(Compress::default()).service(
+            web::resource("/").to(|| async {
+                NamedFile::open_async("Cargo.toml")
+                    .await
+                    .unwrap()
+                    .set_content_encoding(header::ContentEncoding::Gzip)
+            }),
+        ))
+        .await;
+
+        let request = TestRequest::get()
+            .uri("/")
+            .insert_header((header::ACCEPT_ENCODING, "gzip"))
+            .to_request();
+        let res = test::call_service(&srv, request).await;
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers()
+                .get(header::CONTENT_ENCODING)
+                .unwrap()
+                .to_str()
+                .unwrap(),
+            "gzip"
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_named_file_allowed_method() {
+        let req = TestRequest::default().method(Method::GET).to_http_request();
+        let file = NamedFile::open_async("Cargo.toml").await.unwrap();
+        let resp = file.respond_to(&req);
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_static_files() {
+        let srv =
+            test::init_service(App::new().service(Files::new("/", ".").show_files_listing())).await;
+        let req = TestRequest::with_uri("/missing").to_request();
+
+        let resp = test::call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+
+        let srv = test::init_service(App::new().service(Files::new("/", "."))).await;
+
+        let req = TestRequest::default().to_request();
+        let resp = test::call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+
+        let srv =
+            test::init_service(App::new().service(Files::new("/", ".").show_files_listing())).await;
+        let req = TestRequest::with_uri("/tests").to_request();
+        let resp = test::call_service(&srv, req).await;
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            "text/html; charset=utf-8"
+        );
+
+        let bytes = test::read_body(resp).await;
+        assert!(format!("{:?}", bytes).contains("/tests/test.png"));
+    }
+
+    #[actix_rt::test]
+    async fn test_redirect_to_slash_directory() {
+        // should not redirect if no index and files listing is disabled
+        let srv = test::init_service(
+            App::new().service(Files::new("/", ".").redirect_to_slash_directory()),
+        )
+        .await;
+        let req = TestRequest::with_uri("/tests").to_request();
+        let resp = test::call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+
+        // should redirect if index present
+        let srv = test::init_service(
+            App::new().service(
+                Files::new("/", ".")
+                    .index_file("test.png")
+                    .redirect_to_slash_directory(),
+            ),
+        )
+        .await;
+        let req = TestRequest::with_uri("/tests").to_request();
+        let resp = test::call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::FOUND);
+
+        // should redirect if files listing is enabled
+        let srv = test::init_service(
+            App::new().service(
+                Files::new("/", ".")
+                    .show_files_listing()
+                    .redirect_to_slash_directory(),
+            ),
+        )
+        .await;
+        let req = TestRequest::with_uri("/tests").to_request();
+        let resp = test::call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::FOUND);
+
+        // should not redirect if the path is wrong
+        let req = TestRequest::with_uri("/not_existing").to_request();
+        let resp = test::call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+    }
+
+    #[actix_rt::test]
+    async fn test_static_files_bad_directory() {
+        let service = Files::new("/", "./missing").new_service(()).await.unwrap();
+
+        let req = TestRequest::with_uri("/").to_srv_request();
+        let resp = test::call_service(&service, req).await;
+
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+    }
+
+    #[actix_rt::test]
+    async fn test_default_handler_file_missing() {
+        let st = Files::new("/", ".")
+            .default_handler(|req: ServiceRequest| async {
+                Ok(req.into_response(HttpResponse::Ok().body("default content")))
+            })
+            .new_service(())
+            .await
+            .unwrap();
+        let req = TestRequest::with_uri("/missing").to_srv_request();
+        let resp = test::call_service(&st, req).await;
+
+        assert_eq!(resp.status(), StatusCode::OK);
+        let bytes = test::read_body(resp).await;
+        assert_eq!(bytes, web::Bytes::from_static(b"default content"));
+    }
+
+    #[actix_rt::test]
+    async fn test_serve_index_nested() {
+        let service = Files::new(".", ".")
+            .index_file("lib.rs")
+            .new_service(())
+            .await
+            .unwrap();
+
+        let req = TestRequest::default().uri("/src").to_srv_request();
+        let resp = test::call_service(&service, req).await;
+
+        assert_eq!(resp.status(), StatusCode::OK);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            "text/x-rust"
+        );
+        assert_eq!(
+            resp.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+            "inline; filename=\"lib.rs\""
+        );
+    }
+
+    #[actix_rt::test]
+    async fn integration_serve_index() {
+        let srv = test::init_service(
+            App::new().service(Files::new("test", ".").index_file("Cargo.toml")),
+        )
+        .await;
+
+        let req = TestRequest::get().uri("/test").to_request();
+        let res = test::call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+
+        let bytes = test::read_body(res).await;
+
+        let data = Bytes::from(fs::read("Cargo.toml").unwrap());
+        assert_eq!(bytes, data);
+
+        let req = TestRequest::get().uri("/test/").to_request();
+        let res = test::call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+
+        let bytes = test::read_body(res).await;
+        let data = Bytes::from(fs::read("Cargo.toml").unwrap());
+        assert_eq!(bytes, data);
+
+        // nonexistent index file
+        let req = TestRequest::get().uri("/test/unknown").to_request();
+        let res = test::call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::NOT_FOUND);
+
+        let req = TestRequest::get().uri("/test/unknown/").to_request();
+        let res = test::call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::NOT_FOUND);
+    }
+
+    #[actix_rt::test]
+    async fn integration_percent_encoded() {
+        let srv = test::init_service(
+            App::new().service(Files::new("test", ".").index_file("Cargo.toml")),
+        )
+        .await;
+
+        let req = TestRequest::get().uri("/test/%43argo.toml").to_request();
+        let res = test::call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+
+        // `%2F` == `/`
+        let req = TestRequest::get().uri("/test%2Ftest.binary").to_request();
+        let res = test::call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::NOT_FOUND);
+
+        let req = TestRequest::get().uri("/test/Cargo.toml%00").to_request();
+        let res = test::call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::NOT_FOUND);
+    }
+
+    #[actix_rt::test]
+    async fn test_percent_encoding_2() {
+        let temp_dir = tempfile::tempdir().unwrap();
+        let filename = match cfg!(unix) {
+            true => "ض:?#[]{}<>()@!$&'`|*+,;= %20\n.test",
+            false => "ض#[]{}()@!$&'`+,;= %20.test",
+        };
+        let filename_encoded = filename
+            .as_bytes()
+            .iter()
+            .fold(String::new(), |mut buf, c| {
+                write!(&mut buf, "%{:02X}", c).unwrap();
+                buf
+            });
+        std::fs::File::create(temp_dir.path().join(filename)).unwrap();
+
+        let srv = test::init_service(App::new().service(Files::new("/", temp_dir.path()))).await;
+
+        let req = TestRequest::get()
+            .uri(&format!("/{}", filename_encoded))
+            .to_request();
+        let res = test::call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_serve_named_file() {
+        let factory = NamedFile::open_async("Cargo.toml").await.unwrap();
+        let srv = test::init_service(App::new().service(factory)).await;
+
+        let req = TestRequest::get().uri("/Cargo.toml").to_request();
+        let res = test::call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+
+        let bytes = test::read_body(res).await;
+        let data = Bytes::from(fs::read("Cargo.toml").unwrap());
+        assert_eq!(bytes, data);
+
+        let req = TestRequest::get().uri("/test/unknown").to_request();
+        let res = test::call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::NOT_FOUND);
+    }
+
+    #[actix_rt::test]
+    async fn test_serve_named_file_prefix() {
+        let factory = NamedFile::open_async("Cargo.toml").await.unwrap();
+        let srv =
+            test::init_service(App::new().service(web::scope("/test").service(factory))).await;
+
+        let req = TestRequest::get().uri("/test/Cargo.toml").to_request();
+        let res = test::call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+
+        let bytes = test::read_body(res).await;
+        let data = Bytes::from(fs::read("Cargo.toml").unwrap());
+        assert_eq!(bytes, data);
+
+        let req = TestRequest::get().uri("/Cargo.toml").to_request();
+        let res = test::call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::NOT_FOUND);
+    }
+
+    #[actix_rt::test]
+    async fn test_named_file_default_service() {
+        let factory = NamedFile::open_async("Cargo.toml").await.unwrap();
+        let srv = test::init_service(App::new().default_service(factory)).await;
+
+        for route in ["/foobar", "/baz", "/"].iter() {
+            let req = TestRequest::get().uri(route).to_request();
+            let res = test::call_service(&srv, req).await;
+            assert_eq!(res.status(), StatusCode::OK);
+
+            let bytes = test::read_body(res).await;
+            let data = Bytes::from(fs::read("Cargo.toml").unwrap());
+            assert_eq!(bytes, data);
+        }
+    }
+
+    #[actix_rt::test]
+    async fn test_default_handler_named_file() {
+        let factory = NamedFile::open_async("Cargo.toml").await.unwrap();
+        let st = Files::new("/", ".")
+            .default_handler(factory)
+            .new_service(())
+            .await
+            .unwrap();
+        let req = TestRequest::with_uri("/missing").to_srv_request();
+        let resp = test::call_service(&st, req).await;
+
+        assert_eq!(resp.status(), StatusCode::OK);
+        let bytes = test::read_body(resp).await;
+        let data = Bytes::from(fs::read("Cargo.toml").unwrap());
+        assert_eq!(bytes, data);
+    }
+
+    #[actix_rt::test]
+    async fn test_symlinks() {
+        let srv = test::init_service(App::new().service(Files::new("test", "."))).await;
+
+        let req = TestRequest::get()
+            .uri("/test/tests/symlink-test.png")
+            .to_request();
+        let res = test::call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(header::CONTENT_DISPOSITION).unwrap(),
+            "inline; filename=\"symlink-test.png\""
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_index_with_show_files_listing() {
+        let service = Files::new(".", ".")
+            .index_file("lib.rs")
+            .show_files_listing()
+            .new_service(())
+            .await
+            .unwrap();
+
+        // Serve the index if exists
+        let req = TestRequest::default().uri("/src").to_srv_request();
+        let resp = test::call_service(&service, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            "text/x-rust"
+        );
+
+        // Show files listing, otherwise.
+        let req = TestRequest::default().uri("/tests").to_srv_request();
+        let resp = test::call_service(&service, req).await;
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            "text/html; charset=utf-8"
+        );
+        let bytes = test::read_body(resp).await;
+        assert!(format!("{:?}", bytes).contains("/tests/test.png"));
+    }
+
+    #[actix_rt::test]
+    async fn test_path_filter() {
+        // prevent searching subdirectories
+        let st = Files::new("/", ".")
+            .path_filter(|path, _| path.components().count() == 1)
+            .new_service(())
+            .await
+            .unwrap();
+
+        let req = TestRequest::with_uri("/Cargo.toml").to_srv_request();
+        let resp = test::call_service(&st, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/src/lib.rs").to_srv_request();
+        let resp = test::call_service(&st, req).await;
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+    }
+
+    #[actix_rt::test]
+    async fn test_default_handler_filter() {
+        let st = Files::new("/", ".")
+            .default_handler(|req: ServiceRequest| async {
+                Ok(req.into_response(HttpResponse::Ok().body("default content")))
+            })
+            .path_filter(|path, _| path.extension() == Some("png".as_ref()))
+            .new_service(())
+            .await
+            .unwrap();
+        let req = TestRequest::with_uri("/Cargo.toml").to_srv_request();
+        let resp = test::call_service(&st, req).await;
+
+        assert_eq!(resp.status(), StatusCode::OK);
+        let bytes = test::read_body(resp).await;
+        assert_eq!(bytes, web::Bytes::from_static(b"default content"));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_files/named.rs.html b/src/actix_files/named.rs.html new file mode 100644 index 000000000..274798cd3 --- /dev/null +++ b/src/actix_files/named.rs.html @@ -0,0 +1,1379 @@ +named.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
+
use std::{
+    fs::Metadata,
+    io,
+    path::{Path, PathBuf},
+    time::{SystemTime, UNIX_EPOCH},
+};
+
+use actix_web::{
+    body::{self, BoxBody, SizedStream},
+    dev::{
+        self, AppService, HttpServiceFactory, ResourceDef, Service, ServiceFactory, ServiceRequest,
+        ServiceResponse,
+    },
+    http::{
+        header::{
+            self, Charset, ContentDisposition, ContentEncoding, DispositionParam, DispositionType,
+            ExtendedValue, HeaderValue,
+        },
+        StatusCode,
+    },
+    Error, HttpMessage, HttpRequest, HttpResponse, Responder,
+};
+use bitflags::bitflags;
+use derive_more::{Deref, DerefMut};
+use futures_core::future::LocalBoxFuture;
+use mime::Mime;
+
+use crate::{encoding::equiv_utf8_text, range::HttpRange};
+
+bitflags! {
+    #[derive(Debug, Clone, Copy)]
+    pub(crate) struct Flags: u8 {
+        const ETAG =                0b0000_0001;
+        const LAST_MD =             0b0000_0010;
+        const CONTENT_DISPOSITION = 0b0000_0100;
+        const PREFER_UTF8 =         0b0000_1000;
+    }
+}
+
+impl Default for Flags {
+    fn default() -> Self {
+        Flags::from_bits_truncate(0b0000_1111)
+    }
+}
+
+/// A file with an associated name.
+///
+/// `NamedFile` can be registered as services:
+/// ```
+/// use actix_web::App;
+/// use actix_files::NamedFile;
+///
+/// # async fn run() -> Result<(), Box<dyn std::error::Error>> {
+/// let file = NamedFile::open_async("./static/index.html").await?;
+/// let app = App::new().service(file);
+/// # Ok(())
+/// # }
+/// ```
+///
+/// They can also be returned from handlers:
+/// ```
+/// use actix_web::{Responder, get};
+/// use actix_files::NamedFile;
+///
+/// #[get("/")]
+/// async fn index() -> impl Responder {
+///     NamedFile::open_async("./static/index.html").await
+/// }
+/// ```
+#[derive(Debug, Deref, DerefMut)]
+pub struct NamedFile {
+    #[deref]
+    #[deref_mut]
+    file: File,
+    path: PathBuf,
+    modified: Option<SystemTime>,
+    pub(crate) md: Metadata,
+    pub(crate) flags: Flags,
+    pub(crate) status_code: StatusCode,
+    pub(crate) content_type: Mime,
+    pub(crate) content_disposition: ContentDisposition,
+    pub(crate) encoding: Option<ContentEncoding>,
+}
+
+#[cfg(not(feature = "experimental-io-uring"))]
+pub(crate) use std::fs::File;
+
+#[cfg(feature = "experimental-io-uring")]
+pub(crate) use tokio_uring::fs::File;
+
+use super::chunked;
+
+impl NamedFile {
+    /// Creates an instance from a previously opened file.
+    ///
+    /// The given `path` need not exist and is only used to determine the `ContentType` and
+    /// `ContentDisposition` headers.
+    ///
+    /// # Examples
+    /// ```ignore
+    /// use std::{
+    ///     io::{self, Write as _},
+    ///     env,
+    ///     fs::File
+    /// };
+    /// use actix_files::NamedFile;
+    ///
+    /// let mut file = File::create("foo.txt")?;
+    /// file.write_all(b"Hello, world!")?;
+    /// let named_file = NamedFile::from_file(file, "bar.txt")?;
+    /// # std::fs::remove_file("foo.txt");
+    /// Ok(())
+    /// ```
+    pub fn from_file<P: AsRef<Path>>(file: File, path: P) -> io::Result<NamedFile> {
+        let path = path.as_ref().to_path_buf();
+
+        // Get the name of the file and use it to construct default Content-Type
+        // and Content-Disposition values
+        let (content_type, content_disposition) = {
+            let filename = match path.file_name() {
+                Some(name) => name.to_string_lossy(),
+                None => {
+                    return Err(io::Error::new(
+                        io::ErrorKind::InvalidInput,
+                        "Provided path has no filename",
+                    ));
+                }
+            };
+
+            let ct = mime_guess::from_path(&path).first_or_octet_stream();
+
+            let disposition = match ct.type_() {
+                mime::IMAGE | mime::TEXT | mime::AUDIO | mime::VIDEO => DispositionType::Inline,
+                mime::APPLICATION => match ct.subtype() {
+                    mime::JAVASCRIPT | mime::JSON => DispositionType::Inline,
+                    name if name == "wasm" || name == "xhtml" => DispositionType::Inline,
+                    _ => DispositionType::Attachment,
+                },
+                _ => DispositionType::Attachment,
+            };
+
+            // replace special characters in filenames which could occur on some filesystems
+            let filename_s = filename
+                .replace('\n', "%0A") // \n line break
+                .replace('\x0B', "%0B") // \v vertical tab
+                .replace('\x0C', "%0C") // \f form feed
+                .replace('\r', "%0D"); // \r carriage return
+            let mut parameters = vec![DispositionParam::Filename(filename_s)];
+
+            if !filename.is_ascii() {
+                parameters.push(DispositionParam::FilenameExt(ExtendedValue {
+                    charset: Charset::Ext(String::from("UTF-8")),
+                    language_tag: None,
+                    value: filename.into_owned().into_bytes(),
+                }))
+            }
+
+            let cd = ContentDisposition {
+                disposition,
+                parameters,
+            };
+
+            (ct, cd)
+        };
+
+        let md = {
+            #[cfg(not(feature = "experimental-io-uring"))]
+            {
+                file.metadata()?
+            }
+
+            #[cfg(feature = "experimental-io-uring")]
+            {
+                use std::os::unix::prelude::{AsRawFd, FromRawFd};
+
+                let fd = file.as_raw_fd();
+
+                // SAFETY: fd is borrowed and lives longer than the unsafe block
+                unsafe {
+                    let file = std::fs::File::from_raw_fd(fd);
+                    let md = file.metadata();
+                    // SAFETY: forget the fd before exiting block in success or error case but don't
+                    // run destructor (that would close file handle)
+                    std::mem::forget(file);
+                    md?
+                }
+            }
+        };
+
+        let modified = md.modified().ok();
+        let encoding = None;
+
+        Ok(NamedFile {
+            path,
+            file,
+            content_type,
+            content_disposition,
+            md,
+            modified,
+            encoding,
+            status_code: StatusCode::OK,
+            flags: Flags::default(),
+        })
+    }
+
+    /// Attempts to open a file in read-only mode.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_files::NamedFile;
+    /// let file = NamedFile::open("foo.txt");
+    /// ```
+    #[cfg(not(feature = "experimental-io-uring"))]
+    pub fn open<P: AsRef<Path>>(path: P) -> io::Result<NamedFile> {
+        let file = File::open(&path)?;
+        Self::from_file(file, path)
+    }
+
+    /// Attempts to open a file asynchronously in read-only mode.
+    ///
+    /// When the `experimental-io-uring` crate feature is enabled, this will be async. Otherwise, it
+    /// will behave just like `open`.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_files::NamedFile;
+    /// # async fn open() {
+    /// let file = NamedFile::open_async("foo.txt").await.unwrap();
+    /// # }
+    /// ```
+    pub async fn open_async<P: AsRef<Path>>(path: P) -> io::Result<NamedFile> {
+        let file = {
+            #[cfg(not(feature = "experimental-io-uring"))]
+            {
+                File::open(&path)?
+            }
+
+            #[cfg(feature = "experimental-io-uring")]
+            {
+                File::open(&path).await?
+            }
+        };
+
+        Self::from_file(file, path)
+    }
+
+    /// Returns reference to the underlying file object.
+    #[inline]
+    pub fn file(&self) -> &File {
+        &self.file
+    }
+
+    /// Returns the filesystem path to this file.
+    ///
+    /// # Examples
+    /// ```
+    /// # use std::io;
+    /// use actix_files::NamedFile;
+    ///
+    /// # async fn path() -> io::Result<()> {
+    /// let file = NamedFile::open_async("test.txt").await?;
+    /// assert_eq!(file.path().as_os_str(), "foo.txt");
+    /// # Ok(())
+    /// # }
+    /// ```
+    #[inline]
+    pub fn path(&self) -> &Path {
+        self.path.as_path()
+    }
+
+    /// Returns the time the file was last modified.
+    ///
+    /// Returns `None` only on unsupported platforms; see [`std::fs::Metadata::modified()`].
+    /// Therefore, it is usually safe to unwrap this.
+    #[inline]
+    pub fn modified(&self) -> Option<SystemTime> {
+        self.modified
+    }
+
+    /// Returns the filesystem metadata associated with this file.
+    #[inline]
+    pub fn metadata(&self) -> &Metadata {
+        &self.md
+    }
+
+    /// Returns the `Content-Type` header that will be used when serving this file.
+    #[inline]
+    pub fn content_type(&self) -> &Mime {
+        &self.content_type
+    }
+
+    /// Returns the `Content-Disposition` that will be used when serving this file.
+    #[inline]
+    pub fn content_disposition(&self) -> &ContentDisposition {
+        &self.content_disposition
+    }
+
+    /// Returns the `Content-Encoding` that will be used when serving this file.
+    ///
+    /// A return value of `None` indicates that the content is not already using a compressed
+    /// representation and may be subject to compression downstream.
+    #[inline]
+    pub fn content_encoding(&self) -> Option<ContentEncoding> {
+        self.encoding
+    }
+
+    /// Set response status code.
+    #[deprecated(since = "0.7.0", note = "Prefer `Responder::customize()`.")]
+    pub fn set_status_code(mut self, status: StatusCode) -> Self {
+        self.status_code = status;
+        self
+    }
+
+    /// Sets the `Content-Type` header that will be used when serving this file. By default the
+    /// `Content-Type` is inferred from the filename extension.
+    #[inline]
+    pub fn set_content_type(mut self, mime_type: Mime) -> Self {
+        self.content_type = mime_type;
+        self
+    }
+
+    /// Set the Content-Disposition for serving this file. This allows changing the
+    /// `inline/attachment` disposition as well as the filename sent to the peer.
+    ///
+    /// By default the disposition is `inline` for `text/*`, `image/*`, `video/*` and
+    /// `application/{javascript, json, wasm}` mime types, and `attachment` otherwise, and the
+    /// filename is taken from the path provided in the `open` method after converting it to UTF-8
+    /// (using `to_string_lossy`).
+    #[inline]
+    pub fn set_content_disposition(mut self, cd: ContentDisposition) -> Self {
+        self.content_disposition = cd;
+        self.flags.insert(Flags::CONTENT_DISPOSITION);
+        self
+    }
+
+    /// Disables `Content-Disposition` header.
+    ///
+    /// By default, the `Content-Disposition` header is sent.
+    #[inline]
+    pub fn disable_content_disposition(mut self) -> Self {
+        self.flags.remove(Flags::CONTENT_DISPOSITION);
+        self
+    }
+
+    /// Sets content encoding for this file.
+    ///
+    /// This prevents the `Compress` middleware from modifying the file contents and signals to
+    /// browsers/clients how to decode it. For example, if serving a compressed HTML file (e.g.,
+    /// `index.html.gz`) then use `.set_content_encoding(ContentEncoding::Gzip)`.
+    #[inline]
+    pub fn set_content_encoding(mut self, enc: ContentEncoding) -> Self {
+        self.encoding = Some(enc);
+        self
+    }
+
+    /// Specifies whether to return `ETag` header in response.
+    ///
+    /// Default is true.
+    #[inline]
+    pub fn use_etag(mut self, value: bool) -> Self {
+        self.flags.set(Flags::ETAG, value);
+        self
+    }
+
+    /// Specifies whether to return `Last-Modified` header in response.
+    ///
+    /// Default is true.
+    #[inline]
+    pub fn use_last_modified(mut self, value: bool) -> Self {
+        self.flags.set(Flags::LAST_MD, value);
+        self
+    }
+
+    /// Specifies whether text responses should signal a UTF-8 encoding.
+    ///
+    /// Default is false (but will default to true in a future version).
+    #[inline]
+    pub fn prefer_utf8(mut self, value: bool) -> Self {
+        self.flags.set(Flags::PREFER_UTF8, value);
+        self
+    }
+
+    /// Creates an `ETag` in a format is similar to Apache's.
+    pub(crate) fn etag(&self) -> Option<header::EntityTag> {
+        self.modified.as_ref().map(|mtime| {
+            let ino = {
+                #[cfg(unix)]
+                {
+                    #[cfg(unix)]
+                    use std::os::unix::fs::MetadataExt as _;
+
+                    self.md.ino()
+                }
+
+                #[cfg(not(unix))]
+                {
+                    0
+                }
+            };
+
+            let dur = mtime
+                .duration_since(UNIX_EPOCH)
+                .expect("modification time must be after epoch");
+
+            header::EntityTag::new_strong(format!(
+                "{:x}:{:x}:{:x}:{:x}",
+                ino,
+                self.md.len(),
+                dur.as_secs(),
+                dur.subsec_nanos()
+            ))
+        })
+    }
+
+    pub(crate) fn last_modified(&self) -> Option<header::HttpDate> {
+        self.modified.map(|mtime| mtime.into())
+    }
+
+    /// Creates an `HttpResponse` with file as a streaming body.
+    pub fn into_response(self, req: &HttpRequest) -> HttpResponse<BoxBody> {
+        if self.status_code != StatusCode::OK {
+            let mut res = HttpResponse::build(self.status_code);
+
+            let ct = if self.flags.contains(Flags::PREFER_UTF8) {
+                equiv_utf8_text(self.content_type.clone())
+            } else {
+                self.content_type
+            };
+
+            res.insert_header((header::CONTENT_TYPE, ct.to_string()));
+
+            if self.flags.contains(Flags::CONTENT_DISPOSITION) {
+                res.insert_header((
+                    header::CONTENT_DISPOSITION,
+                    self.content_disposition.to_string(),
+                ));
+            }
+
+            if let Some(current_encoding) = self.encoding {
+                res.insert_header((header::CONTENT_ENCODING, current_encoding.as_str()));
+            }
+
+            let reader = chunked::new_chunked_read(self.md.len(), 0, self.file);
+
+            return res.streaming(reader);
+        }
+
+        let etag = if self.flags.contains(Flags::ETAG) {
+            self.etag()
+        } else {
+            None
+        };
+
+        let last_modified = if self.flags.contains(Flags::LAST_MD) {
+            self.last_modified()
+        } else {
+            None
+        };
+
+        // check preconditions
+        let precondition_failed = if !any_match(etag.as_ref(), req) {
+            true
+        } else if let (Some(ref m), Some(header::IfUnmodifiedSince(ref since))) =
+            (last_modified, req.get_header())
+        {
+            let t1: SystemTime = (*m).into();
+            let t2: SystemTime = (*since).into();
+
+            match (t1.duration_since(UNIX_EPOCH), t2.duration_since(UNIX_EPOCH)) {
+                (Ok(t1), Ok(t2)) => t1.as_secs() > t2.as_secs(),
+                _ => false,
+            }
+        } else {
+            false
+        };
+
+        // check last modified
+        let not_modified = if !none_match(etag.as_ref(), req) {
+            true
+        } else if req.headers().contains_key(header::IF_NONE_MATCH) {
+            false
+        } else if let (Some(ref m), Some(header::IfModifiedSince(ref since))) =
+            (last_modified, req.get_header())
+        {
+            let t1: SystemTime = (*m).into();
+            let t2: SystemTime = (*since).into();
+
+            match (t1.duration_since(UNIX_EPOCH), t2.duration_since(UNIX_EPOCH)) {
+                (Ok(t1), Ok(t2)) => t1.as_secs() <= t2.as_secs(),
+                _ => false,
+            }
+        } else {
+            false
+        };
+
+        let mut res = HttpResponse::build(self.status_code);
+
+        let ct = if self.flags.contains(Flags::PREFER_UTF8) {
+            equiv_utf8_text(self.content_type.clone())
+        } else {
+            self.content_type
+        };
+
+        res.insert_header((header::CONTENT_TYPE, ct.to_string()));
+
+        if self.flags.contains(Flags::CONTENT_DISPOSITION) {
+            res.insert_header((
+                header::CONTENT_DISPOSITION,
+                self.content_disposition.to_string(),
+            ));
+        }
+
+        if let Some(current_encoding) = self.encoding {
+            res.insert_header((header::CONTENT_ENCODING, current_encoding.as_str()));
+        }
+
+        if let Some(lm) = last_modified {
+            res.insert_header((header::LAST_MODIFIED, lm.to_string()));
+        }
+
+        if let Some(etag) = etag {
+            res.insert_header((header::ETAG, etag.to_string()));
+        }
+
+        res.insert_header((header::ACCEPT_RANGES, "bytes"));
+
+        let mut length = self.md.len();
+        let mut offset = 0;
+
+        // check for range header
+        if let Some(ranges) = req.headers().get(header::RANGE) {
+            if let Ok(ranges_header) = ranges.to_str() {
+                if let Ok(ranges) = HttpRange::parse(ranges_header, length) {
+                    length = ranges[0].length;
+                    offset = ranges[0].start;
+
+                    // When a Content-Encoding header is present in a 206 partial content response
+                    // for video content, it prevents browser video players from starting playback
+                    // before loading the whole video and also prevents seeking.
+                    //
+                    // See: https://github.com/actix/actix-web/issues/2815
+                    //
+                    // The assumption of this fix is that the video player knows to not send an
+                    // Accept-Encoding header for this request and that downstream middleware will
+                    // not attempt compression for requests without it.
+                    //
+                    // TODO: Solve question around what to do if self.encoding is set and partial
+                    // range is requested. Reject request? Ignoring self.encoding seems wrong, too.
+                    // In practice, it should not come up.
+                    if req.headers().contains_key(&header::ACCEPT_ENCODING) {
+                        // don't allow compression middleware to modify partial content
+                        res.insert_header((
+                            header::CONTENT_ENCODING,
+                            HeaderValue::from_static("identity"),
+                        ));
+                    }
+
+                    res.insert_header((
+                        header::CONTENT_RANGE,
+                        format!("bytes {}-{}/{}", offset, offset + length - 1, self.md.len()),
+                    ));
+                } else {
+                    res.insert_header((header::CONTENT_RANGE, format!("bytes */{}", length)));
+                    return res.status(StatusCode::RANGE_NOT_SATISFIABLE).finish();
+                };
+            } else {
+                return res.status(StatusCode::BAD_REQUEST).finish();
+            };
+        };
+
+        if precondition_failed {
+            return res.status(StatusCode::PRECONDITION_FAILED).finish();
+        } else if not_modified {
+            return res
+                .status(StatusCode::NOT_MODIFIED)
+                .body(body::None::new())
+                .map_into_boxed_body();
+        }
+
+        let reader = chunked::new_chunked_read(length, offset, self.file);
+
+        if offset != 0 || length != self.md.len() {
+            res.status(StatusCode::PARTIAL_CONTENT);
+        }
+
+        res.body(SizedStream::new(length, reader))
+    }
+}
+
+/// Returns true if `req` has no `If-Match` header or one which matches `etag`.
+fn any_match(etag: Option<&header::EntityTag>, req: &HttpRequest) -> bool {
+    match req.get_header::<header::IfMatch>() {
+        None | Some(header::IfMatch::Any) => true,
+
+        Some(header::IfMatch::Items(ref items)) => {
+            if let Some(some_etag) = etag {
+                for item in items {
+                    if item.strong_eq(some_etag) {
+                        return true;
+                    }
+                }
+            }
+
+            false
+        }
+    }
+}
+
+/// Returns true if `req` doesn't have an `If-None-Match` header matching `req`.
+fn none_match(etag: Option<&header::EntityTag>, req: &HttpRequest) -> bool {
+    match req.get_header::<header::IfNoneMatch>() {
+        Some(header::IfNoneMatch::Any) => false,
+
+        Some(header::IfNoneMatch::Items(ref items)) => {
+            if let Some(some_etag) = etag {
+                for item in items {
+                    if item.weak_eq(some_etag) {
+                        return false;
+                    }
+                }
+            }
+
+            true
+        }
+
+        None => true,
+    }
+}
+
+impl Responder for NamedFile {
+    type Body = BoxBody;
+
+    fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body> {
+        self.into_response(req)
+    }
+}
+
+impl ServiceFactory<ServiceRequest> for NamedFile {
+    type Response = ServiceResponse;
+    type Error = Error;
+    type Config = ();
+    type Service = NamedFileService;
+    type InitError = ();
+    type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
+
+    fn new_service(&self, _: ()) -> Self::Future {
+        let service = NamedFileService {
+            path: self.path.clone(),
+        };
+
+        Box::pin(async move { Ok(service) })
+    }
+}
+
+#[doc(hidden)]
+#[derive(Debug)]
+pub struct NamedFileService {
+    path: PathBuf,
+}
+
+impl Service<ServiceRequest> for NamedFileService {
+    type Response = ServiceResponse;
+    type Error = Error;
+    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
+
+    dev::always_ready!();
+
+    fn call(&self, req: ServiceRequest) -> Self::Future {
+        let (req, _) = req.into_parts();
+
+        let path = self.path.clone();
+        Box::pin(async move {
+            let file = NamedFile::open_async(path).await?;
+            let res = file.into_response(&req);
+            Ok(ServiceResponse::new(req, res))
+        })
+    }
+}
+
+impl HttpServiceFactory for NamedFile {
+    fn register(self, config: &mut AppService) {
+        config.register_service(
+            ResourceDef::root_prefix(self.path.to_string_lossy().as_ref()),
+            None,
+            self,
+            None,
+        )
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_files/path_buf.rs.html b/src/actix_files/path_buf.rs.html new file mode 100644 index 000000000..7aa0150a0 --- /dev/null +++ b/src/actix_files/path_buf.rs.html @@ -0,0 +1,377 @@ +path_buf.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
+
use std::{
+    path::{Component, Path, PathBuf},
+    str::FromStr,
+};
+
+use actix_utils::future::{ready, Ready};
+use actix_web::{dev::Payload, FromRequest, HttpRequest};
+
+use crate::error::UriSegmentError;
+
+#[derive(Debug, PartialEq, Eq)]
+pub(crate) struct PathBufWrap(PathBuf);
+
+impl FromStr for PathBufWrap {
+    type Err = UriSegmentError;
+
+    fn from_str(path: &str) -> Result<Self, Self::Err> {
+        Self::parse_path(path, false)
+    }
+}
+
+impl PathBufWrap {
+    /// Parse a path, giving the choice of allowing hidden files to be considered valid segments.
+    ///
+    /// Path traversal is guarded by this method.
+    pub fn parse_path(path: &str, hidden_files: bool) -> Result<Self, UriSegmentError> {
+        let mut buf = PathBuf::new();
+
+        // equivalent to `path.split('/').count()`
+        let mut segment_count = path.matches('/').count() + 1;
+
+        // we can decode the whole path here (instead of per-segment decoding)
+        // because we will reject `%2F` in paths using `segment_count`.
+        let path = percent_encoding::percent_decode_str(path)
+            .decode_utf8()
+            .map_err(|_| UriSegmentError::NotValidUtf8)?;
+
+        // disallow decoding `%2F` into `/`
+        if segment_count != path.matches('/').count() + 1 {
+            return Err(UriSegmentError::BadChar('/'));
+        }
+
+        for segment in path.split('/') {
+            if segment == ".." {
+                segment_count -= 1;
+                buf.pop();
+            } else if !hidden_files && segment.starts_with('.') {
+                return Err(UriSegmentError::BadStart('.'));
+            } else if segment.starts_with('*') {
+                return Err(UriSegmentError::BadStart('*'));
+            } else if segment.ends_with(':') {
+                return Err(UriSegmentError::BadEnd(':'));
+            } else if segment.ends_with('>') {
+                return Err(UriSegmentError::BadEnd('>'));
+            } else if segment.ends_with('<') {
+                return Err(UriSegmentError::BadEnd('<'));
+            } else if segment.is_empty() {
+                segment_count -= 1;
+                continue;
+            } else if cfg!(windows) && segment.contains('\\') {
+                return Err(UriSegmentError::BadChar('\\'));
+            } else if cfg!(windows) && segment.contains(':') {
+                return Err(UriSegmentError::BadChar(':'));
+            } else {
+                buf.push(segment)
+            }
+        }
+
+        // make sure we agree with stdlib parser
+        for (i, component) in buf.components().enumerate() {
+            assert!(
+                matches!(component, Component::Normal(_)),
+                "component `{:?}` is not normal",
+                component
+            );
+            assert!(i < segment_count);
+        }
+
+        Ok(PathBufWrap(buf))
+    }
+}
+
+impl AsRef<Path> for PathBufWrap {
+    fn as_ref(&self) -> &Path {
+        self.0.as_ref()
+    }
+}
+
+impl FromRequest for PathBufWrap {
+    type Error = UriSegmentError;
+    type Future = Ready<Result<Self, Self::Error>>;
+
+    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
+        ready(req.match_info().unprocessed().parse())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_path_buf() {
+        assert_eq!(
+            PathBufWrap::from_str("/test/.tt").map(|t| t.0),
+            Err(UriSegmentError::BadStart('.'))
+        );
+        assert_eq!(
+            PathBufWrap::from_str("/test/*tt").map(|t| t.0),
+            Err(UriSegmentError::BadStart('*'))
+        );
+        assert_eq!(
+            PathBufWrap::from_str("/test/tt:").map(|t| t.0),
+            Err(UriSegmentError::BadEnd(':'))
+        );
+        assert_eq!(
+            PathBufWrap::from_str("/test/tt<").map(|t| t.0),
+            Err(UriSegmentError::BadEnd('<'))
+        );
+        assert_eq!(
+            PathBufWrap::from_str("/test/tt>").map(|t| t.0),
+            Err(UriSegmentError::BadEnd('>'))
+        );
+        assert_eq!(
+            PathBufWrap::from_str("/seg1/seg2/").unwrap().0,
+            PathBuf::from_iter(vec!["seg1", "seg2"])
+        );
+        assert_eq!(
+            PathBufWrap::from_str("/seg1/../seg2/").unwrap().0,
+            PathBuf::from_iter(vec!["seg2"])
+        );
+    }
+
+    #[test]
+    fn test_parse_path() {
+        assert_eq!(
+            PathBufWrap::parse_path("/test/.tt", false).map(|t| t.0),
+            Err(UriSegmentError::BadStart('.'))
+        );
+
+        assert_eq!(
+            PathBufWrap::parse_path("/test/.tt", true).unwrap().0,
+            PathBuf::from_iter(vec!["test", ".tt"])
+        );
+    }
+
+    #[test]
+    fn path_traversal() {
+        assert_eq!(
+            PathBufWrap::parse_path("/../README.md", false).unwrap().0,
+            PathBuf::from_iter(vec!["README.md"])
+        );
+
+        assert_eq!(
+            PathBufWrap::parse_path("/../README.md", true).unwrap().0,
+            PathBuf::from_iter(vec!["README.md"])
+        );
+
+        assert_eq!(
+            PathBufWrap::parse_path("/../../../../../../../../../../etc/passwd", false)
+                .unwrap()
+                .0,
+            PathBuf::from_iter(vec!["etc/passwd"])
+        );
+    }
+
+    #[test]
+    #[cfg_attr(windows, should_panic)]
+    fn windows_drive_traversal() {
+        // detect issues in windows that could lead to path traversal
+        // see <https://github.com/SergioBenitez/Rocket/issues/1949
+
+        assert_eq!(
+            PathBufWrap::parse_path("C:test.txt", false).unwrap().0,
+            PathBuf::from_iter(vec!["C:test.txt"])
+        );
+
+        assert_eq!(
+            PathBufWrap::parse_path("C:../whatever", false).unwrap().0,
+            PathBuf::from_iter(vec!["C:../whatever"])
+        );
+
+        assert_eq!(
+            PathBufWrap::parse_path(":test.txt", false).unwrap().0,
+            PathBuf::from_iter(vec![":test.txt"])
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_files/range.rs.html b/src/actix_files/range.rs.html new file mode 100644 index 000000000..310c7e1e2 --- /dev/null +++ b/src/actix_files/range.rs.html @@ -0,0 +1,677 @@ +range.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::fmt;
+
+use derive_more::Error;
+
+/// Copy of `http_range::HttpRangeParseError`.
+#[derive(Debug, Clone)]
+enum HttpRangeParseError {
+    InvalidRange,
+    NoOverlap,
+}
+
+impl From<http_range::HttpRangeParseError> for HttpRangeParseError {
+    fn from(err: http_range::HttpRangeParseError) -> Self {
+        match err {
+            http_range::HttpRangeParseError::InvalidRange => Self::InvalidRange,
+            http_range::HttpRangeParseError::NoOverlap => Self::NoOverlap,
+        }
+    }
+}
+
+#[derive(Debug, Clone, Error)]
+#[non_exhaustive]
+pub struct ParseRangeErr(#[error(not(source))] HttpRangeParseError);
+
+impl fmt::Display for ParseRangeErr {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("invalid Range header: ")?;
+        f.write_str(match self.0 {
+            HttpRangeParseError::InvalidRange => "invalid syntax",
+            HttpRangeParseError::NoOverlap => "range starts after end of content",
+        })
+    }
+}
+
+/// HTTP Range header representation.
+#[derive(Debug, Clone, Copy)]
+pub struct HttpRange {
+    /// Start of range.
+    pub start: u64,
+
+    /// Length of range.
+    pub length: u64,
+}
+
+impl HttpRange {
+    /// Parses Range HTTP header string as per RFC 2616.
+    ///
+    /// `header` is HTTP Range header (e.g. `bytes=bytes=0-9`).
+    /// `size` is full size of response (file).
+    pub fn parse(header: &str, size: u64) -> Result<Vec<HttpRange>, ParseRangeErr> {
+        let ranges =
+            http_range::HttpRange::parse(header, size).map_err(|err| ParseRangeErr(err.into()))?;
+
+        Ok(ranges
+            .iter()
+            .map(|range| HttpRange {
+                start: range.start,
+                length: range.length,
+            })
+            .collect())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    struct T(&'static str, u64, Vec<HttpRange>);
+
+    #[test]
+    fn test_parse() {
+        let tests = vec![
+            T("", 0, vec![]),
+            T("", 1000, vec![]),
+            T("foo", 0, vec![]),
+            T("bytes=", 0, vec![]),
+            T("bytes=7", 10, vec![]),
+            T("bytes= 7 ", 10, vec![]),
+            T("bytes=1-", 0, vec![]),
+            T("bytes=5-4", 10, vec![]),
+            T("bytes=0-2,5-4", 10, vec![]),
+            T("bytes=2-5,4-3", 10, vec![]),
+            T("bytes=--5,4--3", 10, vec![]),
+            T("bytes=A-", 10, vec![]),
+            T("bytes=A- ", 10, vec![]),
+            T("bytes=A-Z", 10, vec![]),
+            T("bytes= -Z", 10, vec![]),
+            T("bytes=5-Z", 10, vec![]),
+            T("bytes=Ran-dom, garbage", 10, vec![]),
+            T("bytes=0x01-0x02", 10, vec![]),
+            T("bytes=         ", 10, vec![]),
+            T("bytes= , , ,   ", 10, vec![]),
+            T(
+                "bytes=0-9",
+                10,
+                vec![HttpRange {
+                    start: 0,
+                    length: 10,
+                }],
+            ),
+            T(
+                "bytes=0-",
+                10,
+                vec![HttpRange {
+                    start: 0,
+                    length: 10,
+                }],
+            ),
+            T(
+                "bytes=5-",
+                10,
+                vec![HttpRange {
+                    start: 5,
+                    length: 5,
+                }],
+            ),
+            T(
+                "bytes=0-20",
+                10,
+                vec![HttpRange {
+                    start: 0,
+                    length: 10,
+                }],
+            ),
+            T(
+                "bytes=15-,0-5",
+                10,
+                vec![HttpRange {
+                    start: 0,
+                    length: 6,
+                }],
+            ),
+            T(
+                "bytes=1-2,5-",
+                10,
+                vec![
+                    HttpRange {
+                        start: 1,
+                        length: 2,
+                    },
+                    HttpRange {
+                        start: 5,
+                        length: 5,
+                    },
+                ],
+            ),
+            T(
+                "bytes=-2 , 7-",
+                11,
+                vec![
+                    HttpRange {
+                        start: 9,
+                        length: 2,
+                    },
+                    HttpRange {
+                        start: 7,
+                        length: 4,
+                    },
+                ],
+            ),
+            T(
+                "bytes=0-0 ,2-2, 7-",
+                11,
+                vec![
+                    HttpRange {
+                        start: 0,
+                        length: 1,
+                    },
+                    HttpRange {
+                        start: 2,
+                        length: 1,
+                    },
+                    HttpRange {
+                        start: 7,
+                        length: 4,
+                    },
+                ],
+            ),
+            T(
+                "bytes=-5",
+                10,
+                vec![HttpRange {
+                    start: 5,
+                    length: 5,
+                }],
+            ),
+            T(
+                "bytes=-15",
+                10,
+                vec![HttpRange {
+                    start: 0,
+                    length: 10,
+                }],
+            ),
+            T(
+                "bytes=0-499",
+                10000,
+                vec![HttpRange {
+                    start: 0,
+                    length: 500,
+                }],
+            ),
+            T(
+                "bytes=500-999",
+                10000,
+                vec![HttpRange {
+                    start: 500,
+                    length: 500,
+                }],
+            ),
+            T(
+                "bytes=-500",
+                10000,
+                vec![HttpRange {
+                    start: 9500,
+                    length: 500,
+                }],
+            ),
+            T(
+                "bytes=9500-",
+                10000,
+                vec![HttpRange {
+                    start: 9500,
+                    length: 500,
+                }],
+            ),
+            T(
+                "bytes=0-0,-1",
+                10000,
+                vec![
+                    HttpRange {
+                        start: 0,
+                        length: 1,
+                    },
+                    HttpRange {
+                        start: 9999,
+                        length: 1,
+                    },
+                ],
+            ),
+            T(
+                "bytes=500-600,601-999",
+                10000,
+                vec![
+                    HttpRange {
+                        start: 500,
+                        length: 101,
+                    },
+                    HttpRange {
+                        start: 601,
+                        length: 399,
+                    },
+                ],
+            ),
+            T(
+                "bytes=500-700,601-999",
+                10000,
+                vec![
+                    HttpRange {
+                        start: 500,
+                        length: 201,
+                    },
+                    HttpRange {
+                        start: 601,
+                        length: 399,
+                    },
+                ],
+            ),
+            // Match Apache laxity:
+            T(
+                "bytes=   1 -2   ,  4- 5, 7 - 8 , ,,",
+                11,
+                vec![
+                    HttpRange {
+                        start: 1,
+                        length: 2,
+                    },
+                    HttpRange {
+                        start: 4,
+                        length: 2,
+                    },
+                    HttpRange {
+                        start: 7,
+                        length: 2,
+                    },
+                ],
+            ),
+        ];
+
+        for t in tests {
+            let header = t.0;
+            let size = t.1;
+            let expected = t.2;
+
+            let res = HttpRange::parse(header, size);
+
+            if res.is_err() {
+                if expected.is_empty() {
+                    continue;
+                } else {
+                    panic!(
+                        "parse({}, {}) returned error {:?}",
+                        header,
+                        size,
+                        res.unwrap_err()
+                    );
+                }
+            }
+
+            let got = res.unwrap();
+
+            if got.len() != expected.len() {
+                panic!(
+                    "len(parseRange({}, {})) = {}, want {}",
+                    header,
+                    size,
+                    got.len(),
+                    expected.len()
+                );
+            }
+
+            for i in 0..expected.len() {
+                if got[i].start != expected[i].start {
+                    panic!(
+                        "parseRange({}, {})[{}].start = {}, want {}",
+                        header, size, i, got[i].start, expected[i].start
+                    )
+                }
+                if got[i].length != expected[i].length {
+                    panic!(
+                        "parseRange({}, {})[{}].length = {}, want {}",
+                        header, size, i, got[i].length, expected[i].length
+                    )
+                }
+            }
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_files/service.rs.html b/src/actix_files/service.rs.html new file mode 100644 index 000000000..565e5da8b --- /dev/null +++ b/src/actix_files/service.rs.html @@ -0,0 +1,377 @@ +service.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
+
use std::{fmt, io, ops::Deref, path::PathBuf, rc::Rc};
+
+use actix_web::{
+    body::BoxBody,
+    dev::{self, Service, ServiceRequest, ServiceResponse},
+    error::Error,
+    guard::Guard,
+    http::{header, Method},
+    HttpResponse,
+};
+use futures_core::future::LocalBoxFuture;
+
+use crate::{
+    named, Directory, DirectoryRenderer, FilesError, HttpService, MimeOverride, NamedFile,
+    PathBufWrap, PathFilter,
+};
+
+/// Assembled file serving service.
+#[derive(Clone)]
+pub struct FilesService(pub(crate) Rc<FilesServiceInner>);
+
+impl Deref for FilesService {
+    type Target = FilesServiceInner;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+pub struct FilesServiceInner {
+    pub(crate) directory: PathBuf,
+    pub(crate) index: Option<String>,
+    pub(crate) show_index: bool,
+    pub(crate) redirect_to_slash: bool,
+    pub(crate) default: Option<HttpService>,
+    pub(crate) renderer: Rc<DirectoryRenderer>,
+    pub(crate) mime_override: Option<Rc<MimeOverride>>,
+    pub(crate) path_filter: Option<Rc<PathFilter>>,
+    pub(crate) file_flags: named::Flags,
+    pub(crate) guards: Option<Rc<dyn Guard>>,
+    pub(crate) hidden_files: bool,
+}
+
+impl fmt::Debug for FilesServiceInner {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("FilesServiceInner")
+    }
+}
+
+impl FilesService {
+    async fn handle_err(
+        &self,
+        err: io::Error,
+        req: ServiceRequest,
+    ) -> Result<ServiceResponse, Error> {
+        log::debug!("error handling {}: {}", req.path(), err);
+
+        if let Some(ref default) = self.default {
+            default.call(req).await
+        } else {
+            Ok(req.error_response(err))
+        }
+    }
+
+    fn serve_named_file(&self, req: ServiceRequest, mut named_file: NamedFile) -> ServiceResponse {
+        if let Some(ref mime_override) = self.mime_override {
+            let new_disposition = mime_override(&named_file.content_type.type_());
+            named_file.content_disposition.disposition = new_disposition;
+        }
+        named_file.flags = self.file_flags;
+
+        let (req, _) = req.into_parts();
+        let res = named_file.into_response(&req);
+        ServiceResponse::new(req, res)
+    }
+
+    fn show_index(&self, req: ServiceRequest, path: PathBuf) -> ServiceResponse {
+        let dir = Directory::new(self.directory.clone(), path);
+
+        let (req, _) = req.into_parts();
+
+        (self.renderer)(&dir, &req).unwrap_or_else(|e| ServiceResponse::from_err(e, req))
+    }
+}
+
+impl fmt::Debug for FilesService {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("FilesService")
+    }
+}
+
+impl Service<ServiceRequest> for FilesService {
+    type Response = ServiceResponse<BoxBody>;
+    type Error = Error;
+    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
+
+    dev::always_ready!();
+
+    fn call(&self, req: ServiceRequest) -> Self::Future {
+        let is_method_valid = if let Some(guard) = &self.guards {
+            // execute user defined guards
+            (**guard).check(&req.guard_ctx())
+        } else {
+            // default behavior
+            matches!(*req.method(), Method::HEAD | Method::GET)
+        };
+
+        let this = self.clone();
+
+        Box::pin(async move {
+            if !is_method_valid {
+                return Ok(req.into_response(
+                    HttpResponse::MethodNotAllowed()
+                        .insert_header(header::ContentType(mime::TEXT_PLAIN_UTF_8))
+                        .body("Request did not meet this resource's requirements."),
+                ));
+            }
+
+            let path_on_disk =
+                match PathBufWrap::parse_path(req.match_info().unprocessed(), this.hidden_files) {
+                    Ok(item) => item,
+                    Err(err) => return Ok(req.error_response(err)),
+                };
+
+            if let Some(filter) = &this.path_filter {
+                if !filter(path_on_disk.as_ref(), req.head()) {
+                    if let Some(ref default) = this.default {
+                        return default.call(req).await;
+                    } else {
+                        return Ok(req.into_response(HttpResponse::NotFound().finish()));
+                    }
+                }
+            }
+
+            // full file path
+            let path = this.directory.join(&path_on_disk);
+            if let Err(err) = path.canonicalize() {
+                return this.handle_err(err, req).await;
+            }
+
+            if path.is_dir() {
+                if this.redirect_to_slash
+                    && !req.path().ends_with('/')
+                    && (this.index.is_some() || this.show_index)
+                {
+                    let redirect_to = format!("{}/", req.path());
+
+                    return Ok(req.into_response(
+                        HttpResponse::Found()
+                            .insert_header((header::LOCATION, redirect_to))
+                            .finish(),
+                    ));
+                }
+
+                match this.index {
+                    Some(ref index) => {
+                        let named_path = path.join(index);
+                        match NamedFile::open_async(named_path).await {
+                            Ok(named_file) => Ok(this.serve_named_file(req, named_file)),
+                            Err(_) if this.show_index => Ok(this.show_index(req, path)),
+                            Err(err) => this.handle_err(err, req).await,
+                        }
+                    }
+                    None if this.show_index => Ok(this.show_index(req, path)),
+                    None => Ok(ServiceResponse::from_err(
+                        FilesError::IsDirectory,
+                        req.into_parts().0,
+                    )),
+                }
+            } else {
+                match NamedFile::open_async(&path).await {
+                    Ok(mut named_file) => {
+                        if let Some(ref mime_override) = this.mime_override {
+                            let new_disposition = mime_override(&named_file.content_type.type_());
+                            named_file.content_disposition.disposition = new_disposition;
+                        }
+                        named_file.flags = this.file_flags;
+
+                        let (req, _) = req.into_parts();
+                        let res = named_file.into_response(&req);
+                        Ok(ServiceResponse::new(req, res))
+                    }
+                    Err(err) => this.handle_err(err, req).await,
+                }
+            }
+        })
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/body/body_stream.rs.html b/src/actix_http/body/body_stream.rs.html new file mode 100644 index 000000000..6ca3870b3 --- /dev/null +++ b/src/actix_http/body/body_stream.rs.html @@ -0,0 +1,429 @@ +body_stream.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
+
use std::{
+    error::Error as StdError,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use bytes::Bytes;
+use futures_core::{ready, Stream};
+use pin_project_lite::pin_project;
+
+use super::{BodySize, MessageBody};
+
+pin_project! {
+    /// Streaming response wrapper.
+    ///
+    /// Response does not contain `Content-Length` header and appropriate transfer encoding is used.
+    pub struct BodyStream<S> {
+        #[pin]
+        stream: S,
+    }
+}
+
+// TODO: from_infallible method
+
+impl<S, E> BodyStream<S>
+where
+    S: Stream<Item = Result<Bytes, E>>,
+    E: Into<Box<dyn StdError>> + 'static,
+{
+    #[inline]
+    pub fn new(stream: S) -> Self {
+        BodyStream { stream }
+    }
+}
+
+impl<S, E> MessageBody for BodyStream<S>
+where
+    S: Stream<Item = Result<Bytes, E>>,
+    E: Into<Box<dyn StdError>> + 'static,
+{
+    type Error = E;
+
+    #[inline]
+    fn size(&self) -> BodySize {
+        BodySize::Stream
+    }
+
+    /// Attempts to pull out the next value of the underlying [`Stream`].
+    ///
+    /// Empty values are skipped to prevent [`BodyStream`]'s transmission being ended on a
+    /// zero-length chunk, but rather proceed until the underlying [`Stream`] ends.
+    fn poll_next(
+        mut self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+    ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+        loop {
+            let stream = self.as_mut().project().stream;
+
+            let chunk = match ready!(stream.poll_next(cx)) {
+                Some(Ok(ref bytes)) if bytes.is_empty() => continue,
+                opt => opt,
+            };
+
+            return Poll::Ready(chunk);
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::{convert::Infallible, time::Duration};
+
+    use actix_rt::{
+        pin,
+        time::{sleep, Sleep},
+    };
+    use actix_utils::future::poll_fn;
+    use derive_more::{Display, Error};
+    use futures_core::ready;
+    use futures_util::{stream, FutureExt as _};
+    use pin_project_lite::pin_project;
+    use static_assertions::{assert_impl_all, assert_not_impl_any};
+
+    use super::*;
+    use crate::body::to_bytes;
+
+    assert_impl_all!(BodyStream<stream::Empty<Result<Bytes, crate::Error>>>: MessageBody);
+    assert_impl_all!(BodyStream<stream::Empty<Result<Bytes, &'static str>>>: MessageBody);
+    assert_impl_all!(BodyStream<stream::Repeat<Result<Bytes, &'static str>>>: MessageBody);
+    assert_impl_all!(BodyStream<stream::Empty<Result<Bytes, Infallible>>>: MessageBody);
+    assert_impl_all!(BodyStream<stream::Repeat<Result<Bytes, Infallible>>>: MessageBody);
+
+    assert_not_impl_any!(BodyStream<stream::Empty<Bytes>>: MessageBody);
+    assert_not_impl_any!(BodyStream<stream::Repeat<Bytes>>: MessageBody);
+    // crate::Error is not Clone
+    assert_not_impl_any!(BodyStream<stream::Repeat<Result<Bytes, crate::Error>>>: MessageBody);
+
+    #[actix_rt::test]
+    async fn skips_empty_chunks() {
+        let body = BodyStream::new(stream::iter(
+            ["1", "", "2"]
+                .iter()
+                .map(|&v| Ok::<_, Infallible>(Bytes::from(v))),
+        ));
+        pin!(body);
+
+        assert_eq!(
+            poll_fn(|cx| body.as_mut().poll_next(cx))
+                .await
+                .unwrap()
+                .ok(),
+            Some(Bytes::from("1")),
+        );
+        assert_eq!(
+            poll_fn(|cx| body.as_mut().poll_next(cx))
+                .await
+                .unwrap()
+                .ok(),
+            Some(Bytes::from("2")),
+        );
+    }
+
+    #[actix_rt::test]
+    async fn read_to_bytes() {
+        let body = BodyStream::new(stream::iter(
+            ["1", "", "2"]
+                .iter()
+                .map(|&v| Ok::<_, Infallible>(Bytes::from(v))),
+        ));
+
+        assert_eq!(to_bytes(body).await.ok(), Some(Bytes::from("12")));
+    }
+    #[derive(Debug, Display, Error)]
+    #[display(fmt = "stream error")]
+    struct StreamErr;
+
+    #[actix_rt::test]
+    async fn stream_immediate_error() {
+        let body = BodyStream::new(stream::once(async { Err(StreamErr) }));
+        assert!(matches!(to_bytes(body).await, Err(StreamErr)));
+    }
+
+    #[actix_rt::test]
+    async fn stream_string_error() {
+        // `&'static str` does not impl `Error`
+        // but it does impl `Into<Box<dyn Error>>`
+
+        let body = BodyStream::new(stream::once(async { Err("stringy error") }));
+        assert!(matches!(to_bytes(body).await, Err("stringy error")));
+    }
+
+    #[actix_rt::test]
+    async fn stream_boxed_error() {
+        // `Box<dyn Error>` does not impl `Error`
+        // but it does impl `Into<Box<dyn Error>>`
+
+        let body = BodyStream::new(stream::once(async {
+            Err(Box::<dyn StdError>::from("stringy error"))
+        }));
+
+        assert_eq!(
+            to_bytes(body).await.unwrap_err().to_string(),
+            "stringy error"
+        );
+    }
+
+    #[actix_rt::test]
+    async fn stream_delayed_error() {
+        let body = BodyStream::new(stream::iter(vec![Ok(Bytes::from("1")), Err(StreamErr)]));
+        assert!(matches!(to_bytes(body).await, Err(StreamErr)));
+
+        pin_project! {
+            #[derive(Debug)]
+            #[project = TimeDelayStreamProj]
+            enum TimeDelayStream {
+                Start,
+                Sleep { delay: Pin<Box<Sleep>> },
+                Done,
+            }
+        }
+
+        impl Stream for TimeDelayStream {
+            type Item = Result<Bytes, StreamErr>;
+
+            fn poll_next(
+                mut self: Pin<&mut Self>,
+                cx: &mut Context<'_>,
+            ) -> Poll<Option<Self::Item>> {
+                match self.as_mut().get_mut() {
+                    TimeDelayStream::Start => {
+                        let sleep = sleep(Duration::from_millis(1));
+                        self.as_mut().set(TimeDelayStream::Sleep {
+                            delay: Box::pin(sleep),
+                        });
+                        cx.waker().wake_by_ref();
+                        Poll::Pending
+                    }
+
+                    TimeDelayStream::Sleep { ref mut delay } => {
+                        ready!(delay.poll_unpin(cx));
+                        self.set(TimeDelayStream::Done);
+                        cx.waker().wake_by_ref();
+                        Poll::Pending
+                    }
+
+                    TimeDelayStream::Done => Poll::Ready(Some(Err(StreamErr))),
+                }
+            }
+        }
+
+        let body = BodyStream::new(TimeDelayStream::Start);
+        assert!(matches!(to_bytes(body).await, Err(StreamErr)));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/body/boxed.rs.html b/src/actix_http/body/boxed.rs.html new file mode 100644 index 000000000..5901f921a --- /dev/null +++ b/src/actix_http/body/boxed.rs.html @@ -0,0 +1,243 @@ +boxed.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
+
use std::{
+    error::Error as StdError,
+    fmt,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use bytes::Bytes;
+
+use super::{BodySize, MessageBody, MessageBodyMapErr};
+use crate::body;
+
+/// A boxed message body with boxed errors.
+#[derive(Debug)]
+pub struct BoxBody(BoxBodyInner);
+
+enum BoxBodyInner {
+    None(body::None),
+    Bytes(Bytes),
+    Stream(Pin<Box<dyn MessageBody<Error = Box<dyn StdError>>>>),
+}
+
+impl fmt::Debug for BoxBodyInner {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Self::None(arg0) => f.debug_tuple("None").field(arg0).finish(),
+            Self::Bytes(arg0) => f.debug_tuple("Bytes").field(arg0).finish(),
+            Self::Stream(_) => f.debug_tuple("Stream").field(&"dyn MessageBody").finish(),
+        }
+    }
+}
+
+impl BoxBody {
+    /// Boxes body type, erasing type information.
+    ///
+    /// If the body type to wrap is unknown or generic it is better to use [`MessageBody::boxed`] to
+    /// avoid double boxing.
+    #[inline]
+    pub fn new<B>(body: B) -> Self
+    where
+        B: MessageBody + 'static,
+    {
+        match body.size() {
+            BodySize::None => Self(BoxBodyInner::None(body::None)),
+            _ => match body.try_into_bytes() {
+                Ok(bytes) => Self(BoxBodyInner::Bytes(bytes)),
+                Err(body) => {
+                    let body = MessageBodyMapErr::new(body, Into::into);
+                    Self(BoxBodyInner::Stream(Box::pin(body)))
+                }
+            },
+        }
+    }
+
+    /// Returns a mutable pinned reference to the inner message body type.
+    #[inline]
+    pub fn as_pin_mut(&mut self) -> Pin<&mut Self> {
+        Pin::new(self)
+    }
+}
+
+impl MessageBody for BoxBody {
+    type Error = Box<dyn StdError>;
+
+    #[inline]
+    fn size(&self) -> BodySize {
+        match &self.0 {
+            BoxBodyInner::None(none) => none.size(),
+            BoxBodyInner::Bytes(bytes) => bytes.size(),
+            BoxBodyInner::Stream(stream) => stream.size(),
+        }
+    }
+
+    #[inline]
+    fn poll_next(
+        mut self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+    ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+        match &mut self.0 {
+            BoxBodyInner::None(body) => Pin::new(body).poll_next(cx).map_err(|err| match err {}),
+            BoxBodyInner::Bytes(body) => Pin::new(body).poll_next(cx).map_err(|err| match err {}),
+            BoxBodyInner::Stream(body) => Pin::new(body).poll_next(cx),
+        }
+    }
+
+    #[inline]
+    fn try_into_bytes(self) -> Result<Bytes, Self> {
+        match self.0 {
+            BoxBodyInner::None(body) => Ok(body.try_into_bytes().unwrap()),
+            BoxBodyInner::Bytes(body) => Ok(body.try_into_bytes().unwrap()),
+            _ => Err(self),
+        }
+    }
+
+    #[inline]
+    fn boxed(self) -> BoxBody {
+        self
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use static_assertions::{assert_impl_all, assert_not_impl_any};
+
+    use super::*;
+    use crate::body::to_bytes;
+
+    assert_impl_all!(BoxBody: fmt::Debug, MessageBody, Unpin);
+    assert_not_impl_any!(BoxBody: Send, Sync);
+
+    #[actix_rt::test]
+    async fn nested_boxed_body() {
+        let body = Bytes::from_static(&[1, 2, 3]);
+        let boxed_body = BoxBody::new(BoxBody::new(body));
+
+        assert_eq!(
+            to_bytes(boxed_body).await.unwrap(),
+            Bytes::from(vec![1, 2, 3]),
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/body/either.rs.html b/src/actix_http/body/either.rs.html new file mode 100644 index 000000000..2cb9fd6d8 --- /dev/null +++ b/src/actix_http/body/either.rs.html @@ -0,0 +1,245 @@ +either.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
+
use std::{
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use bytes::Bytes;
+use pin_project_lite::pin_project;
+
+use super::{BodySize, BoxBody, MessageBody};
+use crate::Error;
+
+pin_project! {
+    /// An "either" type specialized for body types.
+    ///
+    /// It is common, in middleware especially, to conditionally return an inner service's unknown/
+    /// generic body `B` type or return early with a new response. This type's "right" variant
+    /// defaults to `BoxBody` since error responses are the common case.
+    ///
+    /// For example, middleware will often have `type Response = ServiceResponse<EitherBody<B>>`.
+    /// This means that the inner service's response body type maps to the `Left` variant and the
+    /// middleware's own error responses use the default `Right` variant of `BoxBody`. Of course,
+    /// there's no reason it couldn't use `EitherBody<B, String>` instead if its alternative
+    /// responses have a known type.
+    #[project = EitherBodyProj]
+    #[derive(Debug, Clone)]
+    pub enum EitherBody<L, R = BoxBody> {
+        /// A body of type `L`.
+        Left { #[pin] body: L },
+
+        /// A body of type `R`.
+        Right { #[pin] body: R },
+    }
+}
+
+impl<L> EitherBody<L, BoxBody> {
+    /// Creates new `EitherBody` left variant with a boxed right variant.
+    ///
+    /// If the expected `R` type will be inferred and is not `BoxBody` then use the
+    /// [`left`](Self::left) constructor instead.
+    #[inline]
+    pub fn new(body: L) -> Self {
+        Self::Left { body }
+    }
+}
+
+impl<L, R> EitherBody<L, R> {
+    /// Creates new `EitherBody` using left variant.
+    #[inline]
+    pub fn left(body: L) -> Self {
+        Self::Left { body }
+    }
+
+    /// Creates new `EitherBody` using right variant.
+    #[inline]
+    pub fn right(body: R) -> Self {
+        Self::Right { body }
+    }
+}
+
+impl<L, R> MessageBody for EitherBody<L, R>
+where
+    L: MessageBody + 'static,
+    R: MessageBody + 'static,
+{
+    type Error = Error;
+
+    #[inline]
+    fn size(&self) -> BodySize {
+        match self {
+            EitherBody::Left { body } => body.size(),
+            EitherBody::Right { body } => body.size(),
+        }
+    }
+
+    #[inline]
+    fn poll_next(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+    ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+        match self.project() {
+            EitherBodyProj::Left { body } => body
+                .poll_next(cx)
+                .map_err(|err| Error::new_body().with_cause(err)),
+            EitherBodyProj::Right { body } => body
+                .poll_next(cx)
+                .map_err(|err| Error::new_body().with_cause(err)),
+        }
+    }
+
+    #[inline]
+    fn try_into_bytes(self) -> Result<Bytes, Self> {
+        match self {
+            EitherBody::Left { body } => body
+                .try_into_bytes()
+                .map_err(|body| EitherBody::Left { body }),
+            EitherBody::Right { body } => body
+                .try_into_bytes()
+                .map_err(|body| EitherBody::Right { body }),
+        }
+    }
+
+    #[inline]
+    fn boxed(self) -> BoxBody {
+        match self {
+            EitherBody::Left { body } => body.boxed(),
+            EitherBody::Right { body } => body.boxed(),
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn type_parameter_inference() {
+        let _body: EitherBody<(), _> = EitherBody::new(());
+
+        let _body: EitherBody<_, ()> = EitherBody::left(());
+        let _body: EitherBody<(), _> = EitherBody::right(());
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/body/message_body.rs.html b/src/actix_http/body/message_body.rs.html new file mode 100644 index 000000000..db365ebf7 --- /dev/null +++ b/src/actix_http/body/message_body.rs.html @@ -0,0 +1,1481 @@ +message_body.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
+
//! [`MessageBody`] trait and foreign implementations.
+
+use std::{
+    convert::Infallible,
+    error::Error as StdError,
+    mem,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use bytes::{Bytes, BytesMut};
+use futures_core::ready;
+use pin_project_lite::pin_project;
+
+use super::{BodySize, BoxBody};
+
+/// An interface for types that can be used as a response body.
+///
+/// It is not usually necessary to create custom body types, this trait is already [implemented for
+/// a large number of sensible body types](#foreign-impls) including:
+/// - Empty body: `()`
+/// - Text-based: `String`, `&'static str`, [`ByteString`](https://docs.rs/bytestring/1).
+/// - Byte-based: `Bytes`, `BytesMut`, `Vec<u8>`, `&'static [u8]`;
+/// - Streams: [`BodyStream`](super::BodyStream), [`SizedStream`](super::SizedStream)
+///
+/// # Examples
+/// ```
+/// # use std::convert::Infallible;
+/// # use std::task::{Poll, Context};
+/// # use std::pin::Pin;
+/// # use bytes::Bytes;
+/// # use actix_http::body::{BodySize, MessageBody};
+/// struct Repeat {
+///     chunk: String,
+///     n_times: usize,
+/// }
+///
+/// impl MessageBody for Repeat {
+///     type Error = Infallible;
+///
+///     fn size(&self) -> BodySize {
+///         BodySize::Sized((self.chunk.len() * self.n_times) as u64)
+///     }
+///
+///     fn poll_next(
+///         self: Pin<&mut Self>,
+///         _cx: &mut Context<'_>,
+///     ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+///         let payload_string = self.chunk.repeat(self.n_times);
+///         let payload_bytes = Bytes::from(payload_string);
+///         Poll::Ready(Some(Ok(payload_bytes)))
+///     }
+/// }
+/// ```
+pub trait MessageBody {
+    /// The type of error that will be returned if streaming body fails.
+    ///
+    /// Since it is not appropriate to generate a response mid-stream, it only requires `Error` for
+    /// internal use and logging.
+    type Error: Into<Box<dyn StdError>>;
+
+    /// Body size hint.
+    ///
+    /// If [`BodySize::None`] is returned, optimizations that skip reading the body are allowed.
+    fn size(&self) -> BodySize;
+
+    /// Attempt to pull out the next chunk of body bytes.
+    ///
+    /// # Return Value
+    /// Similar to the `Stream` interface, there are several possible return values, each indicating
+    /// a distinct state:
+    /// - `Poll::Pending` means that this body's next chunk is not ready yet. Implementations must
+    ///   ensure that the current task will be notified when the next chunk may be ready.
+    /// - `Poll::Ready(Some(val))` means that the body has successfully produced a chunk, `val`,
+    ///   and may produce further values on subsequent `poll_next` calls.
+    /// - `Poll::Ready(None)` means that the body is complete, and `poll_next` should not be
+    ///   invoked again.
+    ///
+    /// # Panics
+    /// Once a body is complete (i.e., `poll_next` returned `Ready(None)`), calling its `poll_next`
+    /// method again may panic, block forever, or cause other kinds of problems; this trait places
+    /// no requirements on the effects of such a call. However, as the `poll_next` method is not
+    /// marked unsafe, Rust’s usual rules apply: calls must never cause UB, regardless of its state.
+    fn poll_next(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+    ) -> Poll<Option<Result<Bytes, Self::Error>>>;
+
+    /// Try to convert into the complete chunk of body bytes.
+    ///
+    /// Override this method if the complete body can be trivially extracted. This is useful for
+    /// optimizations where `poll_next` calls can be avoided.
+    ///
+    /// Body types with [`BodySize::None`] are allowed to return empty `Bytes`. Although, if calling
+    /// this method, it is recommended to check `size` first and return early.
+    ///
+    /// # Errors
+    /// The default implementation will error and return the original type back to the caller for
+    /// further use.
+    #[inline]
+    fn try_into_bytes(self) -> Result<Bytes, Self>
+    where
+        Self: Sized,
+    {
+        Err(self)
+    }
+
+    /// Wraps this body into a `BoxBody`.
+    ///
+    /// No-op when called on a `BoxBody`, meaning there is no risk of double boxing when calling
+    /// this on a generic `MessageBody`. Prefer this over [`BoxBody::new`] when a boxed body
+    /// is required.
+    #[inline]
+    fn boxed(self) -> BoxBody
+    where
+        Self: Sized + 'static,
+    {
+        BoxBody::new(self)
+    }
+}
+
+mod foreign_impls {
+    use std::{borrow::Cow, ops::DerefMut};
+
+    use super::*;
+
+    impl<B> MessageBody for &mut B
+    where
+        B: MessageBody + Unpin + ?Sized,
+    {
+        type Error = B::Error;
+
+        fn size(&self) -> BodySize {
+            (**self).size()
+        }
+
+        fn poll_next(
+            mut self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+        ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+            Pin::new(&mut **self).poll_next(cx)
+        }
+    }
+
+    impl MessageBody for Infallible {
+        type Error = Infallible;
+
+        fn size(&self) -> BodySize {
+            match *self {}
+        }
+
+        fn poll_next(
+            self: Pin<&mut Self>,
+            _cx: &mut Context<'_>,
+        ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+            match *self {}
+        }
+    }
+
+    impl MessageBody for () {
+        type Error = Infallible;
+
+        #[inline]
+        fn size(&self) -> BodySize {
+            BodySize::Sized(0)
+        }
+
+        #[inline]
+        fn poll_next(
+            self: Pin<&mut Self>,
+            _cx: &mut Context<'_>,
+        ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+            Poll::Ready(None)
+        }
+
+        #[inline]
+        fn try_into_bytes(self) -> Result<Bytes, Self> {
+            Ok(Bytes::new())
+        }
+    }
+
+    impl<B> MessageBody for Box<B>
+    where
+        B: MessageBody + Unpin + ?Sized,
+    {
+        type Error = B::Error;
+
+        #[inline]
+        fn size(&self) -> BodySize {
+            self.as_ref().size()
+        }
+
+        #[inline]
+        fn poll_next(
+            self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+        ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+            Pin::new(self.get_mut().as_mut()).poll_next(cx)
+        }
+    }
+
+    impl<T, B> MessageBody for Pin<T>
+    where
+        T: DerefMut<Target = B> + Unpin,
+        B: MessageBody + ?Sized,
+    {
+        type Error = B::Error;
+
+        #[inline]
+        fn size(&self) -> BodySize {
+            self.as_ref().size()
+        }
+
+        #[inline]
+        fn poll_next(
+            self: Pin<&mut Self>,
+            cx: &mut Context<'_>,
+        ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+            self.get_mut().as_mut().poll_next(cx)
+        }
+    }
+
+    impl MessageBody for &'static [u8] {
+        type Error = Infallible;
+
+        #[inline]
+        fn size(&self) -> BodySize {
+            BodySize::Sized(self.len() as u64)
+        }
+
+        #[inline]
+        fn poll_next(
+            self: Pin<&mut Self>,
+            _cx: &mut Context<'_>,
+        ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+            if self.is_empty() {
+                Poll::Ready(None)
+            } else {
+                Poll::Ready(Some(Ok(Bytes::from_static(mem::take(self.get_mut())))))
+            }
+        }
+
+        #[inline]
+        fn try_into_bytes(self) -> Result<Bytes, Self> {
+            Ok(Bytes::from_static(self))
+        }
+    }
+
+    impl MessageBody for Bytes {
+        type Error = Infallible;
+
+        #[inline]
+        fn size(&self) -> BodySize {
+            BodySize::Sized(self.len() as u64)
+        }
+
+        #[inline]
+        fn poll_next(
+            self: Pin<&mut Self>,
+            _cx: &mut Context<'_>,
+        ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+            if self.is_empty() {
+                Poll::Ready(None)
+            } else {
+                Poll::Ready(Some(Ok(mem::take(self.get_mut()))))
+            }
+        }
+
+        #[inline]
+        fn try_into_bytes(self) -> Result<Bytes, Self> {
+            Ok(self)
+        }
+    }
+
+    impl MessageBody for BytesMut {
+        type Error = Infallible;
+
+        #[inline]
+        fn size(&self) -> BodySize {
+            BodySize::Sized(self.len() as u64)
+        }
+
+        #[inline]
+        fn poll_next(
+            self: Pin<&mut Self>,
+            _cx: &mut Context<'_>,
+        ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+            if self.is_empty() {
+                Poll::Ready(None)
+            } else {
+                Poll::Ready(Some(Ok(mem::take(self.get_mut()).freeze())))
+            }
+        }
+
+        #[inline]
+        fn try_into_bytes(self) -> Result<Bytes, Self> {
+            Ok(self.freeze())
+        }
+    }
+
+    impl MessageBody for Vec<u8> {
+        type Error = Infallible;
+
+        #[inline]
+        fn size(&self) -> BodySize {
+            BodySize::Sized(self.len() as u64)
+        }
+
+        #[inline]
+        fn poll_next(
+            self: Pin<&mut Self>,
+            _cx: &mut Context<'_>,
+        ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+            if self.is_empty() {
+                Poll::Ready(None)
+            } else {
+                Poll::Ready(Some(Ok(mem::take(self.get_mut()).into())))
+            }
+        }
+
+        #[inline]
+        fn try_into_bytes(self) -> Result<Bytes, Self> {
+            Ok(Bytes::from(self))
+        }
+    }
+
+    impl MessageBody for Cow<'static, [u8]> {
+        type Error = Infallible;
+
+        #[inline]
+        fn size(&self) -> BodySize {
+            BodySize::Sized(self.len() as u64)
+        }
+
+        #[inline]
+        fn poll_next(
+            self: Pin<&mut Self>,
+            _cx: &mut Context<'_>,
+        ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+            if self.is_empty() {
+                Poll::Ready(None)
+            } else {
+                let bytes = match mem::take(self.get_mut()) {
+                    Cow::Borrowed(b) => Bytes::from_static(b),
+                    Cow::Owned(b) => Bytes::from(b),
+                };
+                Poll::Ready(Some(Ok(bytes)))
+            }
+        }
+
+        #[inline]
+        fn try_into_bytes(self) -> Result<Bytes, Self> {
+            match self {
+                Cow::Borrowed(b) => Ok(Bytes::from_static(b)),
+                Cow::Owned(b) => Ok(Bytes::from(b)),
+            }
+        }
+    }
+
+    impl MessageBody for &'static str {
+        type Error = Infallible;
+
+        #[inline]
+        fn size(&self) -> BodySize {
+            BodySize::Sized(self.len() as u64)
+        }
+
+        #[inline]
+        fn poll_next(
+            self: Pin<&mut Self>,
+            _cx: &mut Context<'_>,
+        ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+            if self.is_empty() {
+                Poll::Ready(None)
+            } else {
+                let string = mem::take(self.get_mut());
+                let bytes = Bytes::from_static(string.as_bytes());
+                Poll::Ready(Some(Ok(bytes)))
+            }
+        }
+
+        #[inline]
+        fn try_into_bytes(self) -> Result<Bytes, Self> {
+            Ok(Bytes::from_static(self.as_bytes()))
+        }
+    }
+
+    impl MessageBody for String {
+        type Error = Infallible;
+
+        #[inline]
+        fn size(&self) -> BodySize {
+            BodySize::Sized(self.len() as u64)
+        }
+
+        #[inline]
+        fn poll_next(
+            self: Pin<&mut Self>,
+            _cx: &mut Context<'_>,
+        ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+            if self.is_empty() {
+                Poll::Ready(None)
+            } else {
+                let string = mem::take(self.get_mut());
+                Poll::Ready(Some(Ok(Bytes::from(string))))
+            }
+        }
+
+        #[inline]
+        fn try_into_bytes(self) -> Result<Bytes, Self> {
+            Ok(Bytes::from(self))
+        }
+    }
+
+    impl MessageBody for Cow<'static, str> {
+        type Error = Infallible;
+
+        #[inline]
+        fn size(&self) -> BodySize {
+            BodySize::Sized(self.len() as u64)
+        }
+
+        #[inline]
+        fn poll_next(
+            self: Pin<&mut Self>,
+            _cx: &mut Context<'_>,
+        ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+            if self.is_empty() {
+                Poll::Ready(None)
+            } else {
+                let bytes = match mem::take(self.get_mut()) {
+                    Cow::Borrowed(s) => Bytes::from_static(s.as_bytes()),
+                    Cow::Owned(s) => Bytes::from(s.into_bytes()),
+                };
+                Poll::Ready(Some(Ok(bytes)))
+            }
+        }
+
+        #[inline]
+        fn try_into_bytes(self) -> Result<Bytes, Self> {
+            match self {
+                Cow::Borrowed(s) => Ok(Bytes::from_static(s.as_bytes())),
+                Cow::Owned(s) => Ok(Bytes::from(s.into_bytes())),
+            }
+        }
+    }
+
+    impl MessageBody for bytestring::ByteString {
+        type Error = Infallible;
+
+        #[inline]
+        fn size(&self) -> BodySize {
+            BodySize::Sized(self.len() as u64)
+        }
+
+        #[inline]
+        fn poll_next(
+            self: Pin<&mut Self>,
+            _cx: &mut Context<'_>,
+        ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+            let string = mem::take(self.get_mut());
+            Poll::Ready(Some(Ok(string.into_bytes())))
+        }
+
+        #[inline]
+        fn try_into_bytes(self) -> Result<Bytes, Self> {
+            Ok(self.into_bytes())
+        }
+    }
+}
+
+pin_project! {
+    pub(crate) struct MessageBodyMapErr<B, F> {
+        #[pin]
+        body: B,
+        mapper: Option<F>,
+    }
+}
+
+impl<B, F, E> MessageBodyMapErr<B, F>
+where
+    B: MessageBody,
+    F: FnOnce(B::Error) -> E,
+{
+    pub(crate) fn new(body: B, mapper: F) -> Self {
+        Self {
+            body,
+            mapper: Some(mapper),
+        }
+    }
+}
+
+impl<B, F, E> MessageBody for MessageBodyMapErr<B, F>
+where
+    B: MessageBody,
+    F: FnOnce(B::Error) -> E,
+    E: Into<Box<dyn StdError>>,
+{
+    type Error = E;
+
+    #[inline]
+    fn size(&self) -> BodySize {
+        self.body.size()
+    }
+
+    fn poll_next(
+        mut self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+    ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+        let this = self.as_mut().project();
+
+        match ready!(this.body.poll_next(cx)) {
+            Some(Err(err)) => {
+                let f = self.as_mut().project().mapper.take().unwrap();
+                let mapped_err = (f)(err);
+                Poll::Ready(Some(Err(mapped_err)))
+            }
+            Some(Ok(val)) => Poll::Ready(Some(Ok(val))),
+            None => Poll::Ready(None),
+        }
+    }
+
+    #[inline]
+    fn try_into_bytes(self) -> Result<Bytes, Self> {
+        let Self { body, mapper } = self;
+        body.try_into_bytes().map_err(|body| Self { body, mapper })
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_rt::pin;
+    use actix_utils::future::poll_fn;
+    use futures_util::stream;
+
+    use super::*;
+    use crate::body::{self, EitherBody};
+
+    macro_rules! assert_poll_next {
+        ($pin:expr, $exp:expr) => {
+            assert_eq!(
+                poll_fn(|cx| $pin.as_mut().poll_next(cx))
+                    .await
+                    .unwrap() // unwrap option
+                    .unwrap(), // unwrap result
+                $exp
+            );
+        };
+    }
+
+    macro_rules! assert_poll_next_none {
+        ($pin:expr) => {
+            assert!(poll_fn(|cx| $pin.as_mut().poll_next(cx)).await.is_none());
+        };
+    }
+
+    #[allow(unused_allocation)] // triggered by `Box::new(()).size()`
+    #[actix_rt::test]
+    async fn boxing_equivalence() {
+        assert_eq!(().size(), BodySize::Sized(0));
+        assert_eq!(().size(), Box::new(()).size());
+        assert_eq!(().size(), Box::pin(()).size());
+
+        let pl = Box::new(());
+        pin!(pl);
+        assert_poll_next_none!(pl);
+
+        let mut pl = Box::pin(());
+        assert_poll_next_none!(pl);
+    }
+
+    #[actix_rt::test]
+    async fn mut_equivalence() {
+        assert_eq!(().size(), BodySize::Sized(0));
+        assert_eq!(().size(), (&(&mut ())).size());
+
+        let pl = &mut ();
+        pin!(pl);
+        assert_poll_next_none!(pl);
+
+        let pl = &mut Box::new(());
+        pin!(pl);
+        assert_poll_next_none!(pl);
+
+        let mut body = body::SizedStream::new(
+            8,
+            stream::iter([
+                Ok::<_, std::io::Error>(Bytes::from("1234")),
+                Ok(Bytes::from("5678")),
+            ]),
+        );
+        let body = &mut body;
+        assert_eq!(body.size(), BodySize::Sized(8));
+        pin!(body);
+        assert_poll_next!(body, Bytes::from_static(b"1234"));
+        assert_poll_next!(body, Bytes::from_static(b"5678"));
+        assert_poll_next_none!(body);
+    }
+
+    #[allow(clippy::let_unit_value)]
+    #[actix_rt::test]
+    async fn test_unit() {
+        let pl = ();
+        assert_eq!(pl.size(), BodySize::Sized(0));
+        pin!(pl);
+        assert_poll_next_none!(pl);
+    }
+
+    #[actix_rt::test]
+    async fn test_static_str() {
+        assert_eq!("".size(), BodySize::Sized(0));
+        assert_eq!("test".size(), BodySize::Sized(4));
+
+        let pl = "test";
+        pin!(pl);
+        assert_poll_next!(pl, Bytes::from("test"));
+    }
+
+    #[actix_rt::test]
+    async fn test_static_bytes() {
+        assert_eq!(b"".as_ref().size(), BodySize::Sized(0));
+        assert_eq!(b"test".as_ref().size(), BodySize::Sized(4));
+
+        let pl = b"test".as_ref();
+        pin!(pl);
+        assert_poll_next!(pl, Bytes::from("test"));
+    }
+
+    #[actix_rt::test]
+    async fn test_vec() {
+        assert_eq!(vec![0; 0].size(), BodySize::Sized(0));
+        assert_eq!(Vec::from("test").size(), BodySize::Sized(4));
+
+        let pl = Vec::from("test");
+        pin!(pl);
+        assert_poll_next!(pl, Bytes::from("test"));
+    }
+
+    #[actix_rt::test]
+    async fn test_bytes() {
+        assert_eq!(Bytes::new().size(), BodySize::Sized(0));
+        assert_eq!(Bytes::from_static(b"test").size(), BodySize::Sized(4));
+
+        let pl = Bytes::from_static(b"test");
+        pin!(pl);
+        assert_poll_next!(pl, Bytes::from("test"));
+    }
+
+    #[actix_rt::test]
+    async fn test_bytes_mut() {
+        assert_eq!(BytesMut::new().size(), BodySize::Sized(0));
+        assert_eq!(BytesMut::from(b"test".as_ref()).size(), BodySize::Sized(4));
+
+        let pl = BytesMut::from("test");
+        pin!(pl);
+        assert_poll_next!(pl, Bytes::from("test"));
+    }
+
+    #[actix_rt::test]
+    async fn test_string() {
+        assert_eq!(String::new().size(), BodySize::Sized(0));
+        assert_eq!("test".to_owned().size(), BodySize::Sized(4));
+
+        let pl = "test".to_owned();
+        pin!(pl);
+        assert_poll_next!(pl, Bytes::from("test"));
+    }
+
+    #[actix_rt::test]
+    async fn complete_body_combinators() {
+        let body = Bytes::from_static(b"test");
+        let body = BoxBody::new(body);
+        let body = EitherBody::<_, ()>::left(body);
+        let body = EitherBody::<(), _>::right(body);
+        // Do not support try_into_bytes:
+        // let body = Box::new(body);
+        // let body = Box::pin(body);
+
+        assert_eq!(body.try_into_bytes().unwrap(), Bytes::from("test"));
+    }
+
+    #[actix_rt::test]
+    async fn complete_body_combinators_poll() {
+        let body = Bytes::from_static(b"test");
+        let body = BoxBody::new(body);
+        let body = EitherBody::<_, ()>::left(body);
+        let body = EitherBody::<(), _>::right(body);
+        let mut body = body;
+
+        assert_eq!(body.size(), BodySize::Sized(4));
+        assert_poll_next!(Pin::new(&mut body), Bytes::from("test"));
+        assert_poll_next_none!(Pin::new(&mut body));
+    }
+
+    #[actix_rt::test]
+    async fn none_body_combinators() {
+        fn none_body() -> BoxBody {
+            let body = body::None;
+            let body = BoxBody::new(body);
+            let body = EitherBody::<_, ()>::left(body);
+            let body = EitherBody::<(), _>::right(body);
+            body.boxed()
+        }
+
+        assert_eq!(none_body().size(), BodySize::None);
+        assert_eq!(none_body().try_into_bytes().unwrap(), Bytes::new());
+        assert_poll_next_none!(Pin::new(&mut none_body()));
+    }
+
+    // down-casting used to be done with a method on MessageBody trait
+    // test is kept to demonstrate equivalence of Any trait
+    #[actix_rt::test]
+    async fn test_body_casting() {
+        let mut body = String::from("hello cast");
+        // let mut resp_body: &mut dyn MessageBody<Error = Error> = &mut body;
+        let resp_body: &mut dyn std::any::Any = &mut body;
+        let body = resp_body.downcast_ref::<String>().unwrap();
+        assert_eq!(body, "hello cast");
+        let body = &mut resp_body.downcast_mut::<String>().unwrap();
+        body.push('!');
+        let body = resp_body.downcast_ref::<String>().unwrap();
+        assert_eq!(body, "hello cast!");
+        let not_body = resp_body.downcast_ref::<()>();
+        assert!(not_body.is_none());
+    }
+
+    #[actix_rt::test]
+    async fn non_owning_to_bytes() {
+        let mut body = BoxBody::new(());
+        let bytes = body::to_bytes(&mut body).await.unwrap();
+        assert_eq!(bytes, Bytes::new());
+
+        let mut body = body::BodyStream::new(stream::iter([
+            Ok::<_, std::io::Error>(Bytes::from("1234")),
+            Ok(Bytes::from("5678")),
+        ]));
+        let bytes = body::to_bytes(&mut body).await.unwrap();
+        assert_eq!(bytes, Bytes::from_static(b"12345678"));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/body/mod.rs.html b/src/actix_http/body/mod.rs.html new file mode 100644 index 000000000..0cb4031c1 --- /dev/null +++ b/src/actix_http/body/mod.rs.html @@ -0,0 +1,55 @@ +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
+
//! Traits and structures to aid consuming and writing HTTP payloads.
+//!
+//! "Body" and "payload" are used somewhat interchangeably in this documentation.
+
+// Though the spec kinda reads like "payload" is the possibly-transfer-encoded part of the message
+// and the "body" is the intended possibly-decoded version of that.
+
+mod body_stream;
+mod boxed;
+mod either;
+mod message_body;
+mod none;
+mod size;
+mod sized_stream;
+mod utils;
+
+pub(crate) use self::message_body::MessageBodyMapErr;
+pub use self::{
+    body_stream::BodyStream,
+    boxed::BoxBody,
+    either::EitherBody,
+    message_body::MessageBody,
+    none::None,
+    size::BodySize,
+    sized_stream::SizedStream,
+    utils::{to_bytes, to_bytes_limited, BodyLimitExceeded},
+};
+
\ No newline at end of file diff --git a/src/actix_http/body/none.rs.html b/src/actix_http/body/none.rs.html new file mode 100644 index 000000000..725bddb27 --- /dev/null +++ b/src/actix_http/body/none.rs.html @@ -0,0 +1,103 @@ +none.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::{
+    convert::Infallible,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use bytes::Bytes;
+
+use super::{BodySize, MessageBody};
+
+/// Body type for responses that forbid payloads.
+///
+/// This is distinct from an "empty" response which _would_ contain a `Content-Length` header.
+/// For an "empty" body, use `()` or `Bytes::new()`.
+///
+/// For example, the HTTP spec forbids a payload to be sent with a `204 No Content` response.
+/// In this case, the payload (or lack thereof) is implicit from the status code, so a
+/// `Content-Length` header is not required.
+#[derive(Debug, Clone, Copy, Default)]
+#[non_exhaustive]
+pub struct None;
+
+impl None {
+    /// Constructs new "none" body.
+    #[inline]
+    pub fn new() -> Self {
+        None
+    }
+}
+
+impl MessageBody for None {
+    type Error = Infallible;
+
+    #[inline]
+    fn size(&self) -> BodySize {
+        BodySize::None
+    }
+
+    #[inline]
+    fn poll_next(
+        self: Pin<&mut Self>,
+        _cx: &mut Context<'_>,
+    ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+        Poll::Ready(Option::None)
+    }
+
+    #[inline]
+    fn try_into_bytes(self) -> Result<Bytes, Self> {
+        Ok(Bytes::new())
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/body/size.rs.html b/src/actix_http/body/size.rs.html new file mode 100644 index 000000000..da818e5b9 --- /dev/null +++ b/src/actix_http/body/size.rs.html @@ -0,0 +1,83 @@ +size.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
+
/// Body size hint.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum BodySize {
+    /// Implicitly empty body.
+    ///
+    /// Will omit the Content-Length header. Used for responses to certain methods (e.g., `HEAD`) or
+    /// with particular status codes (e.g., 204 No Content). Consumers that read this as a body size
+    /// hint are allowed to make optimizations that skip reading or writing the payload.
+    None,
+
+    /// Known size body.
+    ///
+    /// Will write `Content-Length: N` header.
+    Sized(u64),
+
+    /// Unknown size body.
+    ///
+    /// Will not write Content-Length header. Can be used with chunked Transfer-Encoding.
+    Stream,
+}
+
+impl BodySize {
+    /// Equivalent to `BodySize::Sized(0)`;
+    pub const ZERO: Self = Self::Sized(0);
+
+    /// Returns true if size hint indicates omitted or empty body.
+    ///
+    /// Streams will return false because it cannot be known without reading the stream.
+    ///
+    /// ```
+    /// # use actix_http::body::BodySize;
+    /// assert!(BodySize::None.is_eof());
+    /// assert!(BodySize::Sized(0).is_eof());
+    ///
+    /// assert!(!BodySize::Sized(64).is_eof());
+    /// assert!(!BodySize::Stream.is_eof());
+    /// ```
+    pub fn is_eof(&self) -> bool {
+        matches!(self, BodySize::None | BodySize::Sized(0))
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/body/sized_stream.rs.html b/src/actix_http/body/sized_stream.rs.html new file mode 100644 index 000000000..32d5a3581 --- /dev/null +++ b/src/actix_http/body/sized_stream.rs.html @@ -0,0 +1,343 @@ +sized_stream.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
+
use std::{
+    error::Error as StdError,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use bytes::Bytes;
+use futures_core::{ready, Stream};
+use pin_project_lite::pin_project;
+
+use super::{BodySize, MessageBody};
+
+pin_project! {
+    /// Known sized streaming response wrapper.
+    ///
+    /// This body implementation should be used if total size of stream is known. Data is sent as-is
+    /// without using chunked transfer encoding.
+    pub struct SizedStream<S> {
+        size: u64,
+        #[pin]
+        stream: S,
+    }
+}
+
+impl<S, E> SizedStream<S>
+where
+    S: Stream<Item = Result<Bytes, E>>,
+    E: Into<Box<dyn StdError>> + 'static,
+{
+    #[inline]
+    pub fn new(size: u64, stream: S) -> Self {
+        SizedStream { size, stream }
+    }
+}
+
+// TODO: from_infallible method
+
+impl<S, E> MessageBody for SizedStream<S>
+where
+    S: Stream<Item = Result<Bytes, E>>,
+    E: Into<Box<dyn StdError>> + 'static,
+{
+    type Error = E;
+
+    #[inline]
+    fn size(&self) -> BodySize {
+        BodySize::Sized(self.size)
+    }
+
+    /// Attempts to pull out the next value of the underlying [`Stream`].
+    ///
+    /// Empty values are skipped to prevent [`SizedStream`]'s transmission being
+    /// ended on a zero-length chunk, but rather proceed until the underlying
+    /// [`Stream`] ends.
+    fn poll_next(
+        mut self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+    ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+        loop {
+            let stream = self.as_mut().project().stream;
+
+            let chunk = match ready!(stream.poll_next(cx)) {
+                Some(Ok(ref bytes)) if bytes.is_empty() => continue,
+                val => val,
+            };
+
+            return Poll::Ready(chunk);
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::convert::Infallible;
+
+    use actix_rt::pin;
+    use actix_utils::future::poll_fn;
+    use futures_util::stream;
+    use static_assertions::{assert_impl_all, assert_not_impl_any};
+
+    use super::*;
+    use crate::body::to_bytes;
+
+    assert_impl_all!(SizedStream<stream::Empty<Result<Bytes, crate::Error>>>: MessageBody);
+    assert_impl_all!(SizedStream<stream::Empty<Result<Bytes, &'static str>>>: MessageBody);
+    assert_impl_all!(SizedStream<stream::Repeat<Result<Bytes, &'static str>>>: MessageBody);
+    assert_impl_all!(SizedStream<stream::Empty<Result<Bytes, Infallible>>>: MessageBody);
+    assert_impl_all!(SizedStream<stream::Repeat<Result<Bytes, Infallible>>>: MessageBody);
+
+    assert_not_impl_any!(SizedStream<stream::Empty<Bytes>>: MessageBody);
+    assert_not_impl_any!(SizedStream<stream::Repeat<Bytes>>: MessageBody);
+    // crate::Error is not Clone
+    assert_not_impl_any!(SizedStream<stream::Repeat<Result<Bytes, crate::Error>>>: MessageBody);
+
+    #[actix_rt::test]
+    async fn skips_empty_chunks() {
+        let body = SizedStream::new(
+            2,
+            stream::iter(
+                ["1", "", "2"]
+                    .iter()
+                    .map(|&v| Ok::<_, Infallible>(Bytes::from(v))),
+            ),
+        );
+
+        pin!(body);
+
+        assert_eq!(
+            poll_fn(|cx| body.as_mut().poll_next(cx))
+                .await
+                .unwrap()
+                .ok(),
+            Some(Bytes::from("1")),
+        );
+
+        assert_eq!(
+            poll_fn(|cx| body.as_mut().poll_next(cx))
+                .await
+                .unwrap()
+                .ok(),
+            Some(Bytes::from("2")),
+        );
+    }
+
+    #[actix_rt::test]
+    async fn read_to_bytes() {
+        let body = SizedStream::new(
+            2,
+            stream::iter(
+                ["1", "", "2"]
+                    .iter()
+                    .map(|&v| Ok::<_, Infallible>(Bytes::from(v))),
+            ),
+        );
+
+        assert_eq!(to_bytes(body).await.ok(), Some(Bytes::from("12")));
+    }
+
+    #[actix_rt::test]
+    async fn stream_string_error() {
+        // `&'static str` does not impl `Error`
+        // but it does impl `Into<Box<dyn Error>>`
+
+        let body = SizedStream::new(0, stream::once(async { Err("stringy error") }));
+        assert_eq!(to_bytes(body).await, Ok(Bytes::new()));
+
+        let body = SizedStream::new(1, stream::once(async { Err("stringy error") }));
+        assert!(matches!(to_bytes(body).await, Err("stringy error")));
+    }
+
+    #[actix_rt::test]
+    async fn stream_boxed_error() {
+        // `Box<dyn Error>` does not impl `Error`
+        // but it does impl `Into<Box<dyn Error>>`
+
+        let body = SizedStream::new(
+            0,
+            stream::once(async { Err(Box::<dyn StdError>::from("stringy error")) }),
+        );
+        assert_eq!(to_bytes(body).await.unwrap(), Bytes::new());
+
+        let body = SizedStream::new(
+            1,
+            stream::once(async { Err(Box::<dyn StdError>::from("stringy error")) }),
+        );
+        assert_eq!(
+            to_bytes(body).await.unwrap_err().to_string(),
+            "stringy error"
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/body/utils.rs.html b/src/actix_http/body/utils.rs.html new file mode 100644 index 000000000..7d506abd8 --- /dev/null +++ b/src/actix_http/body/utils.rs.html @@ -0,0 +1,397 @@ +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
+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
+
use std::task::Poll;
+
+use actix_rt::pin;
+use actix_utils::future::poll_fn;
+use bytes::{Bytes, BytesMut};
+use derive_more::{Display, Error};
+use futures_core::ready;
+
+use super::{BodySize, MessageBody};
+
+/// Collects all the bytes produced by `body`.
+///
+/// Any errors produced by the body stream are returned immediately.
+///
+/// Consider using [`to_bytes_limited`] instead to protect against memory exhaustion.
+///
+/// # Examples
+///
+/// ```
+/// use actix_http::body::{self, to_bytes};
+/// use bytes::Bytes;
+///
+/// # actix_rt::System::new().block_on(async {
+/// let body = body::None::new();
+/// let bytes = to_bytes(body).await.unwrap();
+/// assert!(bytes.is_empty());
+///
+/// let body = Bytes::from_static(b"123");
+/// let bytes = to_bytes(body).await.unwrap();
+/// assert_eq!(bytes, "123");
+/// # });
+/// ```
+pub async fn to_bytes<B: MessageBody>(body: B) -> Result<Bytes, B::Error> {
+    to_bytes_limited(body, usize::MAX)
+        .await
+        .expect("body should never yield more than usize::MAX bytes")
+}
+
+/// Error type returned from [`to_bytes_limited`] when body produced exceeds limit.
+#[derive(Debug, Display, Error)]
+#[display(fmt = "limit exceeded while collecting body bytes")]
+#[non_exhaustive]
+pub struct BodyLimitExceeded;
+
+/// Collects the bytes produced by `body`, up to `limit` bytes.
+///
+/// If a chunk read from `poll_next` causes the total number of bytes read to exceed `limit`, an
+/// `Err(BodyLimitExceeded)` is returned.
+///
+/// Any errors produced by the body stream are returned immediately as `Ok(Err(B::Error))`.
+///
+/// # Examples
+///
+/// ```
+/// use actix_http::body::{self, to_bytes_limited};
+/// use bytes::Bytes;
+///
+/// # actix_rt::System::new().block_on(async {
+/// let body = body::None::new();
+/// let bytes = to_bytes_limited(body, 10).await.unwrap().unwrap();
+/// assert!(bytes.is_empty());
+///
+/// let body = Bytes::from_static(b"123");
+/// let bytes = to_bytes_limited(body, 10).await.unwrap().unwrap();
+/// assert_eq!(bytes, "123");
+///
+/// let body = Bytes::from_static(b"123");
+/// assert!(to_bytes_limited(body, 2).await.is_err());
+/// # });
+/// ```
+pub async fn to_bytes_limited<B: MessageBody>(
+    body: B,
+    limit: usize,
+) -> Result<Result<Bytes, B::Error>, BodyLimitExceeded> {
+    /// Sensible default (32kB) for initial, bounded allocation when collecting body bytes.
+    const INITIAL_ALLOC_BYTES: usize = 32 * 1024;
+
+    let cap = match body.size() {
+        BodySize::None | BodySize::Sized(0) => return Ok(Ok(Bytes::new())),
+        BodySize::Sized(size) if size as usize > limit => return Err(BodyLimitExceeded),
+        BodySize::Sized(size) => (size as usize).min(INITIAL_ALLOC_BYTES),
+        BodySize::Stream => INITIAL_ALLOC_BYTES,
+    };
+
+    let mut exceeded_limit = false;
+    let mut buf = BytesMut::with_capacity(cap);
+
+    pin!(body);
+
+    match poll_fn(|cx| loop {
+        let body = body.as_mut();
+
+        match ready!(body.poll_next(cx)) {
+            Some(Ok(bytes)) => {
+                // if limit is exceeded...
+                if buf.len() + bytes.len() > limit {
+                    // ...set flag to true and break out of poll_fn
+                    exceeded_limit = true;
+                    return Poll::Ready(Ok(()));
+                }
+
+                buf.extend_from_slice(&bytes)
+            }
+            None => return Poll::Ready(Ok(())),
+            Some(Err(err)) => return Poll::Ready(Err(err)),
+        }
+    })
+    .await
+    {
+        // propagate error returned from body poll
+        Err(err) => Ok(Err(err)),
+
+        // limit was exceeded while reading body
+        Ok(()) if exceeded_limit => Err(BodyLimitExceeded),
+
+        // otherwise return body buffer
+        Ok(()) => Ok(Ok(buf.freeze())),
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::io;
+
+    use futures_util::{stream, StreamExt as _};
+
+    use super::*;
+    use crate::{
+        body::{BodyStream, SizedStream},
+        Error,
+    };
+
+    #[actix_rt::test]
+    async fn to_bytes_complete() {
+        let bytes = to_bytes(()).await.unwrap();
+        assert!(bytes.is_empty());
+
+        let body = Bytes::from_static(b"123");
+        let bytes = to_bytes(body).await.unwrap();
+        assert_eq!(bytes, b"123"[..]);
+    }
+
+    #[actix_rt::test]
+    async fn to_bytes_streams() {
+        let stream = stream::iter(vec![Bytes::from_static(b"123"), Bytes::from_static(b"abc")])
+            .map(Ok::<_, Error>);
+        let body = BodyStream::new(stream);
+        let bytes = to_bytes(body).await.unwrap();
+        assert_eq!(bytes, b"123abc"[..]);
+    }
+
+    #[actix_rt::test]
+    async fn to_bytes_limited_complete() {
+        let bytes = to_bytes_limited((), 0).await.unwrap().unwrap();
+        assert!(bytes.is_empty());
+
+        let bytes = to_bytes_limited((), 1).await.unwrap().unwrap();
+        assert!(bytes.is_empty());
+
+        assert!(to_bytes_limited(Bytes::from_static(b"12"), 0)
+            .await
+            .is_err());
+        assert!(to_bytes_limited(Bytes::from_static(b"12"), 1)
+            .await
+            .is_err());
+        assert!(to_bytes_limited(Bytes::from_static(b"12"), 2).await.is_ok());
+        assert!(to_bytes_limited(Bytes::from_static(b"12"), 3).await.is_ok());
+    }
+
+    #[actix_rt::test]
+    async fn to_bytes_limited_streams() {
+        // hinting a larger body fails
+        let body = SizedStream::new(8, stream::empty().map(Ok::<_, Error>));
+        assert!(to_bytes_limited(body, 3).await.is_err());
+
+        // hinting a smaller body is okay
+        let body = SizedStream::new(3, stream::empty().map(Ok::<_, Error>));
+        assert!(to_bytes_limited(body, 3).await.unwrap().unwrap().is_empty());
+
+        // hinting a smaller body then returning a larger one fails
+        let stream = stream::iter(vec![Bytes::from_static(b"1234")]).map(Ok::<_, Error>);
+        let body = SizedStream::new(3, stream);
+        assert!(to_bytes_limited(body, 3).await.is_err());
+
+        let stream = stream::iter(vec![Bytes::from_static(b"123"), Bytes::from_static(b"abc")])
+            .map(Ok::<_, Error>);
+        let body = BodyStream::new(stream);
+        assert!(to_bytes_limited(body, 3).await.is_err());
+    }
+
+    #[actix_rt::test]
+    async fn to_body_limit_error() {
+        let err_stream = stream::once(async { Err(io::Error::new(io::ErrorKind::Other, "")) });
+        let body = SizedStream::new(8, err_stream);
+        // not too big, but propagates error from body stream
+        assert!(to_bytes_limited(body, 10).await.unwrap().is_err());
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/builder.rs.html b/src/actix_http/builder.rs.html new file mode 100644 index 000000000..d2a55a810 --- /dev/null +++ b/src/actix_http/builder.rs.html @@ -0,0 +1,517 @@ +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
+
use std::{fmt, marker::PhantomData, net, rc::Rc, time::Duration};
+
+use actix_codec::Framed;
+use actix_service::{IntoServiceFactory, Service, ServiceFactory};
+
+use crate::{
+    body::{BoxBody, MessageBody},
+    h1::{self, ExpectHandler, H1Service, UpgradeHandler},
+    service::HttpService,
+    ConnectCallback, Extensions, KeepAlive, Request, Response, ServiceConfig,
+};
+
+/// An HTTP service builder.
+///
+/// This type can construct an instance of [`HttpService`] through a builder-like pattern.
+pub struct HttpServiceBuilder<T, S, X = ExpectHandler, U = UpgradeHandler> {
+    keep_alive: KeepAlive,
+    client_request_timeout: Duration,
+    client_disconnect_timeout: Duration,
+    secure: bool,
+    local_addr: Option<net::SocketAddr>,
+    expect: X,
+    upgrade: Option<U>,
+    on_connect_ext: Option<Rc<ConnectCallback<T>>>,
+    _phantom: PhantomData<S>,
+}
+
+impl<T, S> Default for HttpServiceBuilder<T, S, ExpectHandler, UpgradeHandler>
+where
+    S: ServiceFactory<Request, Config = ()>,
+    S::Error: Into<Response<BoxBody>> + 'static,
+    S::InitError: fmt::Debug,
+    <S::Service as Service<Request>>::Future: 'static,
+{
+    fn default() -> Self {
+        HttpServiceBuilder {
+            // ServiceConfig parts (make sure defaults match)
+            keep_alive: KeepAlive::default(),
+            client_request_timeout: Duration::from_secs(5),
+            client_disconnect_timeout: Duration::ZERO,
+            secure: false,
+            local_addr: None,
+
+            // dispatcher parts
+            expect: ExpectHandler,
+            upgrade: None,
+            on_connect_ext: None,
+            _phantom: PhantomData,
+        }
+    }
+}
+
+impl<T, S, X, U> HttpServiceBuilder<T, S, X, U>
+where
+    S: ServiceFactory<Request, Config = ()>,
+    S::Error: Into<Response<BoxBody>> + 'static,
+    S::InitError: fmt::Debug,
+    <S::Service as Service<Request>>::Future: 'static,
+    X: ServiceFactory<Request, Config = (), Response = Request>,
+    X::Error: Into<Response<BoxBody>>,
+    X::InitError: fmt::Debug,
+    U: ServiceFactory<(Request, Framed<T, h1::Codec>), Config = (), Response = ()>,
+    U::Error: fmt::Display,
+    U::InitError: fmt::Debug,
+{
+    /// Set connection keep-alive setting.
+    ///
+    /// Applies to HTTP/1.1 keep-alive and HTTP/2 ping-pong.
+    ///
+    /// By default keep-alive is 5 seconds.
+    pub fn keep_alive<W: Into<KeepAlive>>(mut self, val: W) -> Self {
+        self.keep_alive = val.into();
+        self
+    }
+
+    /// Set connection secure state
+    pub fn secure(mut self) -> Self {
+        self.secure = true;
+        self
+    }
+
+    /// Set the local address that this service is bound to.
+    pub fn local_addr(mut self, addr: net::SocketAddr) -> Self {
+        self.local_addr = Some(addr);
+        self
+    }
+
+    /// Set client request timeout (for first request).
+    ///
+    /// Defines a timeout for reading client request header. If the client does not transmit the
+    /// request head within this duration, the connection is terminated with a `408 Request Timeout`
+    /// response error.
+    ///
+    /// A duration of zero disables the timeout.
+    ///
+    /// By default, the client timeout is 5 seconds.
+    pub fn client_request_timeout(mut self, dur: Duration) -> Self {
+        self.client_request_timeout = dur;
+        self
+    }
+
+    #[doc(hidden)]
+    #[deprecated(since = "3.0.0", note = "Renamed to `client_request_timeout`.")]
+    pub fn client_timeout(self, dur: Duration) -> Self {
+        self.client_request_timeout(dur)
+    }
+
+    /// Set client connection disconnect timeout.
+    ///
+    /// Defines a timeout for disconnect connection. If a disconnect procedure does not complete
+    /// within this time, the request get dropped. This timeout affects secure connections.
+    ///
+    /// A duration of zero disables the timeout.
+    ///
+    /// By default, the disconnect timeout is disabled.
+    pub fn client_disconnect_timeout(mut self, dur: Duration) -> Self {
+        self.client_disconnect_timeout = dur;
+        self
+    }
+
+    #[doc(hidden)]
+    #[deprecated(since = "3.0.0", note = "Renamed to `client_disconnect_timeout`.")]
+    pub fn client_disconnect(self, dur: Duration) -> Self {
+        self.client_disconnect_timeout(dur)
+    }
+
+    /// Provide service for `EXPECT: 100-Continue` support.
+    ///
+    /// Service get called with request that contains `EXPECT` header.
+    /// Service must return request in case of success, in that case
+    /// request will be forwarded to main service.
+    pub fn expect<F, X1>(self, expect: F) -> HttpServiceBuilder<T, S, X1, U>
+    where
+        F: IntoServiceFactory<X1, Request>,
+        X1: ServiceFactory<Request, Config = (), Response = Request>,
+        X1::Error: Into<Response<BoxBody>>,
+        X1::InitError: fmt::Debug,
+    {
+        HttpServiceBuilder {
+            keep_alive: self.keep_alive,
+            client_request_timeout: self.client_request_timeout,
+            client_disconnect_timeout: self.client_disconnect_timeout,
+            secure: self.secure,
+            local_addr: self.local_addr,
+            expect: expect.into_factory(),
+            upgrade: self.upgrade,
+            on_connect_ext: self.on_connect_ext,
+            _phantom: PhantomData,
+        }
+    }
+
+    /// Provide service for custom `Connection: UPGRADE` support.
+    ///
+    /// If service is provided then normal requests handling get halted
+    /// and this service get called with original request and framed object.
+    pub fn upgrade<F, U1>(self, upgrade: F) -> HttpServiceBuilder<T, S, X, U1>
+    where
+        F: IntoServiceFactory<U1, (Request, Framed<T, h1::Codec>)>,
+        U1: ServiceFactory<(Request, Framed<T, h1::Codec>), Config = (), Response = ()>,
+        U1::Error: fmt::Display,
+        U1::InitError: fmt::Debug,
+    {
+        HttpServiceBuilder {
+            keep_alive: self.keep_alive,
+            client_request_timeout: self.client_request_timeout,
+            client_disconnect_timeout: self.client_disconnect_timeout,
+            secure: self.secure,
+            local_addr: self.local_addr,
+            expect: self.expect,
+            upgrade: Some(upgrade.into_factory()),
+            on_connect_ext: self.on_connect_ext,
+            _phantom: PhantomData,
+        }
+    }
+
+    /// Sets the callback to be run on connection establishment.
+    ///
+    /// Has mutable access to a data container that will be merged into request extensions.
+    /// This enables transport layer data (like client certificates) to be accessed in middleware
+    /// and handlers.
+    pub fn on_connect_ext<F>(mut self, f: F) -> Self
+    where
+        F: Fn(&T, &mut Extensions) + 'static,
+    {
+        self.on_connect_ext = Some(Rc::new(f));
+        self
+    }
+
+    /// Finish service configuration and create a service for the HTTP/1 protocol.
+    pub fn h1<F, B>(self, service: F) -> H1Service<T, S, B, X, U>
+    where
+        B: MessageBody,
+        F: IntoServiceFactory<S, Request>,
+        S::Error: Into<Response<BoxBody>>,
+        S::InitError: fmt::Debug,
+        S::Response: Into<Response<B>>,
+    {
+        let cfg = ServiceConfig::new(
+            self.keep_alive,
+            self.client_request_timeout,
+            self.client_disconnect_timeout,
+            self.secure,
+            self.local_addr,
+        );
+
+        H1Service::with_config(cfg, service.into_factory())
+            .expect(self.expect)
+            .upgrade(self.upgrade)
+            .on_connect_ext(self.on_connect_ext)
+    }
+
+    /// Finish service configuration and create a service for the HTTP/2 protocol.
+    #[cfg(feature = "http2")]
+    pub fn h2<F, B>(self, service: F) -> crate::h2::H2Service<T, S, B>
+    where
+        F: IntoServiceFactory<S, Request>,
+        S::Error: Into<Response<BoxBody>> + 'static,
+        S::InitError: fmt::Debug,
+        S::Response: Into<Response<B>> + 'static,
+
+        B: MessageBody + 'static,
+    {
+        let cfg = ServiceConfig::new(
+            self.keep_alive,
+            self.client_request_timeout,
+            self.client_disconnect_timeout,
+            self.secure,
+            self.local_addr,
+        );
+
+        crate::h2::H2Service::with_config(cfg, service.into_factory())
+            .on_connect_ext(self.on_connect_ext)
+    }
+
+    /// Finish service configuration and create `HttpService` instance.
+    pub fn finish<F, B>(self, service: F) -> HttpService<T, S, B, X, U>
+    where
+        F: IntoServiceFactory<S, Request>,
+        S::Error: Into<Response<BoxBody>> + 'static,
+        S::InitError: fmt::Debug,
+        S::Response: Into<Response<B>> + 'static,
+
+        B: MessageBody + 'static,
+    {
+        let cfg = ServiceConfig::new(
+            self.keep_alive,
+            self.client_request_timeout,
+            self.client_disconnect_timeout,
+            self.secure,
+            self.local_addr,
+        );
+
+        HttpService::with_config(cfg, service.into_factory())
+            .expect(self.expect)
+            .upgrade(self.upgrade)
+            .on_connect_ext(self.on_connect_ext)
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/config.rs.html b/src/actix_http/config.rs.html new file mode 100644 index 000000000..d667e80ae --- /dev/null +++ b/src/actix_http/config.rs.html @@ -0,0 +1,473 @@ +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
+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
+
use std::{
+    net,
+    rc::Rc,
+    time::{Duration, Instant},
+};
+
+use bytes::BytesMut;
+
+use crate::{date::DateService, KeepAlive};
+
+/// HTTP service configuration.
+#[derive(Debug, Clone)]
+pub struct ServiceConfig(Rc<Inner>);
+
+#[derive(Debug)]
+struct Inner {
+    keep_alive: KeepAlive,
+    client_request_timeout: Duration,
+    client_disconnect_timeout: Duration,
+    secure: bool,
+    local_addr: Option<std::net::SocketAddr>,
+    date_service: DateService,
+}
+
+impl Default for ServiceConfig {
+    fn default() -> Self {
+        Self::new(
+            KeepAlive::default(),
+            Duration::from_secs(5),
+            Duration::ZERO,
+            false,
+            None,
+        )
+    }
+}
+
+impl ServiceConfig {
+    /// Create instance of `ServiceConfig`.
+    pub fn new(
+        keep_alive: KeepAlive,
+        client_request_timeout: Duration,
+        client_disconnect_timeout: Duration,
+        secure: bool,
+        local_addr: Option<net::SocketAddr>,
+    ) -> ServiceConfig {
+        ServiceConfig(Rc::new(Inner {
+            keep_alive: keep_alive.normalize(),
+            client_request_timeout,
+            client_disconnect_timeout,
+            secure,
+            local_addr,
+            date_service: DateService::new(),
+        }))
+    }
+
+    /// Returns `true` if connection is secure (i.e., using TLS / HTTPS).
+    #[inline]
+    pub fn secure(&self) -> bool {
+        self.0.secure
+    }
+
+    /// Returns the local address that this server is bound to.
+    ///
+    /// Returns `None` for connections via UDS (Unix Domain Socket).
+    #[inline]
+    pub fn local_addr(&self) -> Option<net::SocketAddr> {
+        self.0.local_addr
+    }
+
+    /// Connection keep-alive setting.
+    #[inline]
+    pub fn keep_alive(&self) -> KeepAlive {
+        self.0.keep_alive
+    }
+
+    /// Creates a time object representing the deadline for this connection's keep-alive period, if
+    /// enabled.
+    ///
+    /// When [`KeepAlive::Os`] or [`KeepAlive::Disabled`] is set, this will return `None`.
+    pub fn keep_alive_deadline(&self) -> Option<Instant> {
+        match self.keep_alive() {
+            KeepAlive::Timeout(dur) => Some(self.now() + dur),
+            KeepAlive::Os => None,
+            KeepAlive::Disabled => None,
+        }
+    }
+
+    /// Creates a time object representing the deadline for the client to finish sending the head of
+    /// its first request.
+    ///
+    /// Returns `None` if this `ServiceConfig was` constructed with `client_request_timeout: 0`.
+    pub fn client_request_deadline(&self) -> Option<Instant> {
+        let timeout = self.0.client_request_timeout;
+        (timeout != Duration::ZERO).then(|| self.now() + timeout)
+    }
+
+    /// Creates a time object representing the deadline for the client to disconnect.
+    pub fn client_disconnect_deadline(&self) -> Option<Instant> {
+        let timeout = self.0.client_disconnect_timeout;
+        (timeout != Duration::ZERO).then(|| self.now() + timeout)
+    }
+
+    pub(crate) fn now(&self) -> Instant {
+        self.0.date_service.now()
+    }
+
+    /// Writes date header to `dst` buffer.
+    ///
+    /// Low-level method that utilizes the built-in efficient date service, requiring fewer syscalls
+    /// than normal. Note that a CRLF (`\r\n`) is included in what is written.
+    #[doc(hidden)]
+    pub fn write_date_header(&self, dst: &mut BytesMut, camel_case: bool) {
+        let mut buf: [u8; 37] = [0; 37];
+
+        buf[..6].copy_from_slice(if camel_case { b"Date: " } else { b"date: " });
+
+        self.0
+            .date_service
+            .with_date(|date| buf[6..35].copy_from_slice(&date.bytes));
+
+        buf[35..].copy_from_slice(b"\r\n");
+        dst.extend_from_slice(&buf);
+    }
+
+    #[allow(unused)] // used with `http2` feature flag
+    pub(crate) fn write_date_header_value(&self, dst: &mut BytesMut) {
+        self.0
+            .date_service
+            .with_date(|date| dst.extend_from_slice(&date.bytes));
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_rt::{
+        task::yield_now,
+        time::{sleep, sleep_until},
+    };
+    use memchr::memmem;
+
+    use super::*;
+    use crate::{date::DATE_VALUE_LENGTH, notify_on_drop};
+
+    #[actix_rt::test]
+    async fn test_date_service_update() {
+        let settings =
+            ServiceConfig::new(KeepAlive::Os, Duration::ZERO, Duration::ZERO, false, None);
+
+        yield_now().await;
+
+        let mut buf1 = BytesMut::with_capacity(DATE_VALUE_LENGTH + 10);
+        settings.write_date_header(&mut buf1, false);
+        let now1 = settings.now();
+
+        sleep_until((Instant::now() + Duration::from_secs(2)).into()).await;
+        yield_now().await;
+
+        let now2 = settings.now();
+        let mut buf2 = BytesMut::with_capacity(DATE_VALUE_LENGTH + 10);
+        settings.write_date_header(&mut buf2, false);
+
+        assert_ne!(now1, now2);
+
+        assert_ne!(buf1, buf2);
+
+        drop(settings);
+
+        // Ensure the task will drop eventually
+        let mut times = 0;
+        while !notify_on_drop::is_dropped() {
+            sleep(Duration::from_millis(100)).await;
+            times += 1;
+            assert!(times < 10, "Timeout waiting for task drop");
+        }
+    }
+
+    #[actix_rt::test]
+    async fn test_date_service_drop() {
+        let service = Rc::new(DateService::new());
+
+        // yield so date service have a chance to register the spawned timer update task.
+        yield_now().await;
+
+        let clone1 = service.clone();
+        let clone2 = service.clone();
+        let clone3 = service.clone();
+
+        drop(clone1);
+        assert!(!notify_on_drop::is_dropped());
+        drop(clone2);
+        assert!(!notify_on_drop::is_dropped());
+        drop(clone3);
+        assert!(!notify_on_drop::is_dropped());
+
+        drop(service);
+
+        // Ensure the task will drop eventually
+        let mut times = 0;
+        while !notify_on_drop::is_dropped() {
+            sleep(Duration::from_millis(100)).await;
+            times += 1;
+            assert!(times < 10, "Timeout waiting for task drop");
+        }
+    }
+
+    #[test]
+    fn test_date_len() {
+        assert_eq!(DATE_VALUE_LENGTH, "Sun, 06 Nov 1994 08:49:37 GMT".len());
+    }
+
+    #[actix_rt::test]
+    async fn test_date() {
+        let settings = ServiceConfig::default();
+
+        let mut buf1 = BytesMut::with_capacity(DATE_VALUE_LENGTH + 10);
+        settings.write_date_header(&mut buf1, false);
+
+        let mut buf2 = BytesMut::with_capacity(DATE_VALUE_LENGTH + 10);
+        settings.write_date_header(&mut buf2, false);
+
+        assert_eq!(buf1, buf2);
+    }
+
+    #[actix_rt::test]
+    async fn test_date_camel_case() {
+        let settings = ServiceConfig::default();
+
+        let mut buf = BytesMut::with_capacity(DATE_VALUE_LENGTH + 10);
+        settings.write_date_header(&mut buf, false);
+        assert!(memmem::find(&buf, b"date:").is_some());
+
+        let mut buf = BytesMut::with_capacity(DATE_VALUE_LENGTH + 10);
+        settings.write_date_header(&mut buf, true);
+        assert!(memmem::find(&buf, b"Date:").is_some());
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/date.rs.html b/src/actix_http/date.rs.html new file mode 100644 index 000000000..3bedd5dfd --- /dev/null +++ b/src/actix_http/date.rs.html @@ -0,0 +1,185 @@ +date.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
+
use std::{
+    cell::Cell,
+    fmt::{self, Write},
+    rc::Rc,
+    time::{Duration, Instant, SystemTime},
+};
+
+use actix_rt::{task::JoinHandle, time::interval};
+
+/// "Thu, 01 Jan 1970 00:00:00 GMT".len()
+pub(crate) const DATE_VALUE_LENGTH: usize = 29;
+
+#[derive(Clone, Copy)]
+pub(crate) struct Date {
+    pub(crate) bytes: [u8; DATE_VALUE_LENGTH],
+    pos: usize,
+}
+
+impl Date {
+    fn new() -> Date {
+        let mut date = Date {
+            bytes: [0; DATE_VALUE_LENGTH],
+            pos: 0,
+        };
+        date.update();
+        date
+    }
+
+    fn update(&mut self) {
+        self.pos = 0;
+        write!(self, "{}", httpdate::HttpDate::from(SystemTime::now())).unwrap();
+    }
+}
+
+impl fmt::Write for Date {
+    fn write_str(&mut self, s: &str) -> fmt::Result {
+        let len = s.len();
+        self.bytes[self.pos..self.pos + len].copy_from_slice(s.as_bytes());
+        self.pos += len;
+        Ok(())
+    }
+}
+
+/// Service for update Date and Instant periodically at 500 millis interval.
+pub(crate) struct DateService {
+    current: Rc<Cell<(Date, Instant)>>,
+    handle: JoinHandle<()>,
+}
+
+impl DateService {
+    pub(crate) fn new() -> Self {
+        // shared date and timer for DateService and update async task.
+        let current = Rc::new(Cell::new((Date::new(), Instant::now())));
+        let current_clone = Rc::clone(&current);
+        // spawn an async task sleep for 500 millis and update current date/timer in a loop.
+        // handle is used to stop the task on DateService drop.
+        let handle = actix_rt::spawn(async move {
+            #[cfg(test)]
+            let _notify = crate::notify_on_drop::NotifyOnDrop::new();
+
+            let mut interval = interval(Duration::from_millis(500));
+            loop {
+                let now = interval.tick().await;
+                let date = Date::new();
+                current_clone.set((date, now.into_std()));
+            }
+        });
+
+        DateService { current, handle }
+    }
+
+    pub(crate) fn now(&self) -> Instant {
+        self.current.get().1
+    }
+
+    pub(crate) fn with_date<F: FnMut(&Date)>(&self, mut f: F) {
+        f(&self.current.get().0);
+    }
+}
+
+impl fmt::Debug for DateService {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("DateService").finish_non_exhaustive()
+    }
+}
+
+impl Drop for DateService {
+    fn drop(&mut self) {
+        // stop the timer update async task on drop.
+        self.handle.abort();
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/encoding/decoder.rs.html b/src/actix_http/encoding/decoder.rs.html new file mode 100644 index 000000000..9e4b03b8c --- /dev/null +++ b/src/actix_http/encoding/decoder.rs.html @@ -0,0 +1,605 @@ +decoder.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
+
//! Stream decoders.
+
+use std::{
+    future::Future,
+    io::{self, Write as _},
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use actix_rt::task::{spawn_blocking, JoinHandle};
+use bytes::Bytes;
+#[cfg(feature = "compress-gzip")]
+use flate2::write::{GzDecoder, ZlibDecoder};
+use futures_core::{ready, Stream};
+#[cfg(feature = "compress-zstd")]
+use zstd::stream::write::Decoder as ZstdDecoder;
+
+use crate::{
+    encoding::Writer,
+    error::PayloadError,
+    header::{ContentEncoding, HeaderMap, CONTENT_ENCODING},
+};
+
+const MAX_CHUNK_SIZE_DECODE_IN_PLACE: usize = 2049;
+
+pin_project_lite::pin_project! {
+    pub struct Decoder<S> {
+        decoder: Option<ContentDecoder>,
+        #[pin]
+        stream: S,
+        eof: bool,
+        fut: Option<JoinHandle<Result<(Option<Bytes>, ContentDecoder), io::Error>>>,
+    }
+}
+
+impl<S> Decoder<S>
+where
+    S: Stream<Item = Result<Bytes, PayloadError>>,
+{
+    /// Construct a decoder.
+    #[inline]
+    pub fn new(stream: S, encoding: ContentEncoding) -> Decoder<S> {
+        let decoder = match encoding {
+            #[cfg(feature = "compress-brotli")]
+            ContentEncoding::Brotli => Some(ContentDecoder::Brotli(Box::new(
+                brotli::DecompressorWriter::new(Writer::new(), 8_096),
+            ))),
+
+            #[cfg(feature = "compress-gzip")]
+            ContentEncoding::Deflate => Some(ContentDecoder::Deflate(Box::new(ZlibDecoder::new(
+                Writer::new(),
+            )))),
+
+            #[cfg(feature = "compress-gzip")]
+            ContentEncoding::Gzip => Some(ContentDecoder::Gzip(Box::new(GzDecoder::new(
+                Writer::new(),
+            )))),
+
+            #[cfg(feature = "compress-zstd")]
+            ContentEncoding::Zstd => Some(ContentDecoder::Zstd(Box::new(
+                ZstdDecoder::new(Writer::new()).expect(
+                    "Failed to create zstd decoder. This is a bug. \
+                         Please report it to the actix-web repository.",
+                ),
+            ))),
+            _ => None,
+        };
+
+        Decoder {
+            decoder,
+            stream,
+            fut: None,
+            eof: false,
+        }
+    }
+
+    /// Construct decoder based on headers.
+    #[inline]
+    pub fn from_headers(stream: S, headers: &HeaderMap) -> Decoder<S> {
+        // check content-encoding
+        let encoding = headers
+            .get(&CONTENT_ENCODING)
+            .and_then(|val| val.to_str().ok())
+            .and_then(|x| x.parse().ok())
+            .unwrap_or(ContentEncoding::Identity);
+
+        Self::new(stream, encoding)
+    }
+}
+
+impl<S> Stream for Decoder<S>
+where
+    S: Stream<Item = Result<Bytes, PayloadError>>,
+{
+    type Item = Result<Bytes, PayloadError>;
+
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        let mut this = self.project();
+
+        loop {
+            if let Some(ref mut fut) = this.fut {
+                let (chunk, decoder) = ready!(Pin::new(fut).poll(cx)).map_err(|_| {
+                    PayloadError::Io(io::Error::new(
+                        io::ErrorKind::Other,
+                        "Blocking task was cancelled unexpectedly",
+                    ))
+                })??;
+
+                *this.decoder = Some(decoder);
+                this.fut.take();
+
+                if let Some(chunk) = chunk {
+                    return Poll::Ready(Some(Ok(chunk)));
+                }
+            }
+
+            if *this.eof {
+                return Poll::Ready(None);
+            }
+
+            match ready!(this.stream.as_mut().poll_next(cx)) {
+                Some(Err(err)) => return Poll::Ready(Some(Err(err))),
+
+                Some(Ok(chunk)) => {
+                    if let Some(mut decoder) = this.decoder.take() {
+                        if chunk.len() < MAX_CHUNK_SIZE_DECODE_IN_PLACE {
+                            let chunk = decoder.feed_data(chunk)?;
+                            *this.decoder = Some(decoder);
+
+                            if let Some(chunk) = chunk {
+                                return Poll::Ready(Some(Ok(chunk)));
+                            }
+                        } else {
+                            *this.fut = Some(spawn_blocking(move || {
+                                let chunk = decoder.feed_data(chunk)?;
+                                Ok((chunk, decoder))
+                            }));
+                        }
+
+                        continue;
+                    } else {
+                        return Poll::Ready(Some(Ok(chunk)));
+                    }
+                }
+
+                None => {
+                    *this.eof = true;
+
+                    return if let Some(mut decoder) = this.decoder.take() {
+                        match decoder.feed_eof() {
+                            Ok(Some(res)) => Poll::Ready(Some(Ok(res))),
+                            Ok(None) => Poll::Ready(None),
+                            Err(err) => Poll::Ready(Some(Err(err.into()))),
+                        }
+                    } else {
+                        Poll::Ready(None)
+                    };
+                }
+            }
+        }
+    }
+}
+
+enum ContentDecoder {
+    #[cfg(feature = "compress-gzip")]
+    Deflate(Box<ZlibDecoder<Writer>>),
+
+    #[cfg(feature = "compress-gzip")]
+    Gzip(Box<GzDecoder<Writer>>),
+
+    #[cfg(feature = "compress-brotli")]
+    Brotli(Box<brotli::DecompressorWriter<Writer>>),
+
+    // We need explicit 'static lifetime here because ZstdDecoder need lifetime
+    // argument, and we use `spawn_blocking` in `Decoder::poll_next` that require `FnOnce() -> R + Send + 'static`
+    #[cfg(feature = "compress-zstd")]
+    Zstd(Box<ZstdDecoder<'static, Writer>>),
+}
+
+impl ContentDecoder {
+    fn feed_eof(&mut self) -> io::Result<Option<Bytes>> {
+        match self {
+            #[cfg(feature = "compress-brotli")]
+            ContentDecoder::Brotli(ref mut decoder) => match decoder.flush() {
+                Ok(()) => {
+                    let b = decoder.get_mut().take();
+
+                    if !b.is_empty() {
+                        Ok(Some(b))
+                    } else {
+                        Ok(None)
+                    }
+                }
+                Err(err) => Err(err),
+            },
+
+            #[cfg(feature = "compress-gzip")]
+            ContentDecoder::Gzip(ref mut decoder) => match decoder.try_finish() {
+                Ok(_) => {
+                    let b = decoder.get_mut().take();
+
+                    if !b.is_empty() {
+                        Ok(Some(b))
+                    } else {
+                        Ok(None)
+                    }
+                }
+                Err(err) => Err(err),
+            },
+
+            #[cfg(feature = "compress-gzip")]
+            ContentDecoder::Deflate(ref mut decoder) => match decoder.try_finish() {
+                Ok(_) => {
+                    let b = decoder.get_mut().take();
+                    if !b.is_empty() {
+                        Ok(Some(b))
+                    } else {
+                        Ok(None)
+                    }
+                }
+                Err(err) => Err(err),
+            },
+
+            #[cfg(feature = "compress-zstd")]
+            ContentDecoder::Zstd(ref mut decoder) => match decoder.flush() {
+                Ok(_) => {
+                    let b = decoder.get_mut().take();
+                    if !b.is_empty() {
+                        Ok(Some(b))
+                    } else {
+                        Ok(None)
+                    }
+                }
+                Err(err) => Err(err),
+            },
+        }
+    }
+
+    fn feed_data(&mut self, data: Bytes) -> io::Result<Option<Bytes>> {
+        match self {
+            #[cfg(feature = "compress-brotli")]
+            ContentDecoder::Brotli(ref mut decoder) => match decoder.write_all(&data) {
+                Ok(_) => {
+                    decoder.flush()?;
+                    let b = decoder.get_mut().take();
+
+                    if !b.is_empty() {
+                        Ok(Some(b))
+                    } else {
+                        Ok(None)
+                    }
+                }
+                Err(err) => Err(err),
+            },
+
+            #[cfg(feature = "compress-gzip")]
+            ContentDecoder::Gzip(ref mut decoder) => match decoder.write_all(&data) {
+                Ok(_) => {
+                    decoder.flush()?;
+                    let b = decoder.get_mut().take();
+
+                    if !b.is_empty() {
+                        Ok(Some(b))
+                    } else {
+                        Ok(None)
+                    }
+                }
+                Err(err) => Err(err),
+            },
+
+            #[cfg(feature = "compress-gzip")]
+            ContentDecoder::Deflate(ref mut decoder) => match decoder.write_all(&data) {
+                Ok(_) => {
+                    decoder.flush()?;
+
+                    let b = decoder.get_mut().take();
+                    if !b.is_empty() {
+                        Ok(Some(b))
+                    } else {
+                        Ok(None)
+                    }
+                }
+                Err(err) => Err(err),
+            },
+
+            #[cfg(feature = "compress-zstd")]
+            ContentDecoder::Zstd(ref mut decoder) => match decoder.write_all(&data) {
+                Ok(_) => {
+                    decoder.flush()?;
+
+                    let b = decoder.get_mut().take();
+                    if !b.is_empty() {
+                        Ok(Some(b))
+                    } else {
+                        Ok(None)
+                    }
+                }
+                Err(err) => Err(err),
+            },
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/encoding/encoder.rs.html b/src/actix_http/encoding/encoder.rs.html new file mode 100644 index 000000000..35025be5d --- /dev/null +++ b/src/actix_http/encoding/encoder.rs.html @@ -0,0 +1,879 @@ +encoder.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
+
//! Stream encoders.
+
+use std::{
+    error::Error as StdError,
+    future::Future,
+    io::{self, Write as _},
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use actix_rt::task::{spawn_blocking, JoinHandle};
+use bytes::Bytes;
+use derive_more::Display;
+#[cfg(feature = "compress-gzip")]
+use flate2::write::{GzEncoder, ZlibEncoder};
+use futures_core::ready;
+use pin_project_lite::pin_project;
+use tracing::trace;
+#[cfg(feature = "compress-zstd")]
+use zstd::stream::write::Encoder as ZstdEncoder;
+
+use super::Writer;
+use crate::{
+    body::{self, BodySize, MessageBody},
+    header::{self, ContentEncoding, HeaderValue, CONTENT_ENCODING},
+    ResponseHead, StatusCode,
+};
+
+const MAX_CHUNK_SIZE_ENCODE_IN_PLACE: usize = 1024;
+
+pin_project! {
+    pub struct Encoder<B> {
+        #[pin]
+        body: EncoderBody<B>,
+        encoder: Option<ContentEncoder>,
+        fut: Option<JoinHandle<Result<ContentEncoder, io::Error>>>,
+        eof: bool,
+    }
+}
+
+impl<B: MessageBody> Encoder<B> {
+    fn none() -> Self {
+        Encoder {
+            body: EncoderBody::None {
+                body: body::None::new(),
+            },
+            encoder: None,
+            fut: None,
+            eof: true,
+        }
+    }
+
+    fn empty() -> Self {
+        Encoder {
+            body: EncoderBody::Full { body: Bytes::new() },
+            encoder: None,
+            fut: None,
+            eof: true,
+        }
+    }
+
+    pub fn response(encoding: ContentEncoding, head: &mut ResponseHead, body: B) -> Self {
+        // no need to compress empty bodies
+        match body.size() {
+            BodySize::None => return Self::none(),
+            BodySize::Sized(0) => return Self::empty(),
+            _ => {}
+        }
+
+        let should_encode = !(head.headers().contains_key(&CONTENT_ENCODING)
+            || head.status == StatusCode::SWITCHING_PROTOCOLS
+            || head.status == StatusCode::NO_CONTENT
+            || encoding == ContentEncoding::Identity);
+
+        let body = match body.try_into_bytes() {
+            Ok(body) => EncoderBody::Full { body },
+            Err(body) => EncoderBody::Stream { body },
+        };
+
+        if should_encode {
+            // wrap body only if encoder is feature-enabled
+            if let Some(enc) = ContentEncoder::select(encoding) {
+                update_head(encoding, head);
+
+                return Encoder {
+                    body,
+                    encoder: Some(enc),
+                    fut: None,
+                    eof: false,
+                };
+            }
+        }
+
+        Encoder {
+            body,
+            encoder: None,
+            fut: None,
+            eof: false,
+        }
+    }
+}
+
+pin_project! {
+    #[project = EncoderBodyProj]
+    enum EncoderBody<B> {
+        None { body: body::None },
+        Full { body: Bytes },
+        Stream { #[pin] body: B },
+    }
+}
+
+impl<B> MessageBody for EncoderBody<B>
+where
+    B: MessageBody,
+{
+    type Error = EncoderError;
+
+    #[inline]
+    fn size(&self) -> BodySize {
+        match self {
+            EncoderBody::None { body } => body.size(),
+            EncoderBody::Full { body } => body.size(),
+            EncoderBody::Stream { body } => body.size(),
+        }
+    }
+
+    fn poll_next(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+    ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+        match self.project() {
+            EncoderBodyProj::None { body } => {
+                Pin::new(body).poll_next(cx).map_err(|err| match err {})
+            }
+            EncoderBodyProj::Full { body } => {
+                Pin::new(body).poll_next(cx).map_err(|err| match err {})
+            }
+            EncoderBodyProj::Stream { body } => body
+                .poll_next(cx)
+                .map_err(|err| EncoderError::Body(err.into())),
+        }
+    }
+
+    #[inline]
+    fn try_into_bytes(self) -> Result<Bytes, Self>
+    where
+        Self: Sized,
+    {
+        match self {
+            EncoderBody::None { body } => Ok(body.try_into_bytes().unwrap()),
+            EncoderBody::Full { body } => Ok(body.try_into_bytes().unwrap()),
+            _ => Err(self),
+        }
+    }
+}
+
+impl<B> MessageBody for Encoder<B>
+where
+    B: MessageBody,
+{
+    type Error = EncoderError;
+
+    #[inline]
+    fn size(&self) -> BodySize {
+        if self.encoder.is_some() {
+            BodySize::Stream
+        } else {
+            self.body.size()
+        }
+    }
+
+    fn poll_next(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+    ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+        let mut this = self.project();
+
+        loop {
+            if *this.eof {
+                return Poll::Ready(None);
+            }
+
+            if let Some(ref mut fut) = this.fut {
+                let mut encoder = ready!(Pin::new(fut).poll(cx))
+                    .map_err(|_| {
+                        EncoderError::Io(io::Error::new(
+                            io::ErrorKind::Other,
+                            "Blocking task was cancelled unexpectedly",
+                        ))
+                    })?
+                    .map_err(EncoderError::Io)?;
+
+                let chunk = encoder.take();
+                *this.encoder = Some(encoder);
+                this.fut.take();
+
+                if !chunk.is_empty() {
+                    return Poll::Ready(Some(Ok(chunk)));
+                }
+            }
+
+            let result = ready!(this.body.as_mut().poll_next(cx));
+
+            match result {
+                Some(Err(err)) => return Poll::Ready(Some(Err(err))),
+
+                Some(Ok(chunk)) => {
+                    if let Some(mut encoder) = this.encoder.take() {
+                        if chunk.len() < MAX_CHUNK_SIZE_ENCODE_IN_PLACE {
+                            encoder.write(&chunk).map_err(EncoderError::Io)?;
+                            let chunk = encoder.take();
+                            *this.encoder = Some(encoder);
+
+                            if !chunk.is_empty() {
+                                return Poll::Ready(Some(Ok(chunk)));
+                            }
+                        } else {
+                            *this.fut = Some(spawn_blocking(move || {
+                                encoder.write(&chunk)?;
+                                Ok(encoder)
+                            }));
+                        }
+                    } else {
+                        return Poll::Ready(Some(Ok(chunk)));
+                    }
+                }
+
+                None => {
+                    if let Some(encoder) = this.encoder.take() {
+                        let chunk = encoder.finish().map_err(EncoderError::Io)?;
+
+                        if chunk.is_empty() {
+                            return Poll::Ready(None);
+                        } else {
+                            *this.eof = true;
+                            return Poll::Ready(Some(Ok(chunk)));
+                        }
+                    } else {
+                        return Poll::Ready(None);
+                    }
+                }
+            }
+        }
+    }
+
+    #[inline]
+    fn try_into_bytes(mut self) -> Result<Bytes, Self>
+    where
+        Self: Sized,
+    {
+        if self.encoder.is_some() {
+            Err(self)
+        } else {
+            match self.body.try_into_bytes() {
+                Ok(body) => Ok(body),
+                Err(body) => {
+                    self.body = body;
+                    Err(self)
+                }
+            }
+        }
+    }
+}
+
+fn update_head(encoding: ContentEncoding, head: &mut ResponseHead) {
+    head.headers_mut()
+        .insert(header::CONTENT_ENCODING, encoding.to_header_value());
+    head.headers_mut()
+        .append(header::VARY, HeaderValue::from_static("accept-encoding"));
+
+    head.no_chunking(false);
+}
+
+enum ContentEncoder {
+    #[cfg(feature = "compress-gzip")]
+    Deflate(ZlibEncoder<Writer>),
+
+    #[cfg(feature = "compress-gzip")]
+    Gzip(GzEncoder<Writer>),
+
+    #[cfg(feature = "compress-brotli")]
+    Brotli(Box<brotli::CompressorWriter<Writer>>),
+
+    // Wwe need explicit 'static lifetime here because ZstdEncoder needs a lifetime argument and we
+    // use `spawn_blocking` in `Encoder::poll_next` that requires `FnOnce() -> R + Send + 'static`.
+    #[cfg(feature = "compress-zstd")]
+    Zstd(ZstdEncoder<'static, Writer>),
+}
+
+impl ContentEncoder {
+    fn select(encoding: ContentEncoding) -> Option<Self> {
+        match encoding {
+            #[cfg(feature = "compress-gzip")]
+            ContentEncoding::Deflate => Some(ContentEncoder::Deflate(ZlibEncoder::new(
+                Writer::new(),
+                flate2::Compression::fast(),
+            ))),
+
+            #[cfg(feature = "compress-gzip")]
+            ContentEncoding::Gzip => Some(ContentEncoder::Gzip(GzEncoder::new(
+                Writer::new(),
+                flate2::Compression::fast(),
+            ))),
+
+            #[cfg(feature = "compress-brotli")]
+            ContentEncoding::Brotli => Some(ContentEncoder::Brotli(new_brotli_compressor())),
+
+            #[cfg(feature = "compress-zstd")]
+            ContentEncoding::Zstd => {
+                let encoder = ZstdEncoder::new(Writer::new(), 3).ok()?;
+                Some(ContentEncoder::Zstd(encoder))
+            }
+
+            _ => None,
+        }
+    }
+
+    #[inline]
+    pub(crate) fn take(&mut self) -> Bytes {
+        match *self {
+            #[cfg(feature = "compress-brotli")]
+            ContentEncoder::Brotli(ref mut encoder) => encoder.get_mut().take(),
+
+            #[cfg(feature = "compress-gzip")]
+            ContentEncoder::Deflate(ref mut encoder) => encoder.get_mut().take(),
+
+            #[cfg(feature = "compress-gzip")]
+            ContentEncoder::Gzip(ref mut encoder) => encoder.get_mut().take(),
+
+            #[cfg(feature = "compress-zstd")]
+            ContentEncoder::Zstd(ref mut encoder) => encoder.get_mut().take(),
+        }
+    }
+
+    fn finish(self) -> Result<Bytes, io::Error> {
+        match self {
+            #[cfg(feature = "compress-brotli")]
+            ContentEncoder::Brotli(mut encoder) => match encoder.flush() {
+                Ok(()) => Ok(encoder.into_inner().buf.freeze()),
+                Err(err) => Err(err),
+            },
+
+            #[cfg(feature = "compress-gzip")]
+            ContentEncoder::Gzip(encoder) => match encoder.finish() {
+                Ok(writer) => Ok(writer.buf.freeze()),
+                Err(err) => Err(err),
+            },
+
+            #[cfg(feature = "compress-gzip")]
+            ContentEncoder::Deflate(encoder) => match encoder.finish() {
+                Ok(writer) => Ok(writer.buf.freeze()),
+                Err(err) => Err(err),
+            },
+
+            #[cfg(feature = "compress-zstd")]
+            ContentEncoder::Zstd(encoder) => match encoder.finish() {
+                Ok(writer) => Ok(writer.buf.freeze()),
+                Err(err) => Err(err),
+            },
+        }
+    }
+
+    fn write(&mut self, data: &[u8]) -> Result<(), io::Error> {
+        match *self {
+            #[cfg(feature = "compress-brotli")]
+            ContentEncoder::Brotli(ref mut encoder) => match encoder.write_all(data) {
+                Ok(_) => Ok(()),
+                Err(err) => {
+                    trace!("Error decoding br encoding: {}", err);
+                    Err(err)
+                }
+            },
+
+            #[cfg(feature = "compress-gzip")]
+            ContentEncoder::Gzip(ref mut encoder) => match encoder.write_all(data) {
+                Ok(_) => Ok(()),
+                Err(err) => {
+                    trace!("Error decoding gzip encoding: {}", err);
+                    Err(err)
+                }
+            },
+
+            #[cfg(feature = "compress-gzip")]
+            ContentEncoder::Deflate(ref mut encoder) => match encoder.write_all(data) {
+                Ok(_) => Ok(()),
+                Err(err) => {
+                    trace!("Error decoding deflate encoding: {}", err);
+                    Err(err)
+                }
+            },
+
+            #[cfg(feature = "compress-zstd")]
+            ContentEncoder::Zstd(ref mut encoder) => match encoder.write_all(data) {
+                Ok(_) => Ok(()),
+                Err(err) => {
+                    trace!("Error decoding ztsd encoding: {}", err);
+                    Err(err)
+                }
+            },
+        }
+    }
+}
+
+#[cfg(feature = "compress-brotli")]
+fn new_brotli_compressor() -> Box<brotli::CompressorWriter<Writer>> {
+    Box::new(brotli::CompressorWriter::new(
+        Writer::new(),
+        32 * 1024, // 32 KiB buffer
+        3,         // BROTLI_PARAM_QUALITY
+        22,        // BROTLI_PARAM_LGWIN
+    ))
+}
+
+#[derive(Debug, Display)]
+#[non_exhaustive]
+pub enum EncoderError {
+    /// Wrapped body stream error.
+    #[display(fmt = "body")]
+    Body(Box<dyn StdError>),
+
+    /// Generic I/O error.
+    #[display(fmt = "io")]
+    Io(io::Error),
+}
+
+impl StdError for EncoderError {
+    fn source(&self) -> Option<&(dyn StdError + 'static)> {
+        match self {
+            EncoderError::Body(err) => Some(&**err),
+            EncoderError::Io(err) => Some(err),
+        }
+    }
+}
+
+impl From<EncoderError> for crate::Error {
+    fn from(err: EncoderError) -> Self {
+        crate::Error::new_encoder().with_cause(err)
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/encoding/mod.rs.html b/src/actix_http/encoding/mod.rs.html new file mode 100644 index 000000000..000d6469b --- /dev/null +++ b/src/actix_http/encoding/mod.rs.html @@ -0,0 +1,81 @@ +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
+34
+35
+36
+37
+38
+39
+40
+
//! Content-Encoding support.
+
+use std::io;
+
+use bytes::{Bytes, BytesMut};
+
+mod decoder;
+mod encoder;
+
+pub use self::{decoder::Decoder, encoder::Encoder};
+
+/// Special-purpose writer for streaming (de-)compression.
+///
+/// Pre-allocates 8KiB of capacity.
+struct Writer {
+    buf: BytesMut,
+}
+
+impl Writer {
+    fn new() -> Writer {
+        Writer {
+            buf: BytesMut::with_capacity(8192),
+        }
+    }
+
+    fn take(&mut self) -> Bytes {
+        self.buf.split().freeze()
+    }
+}
+
+impl io::Write for Writer {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.buf.extend_from_slice(buf);
+        Ok(buf.len())
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/error.rs.html b/src/actix_http/error.rs.html new file mode 100644 index 000000000..e7583f8b7 --- /dev/null +++ b/src/actix_http/error.rs.html @@ -0,0 +1,977 @@ +error.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+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
+
//! Error and Result module
+
+use std::{error::Error as StdError, fmt, io, str::Utf8Error, string::FromUtf8Error};
+
+use derive_more::{Display, Error, From};
+pub use http::Error as HttpError;
+use http::{uri::InvalidUri, StatusCode};
+
+use crate::{body::BoxBody, Response};
+
+pub struct Error {
+    inner: Box<ErrorInner>,
+}
+
+pub(crate) struct ErrorInner {
+    #[allow(dead_code)]
+    kind: Kind,
+    cause: Option<Box<dyn StdError>>,
+}
+
+impl Error {
+    fn new(kind: Kind) -> Self {
+        Self {
+            inner: Box::new(ErrorInner { kind, cause: None }),
+        }
+    }
+
+    pub(crate) fn with_cause(mut self, cause: impl Into<Box<dyn StdError>>) -> Self {
+        self.inner.cause = Some(cause.into());
+        self
+    }
+
+    pub(crate) fn new_http() -> Self {
+        Self::new(Kind::Http)
+    }
+
+    pub(crate) fn new_parse() -> Self {
+        Self::new(Kind::Parse)
+    }
+
+    pub(crate) fn new_payload() -> Self {
+        Self::new(Kind::Payload)
+    }
+
+    pub(crate) fn new_body() -> Self {
+        Self::new(Kind::Body)
+    }
+
+    pub(crate) fn new_send_response() -> Self {
+        Self::new(Kind::SendResponse)
+    }
+
+    #[allow(unused)] // available for future use
+    pub(crate) fn new_io() -> Self {
+        Self::new(Kind::Io)
+    }
+
+    #[allow(unused)] // used in encoder behind feature flag so ignore unused warning
+    pub(crate) fn new_encoder() -> Self {
+        Self::new(Kind::Encoder)
+    }
+
+    #[allow(unused)] // used with `ws` feature flag
+    pub(crate) fn new_ws() -> Self {
+        Self::new(Kind::Ws)
+    }
+}
+
+impl From<Error> for Response<BoxBody> {
+    fn from(err: Error) -> Self {
+        // TODO: more appropriate error status codes, usage assessment needed
+        let status_code = match err.inner.kind {
+            Kind::Parse => StatusCode::BAD_REQUEST,
+            _ => StatusCode::INTERNAL_SERVER_ERROR,
+        };
+
+        Response::new(status_code).set_body(BoxBody::new(err.to_string()))
+    }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Display)]
+pub(crate) enum Kind {
+    #[display(fmt = "error processing HTTP")]
+    Http,
+
+    #[display(fmt = "error parsing HTTP message")]
+    Parse,
+
+    #[display(fmt = "request payload read error")]
+    Payload,
+
+    #[display(fmt = "response body write error")]
+    Body,
+
+    #[display(fmt = "send response error")]
+    SendResponse,
+
+    #[display(fmt = "error in WebSocket process")]
+    Ws,
+
+    #[display(fmt = "connection error")]
+    Io,
+
+    #[display(fmt = "encoder error")]
+    Encoder,
+}
+
+impl fmt::Debug for Error {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("actix_http::Error")
+            .field("kind", &self.inner.kind)
+            .field("cause", &self.inner.cause)
+            .finish()
+    }
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self.inner.cause.as_ref() {
+            Some(err) => write!(f, "{}: {}", &self.inner.kind, err),
+            None => write!(f, "{}", &self.inner.kind),
+        }
+    }
+}
+
+impl StdError for Error {
+    fn source(&self) -> Option<&(dyn StdError + 'static)> {
+        self.inner.cause.as_ref().map(Box::as_ref)
+    }
+}
+
+impl From<std::convert::Infallible> for Error {
+    fn from(err: std::convert::Infallible) -> Self {
+        match err {}
+    }
+}
+
+impl From<HttpError> for Error {
+    fn from(err: HttpError) -> Self {
+        Self::new_http().with_cause(err)
+    }
+}
+
+#[cfg(feature = "ws")]
+impl From<crate::ws::HandshakeError> for Error {
+    fn from(err: crate::ws::HandshakeError) -> Self {
+        Self::new_ws().with_cause(err)
+    }
+}
+
+#[cfg(feature = "ws")]
+impl From<crate::ws::ProtocolError> for Error {
+    fn from(err: crate::ws::ProtocolError) -> Self {
+        Self::new_ws().with_cause(err)
+    }
+}
+
+/// A set of errors that can occur during parsing HTTP streams.
+#[derive(Debug, Display, Error)]
+#[non_exhaustive]
+pub enum ParseError {
+    /// An invalid `Method`, such as `GE.T`.
+    #[display(fmt = "invalid method specified")]
+    Method,
+
+    /// An invalid `Uri`, such as `exam ple.domain`.
+    #[display(fmt = "URI error: {}", _0)]
+    Uri(InvalidUri),
+
+    /// An invalid `HttpVersion`, such as `HTP/1.1`
+    #[display(fmt = "invalid HTTP version specified")]
+    Version,
+
+    /// An invalid `Header`.
+    #[display(fmt = "invalid Header provided")]
+    Header,
+
+    /// A message head is too large to be reasonable.
+    #[display(fmt = "message head is too large")]
+    TooLarge,
+
+    /// A message reached EOF, but is not complete.
+    #[display(fmt = "message is incomplete")]
+    Incomplete,
+
+    /// An invalid `Status`, such as `1337 ELITE`.
+    #[display(fmt = "invalid status provided")]
+    Status,
+
+    /// A timeout occurred waiting for an IO event.
+    #[allow(dead_code)]
+    #[display(fmt = "timeout")]
+    Timeout,
+
+    /// An I/O error that occurred while trying to read or write to a network stream.
+    #[display(fmt = "I/O error: {}", _0)]
+    Io(io::Error),
+
+    /// Parsing a field as string failed.
+    #[display(fmt = "UTF-8 error: {}", _0)]
+    Utf8(Utf8Error),
+}
+
+impl From<io::Error> for ParseError {
+    fn from(err: io::Error) -> ParseError {
+        ParseError::Io(err)
+    }
+}
+
+impl From<InvalidUri> for ParseError {
+    fn from(err: InvalidUri) -> ParseError {
+        ParseError::Uri(err)
+    }
+}
+
+impl From<Utf8Error> for ParseError {
+    fn from(err: Utf8Error) -> ParseError {
+        ParseError::Utf8(err)
+    }
+}
+
+impl From<FromUtf8Error> for ParseError {
+    fn from(err: FromUtf8Error) -> ParseError {
+        ParseError::Utf8(err.utf8_error())
+    }
+}
+
+impl From<httparse::Error> for ParseError {
+    fn from(err: httparse::Error) -> ParseError {
+        match err {
+            httparse::Error::HeaderName
+            | httparse::Error::HeaderValue
+            | httparse::Error::NewLine
+            | httparse::Error::Token => ParseError::Header,
+            httparse::Error::Status => ParseError::Status,
+            httparse::Error::TooManyHeaders => ParseError::TooLarge,
+            httparse::Error::Version => ParseError::Version,
+        }
+    }
+}
+
+impl From<ParseError> for Error {
+    fn from(err: ParseError) -> Self {
+        Self::new_parse().with_cause(err)
+    }
+}
+
+impl From<ParseError> for Response<BoxBody> {
+    fn from(err: ParseError) -> Self {
+        Error::from(err).into()
+    }
+}
+
+/// A set of errors that can occur during payload parsing.
+#[derive(Debug, Display)]
+#[non_exhaustive]
+pub enum PayloadError {
+    /// A payload reached EOF, but is not complete.
+    #[display(fmt = "payload reached EOF before completing: {:?}", _0)]
+    Incomplete(Option<io::Error>),
+
+    /// Content encoding stream corruption.
+    #[display(fmt = "can not decode content-encoding")]
+    EncodingCorrupted,
+
+    /// Payload reached size limit.
+    #[display(fmt = "payload reached size limit")]
+    Overflow,
+
+    /// Payload length is unknown.
+    #[display(fmt = "payload length is unknown")]
+    UnknownLength,
+
+    /// HTTP/2 payload error.
+    #[cfg(feature = "http2")]
+    #[display(fmt = "{}", _0)]
+    Http2Payload(::h2::Error),
+
+    /// Generic I/O error.
+    #[display(fmt = "{}", _0)]
+    Io(io::Error),
+}
+
+impl std::error::Error for PayloadError {
+    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+        match self {
+            PayloadError::Incomplete(None) => None,
+            PayloadError::Incomplete(Some(err)) => Some(err),
+            PayloadError::EncodingCorrupted => None,
+            PayloadError::Overflow => None,
+            PayloadError::UnknownLength => None,
+            #[cfg(feature = "http2")]
+            PayloadError::Http2Payload(err) => Some(err),
+            PayloadError::Io(err) => Some(err),
+        }
+    }
+}
+
+#[cfg(feature = "http2")]
+impl From<::h2::Error> for PayloadError {
+    fn from(err: ::h2::Error) -> Self {
+        PayloadError::Http2Payload(err)
+    }
+}
+
+impl From<Option<io::Error>> for PayloadError {
+    fn from(err: Option<io::Error>) -> Self {
+        PayloadError::Incomplete(err)
+    }
+}
+
+impl From<io::Error> for PayloadError {
+    fn from(err: io::Error) -> Self {
+        PayloadError::Incomplete(Some(err))
+    }
+}
+
+impl From<PayloadError> for Error {
+    fn from(err: PayloadError) -> Self {
+        Self::new_payload().with_cause(err)
+    }
+}
+
+/// A set of errors that can occur during dispatching HTTP requests.
+#[derive(Debug, Display, From)]
+#[non_exhaustive]
+pub enum DispatchError {
+    /// Service error.
+    #[display(fmt = "service error")]
+    Service(Response<BoxBody>),
+
+    /// Body streaming error.
+    #[display(fmt = "body error: {}", _0)]
+    Body(Box<dyn StdError>),
+
+    /// Upgrade service error.
+    #[display(fmt = "upgrade error")]
+    Upgrade,
+
+    /// An `io::Error` that occurred while trying to read or write to a network stream.
+    #[display(fmt = "I/O error: {}", _0)]
+    Io(io::Error),
+
+    /// Request parse error.
+    #[display(fmt = "request parse error: {}", _0)]
+    Parse(ParseError),
+
+    /// HTTP/2 error.
+    #[display(fmt = "{}", _0)]
+    #[cfg(feature = "http2")]
+    H2(h2::Error),
+
+    /// The first request did not complete within the specified timeout.
+    #[display(fmt = "request did not complete within the specified timeout")]
+    SlowRequestTimeout,
+
+    /// Disconnect timeout. Makes sense for TLS streams.
+    #[display(fmt = "connection shutdown timeout")]
+    DisconnectTimeout,
+
+    /// Handler dropped payload before reading EOF.
+    #[display(fmt = "handler dropped payload before reading EOF")]
+    HandlerDroppedPayload,
+
+    /// Internal error.
+    #[display(fmt = "internal error")]
+    InternalError,
+}
+
+impl StdError for DispatchError {
+    fn source(&self) -> Option<&(dyn StdError + 'static)> {
+        match self {
+            DispatchError::Service(_res) => None,
+            DispatchError::Body(err) => Some(&**err),
+            DispatchError::Io(err) => Some(err),
+            DispatchError::Parse(err) => Some(err),
+
+            #[cfg(feature = "http2")]
+            DispatchError::H2(err) => Some(err),
+
+            _ => None,
+        }
+    }
+}
+
+/// A set of error that can occur during parsing content type.
+#[derive(Debug, Display, Error)]
+#[cfg_attr(test, derive(PartialEq, Eq))]
+#[non_exhaustive]
+pub enum ContentTypeError {
+    /// Can not parse content type.
+    #[display(fmt = "could not parse content type")]
+    ParseError,
+
+    /// Unknown content encoding.
+    #[display(fmt = "unknown content encoding")]
+    UnknownEncoding,
+}
+
+#[cfg(test)]
+mod tests {
+    use http::Error as HttpError;
+
+    use super::*;
+
+    #[test]
+    fn test_into_response() {
+        let resp: Response<BoxBody> = ParseError::Incomplete.into();
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+
+        let err: HttpError = StatusCode::from_u16(10000).err().unwrap().into();
+        let resp: Response<BoxBody> = Error::new_http().with_cause(err).into();
+        assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
+    }
+
+    #[test]
+    fn test_as_response() {
+        let orig = io::Error::new(io::ErrorKind::Other, "other");
+        let err: Error = ParseError::Io(orig).into();
+        assert_eq!(
+            format!("{}", err),
+            "error parsing HTTP message: I/O error: other"
+        );
+    }
+
+    #[test]
+    fn test_error_display() {
+        let orig = io::Error::new(io::ErrorKind::Other, "other");
+        let err = Error::new_io().with_cause(orig);
+        assert_eq!("connection error: other", err.to_string());
+    }
+
+    #[test]
+    fn test_error_http_response() {
+        let orig = io::Error::new(io::ErrorKind::Other, "other");
+        let err = Error::new_io().with_cause(orig);
+        let resp: Response<BoxBody> = err.into();
+        assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
+    }
+
+    #[test]
+    fn test_payload_error() {
+        let err: PayloadError = io::Error::new(io::ErrorKind::Other, "ParseError").into();
+        assert!(err.to_string().contains("ParseError"));
+
+        let err = PayloadError::Incomplete(None);
+        assert_eq!(
+            err.to_string(),
+            "payload reached EOF before completing: None"
+        );
+    }
+
+    macro_rules! from {
+        ($from:expr => $error:pat) => {
+            match ParseError::from($from) {
+                err @ $error => {
+                    assert!(err.to_string().len() >= 5);
+                }
+                err => unreachable!("{:?}", err),
+            }
+        };
+    }
+
+    macro_rules! from_and_cause {
+        ($from:expr => $error:pat) => {
+            match ParseError::from($from) {
+                e @ $error => {
+                    let desc = format!("{}", e);
+                    assert_eq!(desc, format!("I/O error: {}", $from));
+                }
+                _ => unreachable!("{:?}", $from),
+            }
+        };
+    }
+
+    #[test]
+    fn test_from() {
+        from_and_cause!(io::Error::new(io::ErrorKind::Other, "other") => ParseError::Io(..));
+        from!(httparse::Error::HeaderName => ParseError::Header);
+        from!(httparse::Error::HeaderName => ParseError::Header);
+        from!(httparse::Error::HeaderValue => ParseError::Header);
+        from!(httparse::Error::NewLine => ParseError::Header);
+        from!(httparse::Error::Status => ParseError::Status);
+        from!(httparse::Error::Token => ParseError::Header);
+        from!(httparse::Error::TooManyHeaders => ParseError::TooLarge);
+        from!(httparse::Error::Version => ParseError::Version);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/extensions.rs.html b/src/actix_http/extensions.rs.html new file mode 100644 index 000000000..efc883188 --- /dev/null +++ b/src/actix_http/extensions.rs.html @@ -0,0 +1,603 @@ +extensions.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
+
use std::{
+    any::{Any, TypeId},
+    collections::HashMap,
+    fmt,
+    hash::{BuildHasherDefault, Hasher},
+};
+
+/// A hasher for `TypeId`s that takes advantage of its known characteristics.
+///
+/// Author of `anymap` crate has done research on the topic:
+/// https://github.com/chris-morgan/anymap/blob/2e9a5704/src/lib.rs#L599
+#[derive(Debug, Default)]
+struct NoOpHasher(u64);
+
+impl Hasher for NoOpHasher {
+    fn write(&mut self, _bytes: &[u8]) {
+        unimplemented!("This NoOpHasher can only handle u64s")
+    }
+
+    fn write_u64(&mut self, i: u64) {
+        self.0 = i;
+    }
+
+    fn finish(&self) -> u64 {
+        self.0
+    }
+}
+
+/// A type map for request extensions.
+///
+/// All entries into this map must be owned types (or static references).
+#[derive(Default)]
+pub struct Extensions {
+    /// Use AHasher with a std HashMap with for faster lookups on the small `TypeId` keys.
+    map: HashMap<TypeId, Box<dyn Any>, BuildHasherDefault<NoOpHasher>>,
+}
+
+impl Extensions {
+    /// Creates an empty `Extensions`.
+    #[inline]
+    pub fn new() -> Extensions {
+        Extensions {
+            map: HashMap::default(),
+        }
+    }
+
+    /// Insert an item into the map.
+    ///
+    /// If an item of this type was already stored, it will be replaced and returned.
+    ///
+    /// ```
+    /// # use actix_http::Extensions;
+    /// let mut map = Extensions::new();
+    /// assert_eq!(map.insert(""), None);
+    /// assert_eq!(map.insert(1u32), None);
+    /// assert_eq!(map.insert(2u32), Some(1u32));
+    /// assert_eq!(*map.get::<u32>().unwrap(), 2u32);
+    /// ```
+    pub fn insert<T: 'static>(&mut self, val: T) -> Option<T> {
+        self.map
+            .insert(TypeId::of::<T>(), Box::new(val))
+            .and_then(downcast_owned)
+    }
+
+    /// Check if map contains an item of a given type.
+    ///
+    /// ```
+    /// # use actix_http::Extensions;
+    /// let mut map = Extensions::new();
+    /// assert!(!map.contains::<u32>());
+    ///
+    /// assert_eq!(map.insert(1u32), None);
+    /// assert!(map.contains::<u32>());
+    /// ```
+    pub fn contains<T: 'static>(&self) -> bool {
+        self.map.contains_key(&TypeId::of::<T>())
+    }
+
+    /// Get a reference to an item of a given type.
+    ///
+    /// ```
+    /// # use actix_http::Extensions;
+    /// let mut map = Extensions::new();
+    /// map.insert(1u32);
+    /// assert_eq!(map.get::<u32>(), Some(&1u32));
+    /// ```
+    pub fn get<T: 'static>(&self) -> Option<&T> {
+        self.map
+            .get(&TypeId::of::<T>())
+            .and_then(|boxed| boxed.downcast_ref())
+    }
+
+    /// Get a mutable reference to an item of a given type.
+    ///
+    /// ```
+    /// # use actix_http::Extensions;
+    /// let mut map = Extensions::new();
+    /// map.insert(1u32);
+    /// assert_eq!(map.get_mut::<u32>(), Some(&mut 1u32));
+    /// ```
+    pub fn get_mut<T: 'static>(&mut self) -> Option<&mut T> {
+        self.map
+            .get_mut(&TypeId::of::<T>())
+            .and_then(|boxed| boxed.downcast_mut())
+    }
+
+    /// Remove an item from the map of a given type.
+    ///
+    /// If an item of this type was already stored, it will be returned.
+    ///
+    /// ```
+    /// # use actix_http::Extensions;
+    /// let mut map = Extensions::new();
+    ///
+    /// map.insert(1u32);
+    /// assert_eq!(map.get::<u32>(), Some(&1u32));
+    ///
+    /// assert_eq!(map.remove::<u32>(), Some(1u32));
+    /// assert!(!map.contains::<u32>());
+    /// ```
+    pub fn remove<T: 'static>(&mut self) -> Option<T> {
+        self.map.remove(&TypeId::of::<T>()).and_then(downcast_owned)
+    }
+
+    /// Clear the `Extensions` of all inserted extensions.
+    ///
+    /// ```
+    /// # use actix_http::Extensions;
+    /// let mut map = Extensions::new();
+    ///
+    /// map.insert(1u32);
+    /// assert!(map.contains::<u32>());
+    ///
+    /// map.clear();
+    /// assert!(!map.contains::<u32>());
+    /// ```
+    #[inline]
+    pub fn clear(&mut self) {
+        self.map.clear();
+    }
+
+    /// Extends self with the items from another `Extensions`.
+    pub fn extend(&mut self, other: Extensions) {
+        self.map.extend(other.map);
+    }
+}
+
+impl fmt::Debug for Extensions {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("Extensions").finish()
+    }
+}
+
+fn downcast_owned<T: 'static>(boxed: Box<dyn Any>) -> Option<T> {
+    boxed.downcast().ok().map(|boxed| *boxed)
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_remove() {
+        let mut map = Extensions::new();
+
+        map.insert::<i8>(123);
+        assert!(map.get::<i8>().is_some());
+
+        map.remove::<i8>();
+        assert!(map.get::<i8>().is_none());
+    }
+
+    #[test]
+    fn test_clear() {
+        let mut map = Extensions::new();
+
+        map.insert::<i8>(8);
+        map.insert::<i16>(16);
+        map.insert::<i32>(32);
+
+        assert!(map.contains::<i8>());
+        assert!(map.contains::<i16>());
+        assert!(map.contains::<i32>());
+
+        map.clear();
+
+        assert!(!map.contains::<i8>());
+        assert!(!map.contains::<i16>());
+        assert!(!map.contains::<i32>());
+
+        map.insert::<i8>(10);
+        assert_eq!(*map.get::<i8>().unwrap(), 10);
+    }
+
+    #[test]
+    fn test_integers() {
+        static A: u32 = 8;
+
+        let mut map = Extensions::new();
+
+        map.insert::<i8>(8);
+        map.insert::<i16>(16);
+        map.insert::<i32>(32);
+        map.insert::<i64>(64);
+        map.insert::<i128>(128);
+        map.insert::<u8>(8);
+        map.insert::<u16>(16);
+        map.insert::<u32>(32);
+        map.insert::<u64>(64);
+        map.insert::<u128>(128);
+        map.insert::<&'static u32>(&A);
+        assert!(map.get::<i8>().is_some());
+        assert!(map.get::<i16>().is_some());
+        assert!(map.get::<i32>().is_some());
+        assert!(map.get::<i64>().is_some());
+        assert!(map.get::<i128>().is_some());
+        assert!(map.get::<u8>().is_some());
+        assert!(map.get::<u16>().is_some());
+        assert!(map.get::<u32>().is_some());
+        assert!(map.get::<u64>().is_some());
+        assert!(map.get::<u128>().is_some());
+        assert!(map.get::<&'static u32>().is_some());
+    }
+
+    #[test]
+    fn test_composition() {
+        struct Magi<T>(pub T);
+
+        struct Madoka {
+            pub god: bool,
+        }
+
+        struct Homura {
+            pub attempts: usize,
+        }
+
+        struct Mami {
+            pub guns: usize,
+        }
+
+        let mut map = Extensions::new();
+
+        map.insert(Magi(Madoka { god: false }));
+        map.insert(Magi(Homura { attempts: 0 }));
+        map.insert(Magi(Mami { guns: 999 }));
+
+        assert!(!map.get::<Magi<Madoka>>().unwrap().0.god);
+        assert_eq!(0, map.get::<Magi<Homura>>().unwrap().0.attempts);
+        assert_eq!(999, map.get::<Magi<Mami>>().unwrap().0.guns);
+    }
+
+    #[test]
+    fn test_extensions() {
+        #[derive(Debug, PartialEq)]
+        struct MyType(i32);
+
+        let mut extensions = Extensions::new();
+
+        extensions.insert(5i32);
+        extensions.insert(MyType(10));
+
+        assert_eq!(extensions.get(), Some(&5i32));
+        assert_eq!(extensions.get_mut(), Some(&mut 5i32));
+
+        assert_eq!(extensions.remove::<i32>(), Some(5i32));
+        assert!(extensions.get::<i32>().is_none());
+
+        assert_eq!(extensions.get::<bool>(), None);
+        assert_eq!(extensions.get(), Some(&MyType(10)));
+    }
+
+    #[test]
+    fn test_extend() {
+        #[derive(Debug, PartialEq)]
+        struct MyType(i32);
+
+        let mut extensions = Extensions::new();
+
+        extensions.insert(5i32);
+        extensions.insert(MyType(10));
+
+        let mut other = Extensions::new();
+
+        other.insert(15i32);
+        other.insert(20u8);
+
+        extensions.extend(other);
+
+        assert_eq!(extensions.get(), Some(&15i32));
+        assert_eq!(extensions.get_mut(), Some(&mut 15i32));
+
+        assert_eq!(extensions.remove::<i32>(), Some(15i32));
+        assert!(extensions.get::<i32>().is_none());
+
+        assert_eq!(extensions.get::<bool>(), None);
+        assert_eq!(extensions.get(), Some(&MyType(10)));
+
+        assert_eq!(extensions.get(), Some(&20u8));
+        assert_eq!(extensions.get_mut(), Some(&mut 20u8));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/h1/chunked.rs.html b/src/actix_http/h1/chunked.rs.html new file mode 100644 index 000000000..6b7f56081 --- /dev/null +++ b/src/actix_http/h1/chunked.rs.html @@ -0,0 +1,855 @@ +chunked.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
+
use std::{io, task::Poll};
+
+use bytes::{Buf as _, Bytes, BytesMut};
+use tracing::{debug, trace};
+
+macro_rules! byte (
+    ($rdr:ident) => ({
+        if $rdr.len() > 0 {
+            let b = $rdr[0];
+            $rdr.advance(1);
+            b
+        } else {
+            return Poll::Pending
+        }
+    })
+);
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub(super) enum ChunkedState {
+    Size,
+    SizeLws,
+    Extension,
+    SizeLf,
+    Body,
+    BodyCr,
+    BodyLf,
+    EndCr,
+    EndLf,
+    End,
+}
+
+impl ChunkedState {
+    pub(super) fn step(
+        &self,
+        body: &mut BytesMut,
+        size: &mut u64,
+        buf: &mut Option<Bytes>,
+    ) -> Poll<Result<ChunkedState, io::Error>> {
+        use self::ChunkedState::*;
+        match *self {
+            Size => ChunkedState::read_size(body, size),
+            SizeLws => ChunkedState::read_size_lws(body),
+            Extension => ChunkedState::read_extension(body),
+            SizeLf => ChunkedState::read_size_lf(body, *size),
+            Body => ChunkedState::read_body(body, size, buf),
+            BodyCr => ChunkedState::read_body_cr(body),
+            BodyLf => ChunkedState::read_body_lf(body),
+            EndCr => ChunkedState::read_end_cr(body),
+            EndLf => ChunkedState::read_end_lf(body),
+            End => Poll::Ready(Ok(ChunkedState::End)),
+        }
+    }
+
+    fn read_size(rdr: &mut BytesMut, size: &mut u64) -> Poll<Result<ChunkedState, io::Error>> {
+        let radix = 16;
+
+        let rem = match byte!(rdr) {
+            b @ b'0'..=b'9' => b - b'0',
+            b @ b'a'..=b'f' => b + 10 - b'a',
+            b @ b'A'..=b'F' => b + 10 - b'A',
+            b'\t' | b' ' => return Poll::Ready(Ok(ChunkedState::SizeLws)),
+            b';' => return Poll::Ready(Ok(ChunkedState::Extension)),
+            b'\r' => return Poll::Ready(Ok(ChunkedState::SizeLf)),
+            _ => {
+                return Poll::Ready(Err(io::Error::new(
+                    io::ErrorKind::InvalidInput,
+                    "Invalid chunk size line: Invalid Size",
+                )));
+            }
+        };
+
+        match size.checked_mul(radix) {
+            Some(n) => {
+                *size = n;
+                *size += rem as u64;
+
+                Poll::Ready(Ok(ChunkedState::Size))
+            }
+            None => {
+                debug!("chunk size would overflow u64");
+                Poll::Ready(Err(io::Error::new(
+                    io::ErrorKind::InvalidInput,
+                    "Invalid chunk size line: Size is too big",
+                )))
+            }
+        }
+    }
+
+    fn read_size_lws(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Error>> {
+        match byte!(rdr) {
+            // LWS can follow the chunk size, but no more digits can come
+            b'\t' | b' ' => Poll::Ready(Ok(ChunkedState::SizeLws)),
+            b';' => Poll::Ready(Ok(ChunkedState::Extension)),
+            b'\r' => Poll::Ready(Ok(ChunkedState::SizeLf)),
+            _ => Poll::Ready(Err(io::Error::new(
+                io::ErrorKind::InvalidInput,
+                "Invalid chunk size linear white space",
+            ))),
+        }
+    }
+    fn read_extension(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Error>> {
+        match byte!(rdr) {
+            b'\r' => Poll::Ready(Ok(ChunkedState::SizeLf)),
+            // strictly 0x20 (space) should be disallowed but we don't parse quoted strings here
+            0x00..=0x08 | 0x0a..=0x1f | 0x7f => Poll::Ready(Err(io::Error::new(
+                io::ErrorKind::InvalidInput,
+                "Invalid character in chunk extension",
+            ))),
+            _ => Poll::Ready(Ok(ChunkedState::Extension)), // no supported extensions
+        }
+    }
+    fn read_size_lf(rdr: &mut BytesMut, size: u64) -> Poll<Result<ChunkedState, io::Error>> {
+        match byte!(rdr) {
+            b'\n' if size > 0 => Poll::Ready(Ok(ChunkedState::Body)),
+            b'\n' if size == 0 => Poll::Ready(Ok(ChunkedState::EndCr)),
+            _ => Poll::Ready(Err(io::Error::new(
+                io::ErrorKind::InvalidInput,
+                "Invalid chunk size LF",
+            ))),
+        }
+    }
+
+    fn read_body(
+        rdr: &mut BytesMut,
+        rem: &mut u64,
+        buf: &mut Option<Bytes>,
+    ) -> Poll<Result<ChunkedState, io::Error>> {
+        trace!("Chunked read, remaining={:?}", rem);
+
+        let len = rdr.len() as u64;
+        if len == 0 {
+            Poll::Ready(Ok(ChunkedState::Body))
+        } else {
+            let slice;
+            if *rem > len {
+                slice = rdr.split().freeze();
+                *rem -= len;
+            } else {
+                slice = rdr.split_to(*rem as usize).freeze();
+                *rem = 0;
+            }
+            *buf = Some(slice);
+            if *rem > 0 {
+                Poll::Ready(Ok(ChunkedState::Body))
+            } else {
+                Poll::Ready(Ok(ChunkedState::BodyCr))
+            }
+        }
+    }
+
+    fn read_body_cr(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Error>> {
+        match byte!(rdr) {
+            b'\r' => Poll::Ready(Ok(ChunkedState::BodyLf)),
+            _ => Poll::Ready(Err(io::Error::new(
+                io::ErrorKind::InvalidInput,
+                "Invalid chunk body CR",
+            ))),
+        }
+    }
+    fn read_body_lf(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Error>> {
+        match byte!(rdr) {
+            b'\n' => Poll::Ready(Ok(ChunkedState::Size)),
+            _ => Poll::Ready(Err(io::Error::new(
+                io::ErrorKind::InvalidInput,
+                "Invalid chunk body LF",
+            ))),
+        }
+    }
+    fn read_end_cr(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Error>> {
+        match byte!(rdr) {
+            b'\r' => Poll::Ready(Ok(ChunkedState::EndLf)),
+            _ => Poll::Ready(Err(io::Error::new(
+                io::ErrorKind::InvalidInput,
+                "Invalid chunk end CR",
+            ))),
+        }
+    }
+    fn read_end_lf(rdr: &mut BytesMut) -> Poll<Result<ChunkedState, io::Error>> {
+        match byte!(rdr) {
+            b'\n' => Poll::Ready(Ok(ChunkedState::End)),
+            _ => Poll::Ready(Err(io::Error::new(
+                io::ErrorKind::InvalidInput,
+                "Invalid chunk end LF",
+            ))),
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_codec::Decoder as _;
+    use bytes::{Bytes, BytesMut};
+    use http::Method;
+
+    use crate::{
+        error::ParseError,
+        h1::decoder::{MessageDecoder, PayloadItem},
+        HttpMessage as _, Request,
+    };
+
+    macro_rules! parse_ready {
+        ($e:expr) => {{
+            match MessageDecoder::<Request>::default().decode($e) {
+                Ok(Some((msg, _))) => msg,
+                Ok(_) => unreachable!("Eof during parsing http request"),
+                Err(err) => unreachable!("Error during parsing http request: {:?}", err),
+            }
+        }};
+    }
+
+    macro_rules! expect_parse_err {
+        ($e:expr) => {{
+            match MessageDecoder::<Request>::default().decode($e) {
+                Err(err) => match err {
+                    ParseError::Io(_) => unreachable!("Parse error expected"),
+                    _ => {}
+                },
+                _ => unreachable!("Error expected"),
+            }
+        }};
+    }
+
+    #[test]
+    fn test_parse_chunked_payload_chunk_extension() {
+        let mut buf = BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+            transfer-encoding: chunked\r\n\
+            \r\n",
+        );
+
+        let mut reader = MessageDecoder::<Request>::default();
+        let (msg, pl) = reader.decode(&mut buf).unwrap().unwrap();
+        let mut pl = pl.unwrap();
+        assert!(msg.chunked().unwrap());
+
+        buf.extend(b"4;test\r\ndata\r\n4\r\nline\r\n0\r\n\r\n"); // test: test\r\n\r\n")
+        let chunk = pl.decode(&mut buf).unwrap().unwrap().chunk();
+        assert_eq!(chunk, Bytes::from_static(b"data"));
+        let chunk = pl.decode(&mut buf).unwrap().unwrap().chunk();
+        assert_eq!(chunk, Bytes::from_static(b"line"));
+        let msg = pl.decode(&mut buf).unwrap().unwrap();
+        assert!(msg.eof());
+    }
+
+    #[test]
+    fn test_request_chunked() {
+        let mut buf = BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             transfer-encoding: chunked\r\n\r\n",
+        );
+        let req = parse_ready!(&mut buf);
+
+        if let Ok(val) = req.chunked() {
+            assert!(val);
+        } else {
+            unreachable!("Error");
+        }
+
+        // intentional typo in "chunked"
+        let mut buf = BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             transfer-encoding: chnked\r\n\r\n",
+        );
+        expect_parse_err!(&mut buf);
+    }
+
+    #[test]
+    fn test_http_request_chunked_payload() {
+        let mut buf = BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             transfer-encoding: chunked\r\n\r\n",
+        );
+        let mut reader = MessageDecoder::<Request>::default();
+        let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
+        let mut pl = pl.unwrap();
+        assert!(req.chunked().unwrap());
+
+        buf.extend(b"4\r\ndata\r\n4\r\nline\r\n0\r\n\r\n");
+        assert_eq!(
+            pl.decode(&mut buf).unwrap().unwrap().chunk().as_ref(),
+            b"data"
+        );
+        assert_eq!(
+            pl.decode(&mut buf).unwrap().unwrap().chunk().as_ref(),
+            b"line"
+        );
+        assert!(pl.decode(&mut buf).unwrap().unwrap().eof());
+    }
+
+    #[test]
+    fn test_http_request_chunked_payload_and_next_message() {
+        let mut buf = BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             transfer-encoding: chunked\r\n\r\n",
+        );
+        let mut reader = MessageDecoder::<Request>::default();
+        let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
+        let mut pl = pl.unwrap();
+        assert!(req.chunked().unwrap());
+
+        buf.extend(
+            b"4\r\ndata\r\n4\r\nline\r\n0\r\n\r\n\
+              POST /test2 HTTP/1.1\r\n\
+              transfer-encoding: chunked\r\n\r\n"
+                .iter(),
+        );
+        let msg = pl.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(msg.chunk().as_ref(), b"data");
+        let msg = pl.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(msg.chunk().as_ref(), b"line");
+        let msg = pl.decode(&mut buf).unwrap().unwrap();
+        assert!(msg.eof());
+
+        let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
+        assert!(req.chunked().unwrap());
+        assert_eq!(*req.method(), Method::POST);
+        assert!(req.chunked().unwrap());
+    }
+
+    #[test]
+    fn test_http_request_chunked_payload_chunks() {
+        let mut buf = BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             transfer-encoding: chunked\r\n\r\n",
+        );
+
+        let mut reader = MessageDecoder::<Request>::default();
+        let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
+        let mut pl = pl.unwrap();
+        assert!(req.chunked().unwrap());
+
+        buf.extend(b"4\r\n1111\r\n");
+        let msg = pl.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(msg.chunk().as_ref(), b"1111");
+
+        buf.extend(b"4\r\ndata\r");
+        let msg = pl.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(msg.chunk().as_ref(), b"data");
+
+        buf.extend(b"\n4");
+        assert!(pl.decode(&mut buf).unwrap().is_none());
+
+        buf.extend(b"\r");
+        assert!(pl.decode(&mut buf).unwrap().is_none());
+        buf.extend(b"\n");
+        assert!(pl.decode(&mut buf).unwrap().is_none());
+
+        buf.extend(b"li");
+        let msg = pl.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(msg.chunk().as_ref(), b"li");
+
+        //trailers
+        //buf.feed_data("test: test\r\n");
+        //not_ready!(reader.parse(&mut buf, &mut readbuf));
+
+        buf.extend(b"ne\r\n0\r\n");
+        let msg = pl.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(msg.chunk().as_ref(), b"ne");
+        assert!(pl.decode(&mut buf).unwrap().is_none());
+
+        buf.extend(b"\r\n");
+        assert!(pl.decode(&mut buf).unwrap().unwrap().eof());
+    }
+
+    #[test]
+    fn chunk_extension_quoted() {
+        let mut buf = BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+            Host: localhost:8080\r\n\
+            Transfer-Encoding: chunked\r\n\
+            \r\n\
+            2;hello=b;one=\"1 2 3\"\r\n\
+            xx",
+        );
+
+        let mut reader = MessageDecoder::<Request>::default();
+        let (_msg, pl) = reader.decode(&mut buf).unwrap().unwrap();
+        let mut pl = pl.unwrap();
+
+        let chunk = pl.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(chunk, PayloadItem::Chunk(Bytes::from_static(b"xx")));
+    }
+
+    #[test]
+    fn hrs_chunk_extension_invalid() {
+        let mut buf = BytesMut::from(
+            "GET / HTTP/1.1\r\n\
+            Host: localhost:8080\r\n\
+            Transfer-Encoding: chunked\r\n\
+            \r\n\
+            2;x\nx\r\n\
+            4c\r\n\
+            0\r\n",
+        );
+
+        let mut reader = MessageDecoder::<Request>::default();
+        let (_msg, pl) = reader.decode(&mut buf).unwrap().unwrap();
+        let mut pl = pl.unwrap();
+
+        let err = pl.decode(&mut buf).unwrap_err();
+        assert!(err
+            .to_string()
+            .contains("Invalid character in chunk extension"));
+    }
+
+    #[test]
+    fn hrs_chunk_size_overflow() {
+        let mut buf = BytesMut::from(
+            "GET / HTTP/1.1\r\n\
+            Host: example.com\r\n\
+            Transfer-Encoding: chunked\r\n\
+            \r\n\
+            f0000000000000003\r\n\
+            abc\r\n\
+            0\r\n",
+        );
+
+        let mut reader = MessageDecoder::<Request>::default();
+        let (_msg, pl) = reader.decode(&mut buf).unwrap().unwrap();
+        let mut pl = pl.unwrap();
+
+        let err = pl.decode(&mut buf).unwrap_err();
+        assert!(err
+            .to_string()
+            .contains("Invalid chunk size line: Size is too big"));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/h1/client.rs.html b/src/actix_http/h1/client.rs.html new file mode 100644 index 000000000..0affd3e05 --- /dev/null +++ b/src/actix_http/h1/client.rs.html @@ -0,0 +1,481 @@ +client.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
+
use std::{fmt, io};
+
+use bitflags::bitflags;
+use bytes::{Bytes, BytesMut};
+use http::{Method, Version};
+use tokio_util::codec::{Decoder, Encoder};
+
+use super::{
+    decoder::{self, PayloadDecoder, PayloadItem, PayloadType},
+    encoder, reserve_readbuf, Message, MessageType,
+};
+use crate::{
+    body::BodySize,
+    error::{ParseError, PayloadError},
+    ConnectionType, RequestHeadType, ResponseHead, ServiceConfig,
+};
+
+bitflags! {
+    #[derive(Debug, Clone, Copy)]
+    struct Flags: u8 {
+        const HEAD               = 0b0000_0001;
+        const KEEP_ALIVE_ENABLED = 0b0000_1000;
+        const STREAM             = 0b0001_0000;
+    }
+}
+
+/// HTTP/1 Codec
+pub struct ClientCodec {
+    inner: ClientCodecInner,
+}
+
+/// HTTP/1 Payload Codec
+pub struct ClientPayloadCodec {
+    inner: ClientCodecInner,
+}
+
+struct ClientCodecInner {
+    config: ServiceConfig,
+    decoder: decoder::MessageDecoder<ResponseHead>,
+    payload: Option<PayloadDecoder>,
+    version: Version,
+    conn_type: ConnectionType,
+
+    // encoder part
+    flags: Flags,
+    encoder: encoder::MessageEncoder<RequestHeadType>,
+}
+
+impl Default for ClientCodec {
+    fn default() -> Self {
+        ClientCodec::new(ServiceConfig::default())
+    }
+}
+
+impl fmt::Debug for ClientCodec {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("h1::ClientCodec")
+            .field("flags", &self.inner.flags)
+            .finish_non_exhaustive()
+    }
+}
+
+impl ClientCodec {
+    /// Create HTTP/1 codec.
+    ///
+    /// `keepalive_enabled` how response `connection` header get generated.
+    pub fn new(config: ServiceConfig) -> Self {
+        let flags = if config.keep_alive().enabled() {
+            Flags::KEEP_ALIVE_ENABLED
+        } else {
+            Flags::empty()
+        };
+
+        ClientCodec {
+            inner: ClientCodecInner {
+                config,
+                decoder: decoder::MessageDecoder::default(),
+                payload: None,
+                version: Version::HTTP_11,
+                conn_type: ConnectionType::Close,
+
+                flags,
+                encoder: encoder::MessageEncoder::default(),
+            },
+        }
+    }
+
+    /// Check if request is upgrade
+    pub fn upgrade(&self) -> bool {
+        self.inner.conn_type == ConnectionType::Upgrade
+    }
+
+    /// Check if last response is keep-alive
+    pub fn keep_alive(&self) -> bool {
+        self.inner.conn_type == ConnectionType::KeepAlive
+    }
+
+    /// Check last request's message type
+    pub fn message_type(&self) -> MessageType {
+        if self.inner.flags.contains(Flags::STREAM) {
+            MessageType::Stream
+        } else if self.inner.payload.is_none() {
+            MessageType::None
+        } else {
+            MessageType::Payload
+        }
+    }
+
+    /// Convert message codec to a payload codec
+    pub fn into_payload_codec(self) -> ClientPayloadCodec {
+        ClientPayloadCodec { inner: self.inner }
+    }
+}
+
+impl ClientPayloadCodec {
+    /// Check if last response is keep-alive
+    pub fn keep_alive(&self) -> bool {
+        self.inner.conn_type == ConnectionType::KeepAlive
+    }
+
+    /// Transform payload codec to a message codec
+    pub fn into_message_codec(self) -> ClientCodec {
+        ClientCodec { inner: self.inner }
+    }
+}
+
+impl Decoder for ClientCodec {
+    type Item = ResponseHead;
+    type Error = ParseError;
+
+    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
+        debug_assert!(
+            self.inner.payload.is_none(),
+            "Payload decoder should not be set"
+        );
+
+        if let Some((req, payload)) = self.inner.decoder.decode(src)? {
+            if let Some(conn_type) = req.conn_type() {
+                // do not use peer's keep-alive
+                self.inner.conn_type = if conn_type == ConnectionType::KeepAlive {
+                    self.inner.conn_type
+                } else {
+                    conn_type
+                };
+            }
+
+            if !self.inner.flags.contains(Flags::HEAD) {
+                match payload {
+                    PayloadType::None => self.inner.payload = None,
+                    PayloadType::Payload(pl) => self.inner.payload = Some(pl),
+                    PayloadType::Stream(pl) => {
+                        self.inner.payload = Some(pl);
+                        self.inner.flags.insert(Flags::STREAM);
+                    }
+                }
+            } else {
+                self.inner.payload = None;
+            }
+            reserve_readbuf(src);
+            Ok(Some(req))
+        } else {
+            Ok(None)
+        }
+    }
+}
+
+impl Decoder for ClientPayloadCodec {
+    type Item = Option<Bytes>;
+    type Error = PayloadError;
+
+    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
+        debug_assert!(
+            self.inner.payload.is_some(),
+            "Payload decoder is not specified"
+        );
+
+        Ok(match self.inner.payload.as_mut().unwrap().decode(src)? {
+            Some(PayloadItem::Chunk(chunk)) => {
+                reserve_readbuf(src);
+                Some(Some(chunk))
+            }
+            Some(PayloadItem::Eof) => {
+                self.inner.payload.take();
+                Some(None)
+            }
+            None => None,
+        })
+    }
+}
+
+impl Encoder<Message<(RequestHeadType, BodySize)>> for ClientCodec {
+    type Error = io::Error;
+
+    fn encode(
+        &mut self,
+        item: Message<(RequestHeadType, BodySize)>,
+        dst: &mut BytesMut,
+    ) -> Result<(), Self::Error> {
+        match item {
+            Message::Item((mut head, length)) => {
+                let inner = &mut self.inner;
+                inner.version = head.as_ref().version;
+                inner
+                    .flags
+                    .set(Flags::HEAD, head.as_ref().method == Method::HEAD);
+
+                // connection status
+                inner.conn_type = match head.as_ref().connection_type() {
+                    ConnectionType::KeepAlive => {
+                        if inner.flags.contains(Flags::KEEP_ALIVE_ENABLED) {
+                            ConnectionType::KeepAlive
+                        } else {
+                            ConnectionType::Close
+                        }
+                    }
+                    ConnectionType::Upgrade => ConnectionType::Upgrade,
+                    ConnectionType::Close => ConnectionType::Close,
+                };
+
+                inner.encoder.encode(
+                    dst,
+                    &mut head,
+                    false,
+                    false,
+                    inner.version,
+                    length,
+                    inner.conn_type,
+                    &inner.config,
+                )?;
+            }
+            Message::Chunk(Some(bytes)) => {
+                self.inner.encoder.encode_chunk(bytes.as_ref(), dst)?;
+            }
+            Message::Chunk(None) => {
+                self.inner.encoder.encode_eof(dst)?;
+            }
+        }
+        Ok(())
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/h1/codec.rs.html b/src/actix_http/h1/codec.rs.html new file mode 100644 index 000000000..5e81dc3ce --- /dev/null +++ b/src/actix_http/h1/codec.rs.html @@ -0,0 +1,481 @@ +codec.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
+
use std::{fmt, io};
+
+use bitflags::bitflags;
+use bytes::BytesMut;
+use http::{Method, Version};
+use tokio_util::codec::{Decoder, Encoder};
+
+use super::{
+    decoder::{self, PayloadDecoder, PayloadItem, PayloadType},
+    encoder, Message, MessageType,
+};
+use crate::{body::BodySize, error::ParseError, ConnectionType, Request, Response, ServiceConfig};
+
+bitflags! {
+    #[derive(Debug, Clone, Copy)]
+    struct Flags: u8 {
+        const HEAD               = 0b0000_0001;
+        const KEEP_ALIVE_ENABLED = 0b0000_0010;
+        const STREAM             = 0b0000_0100;
+    }
+}
+
+/// HTTP/1 Codec
+pub struct Codec {
+    config: ServiceConfig,
+    decoder: decoder::MessageDecoder<Request>,
+    payload: Option<PayloadDecoder>,
+    version: Version,
+    conn_type: ConnectionType,
+
+    // encoder part
+    flags: Flags,
+    encoder: encoder::MessageEncoder<Response<()>>,
+}
+
+impl Default for Codec {
+    fn default() -> Self {
+        Codec::new(ServiceConfig::default())
+    }
+}
+
+impl fmt::Debug for Codec {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("h1::Codec")
+            .field("flags", &self.flags)
+            .finish_non_exhaustive()
+    }
+}
+
+impl Codec {
+    /// Create HTTP/1 codec.
+    ///
+    /// `keepalive_enabled` how response `connection` header get generated.
+    pub fn new(config: ServiceConfig) -> Self {
+        let flags = if config.keep_alive().enabled() {
+            Flags::KEEP_ALIVE_ENABLED
+        } else {
+            Flags::empty()
+        };
+
+        Codec {
+            config,
+            flags,
+            decoder: decoder::MessageDecoder::default(),
+            payload: None,
+            version: Version::HTTP_11,
+            conn_type: ConnectionType::Close,
+            encoder: encoder::MessageEncoder::default(),
+        }
+    }
+
+    /// Check if request is upgrade.
+    #[inline]
+    pub fn upgrade(&self) -> bool {
+        self.conn_type == ConnectionType::Upgrade
+    }
+
+    /// Check if last response is keep-alive.
+    #[inline]
+    pub fn keep_alive(&self) -> bool {
+        self.conn_type == ConnectionType::KeepAlive
+    }
+
+    /// Check if keep-alive enabled on server level.
+    #[inline]
+    pub fn keep_alive_enabled(&self) -> bool {
+        self.flags.contains(Flags::KEEP_ALIVE_ENABLED)
+    }
+
+    /// Check last request's message type.
+    #[inline]
+    pub fn message_type(&self) -> MessageType {
+        if self.flags.contains(Flags::STREAM) {
+            MessageType::Stream
+        } else if self.payload.is_none() {
+            MessageType::None
+        } else {
+            MessageType::Payload
+        }
+    }
+
+    #[inline]
+    pub fn config(&self) -> &ServiceConfig {
+        &self.config
+    }
+}
+
+impl Decoder for Codec {
+    type Item = Message<Request>;
+    type Error = ParseError;
+
+    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
+        if let Some(ref mut payload) = self.payload {
+            Ok(match payload.decode(src)? {
+                Some(PayloadItem::Chunk(chunk)) => Some(Message::Chunk(Some(chunk))),
+                Some(PayloadItem::Eof) => {
+                    self.payload.take();
+                    Some(Message::Chunk(None))
+                }
+                None => None,
+            })
+        } else if let Some((req, payload)) = self.decoder.decode(src)? {
+            let head = req.head();
+            self.flags.set(Flags::HEAD, head.method == Method::HEAD);
+            self.version = head.version;
+            self.conn_type = head.connection_type();
+
+            if self.conn_type == ConnectionType::KeepAlive
+                && !self.flags.contains(Flags::KEEP_ALIVE_ENABLED)
+            {
+                self.conn_type = ConnectionType::Close
+            }
+
+            match payload {
+                PayloadType::None => self.payload = None,
+                PayloadType::Payload(pl) => self.payload = Some(pl),
+                PayloadType::Stream(pl) => {
+                    self.payload = Some(pl);
+                    self.flags.insert(Flags::STREAM);
+                }
+            }
+            Ok(Some(Message::Item(req)))
+        } else {
+            Ok(None)
+        }
+    }
+}
+
+impl Encoder<Message<(Response<()>, BodySize)>> for Codec {
+    type Error = io::Error;
+
+    fn encode(
+        &mut self,
+        item: Message<(Response<()>, BodySize)>,
+        dst: &mut BytesMut,
+    ) -> Result<(), Self::Error> {
+        match item {
+            Message::Item((mut res, length)) => {
+                // set response version
+                res.head_mut().version = self.version;
+
+                // connection status
+                self.conn_type = if let Some(ct) = res.head().conn_type() {
+                    if ct == ConnectionType::KeepAlive {
+                        self.conn_type
+                    } else {
+                        ct
+                    }
+                } else {
+                    self.conn_type
+                };
+
+                // encode message
+                self.encoder.encode(
+                    dst,
+                    &mut res,
+                    self.flags.contains(Flags::HEAD),
+                    self.flags.contains(Flags::STREAM),
+                    self.version,
+                    length,
+                    self.conn_type,
+                    &self.config,
+                )?;
+            }
+
+            Message::Chunk(Some(bytes)) => {
+                self.encoder.encode_chunk(bytes.as_ref(), dst)?;
+            }
+
+            Message::Chunk(None) => {
+                self.encoder.encode_eof(dst)?;
+            }
+        }
+
+        Ok(())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::HttpMessage as _;
+
+    #[actix_rt::test]
+    async fn test_http_request_chunked_payload_and_next_message() {
+        let mut codec = Codec::default();
+
+        let mut buf = BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             transfer-encoding: chunked\r\n\r\n",
+        );
+        let item = codec.decode(&mut buf).unwrap().unwrap();
+        let req = item.message();
+
+        assert_eq!(req.method(), Method::GET);
+        assert!(req.chunked().unwrap());
+
+        buf.extend(
+            b"4\r\ndata\r\n4\r\nline\r\n0\r\n\r\n\
+               POST /test2 HTTP/1.1\r\n\
+               transfer-encoding: chunked\r\n\r\n"
+                .iter(),
+        );
+
+        let msg = codec.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(msg.chunk().as_ref(), b"data");
+
+        let msg = codec.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(msg.chunk().as_ref(), b"line");
+
+        let msg = codec.decode(&mut buf).unwrap().unwrap();
+        assert!(msg.eof());
+
+        // decode next message
+        let item = codec.decode(&mut buf).unwrap().unwrap();
+        let req = item.message();
+        assert_eq!(*req.method(), Method::POST);
+        assert!(req.chunked().unwrap());
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/h1/decoder.rs.html b/src/actix_http/h1/decoder.rs.html new file mode 100644 index 000000000..20aef10e6 --- /dev/null +++ b/src/actix_http/h1/decoder.rs.html @@ -0,0 +1,2371 @@ +decoder.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
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+
use std::{io, marker::PhantomData, mem::MaybeUninit, task::Poll};
+
+use actix_codec::Decoder;
+use bytes::{Bytes, BytesMut};
+use http::{
+    header::{self, HeaderName, HeaderValue},
+    Method, StatusCode, Uri, Version,
+};
+use tracing::{debug, error, trace};
+
+use super::chunked::ChunkedState;
+use crate::{error::ParseError, header::HeaderMap, ConnectionType, Request, ResponseHead};
+
+pub(crate) const MAX_BUFFER_SIZE: usize = 131_072;
+const MAX_HEADERS: usize = 96;
+
+/// Incoming message decoder
+pub(crate) struct MessageDecoder<T: MessageType>(PhantomData<T>);
+
+#[derive(Debug)]
+/// Incoming request type
+pub(crate) enum PayloadType {
+    None,
+    Payload(PayloadDecoder),
+    Stream(PayloadDecoder),
+}
+
+impl<T: MessageType> Default for MessageDecoder<T> {
+    fn default() -> Self {
+        MessageDecoder(PhantomData)
+    }
+}
+
+impl<T: MessageType> Decoder for MessageDecoder<T> {
+    type Item = (T, PayloadType);
+    type Error = ParseError;
+
+    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
+        T::decode(src)
+    }
+}
+
+pub(crate) enum PayloadLength {
+    Payload(PayloadType),
+    UpgradeWebSocket,
+    None,
+}
+
+impl PayloadLength {
+    /// Returns true if variant is `None`.
+    fn is_none(&self) -> bool {
+        matches!(self, Self::None)
+    }
+
+    /// Returns true if variant is represents zero-length (not none) payload.
+    fn is_zero(&self) -> bool {
+        matches!(
+            self,
+            PayloadLength::Payload(PayloadType::Payload(PayloadDecoder {
+                kind: Kind::Length(0)
+            }))
+        )
+    }
+}
+
+pub(crate) trait MessageType: Sized {
+    fn set_connection_type(&mut self, conn_type: Option<ConnectionType>);
+
+    fn set_expect(&mut self);
+
+    fn headers_mut(&mut self) -> &mut HeaderMap;
+
+    fn decode(src: &mut BytesMut) -> Result<Option<(Self, PayloadType)>, ParseError>;
+
+    fn set_headers(
+        &mut self,
+        slice: &Bytes,
+        raw_headers: &[HeaderIndex],
+        version: Version,
+    ) -> Result<PayloadLength, ParseError> {
+        let mut ka = None;
+        let mut has_upgrade_websocket = false;
+        let mut expect = false;
+        let mut chunked = false;
+        let mut seen_te = false;
+        let mut content_length = None;
+
+        {
+            let headers = self.headers_mut();
+
+            for idx in raw_headers.iter() {
+                let name = HeaderName::from_bytes(&slice[idx.name.0..idx.name.1]).unwrap();
+
+                // SAFETY: httparse already checks header value is only visible ASCII bytes
+                // from_maybe_shared_unchecked contains debug assertions so they are omitted here
+                let value = unsafe {
+                    HeaderValue::from_maybe_shared_unchecked(slice.slice(idx.value.0..idx.value.1))
+                };
+
+                match name {
+                    header::CONTENT_LENGTH if content_length.is_some() => {
+                        debug!("multiple Content-Length");
+                        return Err(ParseError::Header);
+                    }
+
+                    header::CONTENT_LENGTH => match value.to_str().map(str::trim) {
+                        Ok(val) if val.starts_with('+') => {
+                            debug!("illegal Content-Length: {:?}", val);
+                            return Err(ParseError::Header);
+                        }
+
+                        Ok(val) => {
+                            if let Ok(len) = val.parse::<u64>() {
+                                // accept 0 lengths here and remove them in `decode` after all
+                                // headers have been processed to prevent request smuggling issues
+                                content_length = Some(len);
+                            } else {
+                                debug!("illegal Content-Length: {:?}", val);
+                                return Err(ParseError::Header);
+                            }
+                        }
+
+                        Err(_) => {
+                            debug!("illegal Content-Length: {:?}", value);
+                            return Err(ParseError::Header);
+                        }
+                    },
+
+                    // transfer-encoding
+                    header::TRANSFER_ENCODING if seen_te => {
+                        debug!("multiple Transfer-Encoding not allowed");
+                        return Err(ParseError::Header);
+                    }
+
+                    header::TRANSFER_ENCODING if version == Version::HTTP_11 => {
+                        seen_te = true;
+
+                        if let Ok(val) = value.to_str().map(str::trim) {
+                            if val.eq_ignore_ascii_case("chunked") {
+                                chunked = true;
+                            } else if val.eq_ignore_ascii_case("identity") {
+                                // allow silently since multiple TE headers are already checked
+                            } else {
+                                debug!("illegal Transfer-Encoding: {:?}", val);
+                                return Err(ParseError::Header);
+                            }
+                        } else {
+                            return Err(ParseError::Header);
+                        }
+                    }
+
+                    // connection keep-alive state
+                    header::CONNECTION => {
+                        ka = if let Ok(conn) = value.to_str().map(str::trim) {
+                            if conn.eq_ignore_ascii_case("keep-alive") {
+                                Some(ConnectionType::KeepAlive)
+                            } else if conn.eq_ignore_ascii_case("close") {
+                                Some(ConnectionType::Close)
+                            } else if conn.eq_ignore_ascii_case("upgrade") {
+                                Some(ConnectionType::Upgrade)
+                            } else {
+                                None
+                            }
+                        } else {
+                            None
+                        };
+                    }
+
+                    header::UPGRADE => {
+                        if let Ok(val) = value.to_str().map(str::trim) {
+                            if val.eq_ignore_ascii_case("websocket") {
+                                has_upgrade_websocket = true;
+                            }
+                        }
+                    }
+
+                    header::EXPECT => {
+                        let bytes = value.as_bytes();
+                        if bytes.len() >= 4 && &bytes[0..4] == b"100-" {
+                            expect = true;
+                        }
+                    }
+
+                    _ => {}
+                }
+
+                headers.append(name, value);
+            }
+        }
+
+        self.set_connection_type(ka);
+
+        if expect {
+            self.set_expect()
+        }
+
+        // https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.3
+        if chunked {
+            // Chunked encoding
+            Ok(PayloadLength::Payload(PayloadType::Payload(
+                PayloadDecoder::chunked(),
+            )))
+        } else if has_upgrade_websocket {
+            Ok(PayloadLength::UpgradeWebSocket)
+        } else if let Some(len) = content_length {
+            // Content-Length
+            Ok(PayloadLength::Payload(PayloadType::Payload(
+                PayloadDecoder::length(len),
+            )))
+        } else {
+            Ok(PayloadLength::None)
+        }
+    }
+}
+
+impl MessageType for Request {
+    fn set_connection_type(&mut self, conn_type: Option<ConnectionType>) {
+        if let Some(ctype) = conn_type {
+            self.head_mut().set_connection_type(ctype);
+        }
+    }
+
+    fn set_expect(&mut self) {
+        self.head_mut().set_expect();
+    }
+
+    fn headers_mut(&mut self) -> &mut HeaderMap {
+        &mut self.head_mut().headers
+    }
+
+    fn decode(src: &mut BytesMut) -> Result<Option<(Self, PayloadType)>, ParseError> {
+        let mut headers: [HeaderIndex; MAX_HEADERS] = EMPTY_HEADER_INDEX_ARRAY;
+
+        let (len, method, uri, ver, h_len) = {
+            // SAFETY:
+            // Create an uninitialized array of `MaybeUninit`. The `assume_init` is safe because the
+            // type we are claiming to have initialized here is a bunch of `MaybeUninit`s, which
+            // do not require initialization.
+            let mut parsed = unsafe {
+                MaybeUninit::<[MaybeUninit<httparse::Header<'_>>; MAX_HEADERS]>::uninit()
+                    .assume_init()
+            };
+
+            let mut req = httparse::Request::new(&mut []);
+
+            match req.parse_with_uninit_headers(src, &mut parsed)? {
+                httparse::Status::Complete(len) => {
+                    let method = Method::from_bytes(req.method.unwrap().as_bytes())
+                        .map_err(|_| ParseError::Method)?;
+                    let uri = Uri::try_from(req.path.unwrap())?;
+                    let version = if req.version.unwrap() == 1 {
+                        Version::HTTP_11
+                    } else {
+                        Version::HTTP_10
+                    };
+                    HeaderIndex::record(src, req.headers, &mut headers);
+
+                    (len, method, uri, version, req.headers.len())
+                }
+
+                httparse::Status::Partial => {
+                    return if src.len() >= MAX_BUFFER_SIZE {
+                        trace!("MAX_BUFFER_SIZE unprocessed data reached, closing");
+                        Err(ParseError::TooLarge)
+                    } else {
+                        // Return None to notify more read are needed for parsing request
+                        Ok(None)
+                    };
+                }
+            }
+        };
+
+        let mut msg = Request::new();
+
+        // convert headers
+        let mut length = msg.set_headers(&src.split_to(len).freeze(), &headers[..h_len], ver)?;
+
+        // disallow HTTP/1.0 POST requests that do not contain a Content-Length headers
+        // see https://datatracker.ietf.org/doc/html/rfc1945#section-7.2.2
+        if ver == Version::HTTP_10 && method == Method::POST && length.is_none() {
+            debug!("no Content-Length specified for HTTP/1.0 POST request");
+            return Err(ParseError::Header);
+        }
+
+        // Remove CL value if 0 now that all headers and HTTP/1.0 special cases are processed.
+        // Protects against some request smuggling attacks.
+        // See https://github.com/actix/actix-web/issues/2767.
+        if length.is_zero() {
+            length = PayloadLength::None;
+        }
+
+        // payload decoder
+        let decoder = match length {
+            PayloadLength::Payload(pl) => pl,
+            PayloadLength::UpgradeWebSocket => {
+                // upgrade (WebSocket)
+                PayloadType::Stream(PayloadDecoder::eof())
+            }
+            PayloadLength::None => {
+                if method == Method::CONNECT {
+                    PayloadType::Stream(PayloadDecoder::eof())
+                } else {
+                    PayloadType::None
+                }
+            }
+        };
+
+        let head = msg.head_mut();
+        head.uri = uri;
+        head.method = method;
+        head.version = ver;
+
+        Ok(Some((msg, decoder)))
+    }
+}
+
+impl MessageType for ResponseHead {
+    fn set_connection_type(&mut self, conn_type: Option<ConnectionType>) {
+        if let Some(ctype) = conn_type {
+            ResponseHead::set_connection_type(self, ctype);
+        }
+    }
+
+    fn set_expect(&mut self) {}
+
+    fn headers_mut(&mut self) -> &mut HeaderMap {
+        &mut self.headers
+    }
+
+    fn decode(src: &mut BytesMut) -> Result<Option<(Self, PayloadType)>, ParseError> {
+        let mut headers: [HeaderIndex; MAX_HEADERS] = EMPTY_HEADER_INDEX_ARRAY;
+
+        let (len, ver, status, h_len) = {
+            // SAFETY:
+            // Create an uninitialized array of `MaybeUninit`. The `assume_init` is safe because the
+            // type we are claiming to have initialized here is a bunch of `MaybeUninit`s, which
+            // do not require initialization.
+            let mut parsed = unsafe {
+                MaybeUninit::<[MaybeUninit<httparse::Header<'_>>; MAX_HEADERS]>::uninit()
+                    .assume_init()
+            };
+
+            let mut res = httparse::Response::new(&mut []);
+
+            let mut config = httparse::ParserConfig::default();
+            config.allow_spaces_after_header_name_in_responses(true);
+
+            match config.parse_response_with_uninit_headers(&mut res, src, &mut parsed)? {
+                httparse::Status::Complete(len) => {
+                    let version = if res.version.unwrap() == 1 {
+                        Version::HTTP_11
+                    } else {
+                        Version::HTTP_10
+                    };
+
+                    let status =
+                        StatusCode::from_u16(res.code.unwrap()).map_err(|_| ParseError::Status)?;
+                    HeaderIndex::record(src, res.headers, &mut headers);
+
+                    (len, version, status, res.headers.len())
+                }
+
+                httparse::Status::Partial => {
+                    return if src.len() >= MAX_BUFFER_SIZE {
+                        error!("MAX_BUFFER_SIZE unprocessed data reached, closing");
+                        Err(ParseError::TooLarge)
+                    } else {
+                        Ok(None)
+                    }
+                }
+            }
+        };
+
+        let mut msg = ResponseHead::new(status);
+        msg.version = ver;
+
+        // convert headers
+        let mut length = msg.set_headers(&src.split_to(len).freeze(), &headers[..h_len], ver)?;
+
+        // Remove CL value if 0 now that all headers and HTTP/1.0 special cases are processed.
+        // Protects against some request smuggling attacks.
+        // See https://github.com/actix/actix-web/issues/2767.
+        if length.is_zero() {
+            length = PayloadLength::None;
+        }
+
+        // message payload
+        let decoder = if let PayloadLength::Payload(pl) = length {
+            pl
+        } else if status == StatusCode::SWITCHING_PROTOCOLS {
+            // switching protocol or connect
+            PayloadType::Stream(PayloadDecoder::eof())
+        } else {
+            // for HTTP/1.0 read to eof and close connection
+            if msg.version == Version::HTTP_10 {
+                msg.set_connection_type(ConnectionType::Close);
+                PayloadType::Payload(PayloadDecoder::eof())
+            } else {
+                PayloadType::None
+            }
+        };
+
+        Ok(Some((msg, decoder)))
+    }
+}
+
+#[derive(Clone, Copy)]
+pub(crate) struct HeaderIndex {
+    pub(crate) name: (usize, usize),
+    pub(crate) value: (usize, usize),
+}
+
+pub(crate) const EMPTY_HEADER_INDEX: HeaderIndex = HeaderIndex {
+    name: (0, 0),
+    value: (0, 0),
+};
+
+pub(crate) const EMPTY_HEADER_INDEX_ARRAY: [HeaderIndex; MAX_HEADERS] =
+    [EMPTY_HEADER_INDEX; MAX_HEADERS];
+
+impl HeaderIndex {
+    pub(crate) fn record(
+        bytes: &[u8],
+        headers: &[httparse::Header<'_>],
+        indices: &mut [HeaderIndex],
+    ) {
+        let bytes_ptr = bytes.as_ptr() as usize;
+        for (header, indices) in headers.iter().zip(indices.iter_mut()) {
+            let name_start = header.name.as_ptr() as usize - bytes_ptr;
+            let name_end = name_start + header.name.len();
+            indices.name = (name_start, name_end);
+            let value_start = header.value.as_ptr() as usize - bytes_ptr;
+            let value_end = value_start + header.value.len();
+            indices.value = (value_start, value_end);
+        }
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+/// Chunk type yielded while decoding a payload.
+pub enum PayloadItem {
+    Chunk(Bytes),
+    Eof,
+}
+
+/// Decoder that can handle different payload types.
+///
+/// If a message body does not use `Transfer-Encoding`, it should include a `Content-Length`.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct PayloadDecoder {
+    kind: Kind,
+}
+
+impl PayloadDecoder {
+    /// Constructs a fixed-length payload decoder.
+    pub fn length(x: u64) -> PayloadDecoder {
+        PayloadDecoder {
+            kind: Kind::Length(x),
+        }
+    }
+
+    /// Constructs a chunked encoding decoder.
+    pub fn chunked() -> PayloadDecoder {
+        PayloadDecoder {
+            kind: Kind::Chunked(ChunkedState::Size, 0),
+        }
+    }
+
+    /// Creates an decoder that yields chunks until the stream returns EOF.
+    pub fn eof() -> PayloadDecoder {
+        PayloadDecoder { kind: Kind::Eof }
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+enum Kind {
+    /// A reader used when a `Content-Length` header is passed with a positive integer.
+    Length(u64),
+
+    /// A reader used when `Transfer-Encoding` is `chunked`.
+    Chunked(ChunkedState, u64),
+
+    /// A reader used for responses that don't indicate a length or chunked.
+    ///
+    /// Note: This should only used for `Response`s. It is illegal for a `Request` to be made
+    /// without either of `Content-Length` and `Transfer-Encoding: chunked` missing, as explained
+    /// in [RFC 7230 §3.3.3]:
+    ///
+    /// > If a Transfer-Encoding header field is present in a response and the chunked transfer
+    /// > coding is not the final encoding, the message body length is determined by reading the
+    /// > connection until it is closed by the server. If a Transfer-Encoding header field is
+    /// > present in a request and the chunked transfer coding is not the final encoding, the
+    /// > message body length cannot be determined reliably; the server MUST respond with the 400
+    /// > (Bad Request) status code and then close the connection.
+    ///
+    /// [RFC 7230 §3.3.3]: https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.3
+    Eof,
+}
+
+impl Decoder for PayloadDecoder {
+    type Item = PayloadItem;
+    type Error = io::Error;
+
+    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
+        match self.kind {
+            Kind::Length(ref mut remaining) => {
+                if *remaining == 0 {
+                    Ok(Some(PayloadItem::Eof))
+                } else {
+                    if src.is_empty() {
+                        return Ok(None);
+                    }
+                    let len = src.len() as u64;
+                    let buf;
+                    if *remaining > len {
+                        buf = src.split().freeze();
+                        *remaining -= len;
+                    } else {
+                        buf = src.split_to(*remaining as usize).freeze();
+                        *remaining = 0;
+                    };
+                    trace!("Length read: {}", buf.len());
+                    Ok(Some(PayloadItem::Chunk(buf)))
+                }
+            }
+
+            Kind::Chunked(ref mut state, ref mut size) => {
+                loop {
+                    let mut buf = None;
+
+                    // advances the chunked state
+                    *state = match state.step(src, size, &mut buf) {
+                        Poll::Pending => return Ok(None),
+                        Poll::Ready(Ok(state)) => state,
+                        Poll::Ready(Err(err)) => return Err(err),
+                    };
+
+                    if *state == ChunkedState::End {
+                        trace!("End of chunked stream");
+                        return Ok(Some(PayloadItem::Eof));
+                    }
+
+                    if let Some(buf) = buf {
+                        return Ok(Some(PayloadItem::Chunk(buf)));
+                    }
+
+                    if src.is_empty() {
+                        return Ok(None);
+                    }
+                }
+            }
+
+            Kind::Eof => {
+                if src.is_empty() {
+                    Ok(None)
+                } else {
+                    Ok(Some(PayloadItem::Chunk(src.split().freeze())))
+                }
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::{header::SET_COOKIE, HttpMessage as _};
+
+    impl PayloadType {
+        pub(crate) fn unwrap(self) -> PayloadDecoder {
+            match self {
+                PayloadType::Payload(pl) => pl,
+                _ => panic!(),
+            }
+        }
+
+        pub(crate) fn is_unhandled(&self) -> bool {
+            matches!(self, PayloadType::Stream(_))
+        }
+    }
+
+    impl PayloadItem {
+        pub(crate) fn chunk(self) -> Bytes {
+            match self {
+                PayloadItem::Chunk(chunk) => chunk,
+                _ => panic!("error"),
+            }
+        }
+
+        pub(crate) fn eof(&self) -> bool {
+            matches!(*self, PayloadItem::Eof)
+        }
+    }
+
+    macro_rules! parse_ready {
+        ($e:expr) => {{
+            match MessageDecoder::<Request>::default().decode($e) {
+                Ok(Some((msg, _))) => msg,
+                Ok(_) => unreachable!("Eof during parsing http request"),
+                Err(err) => unreachable!("Error during parsing http request: {:?}", err),
+            }
+        }};
+    }
+
+    macro_rules! expect_parse_err {
+        ($e:expr) => {{
+            match MessageDecoder::<Request>::default().decode($e) {
+                Err(err) => match err {
+                    ParseError::Io(_) => unreachable!("Parse error expected"),
+                    _ => {}
+                },
+                _ => unreachable!("Error expected"),
+            }
+        }};
+    }
+
+    #[test]
+    fn test_parse() {
+        let mut buf = BytesMut::from("GET /test HTTP/1.1\r\n\r\n");
+
+        let mut reader = MessageDecoder::<Request>::default();
+        match reader.decode(&mut buf) {
+            Ok(Some((req, _))) => {
+                assert_eq!(req.version(), Version::HTTP_11);
+                assert_eq!(*req.method(), Method::GET);
+                assert_eq!(req.path(), "/test");
+            }
+            Ok(_) | Err(_) => unreachable!("Error during parsing http request"),
+        }
+    }
+
+    #[test]
+    fn test_parse_partial() {
+        let mut buf = BytesMut::from("PUT /test HTTP/1");
+
+        let mut reader = MessageDecoder::<Request>::default();
+        assert!(reader.decode(&mut buf).unwrap().is_none());
+
+        buf.extend(b".1\r\n\r\n");
+        let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(req.version(), Version::HTTP_11);
+        assert_eq!(*req.method(), Method::PUT);
+        assert_eq!(req.path(), "/test");
+    }
+
+    #[test]
+    fn parse_h09_reject() {
+        let mut buf = BytesMut::from(
+            "GET /test1 HTTP/0.9\r\n\
+            \r\n",
+        );
+
+        let mut reader = MessageDecoder::<Request>::default();
+        reader.decode(&mut buf).unwrap_err();
+
+        let mut buf = BytesMut::from(
+            "POST /test2 HTTP/0.9\r\n\
+            Content-Length: 3\r\n\
+            \r\n
+            abc",
+        );
+
+        let mut reader = MessageDecoder::<Request>::default();
+        reader.decode(&mut buf).unwrap_err();
+    }
+
+    #[test]
+    fn parse_h10_get() {
+        let mut buf = BytesMut::from(
+            "GET /test1 HTTP/1.0\r\n\
+            \r\n",
+        );
+
+        let mut reader = MessageDecoder::<Request>::default();
+        let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(req.version(), Version::HTTP_10);
+        assert_eq!(*req.method(), Method::GET);
+        assert_eq!(req.path(), "/test1");
+
+        let mut buf = BytesMut::from(
+            "GET /test2 HTTP/1.0\r\n\
+            Content-Length: 0\r\n\
+            \r\n",
+        );
+
+        let mut reader = MessageDecoder::<Request>::default();
+        let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(req.version(), Version::HTTP_10);
+        assert_eq!(*req.method(), Method::GET);
+        assert_eq!(req.path(), "/test2");
+
+        let mut buf = BytesMut::from(
+            "GET /test3 HTTP/1.0\r\n\
+            Content-Length: 3\r\n\
+            \r\n
+            abc",
+        );
+
+        let mut reader = MessageDecoder::<Request>::default();
+        let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(req.version(), Version::HTTP_10);
+        assert_eq!(*req.method(), Method::GET);
+        assert_eq!(req.path(), "/test3");
+    }
+
+    #[test]
+    fn parse_h10_post() {
+        let mut buf = BytesMut::from(
+            "POST /test1 HTTP/1.0\r\n\
+            Content-Length: 3\r\n\
+            \r\n\
+            abc",
+        );
+
+        let mut reader = MessageDecoder::<Request>::default();
+        let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(req.version(), Version::HTTP_10);
+        assert_eq!(*req.method(), Method::POST);
+        assert_eq!(req.path(), "/test1");
+
+        let mut buf = BytesMut::from(
+            "POST /test2 HTTP/1.0\r\n\
+            Content-Length: 0\r\n\
+            \r\n",
+        );
+
+        let mut reader = MessageDecoder::<Request>::default();
+        let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(req.version(), Version::HTTP_10);
+        assert_eq!(*req.method(), Method::POST);
+        assert_eq!(req.path(), "/test2");
+
+        let mut buf = BytesMut::from(
+            "POST /test3 HTTP/1.0\r\n\
+            \r\n",
+        );
+
+        let mut reader = MessageDecoder::<Request>::default();
+        let err = reader.decode(&mut buf).unwrap_err();
+        assert!(err.to_string().contains("Header"))
+    }
+
+    #[test]
+    fn test_parse_body() {
+        let mut buf = BytesMut::from("GET /test HTTP/1.1\r\nContent-Length: 4\r\n\r\nbody");
+
+        let mut reader = MessageDecoder::<Request>::default();
+        let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
+        let mut pl = pl.unwrap();
+        assert_eq!(req.version(), Version::HTTP_11);
+        assert_eq!(*req.method(), Method::GET);
+        assert_eq!(req.path(), "/test");
+        assert_eq!(
+            pl.decode(&mut buf).unwrap().unwrap().chunk().as_ref(),
+            b"body"
+        );
+    }
+
+    #[test]
+    fn test_parse_body_crlf() {
+        let mut buf = BytesMut::from("\r\nGET /test HTTP/1.1\r\nContent-Length: 4\r\n\r\nbody");
+
+        let mut reader = MessageDecoder::<Request>::default();
+        let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
+        let mut pl = pl.unwrap();
+        assert_eq!(req.version(), Version::HTTP_11);
+        assert_eq!(*req.method(), Method::GET);
+        assert_eq!(req.path(), "/test");
+        assert_eq!(
+            pl.decode(&mut buf).unwrap().unwrap().chunk().as_ref(),
+            b"body"
+        );
+    }
+
+    #[test]
+    fn test_parse_partial_eof() {
+        let mut buf = BytesMut::from("GET /test HTTP/1.1\r\n");
+        let mut reader = MessageDecoder::<Request>::default();
+        assert!(reader.decode(&mut buf).unwrap().is_none());
+
+        buf.extend(b"\r\n");
+        let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(req.version(), Version::HTTP_11);
+        assert_eq!(*req.method(), Method::GET);
+        assert_eq!(req.path(), "/test");
+    }
+
+    #[test]
+    fn test_headers_split_field() {
+        let mut buf = BytesMut::from("GET /test HTTP/1.1\r\n");
+
+        let mut reader = MessageDecoder::<Request>::default();
+        assert! { reader.decode(&mut buf).unwrap().is_none() }
+
+        buf.extend(b"t");
+        assert! { reader.decode(&mut buf).unwrap().is_none() }
+
+        buf.extend(b"es");
+        assert! { reader.decode(&mut buf).unwrap().is_none() }
+
+        buf.extend(b"t: value\r\n\r\n");
+        let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(req.version(), Version::HTTP_11);
+        assert_eq!(*req.method(), Method::GET);
+        assert_eq!(req.path(), "/test");
+        assert_eq!(
+            req.headers()
+                .get(HeaderName::try_from("test").unwrap())
+                .unwrap()
+                .as_bytes(),
+            b"value"
+        );
+    }
+
+    #[test]
+    fn test_headers_multi_value() {
+        let mut buf = BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             Set-Cookie: c1=cookie1\r\n\
+             Set-Cookie: c2=cookie2\r\n\r\n",
+        );
+        let mut reader = MessageDecoder::<Request>::default();
+        let (req, _) = reader.decode(&mut buf).unwrap().unwrap();
+
+        let val: Vec<_> = req
+            .headers()
+            .get_all(SET_COOKIE)
+            .map(|v| v.to_str().unwrap().to_owned())
+            .collect();
+        assert_eq!(val[0], "c1=cookie1");
+        assert_eq!(val[1], "c2=cookie2");
+    }
+
+    #[test]
+    fn test_conn_default_1_0() {
+        let req = parse_ready!(&mut BytesMut::from("GET /test HTTP/1.0\r\n\r\n"));
+        assert_eq!(req.head().connection_type(), ConnectionType::Close);
+    }
+
+    #[test]
+    fn test_conn_default_1_1() {
+        let req = parse_ready!(&mut BytesMut::from("GET /test HTTP/1.1\r\n\r\n"));
+        assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
+    }
+
+    #[test]
+    fn test_conn_close() {
+        let req = parse_ready!(&mut BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             connection: close\r\n\r\n",
+        ));
+        assert_eq!(req.head().connection_type(), ConnectionType::Close);
+
+        let req = parse_ready!(&mut BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             connection: Close\r\n\r\n",
+        ));
+        assert_eq!(req.head().connection_type(), ConnectionType::Close);
+    }
+
+    #[test]
+    fn test_conn_close_1_0() {
+        let req = parse_ready!(&mut BytesMut::from(
+            "GET /test HTTP/1.0\r\n\
+             connection: close\r\n\r\n",
+        ));
+        assert_eq!(req.head().connection_type(), ConnectionType::Close);
+    }
+
+    #[test]
+    fn test_conn_keep_alive_1_0() {
+        let req = parse_ready!(&mut BytesMut::from(
+            "GET /test HTTP/1.0\r\n\
+             connection: keep-alive\r\n\r\n",
+        ));
+        assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
+
+        let req = parse_ready!(&mut BytesMut::from(
+            "GET /test HTTP/1.0\r\n\
+             connection: Keep-Alive\r\n\r\n",
+        ));
+        assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
+    }
+
+    #[test]
+    fn test_conn_keep_alive_1_1() {
+        let req = parse_ready!(&mut BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             connection: keep-alive\r\n\r\n",
+        ));
+        assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
+    }
+
+    #[test]
+    fn test_conn_other_1_0() {
+        let req = parse_ready!(&mut BytesMut::from(
+            "GET /test HTTP/1.0\r\n\
+             connection: other\r\n\r\n",
+        ));
+        assert_eq!(req.head().connection_type(), ConnectionType::Close);
+    }
+
+    #[test]
+    fn test_conn_other_1_1() {
+        let req = parse_ready!(&mut BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             connection: other\r\n\r\n",
+        ));
+        assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
+    }
+
+    #[test]
+    fn test_conn_upgrade() {
+        let req = parse_ready!(&mut BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             upgrade: websockets\r\n\
+             connection: upgrade\r\n\r\n",
+        ));
+
+        assert!(req.upgrade());
+        assert_eq!(req.head().connection_type(), ConnectionType::Upgrade);
+
+        let req = parse_ready!(&mut BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             upgrade: Websockets\r\n\
+             connection: Upgrade\r\n\r\n",
+        ));
+
+        assert!(req.upgrade());
+        assert_eq!(req.head().connection_type(), ConnectionType::Upgrade);
+    }
+
+    #[test]
+    fn test_conn_upgrade_connect_method() {
+        let req = parse_ready!(&mut BytesMut::from(
+            "CONNECT /test HTTP/1.1\r\n\
+             content-type: text/plain\r\n\r\n",
+        ));
+
+        assert!(req.upgrade());
+    }
+
+    #[test]
+    fn test_headers_bad_content_length() {
+        // string CL
+        expect_parse_err!(&mut BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             content-length: line\r\n\r\n",
+        ));
+
+        // negative CL
+        expect_parse_err!(&mut BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             content-length: -1\r\n\r\n",
+        ));
+    }
+
+    #[test]
+    fn octal_ish_cl_parsed_as_decimal() {
+        let mut buf = BytesMut::from(
+            "POST /test HTTP/1.1\r\n\
+             content-length: 011\r\n\r\n",
+        );
+        let mut reader = MessageDecoder::<Request>::default();
+        let (_req, pl) = reader.decode(&mut buf).unwrap().unwrap();
+        assert!(matches!(
+            pl,
+            PayloadType::Payload(pl) if pl == PayloadDecoder::length(11)
+        ));
+    }
+
+    #[test]
+    fn test_invalid_header() {
+        expect_parse_err!(&mut BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             test line\r\n\r\n",
+        ));
+    }
+
+    #[test]
+    fn test_invalid_name() {
+        expect_parse_err!(&mut BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             test[]: line\r\n\r\n",
+        ));
+    }
+
+    #[test]
+    fn test_http_request_bad_status_line() {
+        expect_parse_err!(&mut BytesMut::from("getpath \r\n\r\n"));
+    }
+
+    #[test]
+    fn test_http_request_upgrade_websocket() {
+        let mut buf = BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             connection: upgrade\r\n\
+             upgrade: websocket\r\n\r\n\
+             some raw data",
+        );
+        let mut reader = MessageDecoder::<Request>::default();
+        let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(req.head().connection_type(), ConnectionType::Upgrade);
+        assert!(req.upgrade());
+        assert!(pl.is_unhandled());
+    }
+
+    #[test]
+    fn test_http_request_upgrade_h2c() {
+        let mut buf = BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             connection: upgrade, http2-settings\r\n\
+             upgrade: h2c\r\n\
+             http2-settings: dummy\r\n\r\n",
+        );
+        let mut reader = MessageDecoder::<Request>::default();
+        let (req, pl) = reader.decode(&mut buf).unwrap().unwrap();
+        // `connection: upgrade, http2-settings` doesn't work properly..
+        // see MessageType::set_headers().
+        //
+        // The line below should be:
+        // assert_eq!(req.head().connection_type(), ConnectionType::Upgrade);
+        assert_eq!(req.head().connection_type(), ConnectionType::KeepAlive);
+        assert!(req.upgrade());
+        assert!(!pl.is_unhandled());
+    }
+
+    #[test]
+    fn test_http_request_parser_utf8() {
+        let req = parse_ready!(&mut BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+             x-test: тест\r\n\r\n",
+        ));
+
+        assert_eq!(
+            req.headers().get("x-test").unwrap().as_bytes(),
+            "тест".as_bytes()
+        );
+    }
+
+    #[test]
+    fn test_http_request_parser_two_slashes() {
+        let req = parse_ready!(&mut BytesMut::from("GET //path HTTP/1.1\r\n\r\n"));
+        assert_eq!(req.path(), "//path");
+    }
+
+    #[test]
+    fn test_http_request_parser_bad_method() {
+        expect_parse_err!(&mut BytesMut::from("!12%()+=~$ /get HTTP/1.1\r\n\r\n"));
+    }
+
+    #[test]
+    fn test_http_request_parser_bad_version() {
+        expect_parse_err!(&mut BytesMut::from("GET //get HT/11\r\n\r\n"));
+    }
+
+    #[test]
+    fn test_response_http10_read_until_eof() {
+        let mut buf = BytesMut::from("HTTP/1.0 200 Ok\r\n\r\ntest data");
+
+        let mut reader = MessageDecoder::<ResponseHead>::default();
+        let (_msg, pl) = reader.decode(&mut buf).unwrap().unwrap();
+        let mut pl = pl.unwrap();
+
+        let chunk = pl.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(chunk, PayloadItem::Chunk(Bytes::from_static(b"test data")));
+    }
+
+    #[test]
+    fn hrs_multiple_content_length() {
+        expect_parse_err!(&mut BytesMut::from(
+            "GET / HTTP/1.1\r\n\
+            Host: example.com\r\n\
+            Content-Length: 4\r\n\
+            Content-Length: 2\r\n\
+            \r\n\
+            abcd",
+        ));
+
+        expect_parse_err!(&mut BytesMut::from(
+            "GET / HTTP/1.1\r\n\
+            Host: example.com\r\n\
+            Content-Length: 0\r\n\
+            Content-Length: 2\r\n\
+            \r\n\
+            ab",
+        ));
+    }
+
+    #[test]
+    fn hrs_content_length_plus() {
+        expect_parse_err!(&mut BytesMut::from(
+            "GET / HTTP/1.1\r\n\
+            Host: example.com\r\n\
+            Content-Length: +3\r\n\
+            \r\n\
+            000",
+        ));
+    }
+
+    #[test]
+    fn hrs_te_http10() {
+        // in HTTP/1.0 transfer encoding is ignored and must therefore contain a CL header
+
+        expect_parse_err!(&mut BytesMut::from(
+            "POST / HTTP/1.0\r\n\
+            Host: example.com\r\n\
+            Transfer-Encoding: chunked\r\n\
+            \r\n\
+            3\r\n\
+            aaa\r\n\
+            0\r\n\
+            ",
+        ));
+    }
+
+    #[test]
+    fn hrs_cl_and_te_http10() {
+        // in HTTP/1.0 transfer encoding is simply ignored so it's fine to have both
+
+        let mut buf = BytesMut::from(
+            "GET / HTTP/1.0\r\n\
+            Host: example.com\r\n\
+            Content-Length: 3\r\n\
+            Transfer-Encoding: chunked\r\n\
+            \r\n\
+            000",
+        );
+
+        parse_ready!(&mut buf);
+    }
+
+    #[test]
+    fn hrs_unknown_transfer_encoding() {
+        let mut buf = BytesMut::from(
+            "GET / HTTP/1.1\r\n\
+            Host: example.com\r\n\
+            Transfer-Encoding: JUNK\r\n\
+            Transfer-Encoding: chunked\r\n\
+            \r\n\
+            5\r\n\
+            hello\r\n\
+            0",
+        );
+
+        expect_parse_err!(&mut buf);
+    }
+
+    #[test]
+    fn hrs_multiple_transfer_encoding() {
+        let mut buf = BytesMut::from(
+            "GET / HTTP/1.1\r\n\
+            Host: example.com\r\n\
+            Content-Length: 51\r\n\
+            Transfer-Encoding: identity\r\n\
+            Transfer-Encoding: chunked\r\n\
+            \r\n\
+            0\r\n\
+            \r\n\
+            GET /forbidden HTTP/1.1\r\n\
+            Host: example.com\r\n\r\n",
+        );
+
+        expect_parse_err!(&mut buf);
+    }
+
+    #[test]
+    fn transfer_encoding_agrees() {
+        let mut buf = BytesMut::from(
+            "GET /test HTTP/1.1\r\n\
+            Host: example.com\r\n\
+            Content-Length: 3\r\n\
+            Transfer-Encoding: identity\r\n\
+            \r\n\
+            0\r\n",
+        );
+
+        let mut reader = MessageDecoder::<Request>::default();
+        let (_msg, pl) = reader.decode(&mut buf).unwrap().unwrap();
+        let mut pl = pl.unwrap();
+
+        let chunk = pl.decode(&mut buf).unwrap().unwrap();
+        assert_eq!(chunk, PayloadItem::Chunk(Bytes::from_static(b"0\r\n")));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/h1/dispatcher.rs.html b/src/actix_http/h1/dispatcher.rs.html new file mode 100644 index 000000000..76c418a5e --- /dev/null +++ b/src/actix_http/h1/dispatcher.rs.html @@ -0,0 +1,2501 @@ +dispatcher.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
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+
use std::{
+    collections::VecDeque,
+    fmt,
+    future::Future,
+    io, mem, net,
+    pin::Pin,
+    rc::Rc,
+    task::{Context, Poll},
+};
+
+use actix_codec::{Framed, FramedParts};
+use actix_rt::time::sleep_until;
+use actix_service::Service;
+use bitflags::bitflags;
+use bytes::{Buf, BytesMut};
+use futures_core::ready;
+use pin_project_lite::pin_project;
+use tokio::io::{AsyncRead, AsyncWrite};
+use tokio_util::codec::{Decoder as _, Encoder as _};
+use tracing::{error, trace};
+
+use super::{
+    codec::Codec,
+    decoder::MAX_BUFFER_SIZE,
+    payload::{Payload, PayloadSender, PayloadStatus},
+    timer::TimerState,
+    Message, MessageType,
+};
+use crate::{
+    body::{BodySize, BoxBody, MessageBody},
+    config::ServiceConfig,
+    error::{DispatchError, ParseError, PayloadError},
+    service::HttpFlow,
+    Error, Extensions, OnConnectData, Request, Response, StatusCode,
+};
+
+const LW_BUFFER_SIZE: usize = 1024;
+const HW_BUFFER_SIZE: usize = 1024 * 8;
+const MAX_PIPELINED_MESSAGES: usize = 16;
+
+bitflags! {
+    #[derive(Debug, Clone, Copy)]
+    pub struct Flags: u8 {
+        /// Set when stream is read for first time.
+        const STARTED          = 0b0000_0001;
+
+        /// Set when full request-response cycle has occurred.
+        const FINISHED         = 0b0000_0010;
+
+        /// Set if connection is in keep-alive (inactive) state.
+        const KEEP_ALIVE       = 0b0000_0100;
+
+        /// Set if in shutdown procedure.
+        const SHUTDOWN         = 0b0000_1000;
+
+        /// Set if read-half is disconnected.
+        const READ_DISCONNECT  = 0b0001_0000;
+
+        /// Set if write-half is disconnected.
+        const WRITE_DISCONNECT = 0b0010_0000;
+    }
+}
+
+// there's 2 versions of Dispatcher state because of:
+// https://github.com/taiki-e/pin-project-lite/issues/3
+//
+// tl;dr: pin-project-lite doesn't play well with other attribute macros
+
+#[cfg(not(test))]
+pin_project! {
+    /// Dispatcher for HTTP/1.1 protocol
+    pub struct Dispatcher<T, S, B, X, U>
+    where
+        S: Service<Request>,
+        S::Error: Into<Response<BoxBody>>,
+
+        B: MessageBody,
+
+        X: Service<Request, Response = Request>,
+        X::Error: Into<Response<BoxBody>>,
+
+        U: Service<(Request, Framed<T, Codec>), Response = ()>,
+        U::Error: fmt::Display,
+    {
+        #[pin]
+        inner: DispatcherState<T, S, B, X, U>,
+    }
+}
+
+#[cfg(test)]
+pin_project! {
+    /// Dispatcher for HTTP/1.1 protocol
+    pub struct Dispatcher<T, S, B, X, U>
+    where
+        S: Service<Request>,
+        S::Error: Into<Response<BoxBody>>,
+
+        B: MessageBody,
+
+        X: Service<Request, Response = Request>,
+        X::Error: Into<Response<BoxBody>>,
+
+        U: Service<(Request, Framed<T, Codec>), Response = ()>,
+        U::Error: fmt::Display,
+    {
+        #[pin]
+        pub(super) inner: DispatcherState<T, S, B, X, U>,
+
+        // used in tests
+        pub(super) poll_count: u64,
+    }
+}
+
+pin_project! {
+    #[project = DispatcherStateProj]
+    pub(super) enum DispatcherState<T, S, B, X, U>
+    where
+        S: Service<Request>,
+        S::Error: Into<Response<BoxBody>>,
+
+        B: MessageBody,
+
+        X: Service<Request, Response = Request>,
+        X::Error: Into<Response<BoxBody>>,
+
+        U: Service<(Request, Framed<T, Codec>), Response = ()>,
+        U::Error: fmt::Display,
+    {
+        Normal { #[pin] inner: InnerDispatcher<T, S, B, X, U> },
+        Upgrade { #[pin] fut: U::Future },
+    }
+}
+
+pin_project! {
+    #[project = InnerDispatcherProj]
+    pub(super) struct InnerDispatcher<T, S, B, X, U>
+    where
+        S: Service<Request>,
+        S::Error: Into<Response<BoxBody>>,
+
+        B: MessageBody,
+
+        X: Service<Request, Response = Request>,
+        X::Error: Into<Response<BoxBody>>,
+
+        U: Service<(Request, Framed<T, Codec>), Response = ()>,
+        U::Error: fmt::Display,
+    {
+        flow: Rc<HttpFlow<S, X, U>>,
+        pub(super) flags: Flags,
+        peer_addr: Option<net::SocketAddr>,
+        conn_data: Option<Rc<Extensions>>,
+        config: ServiceConfig,
+        error: Option<DispatchError>,
+
+        #[pin]
+        pub(super) state: State<S, B, X>,
+        // when Some(_) dispatcher is in state of receiving request payload
+        payload: Option<PayloadSender>,
+        messages: VecDeque<DispatcherMessage>,
+
+        head_timer: TimerState,
+        ka_timer: TimerState,
+        shutdown_timer: TimerState,
+
+        pub(super) io: Option<T>,
+        read_buf: BytesMut,
+        write_buf: BytesMut,
+        codec: Codec,
+    }
+}
+
+enum DispatcherMessage {
+    Item(Request),
+    Upgrade(Request),
+    Error(Response<()>),
+}
+
+pin_project! {
+    #[project = StateProj]
+    pub(super) enum State<S, B, X>
+    where
+        S: Service<Request>,
+        X: Service<Request, Response = Request>,
+        B: MessageBody,
+    {
+        None,
+        ExpectCall { #[pin] fut: X::Future },
+        ServiceCall { #[pin] fut: S::Future },
+        SendPayload { #[pin] body: B },
+        SendErrorPayload { #[pin] body: BoxBody },
+    }
+}
+
+impl<S, B, X> State<S, B, X>
+where
+    S: Service<Request>,
+    X: Service<Request, Response = Request>,
+    B: MessageBody,
+{
+    pub(super) fn is_none(&self) -> bool {
+        matches!(self, State::None)
+    }
+}
+
+impl<S, B, X> fmt::Debug for State<S, B, X>
+where
+    S: Service<Request>,
+    X: Service<Request, Response = Request>,
+    B: MessageBody,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Self::None => write!(f, "State::None"),
+            Self::ExpectCall { .. } => f.debug_struct("State::ExpectCall").finish_non_exhaustive(),
+            Self::ServiceCall { .. } => {
+                f.debug_struct("State::ServiceCall").finish_non_exhaustive()
+            }
+            Self::SendPayload { .. } => {
+                f.debug_struct("State::SendPayload").finish_non_exhaustive()
+            }
+            Self::SendErrorPayload { .. } => f
+                .debug_struct("State::SendErrorPayload")
+                .finish_non_exhaustive(),
+        }
+    }
+}
+
+#[derive(Debug)]
+enum PollResponse {
+    Upgrade(Request),
+    DoNothing,
+    DrainWriteBuf,
+}
+
+impl<T, S, B, X, U> Dispatcher<T, S, B, X, U>
+where
+    T: AsyncRead + AsyncWrite + Unpin,
+
+    S: Service<Request>,
+    S::Error: Into<Response<BoxBody>>,
+    S::Response: Into<Response<B>>,
+
+    B: MessageBody,
+
+    X: Service<Request, Response = Request>,
+    X::Error: Into<Response<BoxBody>>,
+
+    U: Service<(Request, Framed<T, Codec>), Response = ()>,
+    U::Error: fmt::Display,
+{
+    /// Create HTTP/1 dispatcher.
+    pub(crate) fn new(
+        io: T,
+        flow: Rc<HttpFlow<S, X, U>>,
+        config: ServiceConfig,
+        peer_addr: Option<net::SocketAddr>,
+        conn_data: OnConnectData,
+    ) -> Self {
+        Dispatcher {
+            inner: DispatcherState::Normal {
+                inner: InnerDispatcher {
+                    flow,
+                    flags: Flags::empty(),
+                    peer_addr,
+                    conn_data: conn_data.0.map(Rc::new),
+                    config: config.clone(),
+                    error: None,
+
+                    state: State::None,
+                    payload: None,
+                    messages: VecDeque::new(),
+
+                    head_timer: TimerState::new(config.client_request_deadline().is_some()),
+                    ka_timer: TimerState::new(config.keep_alive().enabled()),
+                    shutdown_timer: TimerState::new(config.client_disconnect_deadline().is_some()),
+
+                    io: Some(io),
+                    read_buf: BytesMut::with_capacity(HW_BUFFER_SIZE),
+                    write_buf: BytesMut::with_capacity(HW_BUFFER_SIZE),
+                    codec: Codec::new(config),
+                },
+            },
+
+            #[cfg(test)]
+            poll_count: 0,
+        }
+    }
+}
+
+impl<T, S, B, X, U> InnerDispatcher<T, S, B, X, U>
+where
+    T: AsyncRead + AsyncWrite + Unpin,
+
+    S: Service<Request>,
+    S::Error: Into<Response<BoxBody>>,
+    S::Response: Into<Response<B>>,
+
+    B: MessageBody,
+
+    X: Service<Request, Response = Request>,
+    X::Error: Into<Response<BoxBody>>,
+
+    U: Service<(Request, Framed<T, Codec>), Response = ()>,
+    U::Error: fmt::Display,
+{
+    fn can_read(&self, cx: &mut Context<'_>) -> bool {
+        if self.flags.contains(Flags::READ_DISCONNECT) {
+            false
+        } else if let Some(ref info) = self.payload {
+            info.need_read(cx) == PayloadStatus::Read
+        } else {
+            true
+        }
+    }
+
+    fn client_disconnected(self: Pin<&mut Self>) {
+        let this = self.project();
+
+        this.flags
+            .insert(Flags::READ_DISCONNECT | Flags::WRITE_DISCONNECT);
+
+        if let Some(mut payload) = this.payload.take() {
+            payload.set_error(PayloadError::Incomplete(None));
+        }
+    }
+
+    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
+        let InnerDispatcherProj { io, write_buf, .. } = self.project();
+        let mut io = Pin::new(io.as_mut().unwrap());
+
+        let len = write_buf.len();
+        let mut written = 0;
+
+        while written < len {
+            match io.as_mut().poll_write(cx, &write_buf[written..])? {
+                Poll::Ready(0) => {
+                    error!("write zero; closing");
+                    return Poll::Ready(Err(io::Error::new(io::ErrorKind::WriteZero, "")));
+                }
+
+                Poll::Ready(n) => written += n,
+
+                Poll::Pending => {
+                    write_buf.advance(written);
+                    return Poll::Pending;
+                }
+            }
+        }
+
+        // everything has written to I/O; clear buffer
+        write_buf.clear();
+
+        // flush the I/O and check if get blocked
+        io.poll_flush(cx)
+    }
+
+    fn send_response_inner(
+        self: Pin<&mut Self>,
+        res: Response<()>,
+        body: &impl MessageBody,
+    ) -> Result<BodySize, DispatchError> {
+        let this = self.project();
+
+        let size = body.size();
+
+        this.codec
+            .encode(Message::Item((res, size)), this.write_buf)
+            .map_err(|err| {
+                if let Some(mut payload) = this.payload.take() {
+                    payload.set_error(PayloadError::Incomplete(None));
+                }
+
+                DispatchError::Io(err)
+            })?;
+
+        Ok(size)
+    }
+
+    fn send_response(
+        mut self: Pin<&mut Self>,
+        res: Response<()>,
+        body: B,
+    ) -> Result<(), DispatchError> {
+        let size = self.as_mut().send_response_inner(res, &body)?;
+        let mut this = self.project();
+        this.state.set(match size {
+            BodySize::None | BodySize::Sized(0) => {
+                this.flags.insert(Flags::FINISHED);
+                State::None
+            }
+            _ => State::SendPayload { body },
+        });
+
+        Ok(())
+    }
+
+    fn send_error_response(
+        mut self: Pin<&mut Self>,
+        res: Response<()>,
+        body: BoxBody,
+    ) -> Result<(), DispatchError> {
+        let size = self.as_mut().send_response_inner(res, &body)?;
+        let mut this = self.project();
+        this.state.set(match size {
+            BodySize::None | BodySize::Sized(0) => {
+                this.flags.insert(Flags::FINISHED);
+                State::None
+            }
+            _ => State::SendErrorPayload { body },
+        });
+
+        Ok(())
+    }
+
+    fn send_continue(self: Pin<&mut Self>) {
+        self.project()
+            .write_buf
+            .extend_from_slice(b"HTTP/1.1 100 Continue\r\n\r\n");
+    }
+
+    fn poll_response(
+        mut self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+    ) -> Result<PollResponse, DispatchError> {
+        'res: loop {
+            let mut this = self.as_mut().project();
+            match this.state.as_mut().project() {
+                // no future is in InnerDispatcher state; pop next message
+                StateProj::None => match this.messages.pop_front() {
+                    // handle request message
+                    Some(DispatcherMessage::Item(req)) => {
+                        // Handle `EXPECT: 100-Continue` header
+                        if req.head().expect() {
+                            // set InnerDispatcher state and continue loop to poll it
+                            let fut = this.flow.expect.call(req);
+                            this.state.set(State::ExpectCall { fut });
+                        } else {
+                            // set InnerDispatcher state and continue loop to poll it
+                            let fut = this.flow.service.call(req);
+                            this.state.set(State::ServiceCall { fut });
+                        };
+                    }
+
+                    // handle error message
+                    Some(DispatcherMessage::Error(res)) => {
+                        // send_response would update InnerDispatcher state to SendPayload or None
+                        // (If response body is empty)
+                        // continue loop to poll it
+                        self.as_mut().send_error_response(res, BoxBody::new(()))?;
+                    }
+
+                    // return with upgrade request and poll it exclusively
+                    Some(DispatcherMessage::Upgrade(req)) => return Ok(PollResponse::Upgrade(req)),
+
+                    // all messages are dealt with
+                    None => {
+                        // start keep-alive if last request allowed it
+                        this.flags.set(Flags::KEEP_ALIVE, this.codec.keep_alive());
+
+                        return Ok(PollResponse::DoNothing);
+                    }
+                },
+
+                StateProj::ServiceCall { fut } => {
+                    match fut.poll(cx) {
+                        // service call resolved. send response.
+                        Poll::Ready(Ok(res)) => {
+                            let (res, body) = res.into().replace_body(());
+                            self.as_mut().send_response(res, body)?;
+                        }
+
+                        // send service call error as response
+                        Poll::Ready(Err(err)) => {
+                            let res: Response<BoxBody> = err.into();
+                            let (res, body) = res.replace_body(());
+                            self.as_mut().send_error_response(res, body)?;
+                        }
+
+                        // service call pending and could be waiting for more chunk messages
+                        // (pipeline message limit and/or payload can_read limit)
+                        Poll::Pending => {
+                            // no new message is decoded and no new payload is fed
+                            // nothing to do except waiting for new incoming data from client
+                            if !self.as_mut().poll_request(cx)? {
+                                return Ok(PollResponse::DoNothing);
+                            }
+                            // else loop
+                        }
+                    }
+                }
+
+                StateProj::SendPayload { mut body } => {
+                    // keep populate writer buffer until buffer size limit hit,
+                    // get blocked or finished.
+                    while this.write_buf.len() < super::payload::MAX_BUFFER_SIZE {
+                        match body.as_mut().poll_next(cx) {
+                            Poll::Ready(Some(Ok(item))) => {
+                                this.codec
+                                    .encode(Message::Chunk(Some(item)), this.write_buf)?;
+                            }
+
+                            Poll::Ready(None) => {
+                                this.codec.encode(Message::Chunk(None), this.write_buf)?;
+
+                                // payload stream finished.
+                                // set state to None and handle next message
+                                this.state.set(State::None);
+                                this.flags.insert(Flags::FINISHED);
+
+                                continue 'res;
+                            }
+
+                            Poll::Ready(Some(Err(err))) => {
+                                let err = err.into();
+                                tracing::error!("Response payload stream error: {err:?}");
+                                this.flags.insert(Flags::FINISHED);
+                                return Err(DispatchError::Body(err));
+                            }
+
+                            Poll::Pending => return Ok(PollResponse::DoNothing),
+                        }
+                    }
+
+                    // buffer is beyond max size
+                    // return and try to write the whole buffer to I/O stream.
+                    return Ok(PollResponse::DrainWriteBuf);
+                }
+
+                StateProj::SendErrorPayload { mut body } => {
+                    // TODO: de-dupe impl with SendPayload
+
+                    // keep populate writer buffer until buffer size limit hit,
+                    // get blocked or finished.
+                    while this.write_buf.len() < super::payload::MAX_BUFFER_SIZE {
+                        match body.as_mut().poll_next(cx) {
+                            Poll::Ready(Some(Ok(item))) => {
+                                this.codec
+                                    .encode(Message::Chunk(Some(item)), this.write_buf)?;
+                            }
+
+                            Poll::Ready(None) => {
+                                this.codec.encode(Message::Chunk(None), this.write_buf)?;
+
+                                // payload stream finished
+                                // set state to None and handle next message
+                                this.state.set(State::None);
+                                this.flags.insert(Flags::FINISHED);
+
+                                continue 'res;
+                            }
+
+                            Poll::Ready(Some(Err(err))) => {
+                                tracing::error!("Response payload stream error: {err:?}");
+                                this.flags.insert(Flags::FINISHED);
+                                return Err(DispatchError::Body(
+                                    Error::new_body().with_cause(err).into(),
+                                ));
+                            }
+
+                            Poll::Pending => return Ok(PollResponse::DoNothing),
+                        }
+                    }
+
+                    // buffer is beyond max size
+                    // return and try to write the whole buffer to stream
+                    return Ok(PollResponse::DrainWriteBuf);
+                }
+
+                StateProj::ExpectCall { fut } => {
+                    trace!("  calling expect service");
+
+                    match fut.poll(cx) {
+                        // expect resolved. write continue to buffer and set InnerDispatcher state
+                        // to service call.
+                        Poll::Ready(Ok(req)) => {
+                            this.write_buf
+                                .extend_from_slice(b"HTTP/1.1 100 Continue\r\n\r\n");
+                            let fut = this.flow.service.call(req);
+                            this.state.set(State::ServiceCall { fut });
+                        }
+
+                        // send expect error as response
+                        Poll::Ready(Err(err)) => {
+                            let res: Response<BoxBody> = err.into();
+                            let (res, body) = res.replace_body(());
+                            self.as_mut().send_error_response(res, body)?;
+                        }
+
+                        // expect must be solved before progress can be made.
+                        Poll::Pending => return Ok(PollResponse::DoNothing),
+                    }
+                }
+            }
+        }
+    }
+
+    fn handle_request(
+        mut self: Pin<&mut Self>,
+        req: Request,
+        cx: &mut Context<'_>,
+    ) -> Result<(), DispatchError> {
+        // initialize dispatcher state
+        {
+            let mut this = self.as_mut().project();
+
+            // Handle `EXPECT: 100-Continue` header
+            if req.head().expect() {
+                // set dispatcher state to call expect handler
+                let fut = this.flow.expect.call(req);
+                this.state.set(State::ExpectCall { fut });
+            } else {
+                // set dispatcher state to call service handler
+                let fut = this.flow.service.call(req);
+                this.state.set(State::ServiceCall { fut });
+            };
+        };
+
+        // eagerly poll the future once (or twice if expect is resolved immediately).
+        loop {
+            match self.as_mut().project().state.project() {
+                StateProj::ExpectCall { fut } => {
+                    match fut.poll(cx) {
+                        // expect is resolved; continue loop and poll the service call branch.
+                        Poll::Ready(Ok(req)) => {
+                            self.as_mut().send_continue();
+
+                            let mut this = self.as_mut().project();
+                            let fut = this.flow.service.call(req);
+                            this.state.set(State::ServiceCall { fut });
+
+                            continue;
+                        }
+
+                        // future is error; send response and return a result
+                        // on success to notify the dispatcher a new state is set and the outer loop
+                        // should be continued
+                        Poll::Ready(Err(err)) => {
+                            let res: Response<BoxBody> = err.into();
+                            let (res, body) = res.replace_body(());
+                            return self.send_error_response(res, body);
+                        }
+
+                        // future is pending; return Ok(()) to notify that a new state is
+                        // set and the outer loop should be continue.
+                        Poll::Pending => return Ok(()),
+                    }
+                }
+
+                StateProj::ServiceCall { fut } => {
+                    // return no matter the service call future's result.
+                    return match fut.poll(cx) {
+                        // Future is resolved. Send response and return a result. On success
+                        // to notify the dispatcher a new state is set and the outer loop
+                        // should be continue.
+                        Poll::Ready(Ok(res)) => {
+                            let (res, body) = res.into().replace_body(());
+                            self.as_mut().send_response(res, body)
+                        }
+
+                        // see the comment on ExpectCall state branch's Pending
+                        Poll::Pending => Ok(()),
+
+                        // see the comment on ExpectCall state branch's Ready(Err(_))
+                        Poll::Ready(Err(err)) => {
+                            let res: Response<BoxBody> = err.into();
+                            let (res, body) = res.replace_body(());
+                            self.as_mut().send_error_response(res, body)
+                        }
+                    };
+                }
+
+                _ => {
+                    unreachable!("State must be set to ServiceCall or ExceptCall in handle_request")
+                }
+            }
+        }
+    }
+
+    /// Process one incoming request.
+    ///
+    /// Returns true if any meaningful work was done.
+    fn poll_request(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Result<bool, DispatchError> {
+        let pipeline_queue_full = self.messages.len() >= MAX_PIPELINED_MESSAGES;
+        let can_not_read = !self.can_read(cx);
+
+        // limit amount of non-processed requests
+        if pipeline_queue_full || can_not_read {
+            return Ok(false);
+        }
+
+        let mut this = self.as_mut().project();
+
+        let mut updated = false;
+
+        // decode from read buf as many full requests as possible
+        loop {
+            match this.codec.decode(this.read_buf) {
+                Ok(Some(msg)) => {
+                    updated = true;
+
+                    match msg {
+                        Message::Item(mut req) => {
+                            // head timer only applies to first request on connection
+                            this.head_timer.clear(line!());
+
+                            req.head_mut().peer_addr = *this.peer_addr;
+
+                            req.conn_data.clone_from(this.conn_data);
+
+                            match this.codec.message_type() {
+                                // request has no payload
+                                MessageType::None => {}
+
+                                // Request is upgradable. Add upgrade message and break.
+                                // Everything remaining in read buffer will be handed to
+                                // upgraded Request.
+                                MessageType::Stream if this.flow.upgrade.is_some() => {
+                                    this.messages.push_back(DispatcherMessage::Upgrade(req));
+                                    break;
+                                }
+
+                                // request is not upgradable
+                                MessageType::Payload | MessageType::Stream => {
+                                    // PayloadSender and Payload are smart pointers share the
+                                    // same state. PayloadSender is attached to dispatcher and used
+                                    // to sink new chunked request data to state. Payload is
+                                    // attached to Request and passed to Service::call where the
+                                    // state can be collected and consumed.
+                                    let (sender, payload) = Payload::create(false);
+                                    *req.payload() = crate::Payload::H1 { payload };
+                                    *this.payload = Some(sender);
+                                }
+                            }
+
+                            // handle request early when no future in InnerDispatcher state.
+                            if this.state.is_none() {
+                                self.as_mut().handle_request(req, cx)?;
+                                this = self.as_mut().project();
+                            } else {
+                                this.messages.push_back(DispatcherMessage::Item(req));
+                            }
+                        }
+
+                        Message::Chunk(Some(chunk)) => {
+                            if let Some(ref mut payload) = this.payload {
+                                payload.feed_data(chunk);
+                            } else {
+                                error!("Internal server error: unexpected payload chunk");
+                                this.flags.insert(Flags::READ_DISCONNECT);
+                                this.messages.push_back(DispatcherMessage::Error(
+                                    Response::internal_server_error().drop_body(),
+                                ));
+                                *this.error = Some(DispatchError::InternalError);
+                                break;
+                            }
+                        }
+
+                        Message::Chunk(None) => {
+                            if let Some(mut payload) = this.payload.take() {
+                                payload.feed_eof();
+                            } else {
+                                error!("Internal server error: unexpected eof");
+                                this.flags.insert(Flags::READ_DISCONNECT);
+                                this.messages.push_back(DispatcherMessage::Error(
+                                    Response::internal_server_error().drop_body(),
+                                ));
+                                *this.error = Some(DispatchError::InternalError);
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                // decode is partial and buffer is not full yet
+                // break and wait for more read
+                Ok(None) => break,
+
+                Err(ParseError::Io(err)) => {
+                    trace!("I/O error: {}", &err);
+                    self.as_mut().client_disconnected();
+                    this = self.as_mut().project();
+                    *this.error = Some(DispatchError::Io(err));
+                    break;
+                }
+
+                Err(ParseError::TooLarge) => {
+                    trace!("request head was too big; returning 431 response");
+
+                    if let Some(mut payload) = this.payload.take() {
+                        payload.set_error(PayloadError::Overflow);
+                    }
+
+                    // request heads that overflow buffer size return a 431 error
+                    this.messages
+                        .push_back(DispatcherMessage::Error(Response::with_body(
+                            StatusCode::REQUEST_HEADER_FIELDS_TOO_LARGE,
+                            (),
+                        )));
+
+                    this.flags.insert(Flags::READ_DISCONNECT);
+                    *this.error = Some(ParseError::TooLarge.into());
+
+                    break;
+                }
+
+                Err(err) => {
+                    trace!("parse error {}", &err);
+
+                    if let Some(mut payload) = this.payload.take() {
+                        payload.set_error(PayloadError::EncodingCorrupted);
+                    }
+
+                    // malformed requests should be responded with 400
+                    this.messages.push_back(DispatcherMessage::Error(
+                        Response::bad_request().drop_body(),
+                    ));
+
+                    this.flags.insert(Flags::READ_DISCONNECT);
+                    *this.error = Some(err.into());
+                    break;
+                }
+            }
+        }
+
+        Ok(updated)
+    }
+
+    fn poll_head_timer(
+        mut self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+    ) -> Result<(), DispatchError> {
+        let this = self.as_mut().project();
+
+        if let TimerState::Active { timer } = this.head_timer {
+            if timer.as_mut().poll(cx).is_ready() {
+                // timeout on first request (slow request) return 408
+
+                trace!("timed out on slow request; replying with 408 and closing connection");
+
+                let _ = self.as_mut().send_error_response(
+                    Response::with_body(StatusCode::REQUEST_TIMEOUT, ()),
+                    BoxBody::new(()),
+                );
+
+                self.project().flags.insert(Flags::SHUTDOWN);
+            }
+        };
+
+        Ok(())
+    }
+
+    fn poll_ka_timer(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Result<(), DispatchError> {
+        let this = self.as_mut().project();
+        if let TimerState::Active { timer } = this.ka_timer {
+            debug_assert!(
+                this.flags.contains(Flags::KEEP_ALIVE),
+                "keep-alive flag should be set when timer is active",
+            );
+            debug_assert!(
+                this.state.is_none(),
+                "dispatcher should not be in keep-alive phase if state is not none: {:?}",
+                this.state,
+            );
+
+            // Assert removed by @robjtede on account of issue #2655. There are cases where an I/O
+            // flush can be pending after entering the keep-alive state causing the subsequent flush
+            // wake up to panic here. This appears to be a Linux-only problem. Leaving original code
+            // below for posterity because a simple and reliable test could not be found to trigger
+            // the behavior.
+            // debug_assert!(
+            //     this.write_buf.is_empty(),
+            //     "dispatcher should not be in keep-alive phase if write_buf is not empty",
+            // );
+
+            // keep-alive timer has timed out
+            if timer.as_mut().poll(cx).is_ready() {
+                // no tasks at hand
+                trace!("timer timed out; closing connection");
+                this.flags.insert(Flags::SHUTDOWN);
+
+                if let Some(deadline) = this.config.client_disconnect_deadline() {
+                    // start shutdown timeout if enabled
+                    this.shutdown_timer
+                        .set_and_init(cx, sleep_until(deadline.into()), line!());
+                } else {
+                    // no shutdown timeout, drop socket
+                    this.flags.insert(Flags::WRITE_DISCONNECT);
+                }
+            }
+        }
+
+        Ok(())
+    }
+
+    fn poll_shutdown_timer(
+        mut self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+    ) -> Result<(), DispatchError> {
+        let this = self.as_mut().project();
+        if let TimerState::Active { timer } = this.shutdown_timer {
+            debug_assert!(
+                this.flags.contains(Flags::SHUTDOWN),
+                "shutdown flag should be set when timer is active",
+            );
+
+            // timed-out during shutdown; drop connection
+            if timer.as_mut().poll(cx).is_ready() {
+                trace!("timed-out during shutdown");
+                return Err(DispatchError::DisconnectTimeout);
+            }
+        }
+
+        Ok(())
+    }
+
+    /// Poll head, keep-alive, and disconnect timer.
+    fn poll_timers(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Result<(), DispatchError> {
+        self.as_mut().poll_head_timer(cx)?;
+        self.as_mut().poll_ka_timer(cx)?;
+        self.as_mut().poll_shutdown_timer(cx)?;
+
+        Ok(())
+    }
+
+    /// Returns true when I/O stream can be disconnected after write to it.
+    ///
+    /// It covers these conditions:
+    /// - `std::io::ErrorKind::ConnectionReset` after partial read;
+    /// - all data read done.
+    #[inline(always)] // TODO: bench this inline
+    fn read_available(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Result<bool, DispatchError> {
+        let this = self.project();
+
+        if this.flags.contains(Flags::READ_DISCONNECT) {
+            return Ok(false);
+        };
+
+        let mut io = Pin::new(this.io.as_mut().unwrap());
+
+        let mut read_some = false;
+
+        loop {
+            // Return early when read buf exceed decoder's max buffer size.
+            if this.read_buf.len() >= MAX_BUFFER_SIZE {
+                // At this point it's not known IO stream is still scheduled to be waked up so
+                // force wake up dispatcher just in case.
+                //
+                // Reason:
+                // AsyncRead mostly would only have guarantee wake up when the poll_read
+                // return Poll::Pending.
+                //
+                // Case:
+                // When read_buf is beyond max buffer size the early return could be successfully
+                // be parsed as a new Request. This case would not generate ParseError::TooLarge and
+                // at this point IO stream is not fully read to Pending and would result in
+                // dispatcher stuck until timeout (keep-alive).
+                //
+                // Note:
+                // This is a perf choice to reduce branch on <Request as MessageType>::decode.
+                //
+                // A Request head too large to parse is only checked on `httparse::Status::Partial`.
+
+                match this.payload {
+                    // When dispatcher has a payload the responsibility of wake ups is shifted to
+                    // `h1::payload::Payload` unless the payload is needing a read, in which case it
+                    // might not have access to the waker and could result in the dispatcher
+                    // getting stuck until timeout.
+                    //
+                    // Reason:
+                    // Self wake up when there is payload would waste poll and/or result in
+                    // over read.
+                    //
+                    // Case:
+                    // When payload is (partial) dropped by user there is no need to do
+                    // read anymore. At this case read_buf could always remain beyond
+                    // MAX_BUFFER_SIZE and self wake up would be busy poll dispatcher and
+                    // waste resources.
+                    Some(ref p) if p.need_read(cx) != PayloadStatus::Read => {}
+                    _ => cx.waker().wake_by_ref(),
+                }
+
+                return Ok(false);
+            }
+
+            // grow buffer if necessary.
+            let remaining = this.read_buf.capacity() - this.read_buf.len();
+            if remaining < LW_BUFFER_SIZE {
+                this.read_buf.reserve(HW_BUFFER_SIZE - remaining);
+            }
+
+            match tokio_util::io::poll_read_buf(io.as_mut(), cx, this.read_buf) {
+                Poll::Ready(Ok(n)) => {
+                    this.flags.remove(Flags::FINISHED);
+
+                    if n == 0 {
+                        return Ok(true);
+                    }
+
+                    read_some = true;
+                }
+
+                Poll::Pending => {
+                    return Ok(false);
+                }
+
+                Poll::Ready(Err(err)) => {
+                    return match err.kind() {
+                        // convert WouldBlock error to the same as Pending return
+                        io::ErrorKind::WouldBlock => Ok(false),
+
+                        // connection reset after partial read
+                        io::ErrorKind::ConnectionReset if read_some => Ok(true),
+
+                        _ => Err(DispatchError::Io(err)),
+                    };
+                }
+            }
+        }
+    }
+
+    /// call upgrade service with request.
+    fn upgrade(self: Pin<&mut Self>, req: Request) -> U::Future {
+        let this = self.project();
+        let mut parts = FramedParts::with_read_buf(
+            this.io.take().unwrap(),
+            mem::take(this.codec),
+            mem::take(this.read_buf),
+        );
+        parts.write_buf = mem::take(this.write_buf);
+        let framed = Framed::from_parts(parts);
+        this.flow.upgrade.as_ref().unwrap().call((req, framed))
+    }
+}
+
+impl<T, S, B, X, U> Future for Dispatcher<T, S, B, X, U>
+where
+    T: AsyncRead + AsyncWrite + Unpin,
+
+    S: Service<Request>,
+    S::Error: Into<Response<BoxBody>>,
+    S::Response: Into<Response<B>>,
+
+    B: MessageBody,
+
+    X: Service<Request, Response = Request>,
+    X::Error: Into<Response<BoxBody>>,
+
+    U: Service<(Request, Framed<T, Codec>), Response = ()>,
+    U::Error: fmt::Display,
+{
+    type Output = Result<(), DispatchError>;
+
+    #[inline]
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.as_mut().project();
+
+        #[cfg(test)]
+        {
+            *this.poll_count += 1;
+        }
+
+        match this.inner.project() {
+            DispatcherStateProj::Upgrade { fut: upgrade } => upgrade.poll(cx).map_err(|err| {
+                error!("Upgrade handler error: {}", err);
+                DispatchError::Upgrade
+            }),
+
+            DispatcherStateProj::Normal { mut inner } => {
+                trace!("start flags: {:?}", &inner.flags);
+
+                trace_timer_states(
+                    "start",
+                    &inner.head_timer,
+                    &inner.ka_timer,
+                    &inner.shutdown_timer,
+                );
+
+                inner.as_mut().poll_timers(cx)?;
+
+                let poll = if inner.flags.contains(Flags::SHUTDOWN) {
+                    if inner.flags.contains(Flags::WRITE_DISCONNECT) {
+                        Poll::Ready(Ok(()))
+                    } else {
+                        // flush buffer and wait on blocked
+                        ready!(inner.as_mut().poll_flush(cx))?;
+                        Pin::new(inner.as_mut().project().io.as_mut().unwrap())
+                            .poll_shutdown(cx)
+                            .map_err(DispatchError::from)
+                    }
+                } else {
+                    // read from I/O stream and fill read buffer
+                    let should_disconnect = inner.as_mut().read_available(cx)?;
+
+                    // after reading something from stream, clear keep-alive timer
+                    if !inner.read_buf.is_empty() && inner.flags.contains(Flags::KEEP_ALIVE) {
+                        let inner = inner.as_mut().project();
+                        inner.flags.remove(Flags::KEEP_ALIVE);
+                        inner.ka_timer.clear(line!());
+                    }
+
+                    if !inner.flags.contains(Flags::STARTED) {
+                        inner.as_mut().project().flags.insert(Flags::STARTED);
+
+                        if let Some(deadline) = inner.config.client_request_deadline() {
+                            inner.as_mut().project().head_timer.set_and_init(
+                                cx,
+                                sleep_until(deadline.into()),
+                                line!(),
+                            );
+                        }
+                    }
+
+                    inner.as_mut().poll_request(cx)?;
+
+                    if should_disconnect {
+                        // I/O stream should to be closed
+                        let inner = inner.as_mut().project();
+                        inner.flags.insert(Flags::READ_DISCONNECT);
+                        if let Some(mut payload) = inner.payload.take() {
+                            payload.feed_eof();
+                        }
+                    };
+
+                    loop {
+                        // poll response to populate write buffer
+                        // drain indicates whether write buffer should be emptied before next run
+                        let drain = match inner.as_mut().poll_response(cx)? {
+                            PollResponse::DrainWriteBuf => true,
+
+                            PollResponse::DoNothing => {
+                                // KEEP_ALIVE is set in send_response_inner if client allows it
+                                // FINISHED is set after writing last chunk of response
+                                if inner.flags.contains(Flags::KEEP_ALIVE | Flags::FINISHED) {
+                                    if let Some(timer) = inner.config.keep_alive_deadline() {
+                                        inner.as_mut().project().ka_timer.set_and_init(
+                                            cx,
+                                            sleep_until(timer.into()),
+                                            line!(),
+                                        );
+                                    }
+                                }
+
+                                false
+                            }
+
+                            // upgrade request and goes Upgrade variant of DispatcherState.
+                            PollResponse::Upgrade(req) => {
+                                let upgrade = inner.upgrade(req);
+                                self.as_mut()
+                                    .project()
+                                    .inner
+                                    .set(DispatcherState::Upgrade { fut: upgrade });
+                                return self.poll(cx);
+                            }
+                        };
+
+                        // we didn't get WouldBlock from write operation, so data get written to
+                        // kernel completely (macOS) and we have to write again otherwise response
+                        // can get stuck
+                        //
+                        // TODO: want to find a reference for this behavior
+                        // see introduced commit: 3872d3ba
+                        let flush_was_ready = inner.as_mut().poll_flush(cx)?.is_ready();
+
+                        // this assert seems to always be true but not willing to commit to it until
+                        // we understand what Nikolay meant when writing the above comment
+                        // debug_assert!(flush_was_ready);
+
+                        if !flush_was_ready || !drain {
+                            break;
+                        }
+                    }
+
+                    // client is gone
+                    if inner.flags.contains(Flags::WRITE_DISCONNECT) {
+                        trace!("client is gone; disconnecting");
+                        return Poll::Ready(Ok(()));
+                    }
+
+                    let inner_p = inner.as_mut().project();
+                    let state_is_none = inner_p.state.is_none();
+
+                    // read half is closed; we do not process any responses
+                    if inner_p.flags.contains(Flags::READ_DISCONNECT) && state_is_none {
+                        trace!("read half closed; start shutdown");
+                        inner_p.flags.insert(Flags::SHUTDOWN);
+                    }
+
+                    // keep-alive and stream errors
+                    if state_is_none && inner_p.write_buf.is_empty() {
+                        if let Some(err) = inner_p.error.take() {
+                            error!("stream error: {}", &err);
+                            return Poll::Ready(Err(err));
+                        }
+
+                        // disconnect if keep-alive is not enabled
+                        if inner_p.flags.contains(Flags::FINISHED)
+                            && !inner_p.flags.contains(Flags::KEEP_ALIVE)
+                        {
+                            inner_p.flags.remove(Flags::FINISHED);
+                            inner_p.flags.insert(Flags::SHUTDOWN);
+                            return self.poll(cx);
+                        }
+
+                        // disconnect if shutdown
+                        if inner_p.flags.contains(Flags::SHUTDOWN) {
+                            return self.poll(cx);
+                        }
+                    }
+
+                    trace_timer_states(
+                        "end",
+                        inner_p.head_timer,
+                        inner_p.ka_timer,
+                        inner_p.shutdown_timer,
+                    );
+
+                    Poll::Pending
+                };
+
+                trace!("end flags: {:?}", &inner.flags);
+
+                poll
+            }
+        }
+    }
+}
+
+#[allow(dead_code)]
+fn trace_timer_states(
+    label: &str,
+    head_timer: &TimerState,
+    ka_timer: &TimerState,
+    shutdown_timer: &TimerState,
+) {
+    trace!("{} timers:", label);
+
+    if head_timer.is_enabled() {
+        trace!("  head {}", &head_timer);
+    }
+
+    if ka_timer.is_enabled() {
+        trace!("  keep-alive {}", &ka_timer);
+    }
+
+    if shutdown_timer.is_enabled() {
+        trace!("  shutdown {}", &shutdown_timer);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/h1/encoder.rs.html b/src/actix_http/h1/encoder.rs.html new file mode 100644 index 000000000..8ee454e6b --- /dev/null +++ b/src/actix_http/h1/encoder.rs.html @@ -0,0 +1,1343 @@ +encoder.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
+
use std::{
+    cmp,
+    io::{self, Write as _},
+    marker::PhantomData,
+    ptr::copy_nonoverlapping,
+    slice::from_raw_parts_mut,
+};
+
+use bytes::{BufMut, BytesMut};
+
+use crate::{
+    body::BodySize,
+    header::{
+        map::Value, HeaderMap, HeaderName, CONNECTION, CONTENT_LENGTH, DATE, TRANSFER_ENCODING,
+    },
+    helpers, ConnectionType, RequestHeadType, Response, ServiceConfig, StatusCode, Version,
+};
+
+const AVERAGE_HEADER_SIZE: usize = 30;
+
+#[derive(Debug)]
+pub(crate) struct MessageEncoder<T: MessageType> {
+    #[allow(dead_code)]
+    pub length: BodySize,
+    pub te: TransferEncoding,
+    _phantom: PhantomData<T>,
+}
+
+impl<T: MessageType> Default for MessageEncoder<T> {
+    fn default() -> Self {
+        MessageEncoder {
+            length: BodySize::None,
+            te: TransferEncoding::empty(),
+            _phantom: PhantomData,
+        }
+    }
+}
+
+pub(crate) trait MessageType: Sized {
+    fn status(&self) -> Option<StatusCode>;
+
+    fn headers(&self) -> &HeaderMap;
+
+    fn extra_headers(&self) -> Option<&HeaderMap>;
+
+    fn camel_case(&self) -> bool {
+        false
+    }
+
+    fn chunked(&self) -> bool;
+
+    fn encode_status(&mut self, dst: &mut BytesMut) -> io::Result<()>;
+
+    fn encode_headers(
+        &mut self,
+        dst: &mut BytesMut,
+        version: Version,
+        mut length: BodySize,
+        conn_type: ConnectionType,
+        config: &ServiceConfig,
+    ) -> io::Result<()> {
+        let chunked = self.chunked();
+        let mut skip_len = length != BodySize::Stream;
+        let camel_case = self.camel_case();
+
+        // Content length
+        if let Some(status) = self.status() {
+            match status {
+                StatusCode::CONTINUE
+                | StatusCode::SWITCHING_PROTOCOLS
+                | StatusCode::PROCESSING
+                | StatusCode::NO_CONTENT => {
+                    // skip content-length and transfer-encoding headers
+                    // see https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.1
+                    // and https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2
+                    skip_len = true;
+                    length = BodySize::None
+                }
+
+                StatusCode::NOT_MODIFIED => {
+                    // 304 responses should never have a body but should retain a manually set
+                    // content-length header
+                    // see https://datatracker.ietf.org/doc/html/rfc7232#section-4.1
+                    skip_len = false;
+                    length = BodySize::None;
+                }
+
+                _ => {}
+            }
+        }
+
+        match length {
+            BodySize::Stream => {
+                if chunked {
+                    skip_len = true;
+                    if camel_case {
+                        dst.put_slice(b"\r\nTransfer-Encoding: chunked\r\n")
+                    } else {
+                        dst.put_slice(b"\r\ntransfer-encoding: chunked\r\n")
+                    }
+                } else {
+                    skip_len = false;
+                    dst.put_slice(b"\r\n");
+                }
+            }
+            BodySize::Sized(0) if camel_case => dst.put_slice(b"\r\nContent-Length: 0\r\n"),
+            BodySize::Sized(0) => dst.put_slice(b"\r\ncontent-length: 0\r\n"),
+            BodySize::Sized(len) => helpers::write_content_length(len, dst, camel_case),
+            BodySize::None => dst.put_slice(b"\r\n"),
+        }
+
+        // Connection
+        match conn_type {
+            ConnectionType::Upgrade => dst.put_slice(b"connection: upgrade\r\n"),
+            ConnectionType::KeepAlive if version < Version::HTTP_11 => {
+                if camel_case {
+                    dst.put_slice(b"Connection: keep-alive\r\n")
+                } else {
+                    dst.put_slice(b"connection: keep-alive\r\n")
+                }
+            }
+            ConnectionType::Close if version >= Version::HTTP_11 => {
+                if camel_case {
+                    dst.put_slice(b"Connection: close\r\n")
+                } else {
+                    dst.put_slice(b"connection: close\r\n")
+                }
+            }
+            _ => {}
+        }
+
+        // write headers
+
+        let mut has_date = false;
+
+        let mut buf = dst.chunk_mut().as_mut_ptr();
+        let mut remaining = dst.capacity() - dst.len();
+
+        // tracks bytes written since last buffer resize
+        // since buf is a raw pointer to a bytes container storage but is written to without the
+        // container's knowledge, this is used to sync the containers cursor after data is written
+        let mut pos = 0;
+
+        self.write_headers(|key, value| {
+            match *key {
+                CONNECTION => return,
+                TRANSFER_ENCODING | CONTENT_LENGTH if skip_len => return,
+                DATE => has_date = true,
+                _ => {}
+            }
+
+            let k = key.as_str().as_bytes();
+            let k_len = k.len();
+
+            for val in value.iter() {
+                let v = val.as_ref();
+                let v_len = v.len();
+
+                // key length + value length + colon + space + \r\n
+                let len = k_len + v_len + 4;
+
+                if len > remaining {
+                    // SAFETY: all the bytes written up to position "pos" are initialized
+                    // the written byte count and pointer advancement are kept in sync
+                    unsafe {
+                        dst.advance_mut(pos);
+                    }
+
+                    pos = 0;
+                    dst.reserve(len * 2);
+                    remaining = dst.capacity() - dst.len();
+
+                    // re-assign buf raw pointer since it's possible that the buffer was
+                    // reallocated and/or resized
+                    buf = dst.chunk_mut().as_mut_ptr();
+                }
+
+                // SAFETY: on each write, it is enough to ensure that the advancement of
+                // the cursor matches the number of bytes written
+                unsafe {
+                    if camel_case {
+                        // use Camel-Case headers
+                        write_camel_case(k, buf, k_len);
+                    } else {
+                        write_data(k, buf, k_len);
+                    }
+
+                    buf = buf.add(k_len);
+
+                    write_data(b": ", buf, 2);
+                    buf = buf.add(2);
+
+                    write_data(v, buf, v_len);
+                    buf = buf.add(v_len);
+
+                    write_data(b"\r\n", buf, 2);
+                    buf = buf.add(2);
+                };
+
+                pos += len;
+                remaining -= len;
+            }
+        });
+
+        // final cursor synchronization with the bytes container
+        //
+        // SAFETY: all the bytes written up to position "pos" are initialized
+        // the written byte count and pointer advancement are kept in sync
+        unsafe {
+            dst.advance_mut(pos);
+        }
+
+        if !has_date {
+            // optimized date header, write_date_header writes its own \r\n
+            config.write_date_header(dst, camel_case);
+        }
+
+        // end-of-headers marker
+        dst.extend_from_slice(b"\r\n");
+
+        Ok(())
+    }
+
+    fn write_headers<F>(&mut self, mut f: F)
+    where
+        F: FnMut(&HeaderName, &Value),
+    {
+        match self.extra_headers() {
+            Some(headers) => {
+                // merging headers from head and extra headers.
+                self.headers()
+                    .inner
+                    .iter()
+                    .filter(|(name, _)| !headers.contains_key(*name))
+                    .chain(headers.inner.iter())
+                    .for_each(|(k, v)| f(k, v))
+            }
+            None => self.headers().inner.iter().for_each(|(k, v)| f(k, v)),
+        }
+    }
+}
+
+impl MessageType for Response<()> {
+    fn status(&self) -> Option<StatusCode> {
+        Some(self.head().status)
+    }
+
+    fn chunked(&self) -> bool {
+        self.head().chunked()
+    }
+
+    fn headers(&self) -> &HeaderMap {
+        &self.head().headers
+    }
+
+    fn extra_headers(&self) -> Option<&HeaderMap> {
+        None
+    }
+
+    fn camel_case(&self) -> bool {
+        self.head()
+            .flags
+            .contains(crate::message::Flags::CAMEL_CASE)
+    }
+
+    fn encode_status(&mut self, dst: &mut BytesMut) -> io::Result<()> {
+        let head = self.head();
+        let reason = head.reason().as_bytes();
+        dst.reserve(256 + head.headers.len() * AVERAGE_HEADER_SIZE + reason.len());
+
+        // status line
+        helpers::write_status_line(head.version, head.status.as_u16(), dst);
+        dst.put_slice(reason);
+        Ok(())
+    }
+}
+
+impl MessageType for RequestHeadType {
+    fn status(&self) -> Option<StatusCode> {
+        None
+    }
+
+    fn chunked(&self) -> bool {
+        self.as_ref().chunked()
+    }
+
+    fn camel_case(&self) -> bool {
+        self.as_ref().camel_case_headers()
+    }
+
+    fn headers(&self) -> &HeaderMap {
+        self.as_ref().headers()
+    }
+
+    fn extra_headers(&self) -> Option<&HeaderMap> {
+        self.extra_headers()
+    }
+
+    fn encode_status(&mut self, dst: &mut BytesMut) -> io::Result<()> {
+        let head = self.as_ref();
+        dst.reserve(256 + head.headers.len() * AVERAGE_HEADER_SIZE);
+        write!(
+            helpers::MutWriter(dst),
+            "{} {} {}",
+            head.method,
+            head.uri.path_and_query().map(|u| u.as_str()).unwrap_or("/"),
+            match head.version {
+                Version::HTTP_09 => "HTTP/0.9",
+                Version::HTTP_10 => "HTTP/1.0",
+                Version::HTTP_11 => "HTTP/1.1",
+                Version::HTTP_2 => "HTTP/2.0",
+                Version::HTTP_3 => "HTTP/3.0",
+                _ => return Err(io::Error::new(io::ErrorKind::Other, "unsupported version")),
+            }
+        )
+        .map_err(|e| io::Error::new(io::ErrorKind::Other, e))
+    }
+}
+
+impl<T: MessageType> MessageEncoder<T> {
+    /// Encode chunk.
+    pub fn encode_chunk(&mut self, msg: &[u8], buf: &mut BytesMut) -> io::Result<bool> {
+        self.te.encode(msg, buf)
+    }
+
+    /// Encode EOF.
+    pub fn encode_eof(&mut self, buf: &mut BytesMut) -> io::Result<()> {
+        self.te.encode_eof(buf)
+    }
+
+    /// Encode message.
+    pub fn encode(
+        &mut self,
+        dst: &mut BytesMut,
+        message: &mut T,
+        head: bool,
+        stream: bool,
+        version: Version,
+        length: BodySize,
+        conn_type: ConnectionType,
+        config: &ServiceConfig,
+    ) -> io::Result<()> {
+        // transfer encoding
+        if !head {
+            self.te = match length {
+                BodySize::Sized(0) => TransferEncoding::empty(),
+                BodySize::Sized(len) => TransferEncoding::length(len),
+                BodySize::Stream => {
+                    if message.chunked() && !stream {
+                        TransferEncoding::chunked()
+                    } else {
+                        TransferEncoding::eof()
+                    }
+                }
+                BodySize::None => TransferEncoding::empty(),
+            };
+        } else {
+            self.te = TransferEncoding::empty();
+        }
+
+        message.encode_status(dst)?;
+        message.encode_headers(dst, version, length, conn_type, config)
+    }
+}
+
+/// Encoders to handle different Transfer-Encodings.
+#[derive(Debug)]
+pub(crate) struct TransferEncoding {
+    kind: TransferEncodingKind,
+}
+
+#[derive(Debug, PartialEq, Clone)]
+enum TransferEncodingKind {
+    /// An Encoder for when Transfer-Encoding includes `chunked`.
+    Chunked(bool),
+
+    /// An Encoder for when Content-Length is set.
+    ///
+    /// Enforces that the body is not longer than the Content-Length header.
+    Length(u64),
+
+    /// An Encoder for when Content-Length is not known.
+    ///
+    /// Application decides when to stop writing.
+    Eof,
+}
+
+impl TransferEncoding {
+    #[inline]
+    pub fn empty() -> TransferEncoding {
+        TransferEncoding {
+            kind: TransferEncodingKind::Length(0),
+        }
+    }
+
+    #[inline]
+    pub fn eof() -> TransferEncoding {
+        TransferEncoding {
+            kind: TransferEncodingKind::Eof,
+        }
+    }
+
+    #[inline]
+    pub fn chunked() -> TransferEncoding {
+        TransferEncoding {
+            kind: TransferEncodingKind::Chunked(false),
+        }
+    }
+
+    #[inline]
+    pub fn length(len: u64) -> TransferEncoding {
+        TransferEncoding {
+            kind: TransferEncodingKind::Length(len),
+        }
+    }
+
+    /// Encode message. Return `EOF` state of encoder
+    #[inline]
+    pub fn encode(&mut self, msg: &[u8], buf: &mut BytesMut) -> io::Result<bool> {
+        match self.kind {
+            TransferEncodingKind::Eof => {
+                let eof = msg.is_empty();
+                buf.extend_from_slice(msg);
+                Ok(eof)
+            }
+            TransferEncodingKind::Chunked(ref mut eof) => {
+                if *eof {
+                    return Ok(true);
+                }
+
+                if msg.is_empty() {
+                    *eof = true;
+                    buf.extend_from_slice(b"0\r\n\r\n");
+                } else {
+                    writeln!(helpers::MutWriter(buf), "{:X}\r", msg.len())
+                        .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
+
+                    buf.reserve(msg.len() + 2);
+                    buf.extend_from_slice(msg);
+                    buf.extend_from_slice(b"\r\n");
+                }
+                Ok(*eof)
+            }
+            TransferEncodingKind::Length(ref mut remaining) => {
+                if *remaining > 0 {
+                    if msg.is_empty() {
+                        return Ok(*remaining == 0);
+                    }
+                    let len = cmp::min(*remaining, msg.len() as u64);
+
+                    buf.extend_from_slice(&msg[..len as usize]);
+
+                    *remaining -= len;
+                    Ok(*remaining == 0)
+                } else {
+                    Ok(true)
+                }
+            }
+        }
+    }
+
+    /// Encode eof. Return `EOF` state of encoder
+    #[inline]
+    pub fn encode_eof(&mut self, buf: &mut BytesMut) -> io::Result<()> {
+        match self.kind {
+            TransferEncodingKind::Eof => Ok(()),
+            TransferEncodingKind::Length(rem) => {
+                if rem != 0 {
+                    Err(io::Error::new(io::ErrorKind::UnexpectedEof, ""))
+                } else {
+                    Ok(())
+                }
+            }
+            TransferEncodingKind::Chunked(ref mut eof) => {
+                if !*eof {
+                    *eof = true;
+                    buf.extend_from_slice(b"0\r\n\r\n");
+                }
+                Ok(())
+            }
+        }
+    }
+}
+
+/// # Safety
+/// Callers must ensure that the given `len` matches the given `value` length and that `buf` is
+/// valid for writes of at least `len` bytes.
+unsafe fn write_data(value: &[u8], buf: *mut u8, len: usize) {
+    debug_assert_eq!(value.len(), len);
+    copy_nonoverlapping(value.as_ptr(), buf, len);
+}
+
+/// # Safety
+/// Callers must ensure that the given `len` matches the given `value` length and that `buf` is
+/// valid for writes of at least `len` bytes.
+unsafe fn write_camel_case(value: &[u8], buf: *mut u8, len: usize) {
+    // first copy entire (potentially wrong) slice to output
+    write_data(value, buf, len);
+
+    // SAFETY: We just initialized the buffer with `value`
+    let buffer = from_raw_parts_mut(buf, len);
+
+    let mut iter = value.iter();
+
+    // first character should be uppercase
+    if let Some(c @ b'a'..=b'z') = iter.next() {
+        buffer[0] = c & 0b1101_1111;
+    }
+
+    // track 1 ahead of the current position since that's the location being assigned to
+    let mut index = 2;
+
+    // remaining characters after hyphens should also be uppercase
+    while let Some(&c) = iter.next() {
+        if c == b'-' {
+            // advance iter by one and uppercase if needed
+            if let Some(c @ b'a'..=b'z') = iter.next() {
+                buffer[index] = c & 0b1101_1111;
+            }
+            index += 1;
+        }
+
+        index += 1;
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::rc::Rc;
+
+    use bytes::Bytes;
+    use http::header::{AUTHORIZATION, UPGRADE_INSECURE_REQUESTS};
+
+    use super::*;
+    use crate::{
+        header::{HeaderValue, CONTENT_TYPE},
+        RequestHead,
+    };
+
+    #[test]
+    fn test_chunked_te() {
+        let mut bytes = BytesMut::new();
+        let mut enc = TransferEncoding::chunked();
+        {
+            assert!(!enc.encode(b"test", &mut bytes).ok().unwrap());
+            assert!(enc.encode(b"", &mut bytes).ok().unwrap());
+        }
+        assert_eq!(
+            bytes.split().freeze(),
+            Bytes::from_static(b"4\r\ntest\r\n0\r\n\r\n")
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_camel_case() {
+        let mut bytes = BytesMut::with_capacity(2048);
+        let mut head = RequestHead::default();
+        head.set_camel_case_headers(true);
+        head.headers.insert(DATE, HeaderValue::from_static("date"));
+        head.headers
+            .insert(CONTENT_TYPE, HeaderValue::from_static("plain/text"));
+
+        head.headers
+            .insert(UPGRADE_INSECURE_REQUESTS, HeaderValue::from_static("1"));
+
+        let mut head = RequestHeadType::Owned(head);
+
+        let _ = head.encode_headers(
+            &mut bytes,
+            Version::HTTP_11,
+            BodySize::Sized(0),
+            ConnectionType::Close,
+            &ServiceConfig::default(),
+        );
+        let data = String::from_utf8(Vec::from(bytes.split().freeze().as_ref())).unwrap();
+
+        assert!(data.contains("Content-Length: 0\r\n"));
+        assert!(data.contains("Connection: close\r\n"));
+        assert!(data.contains("Content-Type: plain/text\r\n"));
+        assert!(data.contains("Date: date\r\n"));
+        assert!(data.contains("Upgrade-Insecure-Requests: 1\r\n"));
+
+        let _ = head.encode_headers(
+            &mut bytes,
+            Version::HTTP_11,
+            BodySize::Stream,
+            ConnectionType::KeepAlive,
+            &ServiceConfig::default(),
+        );
+        let data = String::from_utf8(Vec::from(bytes.split().freeze().as_ref())).unwrap();
+        assert!(data.contains("Transfer-Encoding: chunked\r\n"));
+        assert!(data.contains("Content-Type: plain/text\r\n"));
+        assert!(data.contains("Date: date\r\n"));
+
+        let mut head = RequestHead::default();
+        head.set_camel_case_headers(false);
+        head.headers.insert(DATE, HeaderValue::from_static("date"));
+        head.headers
+            .insert(CONTENT_TYPE, HeaderValue::from_static("plain/text"));
+        head.headers
+            .append(CONTENT_TYPE, HeaderValue::from_static("xml"));
+
+        let mut head = RequestHeadType::Owned(head);
+        let _ = head.encode_headers(
+            &mut bytes,
+            Version::HTTP_11,
+            BodySize::Stream,
+            ConnectionType::KeepAlive,
+            &ServiceConfig::default(),
+        );
+        let data = String::from_utf8(Vec::from(bytes.split().freeze().as_ref())).unwrap();
+        assert!(data.contains("transfer-encoding: chunked\r\n"));
+        assert!(data.contains("content-type: xml\r\n"));
+        assert!(data.contains("content-type: plain/text\r\n"));
+        assert!(data.contains("date: date\r\n"));
+    }
+
+    #[actix_rt::test]
+    async fn test_extra_headers() {
+        let mut bytes = BytesMut::with_capacity(2048);
+
+        let mut head = RequestHead::default();
+        head.headers.insert(
+            AUTHORIZATION,
+            HeaderValue::from_static("some authorization"),
+        );
+
+        let mut extra_headers = HeaderMap::new();
+        extra_headers.insert(
+            AUTHORIZATION,
+            HeaderValue::from_static("another authorization"),
+        );
+        extra_headers.insert(DATE, HeaderValue::from_static("date"));
+
+        let mut head = RequestHeadType::Rc(Rc::new(head), Some(extra_headers));
+
+        let _ = head.encode_headers(
+            &mut bytes,
+            Version::HTTP_11,
+            BodySize::Sized(0),
+            ConnectionType::Close,
+            &ServiceConfig::default(),
+        );
+        let data = String::from_utf8(Vec::from(bytes.split().freeze().as_ref())).unwrap();
+        assert!(data.contains("content-length: 0\r\n"));
+        assert!(data.contains("connection: close\r\n"));
+        assert!(data.contains("authorization: another authorization\r\n"));
+        assert!(data.contains("date: date\r\n"));
+    }
+
+    #[actix_rt::test]
+    async fn test_no_content_length() {
+        let mut bytes = BytesMut::with_capacity(2048);
+
+        let mut res = Response::with_body(StatusCode::SWITCHING_PROTOCOLS, ());
+        res.headers_mut().insert(DATE, HeaderValue::from_static(""));
+        res.headers_mut()
+            .insert(CONTENT_LENGTH, HeaderValue::from_static("0"));
+
+        let _ = res.encode_headers(
+            &mut bytes,
+            Version::HTTP_11,
+            BodySize::Stream,
+            ConnectionType::Upgrade,
+            &ServiceConfig::default(),
+        );
+        let data = String::from_utf8(Vec::from(bytes.split().freeze().as_ref())).unwrap();
+        assert!(!data.contains("content-length: 0\r\n"));
+        assert!(!data.contains("transfer-encoding: chunked\r\n"));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/h1/expect.rs.html b/src/actix_http/h1/expect.rs.html new file mode 100644 index 000000000..2940ffa7d --- /dev/null +++ b/src/actix_http/h1/expect.rs.html @@ -0,0 +1,67 @@ +expect.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_service::{Service, ServiceFactory};
+use actix_utils::future::{ready, Ready};
+
+use crate::{Error, Request};
+
+pub struct ExpectHandler;
+
+impl ServiceFactory<Request> for ExpectHandler {
+    type Response = Request;
+    type Error = Error;
+    type Config = ();
+    type Service = ExpectHandler;
+    type InitError = Error;
+    type Future = Ready<Result<Self::Service, Self::InitError>>;
+
+    fn new_service(&self, _: Self::Config) -> Self::Future {
+        ready(Ok(ExpectHandler))
+    }
+}
+
+impl Service<Request> for ExpectHandler {
+    type Response = Request;
+    type Error = Error;
+    type Future = Ready<Result<Self::Response, Self::Error>>;
+
+    actix_service::always_ready!();
+
+    fn call(&self, req: Request) -> Self::Future {
+        ready(Ok(req))
+        // TODO: add some way to trigger error
+        // Err(error::ErrorExpectationFailed("test"))
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/h1/mod.rs.html b/src/actix_http/h1/mod.rs.html new file mode 100644 index 000000000..6113a890b --- /dev/null +++ b/src/actix_http/h1/mod.rs.html @@ -0,0 +1,187 @@ +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
+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
+
//! HTTP/1 protocol implementation.
+
+use bytes::{Bytes, BytesMut};
+
+mod chunked;
+mod client;
+mod codec;
+mod decoder;
+mod dispatcher;
+#[cfg(test)]
+mod dispatcher_tests;
+mod encoder;
+mod expect;
+mod payload;
+mod service;
+mod timer;
+mod upgrade;
+mod utils;
+
+pub use self::{
+    client::{ClientCodec, ClientPayloadCodec},
+    codec::Codec,
+    dispatcher::Dispatcher,
+    expect::ExpectHandler,
+    payload::Payload,
+    service::{H1Service, H1ServiceHandler},
+    upgrade::UpgradeHandler,
+    utils::SendResponse,
+};
+
+#[derive(Debug)]
+/// Codec message
+pub enum Message<T> {
+    /// HTTP message.
+    Item(T),
+
+    /// Payload chunk.
+    Chunk(Option<Bytes>),
+}
+
+impl<T> From<T> for Message<T> {
+    fn from(item: T) -> Self {
+        Message::Item(item)
+    }
+}
+
+/// Incoming request type
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum MessageType {
+    None,
+    Payload,
+    Stream,
+}
+
+const LW: usize = 2 * 1024;
+const HW: usize = 32 * 1024;
+
+pub(crate) fn reserve_readbuf(src: &mut BytesMut) {
+    let cap = src.capacity();
+    if cap < LW {
+        src.reserve(HW - cap);
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::Request;
+
+    impl Message<Request> {
+        pub fn message(self) -> Request {
+            match self {
+                Message::Item(req) => req,
+                _ => panic!("error"),
+            }
+        }
+
+        pub fn chunk(self) -> Bytes {
+            match self {
+                Message::Chunk(Some(data)) => data,
+                _ => panic!("error"),
+            }
+        }
+
+        pub fn eof(self) -> bool {
+            match self {
+                Message::Chunk(None) => true,
+                Message::Chunk(Some(_)) => false,
+                _ => panic!("error"),
+            }
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/h1/payload.rs.html b/src/actix_http/h1/payload.rs.html new file mode 100644 index 000000000..136fd79ac --- /dev/null +++ b/src/actix_http/h1/payload.rs.html @@ -0,0 +1,565 @@ +payload.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
+
//! Payload stream
+
+use std::{
+    cell::RefCell,
+    collections::VecDeque,
+    pin::Pin,
+    rc::{Rc, Weak},
+    task::{Context, Poll, Waker},
+};
+
+use bytes::Bytes;
+use futures_core::Stream;
+
+use crate::error::PayloadError;
+
+/// max buffer size 32k
+pub(crate) const MAX_BUFFER_SIZE: usize = 32_768;
+
+#[derive(Debug, PartialEq, Eq)]
+pub enum PayloadStatus {
+    Read,
+    Pause,
+    Dropped,
+}
+
+/// Buffered stream of bytes chunks
+///
+/// Payload stores chunks in a vector. First chunk can be received with `poll_next`. Payload does
+/// not notify current task when new data is available.
+///
+/// Payload can be used as `Response` body stream.
+#[derive(Debug)]
+pub struct Payload {
+    inner: Rc<RefCell<Inner>>,
+}
+
+impl Payload {
+    /// Creates a payload stream.
+    ///
+    /// This method construct two objects responsible for bytes stream generation:
+    /// - `PayloadSender` - *Sender* side of the stream
+    /// - `Payload` - *Receiver* side of the stream
+    pub fn create(eof: bool) -> (PayloadSender, Payload) {
+        let shared = Rc::new(RefCell::new(Inner::new(eof)));
+
+        (
+            PayloadSender::new(Rc::downgrade(&shared)),
+            Payload { inner: shared },
+        )
+    }
+
+    /// Creates an empty payload.
+    pub(crate) fn empty() -> Payload {
+        Payload {
+            inner: Rc::new(RefCell::new(Inner::new(true))),
+        }
+    }
+
+    /// Length of the data in this payload
+    #[cfg(test)]
+    pub fn len(&self) -> usize {
+        self.inner.borrow().len()
+    }
+
+    /// Is payload empty
+    #[cfg(test)]
+    pub fn is_empty(&self) -> bool {
+        self.inner.borrow().len() == 0
+    }
+
+    /// Put unused data back to payload
+    #[inline]
+    pub fn unread_data(&mut self, data: Bytes) {
+        self.inner.borrow_mut().unread_data(data);
+    }
+}
+
+impl Stream for Payload {
+    type Item = Result<Bytes, PayloadError>;
+
+    fn poll_next(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+    ) -> Poll<Option<Result<Bytes, PayloadError>>> {
+        Pin::new(&mut *self.inner.borrow_mut()).poll_next(cx)
+    }
+}
+
+/// Sender part of the payload stream
+pub struct PayloadSender {
+    inner: Weak<RefCell<Inner>>,
+}
+
+impl PayloadSender {
+    fn new(inner: Weak<RefCell<Inner>>) -> Self {
+        Self { inner }
+    }
+
+    #[inline]
+    pub fn set_error(&mut self, err: PayloadError) {
+        if let Some(shared) = self.inner.upgrade() {
+            shared.borrow_mut().set_error(err)
+        }
+    }
+
+    #[inline]
+    pub fn feed_eof(&mut self) {
+        if let Some(shared) = self.inner.upgrade() {
+            shared.borrow_mut().feed_eof()
+        }
+    }
+
+    #[inline]
+    pub fn feed_data(&mut self, data: Bytes) {
+        if let Some(shared) = self.inner.upgrade() {
+            shared.borrow_mut().feed_data(data)
+        }
+    }
+
+    #[allow(clippy::needless_pass_by_ref_mut)]
+    #[inline]
+    pub fn need_read(&self, cx: &mut Context<'_>) -> PayloadStatus {
+        // we check need_read only if Payload (other side) is alive,
+        // otherwise always return true (consume payload)
+        if let Some(shared) = self.inner.upgrade() {
+            if shared.borrow().need_read {
+                PayloadStatus::Read
+            } else {
+                shared.borrow_mut().register_io(cx);
+                PayloadStatus::Pause
+            }
+        } else {
+            PayloadStatus::Dropped
+        }
+    }
+}
+
+#[derive(Debug)]
+struct Inner {
+    len: usize,
+    eof: bool,
+    err: Option<PayloadError>,
+    need_read: bool,
+    items: VecDeque<Bytes>,
+    task: Option<Waker>,
+    io_task: Option<Waker>,
+}
+
+impl Inner {
+    fn new(eof: bool) -> Self {
+        Inner {
+            eof,
+            len: 0,
+            err: None,
+            items: VecDeque::new(),
+            need_read: true,
+            task: None,
+            io_task: None,
+        }
+    }
+
+    /// Wake up future waiting for payload data to be available.
+    fn wake(&mut self) {
+        if let Some(waker) = self.task.take() {
+            waker.wake();
+        }
+    }
+
+    /// Wake up future feeding data to Payload.
+    fn wake_io(&mut self) {
+        if let Some(waker) = self.io_task.take() {
+            waker.wake();
+        }
+    }
+
+    /// Register future waiting data from payload.
+    /// Waker would be used in `Inner::wake`
+    fn register(&mut self, cx: &Context<'_>) {
+        if self
+            .task
+            .as_ref()
+            .map_or(true, |w| !cx.waker().will_wake(w))
+        {
+            self.task = Some(cx.waker().clone());
+        }
+    }
+
+    // Register future feeding data to payload.
+    /// Waker would be used in `Inner::wake_io`
+    fn register_io(&mut self, cx: &Context<'_>) {
+        if self
+            .io_task
+            .as_ref()
+            .map_or(true, |w| !cx.waker().will_wake(w))
+        {
+            self.io_task = Some(cx.waker().clone());
+        }
+    }
+
+    #[inline]
+    fn set_error(&mut self, err: PayloadError) {
+        self.err = Some(err);
+    }
+
+    #[inline]
+    fn feed_eof(&mut self) {
+        self.eof = true;
+    }
+
+    #[inline]
+    fn feed_data(&mut self, data: Bytes) {
+        self.len += data.len();
+        self.items.push_back(data);
+        self.need_read = self.len < MAX_BUFFER_SIZE;
+        self.wake();
+    }
+
+    #[cfg(test)]
+    fn len(&self) -> usize {
+        self.len
+    }
+
+    fn poll_next(
+        mut self: Pin<&mut Self>,
+        cx: &Context<'_>,
+    ) -> Poll<Option<Result<Bytes, PayloadError>>> {
+        if let Some(data) = self.items.pop_front() {
+            self.len -= data.len();
+            self.need_read = self.len < MAX_BUFFER_SIZE;
+
+            if self.need_read && !self.eof {
+                self.register(cx);
+            }
+            self.wake_io();
+            Poll::Ready(Some(Ok(data)))
+        } else if let Some(err) = self.err.take() {
+            Poll::Ready(Some(Err(err)))
+        } else if self.eof {
+            Poll::Ready(None)
+        } else {
+            self.need_read = true;
+            self.register(cx);
+            self.wake_io();
+            Poll::Pending
+        }
+    }
+
+    fn unread_data(&mut self, data: Bytes) {
+        self.len += data.len();
+        self.items.push_front(data);
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_utils::future::poll_fn;
+    use static_assertions::{assert_impl_all, assert_not_impl_any};
+
+    use super::*;
+
+    assert_impl_all!(Payload: Unpin);
+    assert_not_impl_any!(Payload: Send, Sync);
+
+    assert_impl_all!(Inner: Unpin, Send, Sync);
+
+    #[actix_rt::test]
+    async fn test_unread_data() {
+        let (_, mut payload) = Payload::create(false);
+
+        payload.unread_data(Bytes::from("data"));
+        assert!(!payload.is_empty());
+        assert_eq!(payload.len(), 4);
+
+        assert_eq!(
+            Bytes::from("data"),
+            poll_fn(|cx| Pin::new(&mut payload).poll_next(cx))
+                .await
+                .unwrap()
+                .unwrap()
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/h1/service.rs.html b/src/actix_http/h1/service.rs.html new file mode 100644 index 000000000..befcf98d0 --- /dev/null +++ b/src/actix_http/h1/service.rs.html @@ -0,0 +1,1093 @@ +service.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
+
use std::{
+    fmt,
+    marker::PhantomData,
+    net,
+    rc::Rc,
+    task::{Context, Poll},
+};
+
+use actix_codec::{AsyncRead, AsyncWrite, Framed};
+use actix_rt::net::TcpStream;
+use actix_service::{
+    fn_service, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt as _,
+};
+use actix_utils::future::ready;
+use futures_core::future::LocalBoxFuture;
+use tracing::error;
+
+use super::{codec::Codec, dispatcher::Dispatcher, ExpectHandler, UpgradeHandler};
+use crate::{
+    body::{BoxBody, MessageBody},
+    config::ServiceConfig,
+    error::DispatchError,
+    service::HttpServiceHandler,
+    ConnectCallback, OnConnectData, Request, Response,
+};
+
+/// `ServiceFactory` implementation for HTTP1 transport
+pub struct H1Service<T, S, B, X = ExpectHandler, U = UpgradeHandler> {
+    srv: S,
+    cfg: ServiceConfig,
+    expect: X,
+    upgrade: Option<U>,
+    on_connect_ext: Option<Rc<ConnectCallback<T>>>,
+    _phantom: PhantomData<B>,
+}
+
+impl<T, S, B> H1Service<T, S, B>
+where
+    S: ServiceFactory<Request, Config = ()>,
+    S::Error: Into<Response<BoxBody>>,
+    S::InitError: fmt::Debug,
+    S::Response: Into<Response<B>>,
+    B: MessageBody,
+{
+    /// Create new `HttpService` instance with config.
+    pub(crate) fn with_config<F: IntoServiceFactory<S, Request>>(
+        cfg: ServiceConfig,
+        service: F,
+    ) -> Self {
+        H1Service {
+            cfg,
+            srv: service.into_factory(),
+            expect: ExpectHandler,
+            upgrade: None,
+            on_connect_ext: None,
+            _phantom: PhantomData,
+        }
+    }
+}
+
+impl<S, B, X, U> H1Service<TcpStream, S, B, X, U>
+where
+    S: ServiceFactory<Request, Config = ()>,
+    S::Future: 'static,
+    S::Error: Into<Response<BoxBody>>,
+    S::InitError: fmt::Debug,
+    S::Response: Into<Response<B>>,
+
+    B: MessageBody,
+
+    X: ServiceFactory<Request, Config = (), Response = Request>,
+    X::Future: 'static,
+    X::Error: Into<Response<BoxBody>>,
+    X::InitError: fmt::Debug,
+
+    U: ServiceFactory<(Request, Framed<TcpStream, Codec>), Config = (), Response = ()>,
+    U::Future: 'static,
+    U::Error: fmt::Display + Into<Response<BoxBody>>,
+    U::InitError: fmt::Debug,
+{
+    /// Create simple tcp stream service
+    pub fn tcp(
+        self,
+    ) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = DispatchError, InitError = ()>
+    {
+        fn_service(|io: TcpStream| {
+            let peer_addr = io.peer_addr().ok();
+            ready(Ok((io, peer_addr)))
+        })
+        .and_then(self)
+    }
+}
+
+#[cfg(feature = "openssl")]
+mod openssl {
+    use actix_tls::accept::{
+        openssl::{
+            reexports::{Error as SslError, SslAcceptor},
+            Acceptor, TlsStream,
+        },
+        TlsError,
+    };
+
+    use super::*;
+
+    impl<S, B, X, U> H1Service<TlsStream<TcpStream>, S, B, X, U>
+    where
+        S: ServiceFactory<Request, Config = ()>,
+        S::Future: 'static,
+        S::Error: Into<Response<BoxBody>>,
+        S::InitError: fmt::Debug,
+        S::Response: Into<Response<B>>,
+
+        B: MessageBody,
+
+        X: ServiceFactory<Request, Config = (), Response = Request>,
+        X::Future: 'static,
+        X::Error: Into<Response<BoxBody>>,
+        X::InitError: fmt::Debug,
+
+        U: ServiceFactory<
+            (Request, Framed<TlsStream<TcpStream>, Codec>),
+            Config = (),
+            Response = (),
+        >,
+        U::Future: 'static,
+        U::Error: fmt::Display + Into<Response<BoxBody>>,
+        U::InitError: fmt::Debug,
+    {
+        /// Create OpenSSL based service.
+        pub fn openssl(
+            self,
+            acceptor: SslAcceptor,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<SslError, DispatchError>,
+            InitError = (),
+        > {
+            Acceptor::new(acceptor)
+                .map_init_err(|_| {
+                    unreachable!("TLS acceptor service factory does not error on init")
+                })
+                .map_err(TlsError::into_service_error)
+                .map(|io: TlsStream<TcpStream>| {
+                    let peer_addr = io.get_ref().peer_addr().ok();
+                    (io, peer_addr)
+                })
+                .and_then(self.map_err(TlsError::Service))
+        }
+    }
+}
+
+#[cfg(feature = "rustls-0_20")]
+mod rustls_0_20 {
+    use std::io;
+
+    use actix_service::ServiceFactoryExt as _;
+    use actix_tls::accept::{
+        rustls_0_20::{reexports::ServerConfig, Acceptor, TlsStream},
+        TlsError,
+    };
+
+    use super::*;
+
+    impl<S, B, X, U> H1Service<TlsStream<TcpStream>, S, B, X, U>
+    where
+        S: ServiceFactory<Request, Config = ()>,
+        S::Future: 'static,
+        S::Error: Into<Response<BoxBody>>,
+        S::InitError: fmt::Debug,
+        S::Response: Into<Response<B>>,
+
+        B: MessageBody,
+
+        X: ServiceFactory<Request, Config = (), Response = Request>,
+        X::Future: 'static,
+        X::Error: Into<Response<BoxBody>>,
+        X::InitError: fmt::Debug,
+
+        U: ServiceFactory<
+            (Request, Framed<TlsStream<TcpStream>, Codec>),
+            Config = (),
+            Response = (),
+        >,
+        U::Future: 'static,
+        U::Error: fmt::Display + Into<Response<BoxBody>>,
+        U::InitError: fmt::Debug,
+    {
+        /// Create Rustls v0.20 based service.
+        pub fn rustls(
+            self,
+            config: ServerConfig,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<io::Error, DispatchError>,
+            InitError = (),
+        > {
+            Acceptor::new(config)
+                .map_init_err(|_| {
+                    unreachable!("TLS acceptor service factory does not error on init")
+                })
+                .map_err(TlsError::into_service_error)
+                .map(|io: TlsStream<TcpStream>| {
+                    let peer_addr = io.get_ref().0.peer_addr().ok();
+                    (io, peer_addr)
+                })
+                .and_then(self.map_err(TlsError::Service))
+        }
+    }
+}
+
+#[cfg(feature = "rustls-0_21")]
+mod rustls_0_21 {
+    use std::io;
+
+    use actix_service::ServiceFactoryExt as _;
+    use actix_tls::accept::{
+        rustls_0_21::{reexports::ServerConfig, Acceptor, TlsStream},
+        TlsError,
+    };
+
+    use super::*;
+
+    impl<S, B, X, U> H1Service<TlsStream<TcpStream>, S, B, X, U>
+    where
+        S: ServiceFactory<Request, Config = ()>,
+        S::Future: 'static,
+        S::Error: Into<Response<BoxBody>>,
+        S::InitError: fmt::Debug,
+        S::Response: Into<Response<B>>,
+
+        B: MessageBody,
+
+        X: ServiceFactory<Request, Config = (), Response = Request>,
+        X::Future: 'static,
+        X::Error: Into<Response<BoxBody>>,
+        X::InitError: fmt::Debug,
+
+        U: ServiceFactory<
+            (Request, Framed<TlsStream<TcpStream>, Codec>),
+            Config = (),
+            Response = (),
+        >,
+        U::Future: 'static,
+        U::Error: fmt::Display + Into<Response<BoxBody>>,
+        U::InitError: fmt::Debug,
+    {
+        /// Create Rustls v0.21 based service.
+        pub fn rustls_021(
+            self,
+            config: ServerConfig,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<io::Error, DispatchError>,
+            InitError = (),
+        > {
+            Acceptor::new(config)
+                .map_init_err(|_| {
+                    unreachable!("TLS acceptor service factory does not error on init")
+                })
+                .map_err(TlsError::into_service_error)
+                .map(|io: TlsStream<TcpStream>| {
+                    let peer_addr = io.get_ref().0.peer_addr().ok();
+                    (io, peer_addr)
+                })
+                .and_then(self.map_err(TlsError::Service))
+        }
+    }
+}
+
+#[cfg(feature = "rustls-0_22")]
+mod rustls_0_22 {
+    use std::io;
+
+    use actix_service::ServiceFactoryExt as _;
+    use actix_tls::accept::{
+        rustls_0_22::{reexports::ServerConfig, Acceptor, TlsStream},
+        TlsError,
+    };
+
+    use super::*;
+
+    impl<S, B, X, U> H1Service<TlsStream<TcpStream>, S, B, X, U>
+    where
+        S: ServiceFactory<Request, Config = ()>,
+        S::Future: 'static,
+        S::Error: Into<Response<BoxBody>>,
+        S::InitError: fmt::Debug,
+        S::Response: Into<Response<B>>,
+
+        B: MessageBody,
+
+        X: ServiceFactory<Request, Config = (), Response = Request>,
+        X::Future: 'static,
+        X::Error: Into<Response<BoxBody>>,
+        X::InitError: fmt::Debug,
+
+        U: ServiceFactory<
+            (Request, Framed<TlsStream<TcpStream>, Codec>),
+            Config = (),
+            Response = (),
+        >,
+        U::Future: 'static,
+        U::Error: fmt::Display + Into<Response<BoxBody>>,
+        U::InitError: fmt::Debug,
+    {
+        /// Create Rustls v0.22 based service.
+        pub fn rustls_0_22(
+            self,
+            config: ServerConfig,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<io::Error, DispatchError>,
+            InitError = (),
+        > {
+            Acceptor::new(config)
+                .map_init_err(|_| {
+                    unreachable!("TLS acceptor service factory does not error on init")
+                })
+                .map_err(TlsError::into_service_error)
+                .map(|io: TlsStream<TcpStream>| {
+                    let peer_addr = io.get_ref().0.peer_addr().ok();
+                    (io, peer_addr)
+                })
+                .and_then(self.map_err(TlsError::Service))
+        }
+    }
+}
+
+#[cfg(feature = "rustls-0_23")]
+mod rustls_0_23 {
+    use std::io;
+
+    use actix_service::ServiceFactoryExt as _;
+    use actix_tls::accept::{
+        rustls_0_23::{reexports::ServerConfig, Acceptor, TlsStream},
+        TlsError,
+    };
+
+    use super::*;
+
+    impl<S, B, X, U> H1Service<TlsStream<TcpStream>, S, B, X, U>
+    where
+        S: ServiceFactory<Request, Config = ()>,
+        S::Future: 'static,
+        S::Error: Into<Response<BoxBody>>,
+        S::InitError: fmt::Debug,
+        S::Response: Into<Response<B>>,
+
+        B: MessageBody,
+
+        X: ServiceFactory<Request, Config = (), Response = Request>,
+        X::Future: 'static,
+        X::Error: Into<Response<BoxBody>>,
+        X::InitError: fmt::Debug,
+
+        U: ServiceFactory<
+            (Request, Framed<TlsStream<TcpStream>, Codec>),
+            Config = (),
+            Response = (),
+        >,
+        U::Future: 'static,
+        U::Error: fmt::Display + Into<Response<BoxBody>>,
+        U::InitError: fmt::Debug,
+    {
+        /// Create Rustls v0.23 based service.
+        pub fn rustls_0_23(
+            self,
+            config: ServerConfig,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<io::Error, DispatchError>,
+            InitError = (),
+        > {
+            Acceptor::new(config)
+                .map_init_err(|_| {
+                    unreachable!("TLS acceptor service factory does not error on init")
+                })
+                .map_err(TlsError::into_service_error)
+                .map(|io: TlsStream<TcpStream>| {
+                    let peer_addr = io.get_ref().0.peer_addr().ok();
+                    (io, peer_addr)
+                })
+                .and_then(self.map_err(TlsError::Service))
+        }
+    }
+}
+
+impl<T, S, B, X, U> H1Service<T, S, B, X, U>
+where
+    S: ServiceFactory<Request, Config = ()>,
+    S::Error: Into<Response<BoxBody>>,
+    S::Response: Into<Response<B>>,
+    S::InitError: fmt::Debug,
+    B: MessageBody,
+{
+    pub fn expect<X1>(self, expect: X1) -> H1Service<T, S, B, X1, U>
+    where
+        X1: ServiceFactory<Request, Response = Request>,
+        X1::Error: Into<Response<BoxBody>>,
+        X1::InitError: fmt::Debug,
+    {
+        H1Service {
+            expect,
+            cfg: self.cfg,
+            srv: self.srv,
+            upgrade: self.upgrade,
+            on_connect_ext: self.on_connect_ext,
+            _phantom: PhantomData,
+        }
+    }
+
+    pub fn upgrade<U1>(self, upgrade: Option<U1>) -> H1Service<T, S, B, X, U1>
+    where
+        U1: ServiceFactory<(Request, Framed<T, Codec>), Response = ()>,
+        U1::Error: fmt::Display,
+        U1::InitError: fmt::Debug,
+    {
+        H1Service {
+            upgrade,
+            cfg: self.cfg,
+            srv: self.srv,
+            expect: self.expect,
+            on_connect_ext: self.on_connect_ext,
+            _phantom: PhantomData,
+        }
+    }
+
+    /// Set on connect callback.
+    pub(crate) fn on_connect_ext(mut self, f: Option<Rc<ConnectCallback<T>>>) -> Self {
+        self.on_connect_ext = f;
+        self
+    }
+}
+
+impl<T, S, B, X, U> ServiceFactory<(T, Option<net::SocketAddr>)> for H1Service<T, S, B, X, U>
+where
+    T: AsyncRead + AsyncWrite + Unpin + 'static,
+
+    S: ServiceFactory<Request, Config = ()>,
+    S::Future: 'static,
+    S::Error: Into<Response<BoxBody>>,
+    S::Response: Into<Response<B>>,
+    S::InitError: fmt::Debug,
+
+    B: MessageBody,
+
+    X: ServiceFactory<Request, Config = (), Response = Request>,
+    X::Future: 'static,
+    X::Error: Into<Response<BoxBody>>,
+    X::InitError: fmt::Debug,
+
+    U: ServiceFactory<(Request, Framed<T, Codec>), Config = (), Response = ()>,
+    U::Future: 'static,
+    U::Error: fmt::Display + Into<Response<BoxBody>>,
+    U::InitError: fmt::Debug,
+{
+    type Response = ();
+    type Error = DispatchError;
+    type Config = ();
+    type Service = H1ServiceHandler<T, S::Service, B, X::Service, U::Service>;
+    type InitError = ();
+    type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
+
+    fn new_service(&self, _: ()) -> Self::Future {
+        let service = self.srv.new_service(());
+        let expect = self.expect.new_service(());
+        let upgrade = self.upgrade.as_ref().map(|s| s.new_service(()));
+        let on_connect_ext = self.on_connect_ext.clone();
+        let cfg = self.cfg.clone();
+
+        Box::pin(async move {
+            let expect = expect
+                .await
+                .map_err(|e| error!("Init http expect service error: {:?}", e))?;
+
+            let upgrade = match upgrade {
+                Some(upgrade) => {
+                    let upgrade = upgrade
+                        .await
+                        .map_err(|e| error!("Init http upgrade service error: {:?}", e))?;
+                    Some(upgrade)
+                }
+                None => None,
+            };
+
+            let service = service
+                .await
+                .map_err(|e| error!("Init http service error: {:?}", e))?;
+
+            Ok(H1ServiceHandler::new(
+                cfg,
+                service,
+                expect,
+                upgrade,
+                on_connect_ext,
+            ))
+        })
+    }
+}
+
+/// `Service` implementation for HTTP/1 transport
+pub type H1ServiceHandler<T, S, B, X, U> = HttpServiceHandler<T, S, B, X, U>;
+
+impl<T, S, B, X, U> Service<(T, Option<net::SocketAddr>)> for HttpServiceHandler<T, S, B, X, U>
+where
+    T: AsyncRead + AsyncWrite + Unpin,
+
+    S: Service<Request>,
+    S::Error: Into<Response<BoxBody>>,
+    S::Response: Into<Response<B>>,
+
+    B: MessageBody,
+
+    X: Service<Request, Response = Request>,
+    X::Error: Into<Response<BoxBody>>,
+
+    U: Service<(Request, Framed<T, Codec>), Response = ()>,
+    U::Error: fmt::Display + Into<Response<BoxBody>>,
+{
+    type Response = ();
+    type Error = DispatchError;
+    type Future = Dispatcher<T, S, B, X, U>;
+
+    fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        self._poll_ready(cx).map_err(|err| {
+            error!("HTTP/1 service readiness error: {:?}", err);
+            DispatchError::Service(err)
+        })
+    }
+
+    fn call(&self, (io, addr): (T, Option<net::SocketAddr>)) -> Self::Future {
+        let conn_data = OnConnectData::from_io(&io, self.on_connect_ext.as_deref());
+        Dispatcher::new(io, self.flow.clone(), self.cfg.clone(), addr, conn_data)
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/h1/timer.rs.html b/src/actix_http/h1/timer.rs.html new file mode 100644 index 000000000..5d230b2cb --- /dev/null +++ b/src/actix_http/h1/timer.rs.html @@ -0,0 +1,163 @@ +timer.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
+
use std::{fmt, future::Future, pin::Pin, task::Context};
+
+use actix_rt::time::{Instant, Sleep};
+use tracing::trace;
+
+#[derive(Debug)]
+pub(super) enum TimerState {
+    Disabled,
+    Inactive,
+    Active { timer: Pin<Box<Sleep>> },
+}
+
+impl TimerState {
+    pub(super) fn new(enabled: bool) -> Self {
+        if enabled {
+            Self::Inactive
+        } else {
+            Self::Disabled
+        }
+    }
+
+    pub(super) fn is_enabled(&self) -> bool {
+        matches!(self, Self::Active { .. } | Self::Inactive)
+    }
+
+    pub(super) fn set(&mut self, timer: Sleep, line: u32) {
+        if matches!(self, Self::Disabled) {
+            trace!("setting disabled timer from line {}", line);
+        }
+
+        *self = Self::Active {
+            timer: Box::pin(timer),
+        };
+    }
+
+    pub(super) fn set_and_init(&mut self, cx: &mut Context<'_>, timer: Sleep, line: u32) {
+        self.set(timer, line);
+        self.init(cx);
+    }
+
+    pub(super) fn clear(&mut self, line: u32) {
+        if matches!(self, Self::Disabled) {
+            trace!("trying to clear a disabled timer from line {}", line);
+        }
+
+        if matches!(self, Self::Inactive) {
+            trace!("trying to clear an inactive timer from line {}", line);
+        }
+
+        *self = Self::Inactive;
+    }
+
+    pub(super) fn init(&mut self, cx: &mut Context<'_>) {
+        if let TimerState::Active { timer } = self {
+            let _ = timer.as_mut().poll(cx);
+        }
+    }
+}
+
+impl fmt::Display for TimerState {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            TimerState::Disabled => f.write_str("timer is disabled"),
+            TimerState::Inactive => f.write_str("timer is inactive"),
+            TimerState::Active { timer } => {
+                let deadline = timer.deadline();
+                let now = Instant::now();
+
+                if deadline < now {
+                    f.write_str("timer is active and has reached deadline")
+                } else {
+                    write!(
+                        f,
+                        "timer is active and due to expire in {} milliseconds",
+                        ((deadline - now).as_secs_f32() * 1000.0)
+                    )
+                }
+            }
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/h1/upgrade.rs.html b/src/actix_http/h1/upgrade.rs.html new file mode 100644 index 000000000..7f0b03723 --- /dev/null +++ b/src/actix_http/h1/upgrade.rs.html @@ -0,0 +1,65 @@ +upgrade.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
+
use actix_codec::Framed;
+use actix_service::{Service, ServiceFactory};
+use futures_core::future::LocalBoxFuture;
+
+use crate::{h1::Codec, Error, Request};
+
+pub struct UpgradeHandler;
+
+impl<T> ServiceFactory<(Request, Framed<T, Codec>)> for UpgradeHandler {
+    type Response = ();
+    type Error = Error;
+    type Config = ();
+    type Service = UpgradeHandler;
+    type InitError = Error;
+    type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
+
+    fn new_service(&self, _: ()) -> Self::Future {
+        unimplemented!()
+    }
+}
+
+impl<T> Service<(Request, Framed<T, Codec>)> for UpgradeHandler {
+    type Response = ();
+    type Error = Error;
+    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
+
+    actix_service::always_ready!();
+
+    fn call(&self, _: (Request, Framed<T, Codec>)) -> Self::Future {
+        unimplemented!()
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/h1/utils.rs.html b/src/actix_http/h1/utils.rs.html new file mode 100644 index 000000000..628bb3b96 --- /dev/null +++ b/src/actix_http/h1/utils.rs.html @@ -0,0 +1,277 @@ +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
+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::{
+    future::Future,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use actix_codec::{AsyncRead, AsyncWrite, Framed};
+use pin_project_lite::pin_project;
+
+use crate::{
+    body::{BodySize, MessageBody},
+    h1::{Codec, Message},
+    Error, Response,
+};
+
+pin_project! {
+    /// Send HTTP/1 response
+    pub struct SendResponse<T, B> {
+        res: Option<Message<(Response<()>, BodySize)>>,
+
+        #[pin]
+        body: Option<B>,
+
+        #[pin]
+        framed: Option<Framed<T, Codec>>,
+    }
+}
+
+impl<T, B> SendResponse<T, B>
+where
+    B: MessageBody,
+    B::Error: Into<Error>,
+{
+    pub fn new(framed: Framed<T, Codec>, response: Response<B>) -> Self {
+        let (res, body) = response.into_parts();
+
+        SendResponse {
+            res: Some((res, body.size()).into()),
+            body: Some(body),
+            framed: Some(framed),
+        }
+    }
+}
+
+impl<T, B> Future for SendResponse<T, B>
+where
+    T: AsyncRead + AsyncWrite + Unpin,
+    B: MessageBody,
+    B::Error: Into<Error>,
+{
+    type Output = Result<Framed<T, Codec>, Error>;
+
+    // TODO: rethink if we need loops in polls
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let mut this = self.as_mut().project();
+
+        let mut body_done = this.body.is_none();
+        loop {
+            let mut body_ready = !body_done;
+
+            // send body
+            if this.res.is_none() && body_ready {
+                while body_ready
+                    && !body_done
+                    && !this
+                        .framed
+                        .as_ref()
+                        .as_pin_ref()
+                        .unwrap()
+                        .is_write_buf_full()
+                {
+                    let next = match this.body.as_mut().as_pin_mut().unwrap().poll_next(cx) {
+                        Poll::Ready(Some(Ok(item))) => Poll::Ready(Some(item)),
+                        Poll::Ready(Some(Err(err))) => return Poll::Ready(Err(err.into())),
+                        Poll::Ready(None) => Poll::Ready(None),
+                        Poll::Pending => Poll::Pending,
+                    };
+
+                    match next {
+                        Poll::Ready(item) => {
+                            // body is done when item is None
+                            body_done = item.is_none();
+                            if body_done {
+                                this.body.set(None);
+                            }
+                            let framed = this.framed.as_mut().as_pin_mut().unwrap();
+                            framed
+                                .write(Message::Chunk(item))
+                                .map_err(|err| Error::new_send_response().with_cause(err))?;
+                        }
+                        Poll::Pending => body_ready = false,
+                    }
+                }
+            }
+
+            let framed = this.framed.as_mut().as_pin_mut().unwrap();
+
+            // flush write buffer
+            if !framed.is_write_buf_empty() {
+                match framed
+                    .flush(cx)
+                    .map_err(|err| Error::new_send_response().with_cause(err))?
+                {
+                    Poll::Ready(_) => {
+                        if body_ready {
+                            continue;
+                        } else {
+                            return Poll::Pending;
+                        }
+                    }
+                    Poll::Pending => return Poll::Pending,
+                }
+            }
+
+            // send response
+            if let Some(res) = this.res.take() {
+                framed
+                    .write(res)
+                    .map_err(|err| Error::new_send_response().with_cause(err))?;
+                continue;
+            }
+
+            if !body_done {
+                if body_ready {
+                    continue;
+                } else {
+                    return Poll::Pending;
+                }
+            } else {
+                break;
+            }
+        }
+
+        let framed = this.framed.take().unwrap();
+
+        Poll::Ready(Ok(framed))
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/h2/dispatcher.rs.html b/src/actix_http/h2/dispatcher.rs.html new file mode 100644 index 000000000..a9f1c49f3 --- /dev/null +++ b/src/actix_http/h2/dispatcher.rs.html @@ -0,0 +1,711 @@ +dispatcher.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
+
use std::{
+    cmp,
+    error::Error as StdError,
+    future::Future,
+    marker::PhantomData,
+    net,
+    pin::{pin, Pin},
+    rc::Rc,
+    task::{Context, Poll},
+};
+
+use actix_codec::{AsyncRead, AsyncWrite};
+use actix_rt::time::{sleep, Sleep};
+use actix_service::Service;
+use actix_utils::future::poll_fn;
+use bytes::{Bytes, BytesMut};
+use futures_core::ready;
+use h2::{
+    server::{Connection, SendResponse},
+    Ping, PingPong,
+};
+use pin_project_lite::pin_project;
+
+use crate::{
+    body::{BodySize, BoxBody, MessageBody},
+    config::ServiceConfig,
+    header::{
+        HeaderName, HeaderValue, CONNECTION, CONTENT_LENGTH, DATE, TRANSFER_ENCODING, UPGRADE,
+    },
+    service::HttpFlow,
+    Extensions, Method, OnConnectData, Payload, Request, Response, ResponseHead,
+};
+
+const CHUNK_SIZE: usize = 16_384;
+
+pin_project! {
+    /// Dispatcher for HTTP/2 protocol.
+    pub struct Dispatcher<T, S, B, X, U> {
+        flow: Rc<HttpFlow<S, X, U>>,
+        connection: Connection<T, Bytes>,
+        conn_data: Option<Rc<Extensions>>,
+        config: ServiceConfig,
+        peer_addr: Option<net::SocketAddr>,
+        ping_pong: Option<H2PingPong>,
+        _phantom: PhantomData<B>
+    }
+}
+
+impl<T, S, B, X, U> Dispatcher<T, S, B, X, U>
+where
+    T: AsyncRead + AsyncWrite + Unpin,
+{
+    pub(crate) fn new(
+        mut conn: Connection<T, Bytes>,
+        flow: Rc<HttpFlow<S, X, U>>,
+        config: ServiceConfig,
+        peer_addr: Option<net::SocketAddr>,
+        conn_data: OnConnectData,
+        timer: Option<Pin<Box<Sleep>>>,
+    ) -> Self {
+        let ping_pong = config.keep_alive().duration().map(|dur| H2PingPong {
+            timer: timer
+                .map(|mut timer| {
+                    // reuse timer slot if it was initialized for handshake
+                    timer.as_mut().reset((config.now() + dur).into());
+                    timer
+                })
+                .unwrap_or_else(|| Box::pin(sleep(dur))),
+            in_flight: false,
+            ping_pong: conn.ping_pong().unwrap(),
+        });
+
+        Self {
+            flow,
+            config,
+            peer_addr,
+            connection: conn,
+            conn_data: conn_data.0.map(Rc::new),
+            ping_pong,
+            _phantom: PhantomData,
+        }
+    }
+}
+
+struct H2PingPong {
+    /// Handle to send ping frames from the peer.
+    ping_pong: PingPong,
+
+    /// True when a ping has been sent and is waiting for a reply.
+    in_flight: bool,
+
+    /// Timeout for pong response.
+    timer: Pin<Box<Sleep>>,
+}
+
+impl<T, S, B, X, U> Future for Dispatcher<T, S, B, X, U>
+where
+    T: AsyncRead + AsyncWrite + Unpin,
+
+    S: Service<Request>,
+    S::Error: Into<Response<BoxBody>>,
+    S::Future: 'static,
+    S::Response: Into<Response<B>>,
+
+    B: MessageBody,
+{
+    type Output = Result<(), crate::error::DispatchError>;
+
+    #[inline]
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.get_mut();
+
+        loop {
+            match Pin::new(&mut this.connection).poll_accept(cx)? {
+                Poll::Ready(Some((req, tx))) => {
+                    let (parts, body) = req.into_parts();
+                    let payload = crate::h2::Payload::new(body);
+                    let pl = Payload::H2 { payload };
+                    let mut req = Request::with_payload(pl);
+                    let head_req = parts.method == Method::HEAD;
+
+                    let head = req.head_mut();
+                    head.uri = parts.uri;
+                    head.method = parts.method;
+                    head.version = parts.version;
+                    head.headers = parts.headers.into();
+                    head.peer_addr = this.peer_addr;
+
+                    req.conn_data.clone_from(&this.conn_data);
+
+                    let fut = this.flow.service.call(req);
+                    let config = this.config.clone();
+
+                    // multiplex request handling with spawn task
+                    actix_rt::spawn(async move {
+                        // resolve service call and send response.
+                        let res = match fut.await {
+                            Ok(res) => handle_response(res.into(), tx, config, head_req).await,
+                            Err(err) => {
+                                let res: Response<BoxBody> = err.into();
+                                handle_response(res, tx, config, head_req).await
+                            }
+                        };
+
+                        // log error.
+                        if let Err(err) = res {
+                            match err {
+                                DispatchError::SendResponse(err) => {
+                                    tracing::trace!("Error sending response: {err:?}");
+                                }
+                                DispatchError::SendData(err) => {
+                                    tracing::warn!("Send data error: {err:?}");
+                                }
+                                DispatchError::ResponseBody(err) => {
+                                    tracing::error!("Response payload stream error: {err:?}");
+                                }
+                            }
+                        }
+                    });
+                }
+                Poll::Ready(None) => return Poll::Ready(Ok(())),
+
+                Poll::Pending => match this.ping_pong.as_mut() {
+                    Some(ping_pong) => loop {
+                        if ping_pong.in_flight {
+                            // When there is an in-flight ping-pong, poll pong and and keep-alive
+                            // timer. On successful pong received, update keep-alive timer to
+                            // determine the next timing of ping pong.
+                            match ping_pong.ping_pong.poll_pong(cx)? {
+                                Poll::Ready(_) => {
+                                    ping_pong.in_flight = false;
+
+                                    let dead_line = this.config.keep_alive_deadline().unwrap();
+                                    ping_pong.timer.as_mut().reset(dead_line.into());
+                                }
+                                Poll::Pending => {
+                                    return ping_pong.timer.as_mut().poll(cx).map(|_| Ok(()));
+                                }
+                            }
+                        } else {
+                            // When there is no in-flight ping-pong, keep-alive timer is used to
+                            // wait for next timing of ping-pong. Therefore, at this point it serves
+                            // as an interval instead.
+                            ready!(ping_pong.timer.as_mut().poll(cx));
+
+                            ping_pong.ping_pong.send_ping(Ping::opaque())?;
+
+                            let dead_line = this.config.keep_alive_deadline().unwrap();
+                            ping_pong.timer.as_mut().reset(dead_line.into());
+
+                            ping_pong.in_flight = true;
+                        }
+                    },
+                    None => return Poll::Pending,
+                },
+            }
+        }
+    }
+}
+
+enum DispatchError {
+    SendResponse(h2::Error),
+    SendData(h2::Error),
+    ResponseBody(Box<dyn StdError>),
+}
+
+async fn handle_response<B>(
+    res: Response<B>,
+    mut tx: SendResponse<Bytes>,
+    config: ServiceConfig,
+    head_req: bool,
+) -> Result<(), DispatchError>
+where
+    B: MessageBody,
+{
+    let (res, body) = res.replace_body(());
+
+    // prepare response.
+    let mut size = body.size();
+    let res = prepare_response(config, res.head(), &mut size);
+    let eof_or_head = size.is_eof() || head_req;
+
+    // send response head and return on eof.
+    let mut stream = tx
+        .send_response(res, eof_or_head)
+        .map_err(DispatchError::SendResponse)?;
+
+    if eof_or_head {
+        return Ok(());
+    }
+
+    let mut body = pin!(body);
+
+    // poll response body and send chunks to client
+    while let Some(res) = poll_fn(|cx| body.as_mut().poll_next(cx)).await {
+        let mut chunk = res.map_err(|err| DispatchError::ResponseBody(err.into()))?;
+
+        'send: loop {
+            let chunk_size = cmp::min(chunk.len(), CHUNK_SIZE);
+
+            // reserve enough space and wait for stream ready.
+            stream.reserve_capacity(chunk_size);
+
+            match poll_fn(|cx| stream.poll_capacity(cx)).await {
+                // No capacity left. drop body and return.
+                None => return Ok(()),
+
+                Some(Err(err)) => return Err(DispatchError::SendData(err)),
+
+                Some(Ok(cap)) => {
+                    // split chunk to writeable size and send to client
+                    let len = chunk.len();
+                    let bytes = chunk.split_to(cmp::min(len, cap));
+
+                    stream
+                        .send_data(bytes, false)
+                        .map_err(DispatchError::SendData)?;
+
+                    // Current chuck completely sent. break send loop and poll next one.
+                    if chunk.is_empty() {
+                        break 'send;
+                    }
+                }
+            }
+        }
+    }
+
+    // response body streaming finished. send end of stream and return.
+    stream
+        .send_data(Bytes::new(), true)
+        .map_err(DispatchError::SendData)?;
+
+    Ok(())
+}
+
+fn prepare_response(
+    config: ServiceConfig,
+    head: &ResponseHead,
+    size: &mut BodySize,
+) -> http::Response<()> {
+    let mut has_date = false;
+    let mut skip_len = size != &BodySize::Stream;
+
+    let mut res = http::Response::new(());
+    *res.status_mut() = head.status;
+    *res.version_mut() = http::Version::HTTP_2;
+
+    // Content length
+    match head.status {
+        http::StatusCode::NO_CONTENT
+        | http::StatusCode::CONTINUE
+        | http::StatusCode::PROCESSING => *size = BodySize::None,
+        http::StatusCode::SWITCHING_PROTOCOLS => {
+            skip_len = true;
+            *size = BodySize::Stream;
+        }
+        _ => {}
+    }
+
+    match size {
+        BodySize::None | BodySize::Stream => {}
+
+        BodySize::Sized(0) => {
+            #[allow(clippy::declare_interior_mutable_const)]
+            const HV_ZERO: HeaderValue = HeaderValue::from_static("0");
+            res.headers_mut().insert(CONTENT_LENGTH, HV_ZERO);
+        }
+
+        BodySize::Sized(len) => {
+            let mut buf = itoa::Buffer::new();
+
+            res.headers_mut().insert(
+                CONTENT_LENGTH,
+                HeaderValue::from_str(buf.format(*len)).unwrap(),
+            );
+        }
+    };
+
+    // copy headers
+    for (key, value) in head.headers.iter() {
+        match key {
+            // omit HTTP/1.x only headers according to:
+            // https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.2
+            &CONNECTION | &TRANSFER_ENCODING | &UPGRADE => continue,
+
+            &CONTENT_LENGTH if skip_len => continue,
+            &DATE => has_date = true,
+
+            // omit HTTP/1.x only headers according to:
+            // https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.2
+            hdr if hdr == HeaderName::from_static("keep-alive")
+                || hdr == HeaderName::from_static("proxy-connection") =>
+            {
+                continue
+            }
+
+            _ => {}
+        }
+
+        res.headers_mut().append(key, value.clone());
+    }
+
+    // set date header
+    if !has_date {
+        let mut bytes = BytesMut::with_capacity(29);
+        config.write_date_header_value(&mut bytes);
+        res.headers_mut().insert(
+            DATE,
+            // SAFETY: serialized date-times are known ASCII strings
+            unsafe { HeaderValue::from_maybe_shared_unchecked(bytes.freeze()) },
+        );
+    }
+
+    res
+}
+
\ No newline at end of file diff --git a/src/actix_http/h2/mod.rs.html b/src/actix_http/h2/mod.rs.html new file mode 100644 index 000000000..6244a8889 --- /dev/null +++ b/src/actix_http/h2/mod.rs.html @@ -0,0 +1,215 @@ +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
+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
+
//! HTTP/2 protocol.
+
+use std::{
+    future::Future,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use actix_codec::{AsyncRead, AsyncWrite};
+use actix_rt::time::{sleep_until, Sleep};
+use bytes::Bytes;
+use futures_core::{ready, Stream};
+use h2::{
+    server::{handshake, Connection, Handshake},
+    RecvStream,
+};
+
+use crate::{
+    config::ServiceConfig,
+    error::{DispatchError, PayloadError},
+};
+
+mod dispatcher;
+mod service;
+
+pub use self::{dispatcher::Dispatcher, service::H2Service};
+
+/// HTTP/2 peer stream.
+pub struct Payload {
+    stream: RecvStream,
+}
+
+impl Payload {
+    pub(crate) fn new(stream: RecvStream) -> Self {
+        Self { stream }
+    }
+}
+
+impl Stream for Payload {
+    type Item = Result<Bytes, PayloadError>;
+
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        let this = self.get_mut();
+
+        match ready!(Pin::new(&mut this.stream).poll_data(cx)) {
+            Some(Ok(chunk)) => {
+                let len = chunk.len();
+
+                match this.stream.flow_control().release_capacity(len) {
+                    Ok(()) => Poll::Ready(Some(Ok(chunk))),
+                    Err(err) => Poll::Ready(Some(Err(err.into()))),
+                }
+            }
+            Some(Err(err)) => Poll::Ready(Some(Err(err.into()))),
+            None => Poll::Ready(None),
+        }
+    }
+}
+
+pub(crate) fn handshake_with_timeout<T>(io: T, config: &ServiceConfig) -> HandshakeWithTimeout<T>
+where
+    T: AsyncRead + AsyncWrite + Unpin,
+{
+    HandshakeWithTimeout {
+        handshake: handshake(io),
+        timer: config
+            .client_request_deadline()
+            .map(|deadline| Box::pin(sleep_until(deadline.into()))),
+    }
+}
+
+pub(crate) struct HandshakeWithTimeout<T: AsyncRead + AsyncWrite + Unpin> {
+    handshake: Handshake<T>,
+    timer: Option<Pin<Box<Sleep>>>,
+}
+
+impl<T> Future for HandshakeWithTimeout<T>
+where
+    T: AsyncRead + AsyncWrite + Unpin,
+{
+    type Output = Result<(Connection<T, Bytes>, Option<Pin<Box<Sleep>>>), DispatchError>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.get_mut();
+
+        match Pin::new(&mut this.handshake).poll(cx)? {
+            // return the timer on success handshake; its slot can be re-used for h2 ping-pong
+            Poll::Ready(conn) => Poll::Ready(Ok((conn, this.timer.take()))),
+            Poll::Pending => match this.timer.as_mut() {
+                Some(timer) => {
+                    ready!(timer.as_mut().poll(cx));
+                    Poll::Ready(Err(DispatchError::SlowRequestTimeout))
+                }
+                None => Poll::Pending,
+            },
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use static_assertions::assert_impl_all;
+
+    use super::*;
+
+    assert_impl_all!(Payload: Unpin, Send, Sync);
+}
+
\ No newline at end of file diff --git a/src/actix_http/h2/service.rs.html b/src/actix_http/h2/service.rs.html new file mode 100644 index 000000000..2418117df --- /dev/null +++ b/src/actix_http/h2/service.rs.html @@ -0,0 +1,1037 @@ +service.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
+
use std::{
+    future::Future,
+    marker::PhantomData,
+    mem, net,
+    pin::Pin,
+    rc::Rc,
+    task::{Context, Poll},
+};
+
+use actix_codec::{AsyncRead, AsyncWrite};
+use actix_rt::net::TcpStream;
+use actix_service::{
+    fn_factory, fn_service, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt as _,
+};
+use actix_utils::future::ready;
+use futures_core::{future::LocalBoxFuture, ready};
+use tracing::{error, trace};
+
+use super::{dispatcher::Dispatcher, handshake_with_timeout, HandshakeWithTimeout};
+use crate::{
+    body::{BoxBody, MessageBody},
+    config::ServiceConfig,
+    error::DispatchError,
+    service::HttpFlow,
+    ConnectCallback, OnConnectData, Request, Response,
+};
+
+/// `ServiceFactory` implementation for HTTP/2 transport
+pub struct H2Service<T, S, B> {
+    srv: S,
+    cfg: ServiceConfig,
+    on_connect_ext: Option<Rc<ConnectCallback<T>>>,
+    _phantom: PhantomData<(T, B)>,
+}
+
+impl<T, S, B> H2Service<T, S, B>
+where
+    S: ServiceFactory<Request, Config = ()>,
+    S::Error: Into<Response<BoxBody>> + 'static,
+    S::Response: Into<Response<B>> + 'static,
+    <S::Service as Service<Request>>::Future: 'static,
+
+    B: MessageBody + 'static,
+{
+    /// Create new `H2Service` instance with config.
+    pub(crate) fn with_config<F: IntoServiceFactory<S, Request>>(
+        cfg: ServiceConfig,
+        service: F,
+    ) -> Self {
+        H2Service {
+            cfg,
+            on_connect_ext: None,
+            srv: service.into_factory(),
+            _phantom: PhantomData,
+        }
+    }
+
+    /// Set on connect callback.
+    pub(crate) fn on_connect_ext(mut self, f: Option<Rc<ConnectCallback<T>>>) -> Self {
+        self.on_connect_ext = f;
+        self
+    }
+}
+
+impl<S, B> H2Service<TcpStream, S, B>
+where
+    S: ServiceFactory<Request, Config = ()>,
+    S::Future: 'static,
+    S::Error: Into<Response<BoxBody>> + 'static,
+    S::Response: Into<Response<B>> + 'static,
+    <S::Service as Service<Request>>::Future: 'static,
+
+    B: MessageBody + 'static,
+{
+    /// Create plain TCP based service
+    pub fn tcp(
+        self,
+    ) -> impl ServiceFactory<
+        TcpStream,
+        Config = (),
+        Response = (),
+        Error = DispatchError,
+        InitError = S::InitError,
+    > {
+        fn_factory(|| {
+            ready(Ok::<_, S::InitError>(fn_service(|io: TcpStream| {
+                let peer_addr = io.peer_addr().ok();
+                ready(Ok::<_, DispatchError>((io, peer_addr)))
+            })))
+        })
+        .and_then(self)
+    }
+}
+
+#[cfg(feature = "openssl")]
+mod openssl {
+    use actix_service::ServiceFactoryExt as _;
+    use actix_tls::accept::{
+        openssl::{
+            reexports::{Error as SslError, SslAcceptor},
+            Acceptor, TlsStream,
+        },
+        TlsError,
+    };
+
+    use super::*;
+
+    impl<S, B> H2Service<TlsStream<TcpStream>, S, B>
+    where
+        S: ServiceFactory<Request, Config = ()>,
+        S::Future: 'static,
+        S::Error: Into<Response<BoxBody>> + 'static,
+        S::Response: Into<Response<B>> + 'static,
+        <S::Service as Service<Request>>::Future: 'static,
+
+        B: MessageBody + 'static,
+    {
+        /// Create OpenSSL based service.
+        pub fn openssl(
+            self,
+            acceptor: SslAcceptor,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<SslError, DispatchError>,
+            InitError = S::InitError,
+        > {
+            Acceptor::new(acceptor)
+                .map_init_err(|_| {
+                    unreachable!("TLS acceptor service factory does not error on init")
+                })
+                .map_err(TlsError::into_service_error)
+                .map(|io: TlsStream<TcpStream>| {
+                    let peer_addr = io.get_ref().peer_addr().ok();
+                    (io, peer_addr)
+                })
+                .and_then(self.map_err(TlsError::Service))
+        }
+    }
+}
+
+#[cfg(feature = "rustls-0_20")]
+mod rustls_0_20 {
+    use std::io;
+
+    use actix_service::ServiceFactoryExt as _;
+    use actix_tls::accept::{
+        rustls::{reexports::ServerConfig, Acceptor, TlsStream},
+        TlsError,
+    };
+
+    use super::*;
+
+    impl<S, B> H2Service<TlsStream<TcpStream>, S, B>
+    where
+        S: ServiceFactory<Request, Config = ()>,
+        S::Future: 'static,
+        S::Error: Into<Response<BoxBody>> + 'static,
+        S::Response: Into<Response<B>> + 'static,
+        <S::Service as Service<Request>>::Future: 'static,
+
+        B: MessageBody + 'static,
+    {
+        /// Create Rustls v0.20 based service.
+        pub fn rustls(
+            self,
+            mut config: ServerConfig,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<io::Error, DispatchError>,
+            InitError = S::InitError,
+        > {
+            let mut protos = vec![b"h2".to_vec()];
+            protos.extend_from_slice(&config.alpn_protocols);
+            config.alpn_protocols = protos;
+
+            Acceptor::new(config)
+                .map_init_err(|_| {
+                    unreachable!("TLS acceptor service factory does not error on init")
+                })
+                .map_err(TlsError::into_service_error)
+                .map(|io: TlsStream<TcpStream>| {
+                    let peer_addr = io.get_ref().0.peer_addr().ok();
+                    (io, peer_addr)
+                })
+                .and_then(self.map_err(TlsError::Service))
+        }
+    }
+}
+
+#[cfg(feature = "rustls-0_21")]
+mod rustls_0_21 {
+    use std::io;
+
+    use actix_service::ServiceFactoryExt as _;
+    use actix_tls::accept::{
+        rustls_0_21::{reexports::ServerConfig, Acceptor, TlsStream},
+        TlsError,
+    };
+
+    use super::*;
+
+    impl<S, B> H2Service<TlsStream<TcpStream>, S, B>
+    where
+        S: ServiceFactory<Request, Config = ()>,
+        S::Future: 'static,
+        S::Error: Into<Response<BoxBody>> + 'static,
+        S::Response: Into<Response<B>> + 'static,
+        <S::Service as Service<Request>>::Future: 'static,
+
+        B: MessageBody + 'static,
+    {
+        /// Create Rustls v0.21 based service.
+        pub fn rustls_021(
+            self,
+            mut config: ServerConfig,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<io::Error, DispatchError>,
+            InitError = S::InitError,
+        > {
+            let mut protos = vec![b"h2".to_vec()];
+            protos.extend_from_slice(&config.alpn_protocols);
+            config.alpn_protocols = protos;
+
+            Acceptor::new(config)
+                .map_init_err(|_| {
+                    unreachable!("TLS acceptor service factory does not error on init")
+                })
+                .map_err(TlsError::into_service_error)
+                .map(|io: TlsStream<TcpStream>| {
+                    let peer_addr = io.get_ref().0.peer_addr().ok();
+                    (io, peer_addr)
+                })
+                .and_then(self.map_err(TlsError::Service))
+        }
+    }
+}
+
+#[cfg(feature = "rustls-0_22")]
+mod rustls_0_22 {
+    use std::io;
+
+    use actix_service::ServiceFactoryExt as _;
+    use actix_tls::accept::{
+        rustls_0_22::{reexports::ServerConfig, Acceptor, TlsStream},
+        TlsError,
+    };
+
+    use super::*;
+
+    impl<S, B> H2Service<TlsStream<TcpStream>, S, B>
+    where
+        S: ServiceFactory<Request, Config = ()>,
+        S::Future: 'static,
+        S::Error: Into<Response<BoxBody>> + 'static,
+        S::Response: Into<Response<B>> + 'static,
+        <S::Service as Service<Request>>::Future: 'static,
+
+        B: MessageBody + 'static,
+    {
+        /// Create Rustls v0.22 based service.
+        pub fn rustls_0_22(
+            self,
+            mut config: ServerConfig,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<io::Error, DispatchError>,
+            InitError = S::InitError,
+        > {
+            let mut protos = vec![b"h2".to_vec()];
+            protos.extend_from_slice(&config.alpn_protocols);
+            config.alpn_protocols = protos;
+
+            Acceptor::new(config)
+                .map_init_err(|_| {
+                    unreachable!("TLS acceptor service factory does not error on init")
+                })
+                .map_err(TlsError::into_service_error)
+                .map(|io: TlsStream<TcpStream>| {
+                    let peer_addr = io.get_ref().0.peer_addr().ok();
+                    (io, peer_addr)
+                })
+                .and_then(self.map_err(TlsError::Service))
+        }
+    }
+}
+
+#[cfg(feature = "rustls-0_23")]
+mod rustls_0_23 {
+    use std::io;
+
+    use actix_service::ServiceFactoryExt as _;
+    use actix_tls::accept::{
+        rustls_0_23::{reexports::ServerConfig, Acceptor, TlsStream},
+        TlsError,
+    };
+
+    use super::*;
+
+    impl<S, B> H2Service<TlsStream<TcpStream>, S, B>
+    where
+        S: ServiceFactory<Request, Config = ()>,
+        S::Future: 'static,
+        S::Error: Into<Response<BoxBody>> + 'static,
+        S::Response: Into<Response<B>> + 'static,
+        <S::Service as Service<Request>>::Future: 'static,
+
+        B: MessageBody + 'static,
+    {
+        /// Create Rustls v0.23 based service.
+        pub fn rustls_0_23(
+            self,
+            mut config: ServerConfig,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<io::Error, DispatchError>,
+            InitError = S::InitError,
+        > {
+            let mut protos = vec![b"h2".to_vec()];
+            protos.extend_from_slice(&config.alpn_protocols);
+            config.alpn_protocols = protos;
+
+            Acceptor::new(config)
+                .map_init_err(|_| {
+                    unreachable!("TLS acceptor service factory does not error on init")
+                })
+                .map_err(TlsError::into_service_error)
+                .map(|io: TlsStream<TcpStream>| {
+                    let peer_addr = io.get_ref().0.peer_addr().ok();
+                    (io, peer_addr)
+                })
+                .and_then(self.map_err(TlsError::Service))
+        }
+    }
+}
+
+impl<T, S, B> ServiceFactory<(T, Option<net::SocketAddr>)> for H2Service<T, S, B>
+where
+    T: AsyncRead + AsyncWrite + Unpin + 'static,
+
+    S: ServiceFactory<Request, Config = ()>,
+    S::Future: 'static,
+    S::Error: Into<Response<BoxBody>> + 'static,
+    S::Response: Into<Response<B>> + 'static,
+    <S::Service as Service<Request>>::Future: 'static,
+
+    B: MessageBody + 'static,
+{
+    type Response = ();
+    type Error = DispatchError;
+    type Config = ();
+    type Service = H2ServiceHandler<T, S::Service, B>;
+    type InitError = S::InitError;
+    type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
+
+    fn new_service(&self, _: ()) -> Self::Future {
+        let service = self.srv.new_service(());
+        let cfg = self.cfg.clone();
+        let on_connect_ext = self.on_connect_ext.clone();
+
+        Box::pin(async move {
+            let service = service.await?;
+            Ok(H2ServiceHandler::new(cfg, on_connect_ext, service))
+        })
+    }
+}
+
+/// `Service` implementation for HTTP/2 transport
+pub struct H2ServiceHandler<T, S, B>
+where
+    S: Service<Request>,
+{
+    flow: Rc<HttpFlow<S, (), ()>>,
+    cfg: ServiceConfig,
+    on_connect_ext: Option<Rc<ConnectCallback<T>>>,
+    _phantom: PhantomData<B>,
+}
+
+impl<T, S, B> H2ServiceHandler<T, S, B>
+where
+    S: Service<Request>,
+    S::Error: Into<Response<BoxBody>> + 'static,
+    S::Future: 'static,
+    S::Response: Into<Response<B>> + 'static,
+    B: MessageBody + 'static,
+{
+    fn new(
+        cfg: ServiceConfig,
+        on_connect_ext: Option<Rc<ConnectCallback<T>>>,
+        service: S,
+    ) -> H2ServiceHandler<T, S, B> {
+        H2ServiceHandler {
+            flow: HttpFlow::new(service, (), None),
+            cfg,
+            on_connect_ext,
+            _phantom: PhantomData,
+        }
+    }
+}
+
+impl<T, S, B> Service<(T, Option<net::SocketAddr>)> for H2ServiceHandler<T, S, B>
+where
+    T: AsyncRead + AsyncWrite + Unpin,
+    S: Service<Request>,
+    S::Error: Into<Response<BoxBody>> + 'static,
+    S::Future: 'static,
+    S::Response: Into<Response<B>> + 'static,
+    B: MessageBody + 'static,
+{
+    type Response = ();
+    type Error = DispatchError;
+    type Future = H2ServiceHandlerResponse<T, S, B>;
+
+    fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        self.flow.service.poll_ready(cx).map_err(|err| {
+            let err = err.into();
+            error!("Service readiness error: {:?}", err);
+            DispatchError::Service(err)
+        })
+    }
+
+    fn call(&self, (io, addr): (T, Option<net::SocketAddr>)) -> Self::Future {
+        let on_connect_data = OnConnectData::from_io(&io, self.on_connect_ext.as_deref());
+
+        H2ServiceHandlerResponse {
+            state: State::Handshake(
+                Some(self.flow.clone()),
+                Some(self.cfg.clone()),
+                addr,
+                on_connect_data,
+                handshake_with_timeout(io, &self.cfg),
+            ),
+        }
+    }
+}
+
+enum State<T, S: Service<Request>, B: MessageBody>
+where
+    T: AsyncRead + AsyncWrite + Unpin,
+    S::Future: 'static,
+{
+    Handshake(
+        Option<Rc<HttpFlow<S, (), ()>>>,
+        Option<ServiceConfig>,
+        Option<net::SocketAddr>,
+        OnConnectData,
+        HandshakeWithTimeout<T>,
+    ),
+    Established(Dispatcher<T, S, B, (), ()>),
+}
+
+pub struct H2ServiceHandlerResponse<T, S, B>
+where
+    T: AsyncRead + AsyncWrite + Unpin,
+    S: Service<Request>,
+    S::Error: Into<Response<BoxBody>> + 'static,
+    S::Future: 'static,
+    S::Response: Into<Response<B>> + 'static,
+    B: MessageBody + 'static,
+{
+    state: State<T, S, B>,
+}
+
+impl<T, S, B> Future for H2ServiceHandlerResponse<T, S, B>
+where
+    T: AsyncRead + AsyncWrite + Unpin,
+    S: Service<Request>,
+    S::Error: Into<Response<BoxBody>> + 'static,
+    S::Future: 'static,
+    S::Response: Into<Response<B>> + 'static,
+    B: MessageBody,
+{
+    type Output = Result<(), DispatchError>;
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        match self.state {
+            State::Handshake(
+                ref mut srv,
+                ref mut config,
+                ref peer_addr,
+                ref mut conn_data,
+                ref mut handshake,
+            ) => match ready!(Pin::new(handshake).poll(cx)) {
+                Ok((conn, timer)) => {
+                    let on_connect_data = mem::take(conn_data);
+
+                    self.state = State::Established(Dispatcher::new(
+                        conn,
+                        srv.take().unwrap(),
+                        config.take().unwrap(),
+                        *peer_addr,
+                        on_connect_data,
+                        timer,
+                    ));
+
+                    self.poll(cx)
+                }
+
+                Err(err) => {
+                    trace!("H2 handshake error: {}", err);
+                    Poll::Ready(Err(err))
+                }
+            },
+
+            State::Established(ref mut disp) => Pin::new(disp).poll(cx),
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/header/as_name.rs.html b/src/actix_http/header/as_name.rs.html new file mode 100644 index 000000000..d0f5cf068 --- /dev/null +++ b/src/actix_http/header/as_name.rs.html @@ -0,0 +1,113 @@ +as_name.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
+
//! Sealed [`AsHeaderName`] trait and implementations.
+
+use std::{borrow::Cow, str::FromStr as _};
+
+use http::header::{HeaderName, InvalidHeaderName};
+
+/// Sealed trait implemented for types that can be effectively borrowed as a [`HeaderValue`].
+///
+/// [`HeaderValue`]: super::HeaderValue
+pub trait AsHeaderName: Sealed {}
+
+pub struct Seal;
+
+pub trait Sealed {
+    fn try_as_name(&self, seal: Seal) -> Result<Cow<'_, HeaderName>, InvalidHeaderName>;
+}
+
+impl Sealed for HeaderName {
+    #[inline]
+    fn try_as_name(&self, _: Seal) -> Result<Cow<'_, HeaderName>, InvalidHeaderName> {
+        Ok(Cow::Borrowed(self))
+    }
+}
+impl AsHeaderName for HeaderName {}
+
+impl Sealed for &HeaderName {
+    #[inline]
+    fn try_as_name(&self, _: Seal) -> Result<Cow<'_, HeaderName>, InvalidHeaderName> {
+        Ok(Cow::Borrowed(*self))
+    }
+}
+impl AsHeaderName for &HeaderName {}
+
+impl Sealed for &str {
+    #[inline]
+    fn try_as_name(&self, _: Seal) -> Result<Cow<'_, HeaderName>, InvalidHeaderName> {
+        HeaderName::from_str(self).map(Cow::Owned)
+    }
+}
+impl AsHeaderName for &str {}
+
+impl Sealed for String {
+    #[inline]
+    fn try_as_name(&self, _: Seal) -> Result<Cow<'_, HeaderName>, InvalidHeaderName> {
+        HeaderName::from_str(self).map(Cow::Owned)
+    }
+}
+impl AsHeaderName for String {}
+
+impl Sealed for &String {
+    #[inline]
+    fn try_as_name(&self, _: Seal) -> Result<Cow<'_, HeaderName>, InvalidHeaderName> {
+        HeaderName::from_str(self).map(Cow::Owned)
+    }
+}
+impl AsHeaderName for &String {}
+
\ No newline at end of file diff --git a/src/actix_http/header/common.rs.html b/src/actix_http/header/common.rs.html new file mode 100644 index 000000000..0b1d52034 --- /dev/null +++ b/src/actix_http/header/common.rs.html @@ -0,0 +1,107 @@ +common.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
+
//! Common header names not defined in [`http`].
+//!
+//! Any headers added to this file will need to be re-exported from the list at `crate::headers`.
+
+use http::header::HeaderName;
+
+/// Response header field that indicates how caches have handled that response and its corresponding
+/// request.
+///
+/// See [RFC 9211](https://www.rfc-editor.org/rfc/rfc9211) for full semantics.
+// TODO(breaking): replace with http's version
+pub const CACHE_STATUS: HeaderName = HeaderName::from_static("cache-status");
+
+/// Response header field that allows origin servers to control the behavior of CDN caches
+/// interposed between them and clients separately from other caches that might handle the response.
+///
+/// See [RFC 9213](https://www.rfc-editor.org/rfc/rfc9213) for full semantics.
+// TODO(breaking): replace with http's version
+pub const CDN_CACHE_CONTROL: HeaderName = HeaderName::from_static("cdn-cache-control");
+
+/// Response header that prevents a document from loading any cross-origin resources that don't
+/// explicitly grant the document permission (using [CORP] or [CORS]).
+///
+/// [CORP]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cross-Origin_Resource_Policy_(CORP)
+/// [CORS]: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
+pub const CROSS_ORIGIN_EMBEDDER_POLICY: HeaderName =
+    HeaderName::from_static("cross-origin-embedder-policy");
+
+/// Response header that allows you to ensure a top-level document does not share a browsing context
+/// group with cross-origin documents.
+pub const CROSS_ORIGIN_OPENER_POLICY: HeaderName =
+    HeaderName::from_static("cross-origin-opener-policy");
+
+/// Response header that conveys a desire that the browser blocks no-cors cross-origin/cross-site
+/// requests to the given resource.
+pub const CROSS_ORIGIN_RESOURCE_POLICY: HeaderName =
+    HeaderName::from_static("cross-origin-resource-policy");
+
+/// Response header that provides a mechanism to allow and deny the use of browser features in a
+/// document or within any `<iframe>` elements in the document.
+pub const PERMISSIONS_POLICY: HeaderName = HeaderName::from_static("permissions-policy");
+
+/// Request header (de-facto standard) for identifying the originating IP address of a client
+/// connecting to a web server through a proxy server.
+pub const X_FORWARDED_FOR: HeaderName = HeaderName::from_static("x-forwarded-for");
+
+/// Request header (de-facto standard) for identifying the original host requested by the client in
+/// the `Host` HTTP request header.
+pub const X_FORWARDED_HOST: HeaderName = HeaderName::from_static("x-forwarded-host");
+
+/// Request header (de-facto standard) for identifying the protocol that a client used to connect to
+/// your proxy or load balancer.
+pub const X_FORWARDED_PROTO: HeaderName = HeaderName::from_static("x-forwarded-proto");
+
\ No newline at end of file diff --git a/src/actix_http/header/into_pair.rs.html b/src/actix_http/header/into_pair.rs.html new file mode 100644 index 000000000..574f62304 --- /dev/null +++ b/src/actix_http/header/into_pair.rs.html @@ -0,0 +1,241 @@ +into_pair.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
+
//! [`TryIntoHeaderPair`] trait and implementations.
+
+use super::{
+    Header, HeaderName, HeaderValue, InvalidHeaderName, InvalidHeaderValue, TryIntoHeaderValue,
+};
+use crate::error::HttpError;
+
+/// An interface for types that can be converted into a [`HeaderName`] + [`HeaderValue`] pair for
+/// insertion into a [`HeaderMap`].
+///
+/// [`HeaderMap`]: super::HeaderMap
+pub trait TryIntoHeaderPair: Sized {
+    type Error: Into<HttpError>;
+
+    fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error>;
+}
+
+#[derive(Debug)]
+pub enum InvalidHeaderPart {
+    Name(InvalidHeaderName),
+    Value(InvalidHeaderValue),
+}
+
+impl From<InvalidHeaderPart> for HttpError {
+    fn from(part_err: InvalidHeaderPart) -> Self {
+        match part_err {
+            InvalidHeaderPart::Name(err) => err.into(),
+            InvalidHeaderPart::Value(err) => err.into(),
+        }
+    }
+}
+
+impl<V> TryIntoHeaderPair for (HeaderName, V)
+where
+    V: TryIntoHeaderValue,
+    V::Error: Into<InvalidHeaderValue>,
+{
+    type Error = InvalidHeaderPart;
+
+    fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
+        let (name, value) = self;
+        let value = value
+            .try_into_value()
+            .map_err(|err| InvalidHeaderPart::Value(err.into()))?;
+        Ok((name, value))
+    }
+}
+
+impl<V> TryIntoHeaderPair for (&HeaderName, V)
+where
+    V: TryIntoHeaderValue,
+    V::Error: Into<InvalidHeaderValue>,
+{
+    type Error = InvalidHeaderPart;
+
+    fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
+        let (name, value) = self;
+        let value = value
+            .try_into_value()
+            .map_err(|err| InvalidHeaderPart::Value(err.into()))?;
+        Ok((name.clone(), value))
+    }
+}
+
+impl<V> TryIntoHeaderPair for (&[u8], V)
+where
+    V: TryIntoHeaderValue,
+    V::Error: Into<InvalidHeaderValue>,
+{
+    type Error = InvalidHeaderPart;
+
+    fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
+        let (name, value) = self;
+        let name = HeaderName::try_from(name).map_err(InvalidHeaderPart::Name)?;
+        let value = value
+            .try_into_value()
+            .map_err(|err| InvalidHeaderPart::Value(err.into()))?;
+        Ok((name, value))
+    }
+}
+
+impl<V> TryIntoHeaderPair for (&str, V)
+where
+    V: TryIntoHeaderValue,
+    V::Error: Into<InvalidHeaderValue>,
+{
+    type Error = InvalidHeaderPart;
+
+    fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
+        let (name, value) = self;
+        let name = HeaderName::try_from(name).map_err(InvalidHeaderPart::Name)?;
+        let value = value
+            .try_into_value()
+            .map_err(|err| InvalidHeaderPart::Value(err.into()))?;
+        Ok((name, value))
+    }
+}
+
+impl<V> TryIntoHeaderPair for (String, V)
+where
+    V: TryIntoHeaderValue,
+    V::Error: Into<InvalidHeaderValue>,
+{
+    type Error = InvalidHeaderPart;
+
+    #[inline]
+    fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
+        let (name, value) = self;
+        (name.as_str(), value).try_into_pair()
+    }
+}
+
+impl<T: Header> TryIntoHeaderPair for T {
+    type Error = <T as TryIntoHeaderValue>::Error;
+
+    #[inline]
+    fn try_into_pair(self) -> Result<(HeaderName, HeaderValue), Self::Error> {
+        Ok((T::name(), self.try_into_value()?))
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/header/into_value.rs.html b/src/actix_http/header/into_value.rs.html new file mode 100644 index 000000000..30088a0e2 --- /dev/null +++ b/src/actix_http/header/into_value.rs.html @@ -0,0 +1,263 @@ +into_value.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
+
//! [`TryIntoHeaderValue`] trait and implementations.
+
+use bytes::Bytes;
+use http::{header::InvalidHeaderValue, Error as HttpError, HeaderValue};
+use mime::Mime;
+
+/// An interface for types that can be converted into a [`HeaderValue`].
+pub trait TryIntoHeaderValue: Sized {
+    /// The type returned in the event of a conversion error.
+    type Error: Into<HttpError>;
+
+    /// Try to convert value to a HeaderValue.
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error>;
+}
+
+impl TryIntoHeaderValue for HeaderValue {
+    type Error = InvalidHeaderValue;
+
+    #[inline]
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        Ok(self)
+    }
+}
+
+impl TryIntoHeaderValue for &HeaderValue {
+    type Error = InvalidHeaderValue;
+
+    #[inline]
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        Ok(self.clone())
+    }
+}
+
+impl TryIntoHeaderValue for &str {
+    type Error = InvalidHeaderValue;
+
+    #[inline]
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        self.parse()
+    }
+}
+
+impl TryIntoHeaderValue for &[u8] {
+    type Error = InvalidHeaderValue;
+
+    #[inline]
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        HeaderValue::from_bytes(self)
+    }
+}
+
+impl TryIntoHeaderValue for Bytes {
+    type Error = InvalidHeaderValue;
+
+    #[inline]
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        HeaderValue::from_maybe_shared(self)
+    }
+}
+
+impl TryIntoHeaderValue for Vec<u8> {
+    type Error = InvalidHeaderValue;
+
+    #[inline]
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        HeaderValue::try_from(self)
+    }
+}
+
+impl TryIntoHeaderValue for String {
+    type Error = InvalidHeaderValue;
+
+    #[inline]
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        HeaderValue::try_from(self)
+    }
+}
+
+impl TryIntoHeaderValue for usize {
+    type Error = InvalidHeaderValue;
+
+    #[inline]
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        HeaderValue::try_from(self.to_string())
+    }
+}
+
+impl TryIntoHeaderValue for i64 {
+    type Error = InvalidHeaderValue;
+
+    #[inline]
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        HeaderValue::try_from(self.to_string())
+    }
+}
+
+impl TryIntoHeaderValue for u64 {
+    type Error = InvalidHeaderValue;
+
+    #[inline]
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        HeaderValue::try_from(self.to_string())
+    }
+}
+
+impl TryIntoHeaderValue for i32 {
+    type Error = InvalidHeaderValue;
+
+    #[inline]
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        HeaderValue::try_from(self.to_string())
+    }
+}
+
+impl TryIntoHeaderValue for u32 {
+    type Error = InvalidHeaderValue;
+
+    #[inline]
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        HeaderValue::try_from(self.to_string())
+    }
+}
+
+impl TryIntoHeaderValue for Mime {
+    type Error = InvalidHeaderValue;
+
+    #[inline]
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        HeaderValue::from_str(self.as_ref())
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/header/map.rs.html b/src/actix_http/header/map.rs.html new file mode 100644 index 000000000..f7258d97a --- /dev/null +++ b/src/actix_http/header/map.rs.html @@ -0,0 +1,2281 @@ +map.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
+
//! A multi-value [`HeaderMap`] and its iterators.
+
+use std::{borrow::Cow, collections::hash_map, iter, ops};
+
+use ahash::AHashMap;
+use http::header::{HeaderName, HeaderValue};
+use smallvec::{smallvec, SmallVec};
+
+use super::AsHeaderName;
+
+/// A multi-map of HTTP headers.
+///
+/// `HeaderMap` is a "multi-map" of [`HeaderName`] to one or more [`HeaderValue`]s.
+///
+/// # Examples
+/// ```
+/// use actix_http::header::{self, HeaderMap, HeaderValue};
+///
+/// let mut map = HeaderMap::new();
+///
+/// map.insert(header::CONTENT_TYPE, HeaderValue::from_static("text/plain"));
+/// map.insert(header::ORIGIN, HeaderValue::from_static("example.com"));
+///
+/// assert!(map.contains_key(header::CONTENT_TYPE));
+/// assert!(map.contains_key(header::ORIGIN));
+///
+/// let mut removed = map.remove(header::ORIGIN);
+/// assert_eq!(removed.next().unwrap(), "example.com");
+///
+/// assert!(!map.contains_key(header::ORIGIN));
+/// ```
+#[derive(Debug, Clone, Default)]
+pub struct HeaderMap {
+    pub(crate) inner: AHashMap<HeaderName, Value>,
+}
+
+/// A bespoke non-empty list for HeaderMap values.
+#[derive(Debug, Clone)]
+pub(crate) struct Value {
+    inner: SmallVec<[HeaderValue; 4]>,
+}
+
+impl Value {
+    fn one(val: HeaderValue) -> Self {
+        Self {
+            inner: smallvec![val],
+        }
+    }
+
+    fn first(&self) -> &HeaderValue {
+        &self.inner[0]
+    }
+
+    fn first_mut(&mut self) -> &mut HeaderValue {
+        &mut self.inner[0]
+    }
+
+    fn append(&mut self, new_val: HeaderValue) {
+        self.inner.push(new_val)
+    }
+}
+
+impl ops::Deref for Value {
+    type Target = SmallVec<[HeaderValue; 4]>;
+
+    fn deref(&self) -> &Self::Target {
+        &self.inner
+    }
+}
+
+impl HeaderMap {
+    /// Create an empty `HeaderMap`.
+    ///
+    /// The map will be created without any capacity; this function will not allocate.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::HeaderMap;
+    /// let map = HeaderMap::new();
+    ///
+    /// assert!(map.is_empty());
+    /// assert_eq!(0, map.capacity());
+    /// ```
+    pub fn new() -> Self {
+        HeaderMap::default()
+    }
+
+    /// Create an empty `HeaderMap` with the specified capacity.
+    ///
+    /// The map will be able to hold at least `capacity` elements without needing to reallocate.
+    /// If `capacity` is 0, the map will be created without allocating.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::HeaderMap;
+    /// let map = HeaderMap::with_capacity(16);
+    ///
+    /// assert!(map.is_empty());
+    /// assert!(map.capacity() >= 16);
+    /// ```
+    pub fn with_capacity(capacity: usize) -> Self {
+        HeaderMap {
+            inner: AHashMap::with_capacity(capacity),
+        }
+    }
+
+    /// Create new `HeaderMap` from a `http::HeaderMap`-like drain.
+    pub(crate) fn from_drain<I>(mut drain: I) -> Self
+    where
+        I: Iterator<Item = (Option<HeaderName>, HeaderValue)>,
+    {
+        let (first_name, first_value) = match drain.next() {
+            None => return HeaderMap::new(),
+            Some((name, val)) => {
+                let name = name.expect("drained first item had no name");
+                (name, val)
+            }
+        };
+
+        let (lb, ub) = drain.size_hint();
+        let capacity = ub.unwrap_or(lb);
+
+        let mut map = HeaderMap::with_capacity(capacity);
+        map.append(first_name.clone(), first_value);
+
+        let (map, _) = drain.fold((map, first_name), |(mut map, prev_name), (name, value)| {
+            let name = name.unwrap_or(prev_name);
+            map.append(name.clone(), value);
+            (map, name)
+        });
+
+        map
+    }
+
+    /// Returns the number of values stored in the map.
+    ///
+    /// See also: [`len_keys`](Self::len_keys).
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::{self, HeaderMap, HeaderValue};
+    /// let mut map = HeaderMap::new();
+    /// assert_eq!(map.len(), 0);
+    ///
+    /// map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+    /// map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+    /// assert_eq!(map.len(), 2);
+    ///
+    /// map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+    /// assert_eq!(map.len(), 3);
+    /// ```
+    pub fn len(&self) -> usize {
+        self.inner.values().map(|vals| vals.len()).sum()
+    }
+
+    /// Returns the number of _keys_ stored in the map.
+    ///
+    /// The number of values stored will be at least this number. See also: [`Self::len`].
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::{self, HeaderMap, HeaderValue};
+    /// let mut map = HeaderMap::new();
+    /// assert_eq!(map.len_keys(), 0);
+    ///
+    /// map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+    /// map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+    /// assert_eq!(map.len_keys(), 2);
+    ///
+    /// map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+    /// assert_eq!(map.len_keys(), 2);
+    /// ```
+    pub fn len_keys(&self) -> usize {
+        self.inner.len()
+    }
+
+    /// Returns true if the map contains no elements.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::{self, HeaderMap, HeaderValue};
+    /// let mut map = HeaderMap::new();
+    /// assert!(map.is_empty());
+    ///
+    /// map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+    /// assert!(!map.is_empty());
+    /// ```
+    pub fn is_empty(&self) -> bool {
+        self.inner.len() == 0
+    }
+
+    /// Clears the map, removing all name-value pairs.
+    ///
+    /// Keeps the allocated memory for reuse.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::{self, HeaderMap, HeaderValue};
+    /// let mut map = HeaderMap::new();
+    ///
+    /// map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+    /// map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+    /// assert_eq!(map.len(), 2);
+    ///
+    /// map.clear();
+    /// assert!(map.is_empty());
+    /// ```
+    pub fn clear(&mut self) {
+        self.inner.clear();
+    }
+
+    fn get_value(&self, key: impl AsHeaderName) -> Option<&Value> {
+        match key.try_as_name(super::as_name::Seal).ok()? {
+            Cow::Borrowed(name) => self.inner.get(name),
+            Cow::Owned(name) => self.inner.get(&name),
+        }
+    }
+
+    /// Returns a reference to the _first_ value associated with a header name.
+    ///
+    /// Returns `None` if there is no value associated with the key.
+    ///
+    /// Even when multiple values are associated with the key, the "first" one is returned but is
+    /// not guaranteed to be chosen with any particular order; though, the returned item will be
+    /// consistent for each call to `get` if the map has not changed.
+    ///
+    /// See also: [`get_all`](Self::get_all).
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::{self, HeaderMap, HeaderValue};
+    /// let mut map = HeaderMap::new();
+    ///
+    /// map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+    ///
+    /// let cookie = map.get(header::SET_COOKIE).unwrap();
+    /// assert_eq!(cookie, "one=1");
+    ///
+    /// map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+    /// assert_eq!(map.get(header::SET_COOKIE).unwrap(), "one=1");
+    ///
+    /// assert_eq!(map.get(header::SET_COOKIE), map.get("set-cookie"));
+    /// assert_eq!(map.get(header::SET_COOKIE), map.get("Set-Cookie"));
+    ///
+    /// assert!(map.get(header::HOST).is_none());
+    /// assert!(map.get("INVALID HEADER NAME").is_none());
+    /// ```
+    pub fn get(&self, key: impl AsHeaderName) -> Option<&HeaderValue> {
+        self.get_value(key).map(Value::first)
+    }
+
+    /// Returns a mutable reference to the _first_ value associated a header name.
+    ///
+    /// Returns `None` if there is no value associated with the key.
+    ///
+    /// Even when multiple values are associated with the key, the "first" one is returned but is
+    /// not guaranteed to be chosen with any particular order; though, the returned item will be
+    /// consistent for each call to `get_mut` if the map has not changed.
+    ///
+    /// See also: [`get_all`](Self::get_all).
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::{self, HeaderMap, HeaderValue};
+    /// let mut map = HeaderMap::new();
+    ///
+    /// map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+    ///
+    /// let mut cookie = map.get_mut(header::SET_COOKIE).unwrap();
+    /// assert_eq!(cookie, "one=1");
+    ///
+    /// *cookie = HeaderValue::from_static("three=3");
+    /// assert_eq!(map.get(header::SET_COOKIE).unwrap(), "three=3");
+    ///
+    /// assert!(map.get(header::HOST).is_none());
+    /// assert!(map.get("INVALID HEADER NAME").is_none());
+    /// ```
+    pub fn get_mut(&mut self, key: impl AsHeaderName) -> Option<&mut HeaderValue> {
+        match key.try_as_name(super::as_name::Seal).ok()? {
+            Cow::Borrowed(name) => self.inner.get_mut(name).map(Value::first_mut),
+            Cow::Owned(name) => self.inner.get_mut(&name).map(Value::first_mut),
+        }
+    }
+
+    /// Returns an iterator over all values associated with a header name.
+    ///
+    /// The returned iterator does not incur any allocations and will yield no items if there are no
+    /// values associated with the key. Iteration order is guaranteed to be the same as
+    /// insertion order.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::{self, HeaderMap, HeaderValue};
+    /// let mut map = HeaderMap::new();
+    ///
+    /// let mut none_iter = map.get_all(header::ORIGIN);
+    /// assert!(none_iter.next().is_none());
+    ///
+    /// map.insert(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+    /// map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+    ///
+    /// let mut set_cookies_iter = map.get_all(header::SET_COOKIE);
+    /// assert_eq!(set_cookies_iter.next().unwrap(), "one=1");
+    /// assert_eq!(set_cookies_iter.next().unwrap(), "two=2");
+    /// assert!(set_cookies_iter.next().is_none());
+    /// ```
+    pub fn get_all(&self, key: impl AsHeaderName) -> std::slice::Iter<'_, HeaderValue> {
+        match self.get_value(key) {
+            Some(value) => value.iter(),
+            None => [].iter(),
+        }
+    }
+
+    // TODO: get_all_mut ?
+
+    /// Returns `true` if the map contains a value for the specified key.
+    ///
+    /// Invalid header names will simply return false.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::{self, HeaderMap, HeaderValue};
+    /// let mut map = HeaderMap::new();
+    /// assert!(!map.contains_key(header::ACCEPT));
+    ///
+    /// map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+    /// assert!(map.contains_key(header::ACCEPT));
+    /// ```
+    pub fn contains_key(&self, key: impl AsHeaderName) -> bool {
+        match key.try_as_name(super::as_name::Seal) {
+            Ok(Cow::Borrowed(name)) => self.inner.contains_key(name),
+            Ok(Cow::Owned(name)) => self.inner.contains_key(&name),
+            Err(_) => false,
+        }
+    }
+
+    /// Inserts (overrides) a name-value pair in the map.
+    ///
+    /// If the map already contained this key, the new value is associated with the key and all
+    /// previous values are removed and returned as a `Removed` iterator. The key is not updated;
+    /// this matters for types that can be `==` without being identical.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::{self, HeaderMap, HeaderValue};
+    /// let mut map = HeaderMap::new();
+    ///
+    /// map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+    /// assert!(map.contains_key(header::ACCEPT));
+    /// assert_eq!(map.len(), 1);
+    ///
+    /// let mut removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/csv"));
+    /// assert_eq!(removed.next().unwrap(), "text/plain");
+    /// assert!(removed.next().is_none());
+    ///
+    /// assert_eq!(map.len(), 1);
+    /// ```
+    ///
+    /// A convenience method is provided on the returned iterator to check if the insertion replaced
+    /// any values.
+    /// ```
+    /// # use actix_http::header::{self, HeaderMap, HeaderValue};
+    /// let mut map = HeaderMap::new();
+    ///
+    /// let removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/plain"));
+    /// assert!(removed.is_empty());
+    ///
+    /// let removed = map.insert(header::ACCEPT, HeaderValue::from_static("text/html"));
+    /// assert!(!removed.is_empty());
+    /// ```
+    pub fn insert(&mut self, key: HeaderName, val: HeaderValue) -> Removed {
+        let value = self.inner.insert(key, Value::one(val));
+        Removed::new(value)
+    }
+
+    /// Appends a name-value pair to the map.
+    ///
+    /// If the map already contained this key, the new value is added to the list of values
+    /// currently associated with the key. The key is not updated; this matters for types that can
+    /// be `==` without being identical.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::{self, HeaderMap, HeaderValue};
+    /// let mut map = HeaderMap::new();
+    ///
+    /// map.append(header::HOST, HeaderValue::from_static("example.com"));
+    /// assert_eq!(map.len(), 1);
+    ///
+    /// map.append(header::ACCEPT, HeaderValue::from_static("text/csv"));
+    /// assert_eq!(map.len(), 2);
+    ///
+    /// map.append(header::ACCEPT, HeaderValue::from_static("text/html"));
+    /// assert_eq!(map.len(), 3);
+    /// ```
+    pub fn append(&mut self, key: HeaderName, value: HeaderValue) {
+        match self.inner.entry(key) {
+            hash_map::Entry::Occupied(mut entry) => {
+                entry.get_mut().append(value);
+            }
+            hash_map::Entry::Vacant(entry) => {
+                entry.insert(Value::one(value));
+            }
+        };
+    }
+
+    /// Removes all headers for a particular header name from the map.
+    ///
+    /// Providing an invalid header names (as a string argument) will have no effect and return
+    /// without error.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::{self, HeaderMap, HeaderValue};
+    /// let mut map = HeaderMap::new();
+    ///
+    /// map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+    /// map.append(header::SET_COOKIE, HeaderValue::from_static("one=2"));
+    ///
+    /// assert_eq!(map.len(), 2);
+    ///
+    /// let mut removed = map.remove(header::SET_COOKIE);
+    /// assert_eq!(removed.next().unwrap(), "one=1");
+    /// assert_eq!(removed.next().unwrap(), "one=2");
+    /// assert!(removed.next().is_none());
+    ///
+    /// assert!(map.is_empty());
+    /// ```
+    ///
+    /// A convenience method is provided on the returned iterator to check if the `remove` call
+    /// actually removed any values.
+    /// ```
+    /// # use actix_http::header::{self, HeaderMap, HeaderValue};
+    /// let mut map = HeaderMap::new();
+    ///
+    /// let removed = map.remove("accept");
+    /// assert!(removed.is_empty());
+    ///
+    /// map.insert(header::ACCEPT, HeaderValue::from_static("text/html"));
+    /// let removed = map.remove("accept");
+    /// assert!(!removed.is_empty());
+    /// ```
+    pub fn remove(&mut self, key: impl AsHeaderName) -> Removed {
+        let value = match key.try_as_name(super::as_name::Seal) {
+            Ok(Cow::Borrowed(name)) => self.inner.remove(name),
+            Ok(Cow::Owned(name)) => self.inner.remove(&name),
+            Err(_) => None,
+        };
+
+        Removed::new(value)
+    }
+
+    /// Returns the number of single-value headers the map can hold without needing to reallocate.
+    ///
+    /// Since this is a multi-value map, the actual capacity is much larger when considering
+    /// each header name can be associated with an arbitrary number of values. The effect is that
+    /// the size of `len` may be greater than `capacity` since it counts all the values.
+    /// Conversely, [`len_keys`](Self::len_keys) will never be larger than capacity.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::HeaderMap;
+    /// let map = HeaderMap::with_capacity(16);
+    ///
+    /// assert!(map.is_empty());
+    /// assert!(map.capacity() >= 16);
+    /// ```
+    pub fn capacity(&self) -> usize {
+        self.inner.capacity()
+    }
+
+    /// Reserves capacity for at least `additional` more headers to be inserted in the map.
+    ///
+    /// The header map may reserve more space to avoid frequent reallocations. Additional capacity
+    /// only considers single-value headers.
+    ///
+    /// # Panics
+    /// Panics if the new allocation size overflows usize.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::HeaderMap;
+    /// let mut map = HeaderMap::with_capacity(2);
+    /// assert!(map.capacity() >= 2);
+    ///
+    /// map.reserve(100);
+    /// assert!(map.capacity() >= 102);
+    ///
+    /// assert!(map.is_empty());
+    /// ```
+    pub fn reserve(&mut self, additional: usize) {
+        self.inner.reserve(additional)
+    }
+
+    /// An iterator over all name-value pairs.
+    ///
+    /// Names will be yielded for each associated value. So, if a key has 3 associated values, it
+    /// will be yielded 3 times. The iteration order should be considered arbitrary.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::{self, HeaderMap, HeaderValue};
+    /// let mut map = HeaderMap::new();
+    ///
+    /// let mut iter = map.iter();
+    /// assert!(iter.next().is_none());
+    ///
+    /// map.append(header::HOST, HeaderValue::from_static("duck.com"));
+    /// map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+    /// map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+    ///
+    /// let mut iter = map.iter();
+    /// assert!(iter.next().is_some());
+    /// assert!(iter.next().is_some());
+    /// assert!(iter.next().is_some());
+    /// assert!(iter.next().is_none());
+    ///
+    /// let pairs = map.iter().collect::<Vec<_>>();
+    /// assert!(pairs.contains(&(&header::HOST, &HeaderValue::from_static("duck.com"))));
+    /// assert!(pairs.contains(&(&header::SET_COOKIE, &HeaderValue::from_static("one=1"))));
+    /// assert!(pairs.contains(&(&header::SET_COOKIE, &HeaderValue::from_static("two=2"))));
+    /// ```
+    pub fn iter(&self) -> Iter<'_> {
+        Iter::new(self.inner.iter())
+    }
+
+    /// An iterator over all contained header names.
+    ///
+    /// Each name will only be yielded once even if it has multiple associated values. The iteration
+    /// order should be considered arbitrary.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::{self, HeaderMap, HeaderValue};
+    /// let mut map = HeaderMap::new();
+    ///
+    /// let mut iter = map.keys();
+    /// assert!(iter.next().is_none());
+    ///
+    /// map.append(header::HOST, HeaderValue::from_static("duck.com"));
+    /// map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+    /// map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+    ///
+    /// let keys = map.keys().cloned().collect::<Vec<_>>();
+    /// assert_eq!(keys.len(), 2);
+    /// assert!(keys.contains(&header::HOST));
+    /// assert!(keys.contains(&header::SET_COOKIE));
+    /// ```
+    pub fn keys(&self) -> Keys<'_> {
+        Keys(self.inner.keys())
+    }
+
+    /// Retains only the headers specified by the predicate.
+    ///
+    /// In other words, removes all headers `(name, val)` for which `retain_fn(&name, &mut val)`
+    /// returns false.
+    ///
+    /// The order in which headers are visited should be considered arbitrary.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::{self, HeaderMap, HeaderValue};
+    /// let mut map = HeaderMap::new();
+    ///
+    /// map.append(header::HOST, HeaderValue::from_static("duck.com"));
+    /// map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+    /// map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+    ///
+    /// map.retain(|name, val| val.as_bytes().starts_with(b"one"));
+    ///
+    /// assert_eq!(map.len(), 1);
+    /// assert!(map.contains_key(&header::SET_COOKIE));
+    /// ```
+    pub fn retain<F>(&mut self, mut retain_fn: F)
+    where
+        F: FnMut(&HeaderName, &mut HeaderValue) -> bool,
+    {
+        self.inner.retain(|name, vals| {
+            vals.inner.retain(|val| retain_fn(name, val));
+
+            // invariant: make sure newly empty value lists are removed
+            !vals.is_empty()
+        })
+    }
+
+    /// Clears the map, returning all name-value sets as an iterator.
+    ///
+    /// Header names will only be yielded for the first value in each set. All items that are
+    /// yielded without a name and after an item with a name are associated with that same name.
+    /// The first item will always contain a name.
+    ///
+    /// Keeps the allocated memory for reuse.
+    /// # Examples
+    /// ```
+    /// # use actix_http::header::{self, HeaderMap, HeaderValue};
+    /// let mut map = HeaderMap::new();
+    ///
+    /// let mut iter = map.drain();
+    /// assert!(iter.next().is_none());
+    /// drop(iter);
+    ///
+    /// map.append(header::SET_COOKIE, HeaderValue::from_static("one=1"));
+    /// map.append(header::SET_COOKIE, HeaderValue::from_static("two=2"));
+    ///
+    /// let mut iter = map.drain();
+    /// assert_eq!(iter.next().unwrap(), (Some(header::SET_COOKIE), HeaderValue::from_static("one=1")));
+    /// assert_eq!(iter.next().unwrap(), (None, HeaderValue::from_static("two=2")));
+    /// drop(iter);
+    ///
+    /// assert!(map.is_empty());
+    /// ```
+    pub fn drain(&mut self) -> Drain<'_> {
+        Drain::new(self.inner.drain())
+    }
+}
+
+/// Note that this implementation will clone a [HeaderName] for each value. Consider using
+/// [`drain`](Self::drain) to control header name cloning.
+impl IntoIterator for HeaderMap {
+    type Item = (HeaderName, HeaderValue);
+    type IntoIter = IntoIter;
+
+    #[inline]
+    fn into_iter(self) -> Self::IntoIter {
+        IntoIter::new(self.inner.into_iter())
+    }
+}
+
+impl<'a> IntoIterator for &'a HeaderMap {
+    type Item = (&'a HeaderName, &'a HeaderValue);
+    type IntoIter = Iter<'a>;
+
+    #[inline]
+    fn into_iter(self) -> Self::IntoIter {
+        Iter::new(self.inner.iter())
+    }
+}
+
+/// Convert a `http::HeaderMap` to our `HeaderMap`.
+impl From<http::HeaderMap> for HeaderMap {
+    fn from(mut map: http::HeaderMap) -> Self {
+        Self::from_drain(map.drain())
+    }
+}
+
+/// Convert our `HeaderMap` to a `http::HeaderMap`.
+impl From<HeaderMap> for http::HeaderMap {
+    fn from(map: HeaderMap) -> Self {
+        Self::from_iter(map)
+    }
+}
+
+/// Convert our `&HeaderMap` to a `http::HeaderMap`.
+impl From<&HeaderMap> for http::HeaderMap {
+    fn from(map: &HeaderMap) -> Self {
+        map.to_owned().into()
+    }
+}
+
+/// Iterator over removed, owned values with the same associated name.
+///
+/// Returned from methods that remove or replace items. See [`HeaderMap::insert`]
+/// and [`HeaderMap::remove`].
+#[derive(Debug)]
+pub struct Removed {
+    inner: Option<smallvec::IntoIter<[HeaderValue; 4]>>,
+}
+
+impl Removed {
+    fn new(value: Option<Value>) -> Self {
+        let inner = value.map(|value| value.inner.into_iter());
+        Self { inner }
+    }
+
+    /// Returns true if iterator contains no elements, without consuming it.
+    ///
+    /// If called immediately after [`HeaderMap::insert`] or [`HeaderMap::remove`], it will indicate
+    /// whether any items were actually replaced or removed, respectively.
+    pub fn is_empty(&self) -> bool {
+        match self.inner {
+            // size hint lower bound of smallvec is the correct length
+            Some(ref iter) => iter.size_hint().0 == 0,
+            None => true,
+        }
+    }
+}
+
+impl Iterator for Removed {
+    type Item = HeaderValue;
+
+    #[inline]
+    fn next(&mut self) -> Option<Self::Item> {
+        self.inner.as_mut()?.next()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        match self.inner {
+            Some(ref iter) => iter.size_hint(),
+            None => (0, None),
+        }
+    }
+}
+
+impl ExactSizeIterator for Removed {}
+
+impl iter::FusedIterator for Removed {}
+
+/// Iterator over all names in the map.
+#[derive(Debug)]
+pub struct Keys<'a>(hash_map::Keys<'a, HeaderName, Value>);
+
+impl<'a> Iterator for Keys<'a> {
+    type Item = &'a HeaderName;
+
+    #[inline]
+    fn next(&mut self) -> Option<Self::Item> {
+        self.0.next()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.0.size_hint()
+    }
+}
+
+impl ExactSizeIterator for Keys<'_> {}
+
+impl iter::FusedIterator for Keys<'_> {}
+
+/// Iterator over borrowed name-value pairs.
+#[derive(Debug)]
+pub struct Iter<'a> {
+    inner: hash_map::Iter<'a, HeaderName, Value>,
+    multi_inner: Option<(&'a HeaderName, &'a SmallVec<[HeaderValue; 4]>)>,
+    multi_idx: usize,
+}
+
+impl<'a> Iter<'a> {
+    fn new(iter: hash_map::Iter<'a, HeaderName, Value>) -> Self {
+        Self {
+            inner: iter,
+            multi_idx: 0,
+            multi_inner: None,
+        }
+    }
+}
+
+impl<'a> Iterator for Iter<'a> {
+    type Item = (&'a HeaderName, &'a HeaderValue);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        // handle in-progress multi value lists first
+        if let Some((name, ref mut vals)) = self.multi_inner {
+            match vals.get(self.multi_idx) {
+                Some(val) => {
+                    self.multi_idx += 1;
+                    return Some((name, val));
+                }
+                None => {
+                    // no more items in value list; reset state
+                    self.multi_idx = 0;
+                    self.multi_inner = None;
+                }
+            }
+        }
+
+        let (name, value) = self.inner.next()?;
+
+        // set up new inner iter and recurse into it
+        self.multi_inner = Some((name, &value.inner));
+        self.next()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        // take inner lower bound
+        // make no attempt at an upper bound
+        (self.inner.size_hint().0, None)
+    }
+}
+
+impl ExactSizeIterator for Iter<'_> {}
+
+impl iter::FusedIterator for Iter<'_> {}
+
+/// Iterator over drained name-value pairs.
+///
+/// Iterator items are `(Option<HeaderName>, HeaderValue)` to avoid cloning.
+#[derive(Debug)]
+pub struct Drain<'a> {
+    inner: hash_map::Drain<'a, HeaderName, Value>,
+    multi_inner: Option<(Option<HeaderName>, SmallVec<[HeaderValue; 4]>)>,
+    multi_idx: usize,
+}
+
+impl<'a> Drain<'a> {
+    fn new(iter: hash_map::Drain<'a, HeaderName, Value>) -> Self {
+        Self {
+            inner: iter,
+            multi_inner: None,
+            multi_idx: 0,
+        }
+    }
+}
+
+impl<'a> Iterator for Drain<'a> {
+    type Item = (Option<HeaderName>, HeaderValue);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        // handle in-progress multi value iterators first
+        if let Some((ref mut name, ref mut vals)) = self.multi_inner {
+            if !vals.is_empty() {
+                // OPTIMIZE: array removals
+                return Some((name.take(), vals.remove(0)));
+            } else {
+                // no more items in value iterator; reset state
+                self.multi_inner = None;
+                self.multi_idx = 0;
+            }
+        }
+
+        let (name, value) = self.inner.next()?;
+
+        // set up new inner iter and recurse into it
+        self.multi_inner = Some((Some(name), value.inner));
+        self.next()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        // take inner lower bound
+        // make no attempt at an upper bound
+        (self.inner.size_hint().0, None)
+    }
+}
+
+impl ExactSizeIterator for Drain<'_> {}
+
+impl iter::FusedIterator for Drain<'_> {}
+
+/// Iterator over owned name-value pairs.
+///
+/// Implementation necessarily clones header names for each value.
+#[derive(Debug)]
+pub struct IntoIter {
+    inner: hash_map::IntoIter<HeaderName, Value>,
+    multi_inner: Option<(HeaderName, smallvec::IntoIter<[HeaderValue; 4]>)>,
+}
+
+impl IntoIter {
+    fn new(inner: hash_map::IntoIter<HeaderName, Value>) -> Self {
+        Self {
+            inner,
+            multi_inner: None,
+        }
+    }
+}
+
+impl Iterator for IntoIter {
+    type Item = (HeaderName, HeaderValue);
+
+    fn next(&mut self) -> Option<Self::Item> {
+        // handle in-progress multi value iterators first
+        if let Some((ref name, ref mut vals)) = self.multi_inner {
+            match vals.next() {
+                Some(val) => {
+                    return Some((name.clone(), val));
+                }
+                None => {
+                    // no more items in value iterator; reset state
+                    self.multi_inner = None;
+                }
+            }
+        }
+
+        let (name, value) = self.inner.next()?;
+
+        // set up new inner iter and recurse into it
+        self.multi_inner = Some((name, value.inner.into_iter()));
+        self.next()
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        // take inner lower bound
+        // make no attempt at an upper bound
+        (self.inner.size_hint().0, None)
+    }
+}
+
+impl ExactSizeIterator for IntoIter {}
+
+impl iter::FusedIterator for IntoIter {}
+
+#[cfg(test)]
+mod tests {
+    use std::iter::FusedIterator;
+
+    use http::header;
+    use static_assertions::assert_impl_all;
+
+    use super::*;
+
+    assert_impl_all!(HeaderMap: IntoIterator);
+    assert_impl_all!(Keys<'_>: Iterator, ExactSizeIterator, FusedIterator);
+    assert_impl_all!(std::slice::Iter<'_, HeaderValue>: Iterator, ExactSizeIterator, FusedIterator);
+    assert_impl_all!(Removed: Iterator, ExactSizeIterator, FusedIterator);
+    assert_impl_all!(Iter<'_>: Iterator, ExactSizeIterator, FusedIterator);
+    assert_impl_all!(IntoIter: Iterator, ExactSizeIterator, FusedIterator);
+    assert_impl_all!(Drain<'_>: Iterator, ExactSizeIterator, FusedIterator);
+
+    #[test]
+    fn create() {
+        let map = HeaderMap::new();
+        assert_eq!(map.len(), 0);
+        assert_eq!(map.capacity(), 0);
+
+        let map = HeaderMap::with_capacity(16);
+        assert_eq!(map.len(), 0);
+        assert!(map.capacity() >= 16);
+    }
+
+    #[test]
+    fn insert() {
+        let mut map = HeaderMap::new();
+
+        map.insert(header::LOCATION, HeaderValue::from_static("/test"));
+        assert_eq!(map.len(), 1);
+    }
+
+    #[test]
+    fn contains() {
+        let mut map = HeaderMap::new();
+        assert!(!map.contains_key(header::LOCATION));
+
+        map.insert(header::LOCATION, HeaderValue::from_static("/test"));
+        assert!(map.contains_key(header::LOCATION));
+        assert!(map.contains_key("Location"));
+        assert!(map.contains_key("Location".to_owned()));
+        assert!(map.contains_key("location"));
+    }
+
+    #[test]
+    fn entries_iter() {
+        let mut map = HeaderMap::new();
+
+        map.append(header::HOST, HeaderValue::from_static("duck.com"));
+        map.append(header::COOKIE, HeaderValue::from_static("one=1"));
+        map.append(header::COOKIE, HeaderValue::from_static("two=2"));
+
+        let mut iter = map.iter();
+        assert!(iter.next().is_some());
+        assert!(iter.next().is_some());
+        assert!(iter.next().is_some());
+        assert!(iter.next().is_none());
+
+        let pairs = map.iter().collect::<Vec<_>>();
+        assert!(pairs.contains(&(&header::HOST, &HeaderValue::from_static("duck.com"))));
+        assert!(pairs.contains(&(&header::COOKIE, &HeaderValue::from_static("one=1"))));
+        assert!(pairs.contains(&(&header::COOKIE, &HeaderValue::from_static("two=2"))));
+    }
+
+    #[test]
+    fn drain_iter() {
+        let mut map = HeaderMap::new();
+
+        map.append(header::COOKIE, HeaderValue::from_static("one=1"));
+        map.append(header::COOKIE, HeaderValue::from_static("two=2"));
+
+        let mut vals = vec![];
+        let mut iter = map.drain();
+
+        let (name, val) = iter.next().unwrap();
+        assert_eq!(name, Some(header::COOKIE));
+        vals.push(val);
+
+        let (name, val) = iter.next().unwrap();
+        assert!(name.is_none());
+        vals.push(val);
+
+        assert!(vals.contains(&HeaderValue::from_static("one=1")));
+        assert!(vals.contains(&HeaderValue::from_static("two=2")));
+
+        assert!(iter.next().is_none());
+        drop(iter);
+
+        assert!(map.is_empty());
+    }
+
+    #[test]
+    fn retain() {
+        let mut map = HeaderMap::new();
+
+        map.append(header::LOCATION, HeaderValue::from_static("/test"));
+        map.append(header::HOST, HeaderValue::from_static("duck.com"));
+        map.append(header::COOKIE, HeaderValue::from_static("one=1"));
+        map.append(header::COOKIE, HeaderValue::from_static("two=2"));
+
+        assert_eq!(map.len(), 4);
+
+        // by value
+        map.retain(|_, val| !val.as_bytes().contains(&b'/'));
+        assert_eq!(map.len(), 3);
+
+        // by name
+        map.retain(|name, _| name.as_str() != "cookie");
+        assert_eq!(map.len(), 1);
+
+        // keep but mutate value
+        map.retain(|_, val| {
+            *val = HeaderValue::from_static("replaced");
+            true
+        });
+        assert_eq!(map.len(), 1);
+        assert_eq!(map.get("host").unwrap(), "replaced");
+    }
+
+    #[test]
+    fn retain_removes_empty_value_lists() {
+        let mut map = HeaderMap::with_capacity(3);
+
+        map.append(header::HOST, HeaderValue::from_static("duck.com"));
+        map.append(header::HOST, HeaderValue::from_static("duck.com"));
+
+        assert_eq!(map.len(), 2);
+        assert_eq!(map.len_keys(), 1);
+        assert_eq!(map.inner.len(), 1);
+        assert_eq!(map.capacity(), 3);
+
+        // remove everything
+        map.retain(|_n, _v| false);
+
+        assert_eq!(map.len(), 0);
+        assert_eq!(map.len_keys(), 0);
+        assert_eq!(map.inner.len(), 0);
+        assert_eq!(map.capacity(), 3);
+    }
+
+    #[test]
+    fn entries_into_iter() {
+        let mut map = HeaderMap::new();
+
+        map.append(header::HOST, HeaderValue::from_static("duck.com"));
+        map.append(header::COOKIE, HeaderValue::from_static("one=1"));
+        map.append(header::COOKIE, HeaderValue::from_static("two=2"));
+
+        let mut iter = map.into_iter();
+        assert!(iter.next().is_some());
+        assert!(iter.next().is_some());
+        assert!(iter.next().is_some());
+        assert!(iter.next().is_none());
+    }
+
+    #[test]
+    fn iter_and_into_iter_same_order() {
+        let mut map = HeaderMap::new();
+
+        map.append(header::HOST, HeaderValue::from_static("duck.com"));
+        map.append(header::COOKIE, HeaderValue::from_static("one=1"));
+        map.append(header::COOKIE, HeaderValue::from_static("two=2"));
+
+        let mut iter = map.iter();
+        let mut into_iter = map.clone().into_iter();
+
+        assert_eq!(iter.next().map(owned_pair), into_iter.next());
+        assert_eq!(iter.next().map(owned_pair), into_iter.next());
+        assert_eq!(iter.next().map(owned_pair), into_iter.next());
+        assert_eq!(iter.next().map(owned_pair), into_iter.next());
+    }
+
+    #[test]
+    fn get_all_and_remove_same_order() {
+        let mut map = HeaderMap::new();
+
+        map.append(header::COOKIE, HeaderValue::from_static("one=1"));
+        map.append(header::COOKIE, HeaderValue::from_static("two=2"));
+
+        let mut vals = map.get_all(header::COOKIE);
+        let mut removed = map.clone().remove(header::COOKIE);
+
+        assert_eq!(vals.next(), removed.next().as_ref());
+        assert_eq!(vals.next(), removed.next().as_ref());
+        assert_eq!(vals.next(), removed.next().as_ref());
+    }
+
+    #[test]
+    fn get_all_iteration_order_matches_insertion_order() {
+        let mut map = HeaderMap::new();
+
+        let mut vals = map.get_all(header::COOKIE);
+        assert!(vals.next().is_none());
+
+        map.append(header::COOKIE, HeaderValue::from_static("1"));
+        let mut vals = map.get_all(header::COOKIE);
+        assert_eq!(vals.next().unwrap().as_bytes(), b"1");
+        assert!(vals.next().is_none());
+
+        map.append(header::COOKIE, HeaderValue::from_static("2"));
+        let mut vals = map.get_all(header::COOKIE);
+        assert_eq!(vals.next().unwrap().as_bytes(), b"1");
+        assert_eq!(vals.next().unwrap().as_bytes(), b"2");
+        assert!(vals.next().is_none());
+
+        map.append(header::COOKIE, HeaderValue::from_static("3"));
+        map.append(header::COOKIE, HeaderValue::from_static("4"));
+        map.append(header::COOKIE, HeaderValue::from_static("5"));
+        let mut vals = map.get_all(header::COOKIE);
+        assert_eq!(vals.next().unwrap().as_bytes(), b"1");
+        assert_eq!(vals.next().unwrap().as_bytes(), b"2");
+        assert_eq!(vals.next().unwrap().as_bytes(), b"3");
+        assert_eq!(vals.next().unwrap().as_bytes(), b"4");
+        assert_eq!(vals.next().unwrap().as_bytes(), b"5");
+        assert!(vals.next().is_none());
+
+        let _ = map.insert(header::COOKIE, HeaderValue::from_static("6"));
+        let mut vals = map.get_all(header::COOKIE);
+        assert_eq!(vals.next().unwrap().as_bytes(), b"6");
+        assert!(vals.next().is_none());
+
+        let _ = map.insert(header::COOKIE, HeaderValue::from_static("7"));
+        let _ = map.insert(header::COOKIE, HeaderValue::from_static("8"));
+        let mut vals = map.get_all(header::COOKIE);
+        assert_eq!(vals.next().unwrap().as_bytes(), b"8");
+        assert!(vals.next().is_none());
+
+        map.append(header::COOKIE, HeaderValue::from_static("9"));
+        let mut vals = map.get_all(header::COOKIE);
+        assert_eq!(vals.next().unwrap().as_bytes(), b"8");
+        assert_eq!(vals.next().unwrap().as_bytes(), b"9");
+        assert!(vals.next().is_none());
+
+        // check for fused-ness
+        assert!(vals.next().is_none());
+    }
+
+    fn owned_pair<'a>((name, val): (&'a HeaderName, &'a HeaderValue)) -> (HeaderName, HeaderValue) {
+        (name.clone(), val.clone())
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/header/mod.rs.html b/src/actix_http/header/mod.rs.html new file mode 100644 index 000000000..1ac06d741 --- /dev/null +++ b/src/actix_http/header/mod.rs.html @@ -0,0 +1,181 @@ +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
+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
+
//! Pre-defined `HeaderName`s, traits for parsing and conversion, and other header utility methods.
+
+// declaring new header consts will yield this error
+#![allow(clippy::declare_interior_mutable_const)]
+
+// re-export from http except header map related items
+pub use ::http::header::{
+    HeaderName, HeaderValue, InvalidHeaderName, InvalidHeaderValue, ToStrError,
+};
+// re-export const header names, list is explicit so that any updates to `common` module do not
+// conflict with this set
+pub use ::http::header::{
+    ACCEPT, ACCEPT_CHARSET, ACCEPT_ENCODING, ACCEPT_LANGUAGE, ACCEPT_RANGES,
+    ACCESS_CONTROL_ALLOW_CREDENTIALS, ACCESS_CONTROL_ALLOW_HEADERS, ACCESS_CONTROL_ALLOW_METHODS,
+    ACCESS_CONTROL_ALLOW_ORIGIN, ACCESS_CONTROL_EXPOSE_HEADERS, ACCESS_CONTROL_MAX_AGE,
+    ACCESS_CONTROL_REQUEST_HEADERS, ACCESS_CONTROL_REQUEST_METHOD, AGE, ALLOW, ALT_SVC,
+    AUTHORIZATION, CACHE_CONTROL, CONNECTION, CONTENT_DISPOSITION, CONTENT_ENCODING,
+    CONTENT_LANGUAGE, CONTENT_LENGTH, CONTENT_LOCATION, CONTENT_RANGE, CONTENT_SECURITY_POLICY,
+    CONTENT_SECURITY_POLICY_REPORT_ONLY, CONTENT_TYPE, COOKIE, DATE, DNT, ETAG, EXPECT, EXPIRES,
+    FORWARDED, FROM, HOST, IF_MATCH, IF_MODIFIED_SINCE, IF_NONE_MATCH, IF_RANGE,
+    IF_UNMODIFIED_SINCE, LAST_MODIFIED, LINK, LOCATION, MAX_FORWARDS, ORIGIN, PRAGMA,
+    PROXY_AUTHENTICATE, PROXY_AUTHORIZATION, PUBLIC_KEY_PINS, PUBLIC_KEY_PINS_REPORT_ONLY, RANGE,
+    REFERER, REFERRER_POLICY, REFRESH, RETRY_AFTER, SEC_WEBSOCKET_ACCEPT, SEC_WEBSOCKET_EXTENSIONS,
+    SEC_WEBSOCKET_KEY, SEC_WEBSOCKET_PROTOCOL, SEC_WEBSOCKET_VERSION, SERVER, SET_COOKIE,
+    STRICT_TRANSPORT_SECURITY, TE, TRAILER, TRANSFER_ENCODING, UPGRADE, UPGRADE_INSECURE_REQUESTS,
+    USER_AGENT, VARY, VIA, WARNING, WWW_AUTHENTICATE, X_CONTENT_TYPE_OPTIONS,
+    X_DNS_PREFETCH_CONTROL, X_FRAME_OPTIONS, X_XSS_PROTECTION,
+};
+use percent_encoding::{AsciiSet, CONTROLS};
+
+use crate::{error::ParseError, HttpMessage};
+
+mod as_name;
+mod common;
+mod into_pair;
+mod into_value;
+pub mod map;
+mod shared;
+mod utils;
+
+pub use self::{
+    as_name::AsHeaderName,
+    // re-export list is explicit so that any updates to `http` do not conflict with this set
+    common::{
+        CACHE_STATUS, CDN_CACHE_CONTROL, CROSS_ORIGIN_EMBEDDER_POLICY, CROSS_ORIGIN_OPENER_POLICY,
+        CROSS_ORIGIN_RESOURCE_POLICY, PERMISSIONS_POLICY, X_FORWARDED_FOR, X_FORWARDED_HOST,
+        X_FORWARDED_PROTO,
+    },
+    into_pair::TryIntoHeaderPair,
+    into_value::TryIntoHeaderValue,
+    map::HeaderMap,
+    shared::{
+        parse_extended_value, q, Charset, ContentEncoding, ExtendedValue, HttpDate, LanguageTag,
+        Quality, QualityItem,
+    },
+    utils::{fmt_comma_delimited, from_comma_delimited, from_one_raw_str, http_percent_encode},
+};
+
+/// An interface for types that already represent a valid header.
+pub trait Header: TryIntoHeaderValue {
+    /// Returns the name of the header field.
+    fn name() -> HeaderName;
+
+    /// Parse the header from a HTTP message.
+    fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError>;
+}
+
+/// This encode set is used for HTTP header values and is defined at
+/// <https://datatracker.ietf.org/doc/html/rfc5987#section-3.2>.
+pub(crate) const HTTP_VALUE: &AsciiSet = &CONTROLS
+    .add(b' ')
+    .add(b'"')
+    .add(b'%')
+    .add(b'\'')
+    .add(b'(')
+    .add(b')')
+    .add(b'*')
+    .add(b',')
+    .add(b'/')
+    .add(b':')
+    .add(b';')
+    .add(b'<')
+    .add(b'-')
+    .add(b'>')
+    .add(b'?')
+    .add(b'[')
+    .add(b'\\')
+    .add(b']')
+    .add(b'{')
+    .add(b'}');
+
\ No newline at end of file diff --git a/src/actix_http/header/shared/charset.rs.html b/src/actix_http/header/shared/charset.rs.html new file mode 100644 index 000000000..c371b7f90 --- /dev/null +++ b/src/actix_http/header/shared/charset.rs.html @@ -0,0 +1,311 @@ +charset.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
+
use std::{fmt, str};
+
+use self::Charset::*;
+
+/// A MIME character set.
+///
+/// The string representation is normalized to upper case.
+///
+/// See <http://www.iana.org/assignments/character-sets/character-sets.xhtml>.
+#[derive(Debug, Clone, PartialEq, Eq)]
+#[allow(non_camel_case_types)]
+pub enum Charset {
+    /// US ASCII
+    Us_Ascii,
+    /// ISO-8859-1
+    Iso_8859_1,
+    /// ISO-8859-2
+    Iso_8859_2,
+    /// ISO-8859-3
+    Iso_8859_3,
+    /// ISO-8859-4
+    Iso_8859_4,
+    /// ISO-8859-5
+    Iso_8859_5,
+    /// ISO-8859-6
+    Iso_8859_6,
+    /// ISO-8859-7
+    Iso_8859_7,
+    /// ISO-8859-8
+    Iso_8859_8,
+    /// ISO-8859-9
+    Iso_8859_9,
+    /// ISO-8859-10
+    Iso_8859_10,
+    /// Shift_JIS
+    Shift_Jis,
+    /// EUC-JP
+    Euc_Jp,
+    /// ISO-2022-KR
+    Iso_2022_Kr,
+    /// EUC-KR
+    Euc_Kr,
+    /// ISO-2022-JP
+    Iso_2022_Jp,
+    /// ISO-2022-JP-2
+    Iso_2022_Jp_2,
+    /// ISO-8859-6-E
+    Iso_8859_6_E,
+    /// ISO-8859-6-I
+    Iso_8859_6_I,
+    /// ISO-8859-8-E
+    Iso_8859_8_E,
+    /// ISO-8859-8-I
+    Iso_8859_8_I,
+    /// GB2312
+    Gb2312,
+    /// Big5
+    Big5,
+    /// KOI8-R
+    Koi8_R,
+    /// An arbitrary charset specified as a string
+    Ext(String),
+}
+
+impl Charset {
+    fn label(&self) -> &str {
+        match *self {
+            Us_Ascii => "US-ASCII",
+            Iso_8859_1 => "ISO-8859-1",
+            Iso_8859_2 => "ISO-8859-2",
+            Iso_8859_3 => "ISO-8859-3",
+            Iso_8859_4 => "ISO-8859-4",
+            Iso_8859_5 => "ISO-8859-5",
+            Iso_8859_6 => "ISO-8859-6",
+            Iso_8859_7 => "ISO-8859-7",
+            Iso_8859_8 => "ISO-8859-8",
+            Iso_8859_9 => "ISO-8859-9",
+            Iso_8859_10 => "ISO-8859-10",
+            Shift_Jis => "Shift-JIS",
+            Euc_Jp => "EUC-JP",
+            Iso_2022_Kr => "ISO-2022-KR",
+            Euc_Kr => "EUC-KR",
+            Iso_2022_Jp => "ISO-2022-JP",
+            Iso_2022_Jp_2 => "ISO-2022-JP-2",
+            Iso_8859_6_E => "ISO-8859-6-E",
+            Iso_8859_6_I => "ISO-8859-6-I",
+            Iso_8859_8_E => "ISO-8859-8-E",
+            Iso_8859_8_I => "ISO-8859-8-I",
+            Gb2312 => "GB2312",
+            Big5 => "Big5",
+            Koi8_R => "KOI8-R",
+            Ext(ref s) => s,
+        }
+    }
+}
+
+impl fmt::Display for Charset {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str(self.label())
+    }
+}
+
+impl str::FromStr for Charset {
+    type Err = crate::Error;
+
+    fn from_str(s: &str) -> Result<Charset, crate::Error> {
+        Ok(match s.to_ascii_uppercase().as_ref() {
+            "US-ASCII" => Us_Ascii,
+            "ISO-8859-1" => Iso_8859_1,
+            "ISO-8859-2" => Iso_8859_2,
+            "ISO-8859-3" => Iso_8859_3,
+            "ISO-8859-4" => Iso_8859_4,
+            "ISO-8859-5" => Iso_8859_5,
+            "ISO-8859-6" => Iso_8859_6,
+            "ISO-8859-7" => Iso_8859_7,
+            "ISO-8859-8" => Iso_8859_8,
+            "ISO-8859-9" => Iso_8859_9,
+            "ISO-8859-10" => Iso_8859_10,
+            "SHIFT-JIS" => Shift_Jis,
+            "EUC-JP" => Euc_Jp,
+            "ISO-2022-KR" => Iso_2022_Kr,
+            "EUC-KR" => Euc_Kr,
+            "ISO-2022-JP" => Iso_2022_Jp,
+            "ISO-2022-JP-2" => Iso_2022_Jp_2,
+            "ISO-8859-6-E" => Iso_8859_6_E,
+            "ISO-8859-6-I" => Iso_8859_6_I,
+            "ISO-8859-8-E" => Iso_8859_8_E,
+            "ISO-8859-8-I" => Iso_8859_8_I,
+            "GB2312" => Gb2312,
+            "BIG5" => Big5,
+            "KOI8-R" => Koi8_R,
+            s => Ext(s.to_owned()),
+        })
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_parse() {
+        assert_eq!(Us_Ascii, "us-ascii".parse().unwrap());
+        assert_eq!(Us_Ascii, "US-Ascii".parse().unwrap());
+        assert_eq!(Us_Ascii, "US-ASCII".parse().unwrap());
+        assert_eq!(Shift_Jis, "Shift-JIS".parse().unwrap());
+        assert_eq!(Ext("ABCD".to_owned()), "abcd".parse().unwrap());
+    }
+
+    #[test]
+    fn test_display() {
+        assert_eq!("US-ASCII", format!("{}", Us_Ascii));
+        assert_eq!("ABCD", format!("{}", Ext("ABCD".to_owned())));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/header/shared/content_encoding.rs.html b/src/actix_http/header/shared/content_encoding.rs.html new file mode 100644 index 000000000..d8707ea04 --- /dev/null +++ b/src/actix_http/header/shared/content_encoding.rs.html @@ -0,0 +1,247 @@ +content_encoding.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
+
use std::str::FromStr;
+
+use derive_more::{Display, Error};
+use http::header::InvalidHeaderValue;
+
+use crate::{
+    error::ParseError,
+    header::{self, from_one_raw_str, Header, HeaderName, HeaderValue, TryIntoHeaderValue},
+    HttpMessage,
+};
+
+/// Error returned when a content encoding is unknown.
+#[derive(Debug, Display, Error)]
+#[display(fmt = "unsupported content encoding")]
+pub struct ContentEncodingParseError;
+
+/// Represents a supported content encoding.
+///
+/// Includes a commonly-used subset of media types appropriate for use as HTTP content encodings.
+/// See [IANA HTTP Content Coding Registry].
+///
+/// [IANA HTTP Content Coding Registry]: https://www.iana.org/assignments/http-parameters/http-parameters.xhtml
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+#[non_exhaustive]
+pub enum ContentEncoding {
+    /// Indicates the no-op identity encoding.
+    ///
+    /// I.e., no compression or modification.
+    Identity,
+
+    /// A format using the Brotli algorithm.
+    Brotli,
+
+    /// A format using the zlib structure with deflate algorithm.
+    Deflate,
+
+    /// Gzip algorithm.
+    Gzip,
+
+    /// Zstd algorithm.
+    Zstd,
+}
+
+impl ContentEncoding {
+    /// Convert content encoding to string.
+    #[inline]
+    pub const fn as_str(self) -> &'static str {
+        match self {
+            ContentEncoding::Brotli => "br",
+            ContentEncoding::Gzip => "gzip",
+            ContentEncoding::Deflate => "deflate",
+            ContentEncoding::Zstd => "zstd",
+            ContentEncoding::Identity => "identity",
+        }
+    }
+
+    /// Convert content encoding to header value.
+    #[inline]
+    pub const fn to_header_value(self) -> HeaderValue {
+        match self {
+            ContentEncoding::Brotli => HeaderValue::from_static("br"),
+            ContentEncoding::Gzip => HeaderValue::from_static("gzip"),
+            ContentEncoding::Deflate => HeaderValue::from_static("deflate"),
+            ContentEncoding::Zstd => HeaderValue::from_static("zstd"),
+            ContentEncoding::Identity => HeaderValue::from_static("identity"),
+        }
+    }
+}
+
+impl Default for ContentEncoding {
+    #[inline]
+    fn default() -> Self {
+        Self::Identity
+    }
+}
+
+impl FromStr for ContentEncoding {
+    type Err = ContentEncodingParseError;
+
+    fn from_str(enc: &str) -> Result<Self, Self::Err> {
+        let enc = enc.trim();
+
+        if enc.eq_ignore_ascii_case("br") {
+            Ok(ContentEncoding::Brotli)
+        } else if enc.eq_ignore_ascii_case("gzip") {
+            Ok(ContentEncoding::Gzip)
+        } else if enc.eq_ignore_ascii_case("deflate") {
+            Ok(ContentEncoding::Deflate)
+        } else if enc.eq_ignore_ascii_case("identity") {
+            Ok(ContentEncoding::Identity)
+        } else if enc.eq_ignore_ascii_case("zstd") {
+            Ok(ContentEncoding::Zstd)
+        } else {
+            Err(ContentEncodingParseError)
+        }
+    }
+}
+
+impl TryFrom<&str> for ContentEncoding {
+    type Error = ContentEncodingParseError;
+
+    fn try_from(val: &str) -> Result<Self, Self::Error> {
+        val.parse()
+    }
+}
+
+impl TryIntoHeaderValue for ContentEncoding {
+    type Error = InvalidHeaderValue;
+
+    fn try_into_value(self) -> Result<http::HeaderValue, Self::Error> {
+        Ok(HeaderValue::from_static(self.as_str()))
+    }
+}
+
+impl Header for ContentEncoding {
+    fn name() -> HeaderName {
+        header::CONTENT_ENCODING
+    }
+
+    fn parse<T: HttpMessage>(msg: &T) -> Result<Self, ParseError> {
+        from_one_raw_str(msg.headers().get(Self::name()))
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/header/shared/extended.rs.html b/src/actix_http/header/shared/extended.rs.html new file mode 100644 index 000000000..a18c7490d --- /dev/null +++ b/src/actix_http/header/shared/extended.rs.html @@ -0,0 +1,389 @@ +extended.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
+
//! Originally taken from `hyper::header::parsing`.
+
+use std::{fmt, str::FromStr};
+
+use language_tags::LanguageTag;
+
+use crate::header::{Charset, HTTP_VALUE};
+
+/// The value part of an extended parameter consisting of three parts:
+/// - The REQUIRED character set name (`charset`).
+/// - The OPTIONAL language information (`language_tag`).
+/// - A character sequence representing the actual value (`value`), separated by single quotes.
+///
+/// It is defined in [RFC 5987 §3.2](https://datatracker.ietf.org/doc/html/rfc5987#section-3.2).
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub struct ExtendedValue {
+    /// The character set that is used to encode the `value` to a string.
+    pub charset: Charset,
+
+    /// The human language details of the `value`, if available.
+    pub language_tag: Option<LanguageTag>,
+
+    /// The parameter value, as expressed in octets.
+    pub value: Vec<u8>,
+}
+
+/// Parses extended header parameter values (`ext-value`), as defined
+/// in [RFC 5987 §3.2](https://datatracker.ietf.org/doc/html/rfc5987#section-3.2).
+///
+/// Extended values are denoted by parameter names that end with `*`.
+///
+/// ## ABNF
+///
+/// ```plain
+/// ext-value     = charset  "'" [ language ] "'" value-chars
+///               ; like RFC 2231's <extended-initial-value>
+///               ; (see [RFC 2231 §7])
+///
+/// charset       = "UTF-8" / "ISO-8859-1" / mime-charset
+///
+/// mime-charset  = 1*mime-charsetc
+/// mime-charsetc = ALPHA / DIGIT
+///               / "!" / "#" / "$" / "%" / "&"
+///               / "+" / "-" / "^" / "_" / "`"
+///               / "{" / "}" / "~"
+///               ; as <mime-charset> in [RFC 2978 §2.3]
+///               ; except that the single quote is not included
+///               ; SHOULD be registered in the IANA charset registry
+///
+/// language      = <Language-Tag, defined in [RFC 5646 §2.1]>
+///
+/// value-chars   = *( pct-encoded / attr-char )
+///
+/// pct-encoded   = "%" HEXDIG HEXDIG
+///               ; see [RFC 3986 §2.1]
+///
+/// attr-char     = ALPHA / DIGIT
+///               / "!" / "#" / "$" / "&" / "+" / "-" / "."
+///               / "^" / "_" / "`" / "|" / "~"
+///               ; token except ( "*" / "'" / "%" )
+/// ```
+///
+/// [RFC 2231 §7]: https://datatracker.ietf.org/doc/html/rfc2231#section-7
+/// [RFC 2978 §2.3]: https://datatracker.ietf.org/doc/html/rfc2978#section-2.3
+/// [RFC 3986 §2.1]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.1
+pub fn parse_extended_value(val: &str) -> Result<ExtendedValue, crate::error::ParseError> {
+    // Break into three pieces separated by the single-quote character
+    let mut parts = val.splitn(3, '\'');
+
+    // Interpret the first piece as a Charset
+    let charset: Charset = match parts.next() {
+        None => return Err(crate::error::ParseError::Header),
+        Some(n) => FromStr::from_str(n).map_err(|_| crate::error::ParseError::Header)?,
+    };
+
+    // Interpret the second piece as a language tag
+    let language_tag: Option<LanguageTag> = match parts.next() {
+        None => return Err(crate::error::ParseError::Header),
+        Some("") => None,
+        Some(s) => match s.parse() {
+            Ok(lt) => Some(lt),
+            Err(_) => return Err(crate::error::ParseError::Header),
+        },
+    };
+
+    // Interpret the third piece as a sequence of value characters
+    let value: Vec<u8> = match parts.next() {
+        None => return Err(crate::error::ParseError::Header),
+        Some(v) => percent_encoding::percent_decode(v.as_bytes()).collect(),
+    };
+
+    Ok(ExtendedValue {
+        charset,
+        language_tag,
+        value,
+    })
+}
+
+impl fmt::Display for ExtendedValue {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let encoded_value = percent_encoding::percent_encode(&self.value[..], HTTP_VALUE);
+        if let Some(ref lang) = self.language_tag {
+            write!(f, "{}'{}'{}", self.charset, lang, encoded_value)
+        } else {
+            write!(f, "{}''{}", self.charset, encoded_value)
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_parse_extended_value_with_encoding_and_language_tag() {
+        let expected_language_tag = "en".parse::<LanguageTag>().unwrap();
+        // RFC 5987, Section 3.2.2
+        // Extended notation, using the Unicode character U+00A3 (POUND SIGN)
+        let result = parse_extended_value("iso-8859-1'en'%A3%20rates");
+        assert!(result.is_ok());
+        let extended_value = result.unwrap();
+        assert_eq!(Charset::Iso_8859_1, extended_value.charset);
+        assert!(extended_value.language_tag.is_some());
+        assert_eq!(expected_language_tag, extended_value.language_tag.unwrap());
+        assert_eq!(
+            vec![163, b' ', b'r', b'a', b't', b'e', b's'],
+            extended_value.value
+        );
+    }
+
+    #[test]
+    fn test_parse_extended_value_with_encoding() {
+        // RFC 5987, Section 3.2.2
+        // Extended notation, using the Unicode characters U+00A3 (POUND SIGN)
+        // and U+20AC (EURO SIGN)
+        let result = parse_extended_value("UTF-8''%c2%a3%20and%20%e2%82%ac%20rates");
+        assert!(result.is_ok());
+        let extended_value = result.unwrap();
+        assert_eq!(Charset::Ext("UTF-8".to_string()), extended_value.charset);
+        assert!(extended_value.language_tag.is_none());
+        assert_eq!(
+            vec![
+                194, 163, b' ', b'a', b'n', b'd', b' ', 226, 130, 172, b' ', b'r', b'a', b't',
+                b'e', b's',
+            ],
+            extended_value.value
+        );
+    }
+
+    #[test]
+    fn test_parse_extended_value_missing_language_tag_and_encoding() {
+        // From: https://greenbytes.de/tech/tc2231/#attwithfn2231quot2
+        let result = parse_extended_value("foo%20bar.html");
+        assert!(result.is_err());
+    }
+
+    #[test]
+    fn test_parse_extended_value_partially_formatted() {
+        let result = parse_extended_value("UTF-8'missing third part");
+        assert!(result.is_err());
+    }
+
+    #[test]
+    fn test_parse_extended_value_partially_formatted_blank() {
+        let result = parse_extended_value("blank second part'");
+        assert!(result.is_err());
+    }
+
+    #[test]
+    fn test_fmt_extended_value_with_encoding_and_language_tag() {
+        let extended_value = ExtendedValue {
+            charset: Charset::Iso_8859_1,
+            language_tag: Some("en".parse().expect("Could not parse language tag")),
+            value: vec![163, b' ', b'r', b'a', b't', b'e', b's'],
+        };
+        assert_eq!("ISO-8859-1'en'%A3%20rates", format!("{}", extended_value));
+    }
+
+    #[test]
+    fn test_fmt_extended_value_with_encoding() {
+        let extended_value = ExtendedValue {
+            charset: Charset::Ext("UTF-8".to_string()),
+            language_tag: None,
+            value: vec![
+                194, 163, b' ', b'a', b'n', b'd', b' ', 226, 130, 172, b' ', b'r', b'a', b't',
+                b'e', b's',
+            ],
+        };
+        assert_eq!(
+            "UTF-8''%C2%A3%20and%20%E2%82%AC%20rates",
+            format!("{}", extended_value)
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/header/shared/http_date.rs.html b/src/actix_http/header/shared/http_date.rs.html new file mode 100644 index 000000000..1d47e0984 --- /dev/null +++ b/src/actix_http/header/shared/http_date.rs.html @@ -0,0 +1,161 @@ +http_date.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
+
use std::{fmt, io::Write, str::FromStr, time::SystemTime};
+
+use bytes::BytesMut;
+use http::header::{HeaderValue, InvalidHeaderValue};
+
+use crate::{
+    date::DATE_VALUE_LENGTH, error::ParseError, header::TryIntoHeaderValue, helpers::MutWriter,
+};
+
+/// A timestamp with HTTP-style formatting and parsing.
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
+pub struct HttpDate(SystemTime);
+
+impl FromStr for HttpDate {
+    type Err = ParseError;
+
+    fn from_str(s: &str) -> Result<HttpDate, ParseError> {
+        match httpdate::parse_http_date(s) {
+            Ok(sys_time) => Ok(HttpDate(sys_time)),
+            Err(_) => Err(ParseError::Header),
+        }
+    }
+}
+
+impl fmt::Display for HttpDate {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        httpdate::HttpDate::from(self.0).fmt(f)
+    }
+}
+
+impl TryIntoHeaderValue for HttpDate {
+    type Error = InvalidHeaderValue;
+
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        let mut buf = BytesMut::with_capacity(DATE_VALUE_LENGTH);
+        let mut wrt = MutWriter(&mut buf);
+
+        // unwrap: date output is known to be well formed and of known length
+        write!(wrt, "{}", self).unwrap();
+
+        HeaderValue::from_maybe_shared(buf.split().freeze())
+    }
+}
+
+impl From<SystemTime> for HttpDate {
+    fn from(sys_time: SystemTime) -> HttpDate {
+        HttpDate(sys_time)
+    }
+}
+
+impl From<HttpDate> for SystemTime {
+    fn from(HttpDate(sys_time): HttpDate) -> SystemTime {
+        sys_time
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::time::Duration;
+
+    use super::*;
+
+    #[test]
+    fn date_header() {
+        macro_rules! assert_parsed_date {
+            ($case:expr, $exp:expr) => {
+                assert_eq!($case.parse::<HttpDate>().unwrap(), $exp);
+            };
+        }
+
+        // 784198117 = SystemTime::from(datetime!(1994-11-07 08:48:37).assume_utc()).duration_since(SystemTime::UNIX_EPOCH));
+        let nov_07 = HttpDate(SystemTime::UNIX_EPOCH + Duration::from_secs(784198117));
+
+        assert_parsed_date!("Mon, 07 Nov 1994 08:48:37 GMT", nov_07);
+        assert_parsed_date!("Monday, 07-Nov-94 08:48:37 GMT", nov_07);
+        assert_parsed_date!("Mon Nov  7 08:48:37 1994", nov_07);
+
+        assert!("this-is-no-date".parse::<HttpDate>().is_err());
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/header/shared/mod.rs.html b/src/actix_http/header/shared/mod.rs.html new file mode 100644 index 000000000..a5000f917 --- /dev/null +++ b/src/actix_http/header/shared/mod.rs.html @@ -0,0 +1,39 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+
//! Originally taken from `hyper::header::shared`.
+
+pub use language_tags::LanguageTag;
+
+mod charset;
+mod content_encoding;
+mod extended;
+mod http_date;
+mod quality;
+mod quality_item;
+
+pub use self::{
+    charset::Charset,
+    content_encoding::ContentEncoding,
+    extended::{parse_extended_value, ExtendedValue},
+    http_date::HttpDate,
+    quality::{q, Quality},
+    quality_item::QualityItem,
+};
+
\ No newline at end of file diff --git a/src/actix_http/header/shared/quality.rs.html b/src/actix_http/header/shared/quality.rs.html new file mode 100644 index 000000000..c0340027e --- /dev/null +++ b/src/actix_http/header/shared/quality.rs.html @@ -0,0 +1,445 @@ +quality.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
+
use std::fmt;
+
+use derive_more::{Display, Error};
+
+const MAX_QUALITY_INT: u16 = 1000;
+const MAX_QUALITY_FLOAT: f32 = 1.0;
+
+/// Represents a quality used in q-factor values.
+///
+/// The default value is equivalent to `q=1.0` (the [max](Self::MAX) value).
+///
+/// # Implementation notes
+/// The quality value is defined as a number between 0.0 and 1.0 with three decimal places.
+/// This means there are 1001 possible values. Since floating point numbers are not exact and the
+/// smallest floating point data type (`f32`) consumes four bytes, we use an `u16` value to store
+/// the quality internally.
+///
+/// [RFC 7231 §5.3.1] gives more information on quality values in HTTP header fields.
+///
+/// # Examples
+/// ```
+/// use actix_http::header::{Quality, q};
+/// assert_eq!(q(1.0), Quality::MAX);
+///
+/// assert_eq!(q(0.42).to_string(), "0.42");
+/// assert_eq!(q(1.0).to_string(), "1");
+/// assert_eq!(Quality::MIN.to_string(), "0.001");
+/// assert_eq!(Quality::ZERO.to_string(), "0");
+/// ```
+///
+/// [RFC 7231 §5.3.1]: https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.1
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Quality(pub(super) u16);
+
+impl Quality {
+    /// The maximum quality value, equivalent to `q=1.0`.
+    pub const MAX: Quality = Quality(MAX_QUALITY_INT);
+
+    /// The minimum, non-zero quality value, equivalent to `q=0.001`.
+    pub const MIN: Quality = Quality(1);
+
+    /// The zero quality value, equivalent to `q=0.0`.
+    pub const ZERO: Quality = Quality(0);
+
+    /// Converts a float in the range 0.0–1.0 to a `Quality`.
+    ///
+    /// Intentionally private. External uses should rely on the `TryFrom` impl.
+    ///
+    /// # Panics
+    /// Panics in debug mode when value is not in the range 0.0 <= n <= 1.0.
+    fn from_f32(value: f32) -> Self {
+        // Check that `value` is within range should be done before calling this method.
+        // Just in case, this debug_assert should catch if we were forgetful.
+        debug_assert!(
+            (0.0..=MAX_QUALITY_FLOAT).contains(&value),
+            "q value must be between 0.0 and 1.0"
+        );
+
+        Quality((value * MAX_QUALITY_INT as f32) as u16)
+    }
+}
+
+/// The default value is [`Quality::MAX`].
+impl Default for Quality {
+    fn default() -> Quality {
+        Quality::MAX
+    }
+}
+
+impl fmt::Display for Quality {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self.0 {
+            0 => f.write_str("0"),
+            MAX_QUALITY_INT => f.write_str("1"),
+
+            // some number in the range 1–999
+            x => {
+                f.write_str("0.")?;
+
+                // This implementation avoids string allocation for removing trailing zeroes.
+                // In benchmarks it is twice as fast as approach using something like
+                // `format!("{}").trim_end_matches('0')` for non-fast-path quality values.
+
+                if x < 10 {
+                    // x in is range 1–9
+
+                    f.write_str("00")?;
+
+                    // 0 is already handled so it's not possible to have a trailing 0 in this range
+                    // we can just write the integer
+                    itoa_fmt(f, x)
+                } else if x < 100 {
+                    // x in is range 10–99
+
+                    f.write_str("0")?;
+
+                    if x % 10 == 0 {
+                        // trailing 0, divide by 10 and write
+                        itoa_fmt(f, x / 10)
+                    } else {
+                        itoa_fmt(f, x)
+                    }
+                } else {
+                    // x is in range 100–999
+
+                    if x % 100 == 0 {
+                        // two trailing 0s, divide by 100 and write
+                        itoa_fmt(f, x / 100)
+                    } else if x % 10 == 0 {
+                        // one trailing 0, divide by 10 and write
+                        itoa_fmt(f, x / 10)
+                    } else {
+                        itoa_fmt(f, x)
+                    }
+                }
+            }
+        }
+    }
+}
+
+/// Write integer to a `fmt::Write`.
+pub fn itoa_fmt<W: fmt::Write, V: itoa::Integer>(mut wr: W, value: V) -> fmt::Result {
+    let mut buf = itoa::Buffer::new();
+    wr.write_str(buf.format(value))
+}
+
+#[derive(Debug, Clone, Display, Error)]
+#[display(fmt = "quality out of bounds")]
+#[non_exhaustive]
+pub struct QualityOutOfBounds;
+
+impl TryFrom<f32> for Quality {
+    type Error = QualityOutOfBounds;
+
+    #[inline]
+    fn try_from(value: f32) -> Result<Self, Self::Error> {
+        if (0.0..=MAX_QUALITY_FLOAT).contains(&value) {
+            Ok(Quality::from_f32(value))
+        } else {
+            Err(QualityOutOfBounds)
+        }
+    }
+}
+
+/// Convenience function to create a [`Quality`] from an `f32` (0.0–1.0).
+///
+/// Not recommended for use with user input. Rely on the `TryFrom` impls where possible.
+///
+/// # Panics
+/// Panics if value is out of range.
+///
+/// # Examples
+/// ```
+/// # use actix_http::header::{q, Quality};
+/// let q1 = q(1.0);
+/// assert_eq!(q1, Quality::MAX);
+///
+/// let q2 = q(0.001);
+/// assert_eq!(q2, Quality::MIN);
+///
+/// let q3 = q(0.0);
+/// assert_eq!(q3, Quality::ZERO);
+///
+/// let q4 = q(0.42);
+/// ```
+///
+/// An out-of-range `f32` quality will panic.
+/// ```should_panic
+/// # use actix_http::header::q;
+/// let _q2 = q(1.42);
+/// ```
+#[inline]
+pub fn q<T>(quality: T) -> Quality
+where
+    T: TryInto<Quality>,
+    T::Error: fmt::Debug,
+{
+    quality.try_into().expect("quality value was out of bounds")
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn q_helper() {
+        assert_eq!(q(0.5), Quality(500));
+    }
+
+    #[test]
+    fn display_output() {
+        assert_eq!(Quality::ZERO.to_string(), "0");
+        assert_eq!(Quality::MIN.to_string(), "0.001");
+        assert_eq!(Quality::MAX.to_string(), "1");
+
+        assert_eq!(q(0.0).to_string(), "0");
+        assert_eq!(q(1.0).to_string(), "1");
+        assert_eq!(q(0.001).to_string(), "0.001");
+        assert_eq!(q(0.5).to_string(), "0.5");
+        assert_eq!(q(0.22).to_string(), "0.22");
+        assert_eq!(q(0.123).to_string(), "0.123");
+        assert_eq!(q(0.999).to_string(), "0.999");
+
+        for x in 0..=1000 {
+            // if trailing zeroes are handled correctly, we would not expect the serialized length
+            // to ever exceed "0." + 3 decimal places = 5 in length
+            assert!(q(x as f32 / 1000.0).to_string().len() <= 5);
+        }
+    }
+
+    #[test]
+    #[should_panic]
+    fn negative_quality() {
+        q(-1.0);
+    }
+
+    #[test]
+    #[should_panic]
+    fn quality_out_of_bounds() {
+        q(2.0);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/header/shared/quality_item.rs.html b/src/actix_http/header/shared/quality_item.rs.html new file mode 100644 index 000000000..1ac5c29f7 --- /dev/null +++ b/src/actix_http/header/shared/quality_item.rs.html @@ -0,0 +1,611 @@ +quality_item.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
+
use std::{cmp, fmt, str};
+
+use super::Quality;
+use crate::error::ParseError;
+
+/// Represents an item with a quality value as defined
+/// in [RFC 7231 §5.3.1](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.1).
+///
+/// # Parsing and Formatting
+/// This wrapper be used to parse header value items that have a q-factor annotation as well as
+/// serialize items with a their q-factor.
+///
+/// # Ordering
+/// Since this context of use for this type is header value items, ordering is defined for
+/// `QualityItem`s but _only_ considers the item's quality. Order of appearance should be used as
+/// the secondary sorting parameter; i.e., a stable sort over the quality values will produce a
+/// correctly sorted sequence.
+///
+/// # Examples
+/// ```
+/// # use actix_http::header::{QualityItem, q};
+/// let q_item: QualityItem<String> = "hello;q=0.3".parse().unwrap();
+/// assert_eq!(&q_item.item, "hello");
+/// assert_eq!(q_item.quality, q(0.3));
+///
+/// // note that format is normalized compared to parsed item
+/// assert_eq!(q_item.to_string(), "hello; q=0.3");
+///
+/// // item with q=0.3 is greater than item with q=0.1
+/// let q_item_fallback: QualityItem<String> = "abc;q=0.1".parse().unwrap();
+/// assert!(q_item > q_item_fallback);
+/// ```
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub struct QualityItem<T> {
+    /// The wrapped contents of the field.
+    pub item: T,
+
+    /// The quality (client or server preference) for the value.
+    pub quality: Quality,
+}
+
+impl<T> QualityItem<T> {
+    /// Constructs a new `QualityItem` from an item and a quality value.
+    ///
+    /// The item can be of any type. The quality should be a value in the range [0, 1].
+    pub fn new(item: T, quality: Quality) -> Self {
+        QualityItem { item, quality }
+    }
+
+    /// Constructs a new `QualityItem` from an item, using the maximum q-value.
+    pub fn max(item: T) -> Self {
+        Self::new(item, Quality::MAX)
+    }
+
+    /// Constructs a new `QualityItem` from an item, using the minimum, non-zero q-value.
+    pub fn min(item: T) -> Self {
+        Self::new(item, Quality::MIN)
+    }
+
+    /// Constructs a new `QualityItem` from an item, using zero q-value of zero.
+    pub fn zero(item: T) -> Self {
+        Self::new(item, Quality::ZERO)
+    }
+}
+
+impl<T: PartialEq> PartialOrd for QualityItem<T> {
+    fn partial_cmp(&self, other: &QualityItem<T>) -> Option<cmp::Ordering> {
+        self.quality.partial_cmp(&other.quality)
+    }
+}
+
+impl<T: fmt::Display> fmt::Display for QualityItem<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(&self.item, f)?;
+
+        match self.quality {
+            // q-factor value is implied for max value
+            Quality::MAX => Ok(()),
+
+            // fast path for zero
+            Quality::ZERO => f.write_str("; q=0"),
+
+            // quality formatting is already using itoa
+            q => write!(f, "; q={}", q),
+        }
+    }
+}
+
+impl<T: str::FromStr> str::FromStr for QualityItem<T> {
+    type Err = ParseError;
+
+    fn from_str(q_item_str: &str) -> Result<Self, Self::Err> {
+        if !q_item_str.is_ascii() {
+            return Err(ParseError::Header);
+        }
+
+        // set defaults used if quality-item parsing fails, i.e., item has no q attribute
+        let mut raw_item = q_item_str;
+        let mut quality = Quality::MAX;
+
+        let parts = q_item_str
+            .rsplit_once(';')
+            .map(|(item, q_attr)| (item.trim(), q_attr.trim()));
+
+        if let Some((val, q_attr)) = parts {
+            // example for item with q-factor:
+            //
+            // gzip;q=0.65
+            // ^^^^         val
+            //      ^^^^^^  q_attr
+            //      ^^      q
+            //        ^^^^  q_val
+
+            if q_attr.len() < 2 {
+                // Can't possibly be an attribute since an attribute needs at least a name followed
+                // by an equals sign. And bare identifiers are forbidden.
+                return Err(ParseError::Header);
+            }
+
+            let q = &q_attr[0..2];
+
+            if q == "q=" || q == "Q=" {
+                let q_val = &q_attr[2..];
+                if q_val.len() > 5 {
+                    // longer than 5 indicates an over-precise q-factor
+                    return Err(ParseError::Header);
+                }
+
+                let q_value = q_val.parse::<f32>().map_err(|_| ParseError::Header)?;
+                let q_value = Quality::try_from(q_value).map_err(|_| ParseError::Header)?;
+
+                quality = q_value;
+                raw_item = val;
+            }
+        }
+
+        let item = raw_item.parse::<T>().map_err(|_| ParseError::Header)?;
+
+        Ok(QualityItem::new(item, quality))
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    // copy of encoding from actix-web headers
+    #[allow(clippy::enum_variant_names)] // allow Encoding prefix on EncodingExt
+    #[derive(Debug, Clone, PartialEq, Eq)]
+    pub enum Encoding {
+        Chunked,
+        Brotli,
+        Gzip,
+        Deflate,
+        Compress,
+        Identity,
+        Trailers,
+        EncodingExt(String),
+    }
+
+    impl fmt::Display for Encoding {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            use Encoding::*;
+            f.write_str(match *self {
+                Chunked => "chunked",
+                Brotli => "br",
+                Gzip => "gzip",
+                Deflate => "deflate",
+                Compress => "compress",
+                Identity => "identity",
+                Trailers => "trailers",
+                EncodingExt(ref s) => s.as_ref(),
+            })
+        }
+    }
+
+    impl str::FromStr for Encoding {
+        type Err = crate::error::ParseError;
+        fn from_str(s: &str) -> Result<Encoding, crate::error::ParseError> {
+            use Encoding::*;
+            match s {
+                "chunked" => Ok(Chunked),
+                "br" => Ok(Brotli),
+                "deflate" => Ok(Deflate),
+                "gzip" => Ok(Gzip),
+                "compress" => Ok(Compress),
+                "identity" => Ok(Identity),
+                "trailers" => Ok(Trailers),
+                _ => Ok(EncodingExt(s.to_owned())),
+            }
+        }
+    }
+
+    #[test]
+    fn test_quality_item_fmt_q_1() {
+        use Encoding::*;
+        let x = QualityItem::max(Chunked);
+        assert_eq!(format!("{}", x), "chunked");
+    }
+    #[test]
+    fn test_quality_item_fmt_q_0001() {
+        use Encoding::*;
+        let x = QualityItem::new(Chunked, Quality(1));
+        assert_eq!(format!("{}", x), "chunked; q=0.001");
+    }
+    #[test]
+    fn test_quality_item_fmt_q_05() {
+        use Encoding::*;
+        // Custom value
+        let x = QualityItem {
+            item: EncodingExt("identity".to_owned()),
+            quality: Quality(500),
+        };
+        assert_eq!(format!("{}", x), "identity; q=0.5");
+    }
+
+    #[test]
+    fn test_quality_item_fmt_q_0() {
+        use Encoding::*;
+        // Custom value
+        let x = QualityItem {
+            item: EncodingExt("identity".to_owned()),
+            quality: Quality(0),
+        };
+        assert_eq!(x.to_string(), "identity; q=0");
+    }
+
+    #[test]
+    fn test_quality_item_from_str1() {
+        use Encoding::*;
+        let x: Result<QualityItem<Encoding>, _> = "chunked".parse();
+        assert_eq!(
+            x.unwrap(),
+            QualityItem {
+                item: Chunked,
+                quality: Quality(1000),
+            }
+        );
+    }
+
+    #[test]
+    fn test_quality_item_from_str2() {
+        use Encoding::*;
+        let x: Result<QualityItem<Encoding>, _> = "chunked; q=1".parse();
+        assert_eq!(
+            x.unwrap(),
+            QualityItem {
+                item: Chunked,
+                quality: Quality(1000),
+            }
+        );
+    }
+
+    #[test]
+    fn test_quality_item_from_str3() {
+        use Encoding::*;
+        let x: Result<QualityItem<Encoding>, _> = "gzip; q=0.5".parse();
+        assert_eq!(
+            x.unwrap(),
+            QualityItem {
+                item: Gzip,
+                quality: Quality(500),
+            }
+        );
+    }
+
+    #[test]
+    fn test_quality_item_from_str4() {
+        use Encoding::*;
+        let x: Result<QualityItem<Encoding>, _> = "gzip; q=0.273".parse();
+        assert_eq!(
+            x.unwrap(),
+            QualityItem {
+                item: Gzip,
+                quality: Quality(273),
+            }
+        );
+    }
+
+    #[test]
+    fn test_quality_item_from_str5() {
+        let x: Result<QualityItem<Encoding>, _> = "gzip; q=0.2739999".parse();
+        assert!(x.is_err());
+    }
+
+    #[test]
+    fn test_quality_item_from_str6() {
+        let x: Result<QualityItem<Encoding>, _> = "gzip; q=2".parse();
+        assert!(x.is_err());
+    }
+
+    #[test]
+    fn test_quality_item_ordering() {
+        let x: QualityItem<Encoding> = "gzip; q=0.5".parse().ok().unwrap();
+        let y: QualityItem<Encoding> = "gzip; q=0.273".parse().ok().unwrap();
+        let comparison_result: bool = x.gt(&y);
+        assert!(comparison_result)
+    }
+
+    #[test]
+    fn test_fuzzing_bugs() {
+        assert!("99999;".parse::<QualityItem<String>>().is_err());
+        assert!("\x0d;;;=\u{d6aa}==".parse::<QualityItem<String>>().is_err())
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/header/utils.rs.html b/src/actix_http/header/utils.rs.html new file mode 100644 index 000000000..b23de3beb --- /dev/null +++ b/src/actix_http/header/utils.rs.html @@ -0,0 +1,209 @@ +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
+
//! Header parsing utilities.
+
+use std::{fmt, str::FromStr};
+
+use super::HeaderValue;
+use crate::{error::ParseError, header::HTTP_VALUE};
+
+/// Reads a comma-delimited raw header into a Vec.
+#[inline]
+pub fn from_comma_delimited<'a, I, T>(all: I) -> Result<Vec<T>, ParseError>
+where
+    I: Iterator<Item = &'a HeaderValue> + 'a,
+    T: FromStr,
+{
+    let size_guess = all.size_hint().1.unwrap_or(2);
+    let mut result = Vec::with_capacity(size_guess);
+
+    for h in all {
+        let s = h.to_str().map_err(|_| ParseError::Header)?;
+
+        result.extend(
+            s.split(',')
+                .filter_map(|x| match x.trim() {
+                    "" => None,
+                    y => Some(y),
+                })
+                .filter_map(|x| x.trim().parse().ok()),
+        )
+    }
+
+    Ok(result)
+}
+
+/// Reads a single string when parsing a header.
+#[inline]
+pub fn from_one_raw_str<T: FromStr>(val: Option<&HeaderValue>) -> Result<T, ParseError> {
+    if let Some(line) = val {
+        let line = line.to_str().map_err(|_| ParseError::Header)?;
+
+        if !line.is_empty() {
+            return T::from_str(line).or(Err(ParseError::Header));
+        }
+    }
+
+    Err(ParseError::Header)
+}
+
+/// Format an array into a comma-delimited string.
+#[inline]
+pub fn fmt_comma_delimited<T>(f: &mut fmt::Formatter<'_>, parts: &[T]) -> fmt::Result
+where
+    T: fmt::Display,
+{
+    let mut iter = parts.iter();
+
+    if let Some(part) = iter.next() {
+        fmt::Display::fmt(part, f)?;
+    }
+
+    for part in iter {
+        f.write_str(", ")?;
+        fmt::Display::fmt(part, f)?;
+    }
+
+    Ok(())
+}
+
+/// Percent encode a sequence of bytes with a character set defined in [RFC 5987 §3.2].
+///
+/// [RFC 5987 §3.2]: https://datatracker.ietf.org/doc/html/rfc5987#section-3.2
+#[inline]
+pub fn http_percent_encode(f: &mut fmt::Formatter<'_>, bytes: &[u8]) -> fmt::Result {
+    let encoded = percent_encoding::percent_encode(bytes, HTTP_VALUE);
+    fmt::Display::fmt(&encoded, f)
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn comma_delimited_parsing() {
+        let headers = [];
+        let res: Vec<usize> = from_comma_delimited(headers.iter()).unwrap();
+        assert_eq!(res, vec![0; 0]);
+
+        let headers = [
+            HeaderValue::from_static("1, 2"),
+            HeaderValue::from_static("3,4"),
+        ];
+        let res: Vec<usize> = from_comma_delimited(headers.iter()).unwrap();
+        assert_eq!(res, vec![1, 2, 3, 4]);
+
+        let headers = [
+            HeaderValue::from_static(""),
+            HeaderValue::from_static(","),
+            HeaderValue::from_static("  "),
+            HeaderValue::from_static("1    ,"),
+            HeaderValue::from_static(""),
+        ];
+        let res: Vec<usize> = from_comma_delimited(headers.iter()).unwrap();
+        assert_eq!(res, vec![1]);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/helpers.rs.html b/src/actix_http/helpers.rs.html new file mode 100644 index 000000000..f3dcc63c0 --- /dev/null +++ b/src/actix_http/helpers.rs.html @@ -0,0 +1,385 @@ +helpers.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
+
use std::io;
+
+use bytes::BufMut;
+use http::Version;
+
+const DIGITS_START: u8 = b'0';
+
+pub(crate) fn write_status_line<B: BufMut>(version: Version, n: u16, buf: &mut B) {
+    match version {
+        Version::HTTP_11 => buf.put_slice(b"HTTP/1.1 "),
+        Version::HTTP_10 => buf.put_slice(b"HTTP/1.0 "),
+        Version::HTTP_09 => buf.put_slice(b"HTTP/0.9 "),
+        _ => {
+            // other HTTP version handlers do not use this method
+        }
+    }
+
+    let d100 = (n / 100) as u8;
+    let d10 = ((n / 10) % 10) as u8;
+    let d1 = (n % 10) as u8;
+
+    buf.put_u8(DIGITS_START + d100);
+    buf.put_u8(DIGITS_START + d10);
+    buf.put_u8(DIGITS_START + d1);
+
+    // trailing space before reason
+    buf.put_u8(b' ');
+}
+
+/// Write out content length header.
+///
+/// Buffer must to contain enough space or be implicitly extendable.
+pub fn write_content_length<B: BufMut>(n: u64, buf: &mut B, camel_case: bool) {
+    if n == 0 {
+        if camel_case {
+            buf.put_slice(b"\r\nContent-Length: 0\r\n");
+        } else {
+            buf.put_slice(b"\r\ncontent-length: 0\r\n");
+        }
+
+        return;
+    }
+
+    let mut buffer = itoa::Buffer::new();
+
+    if camel_case {
+        buf.put_slice(b"\r\nContent-Length: ");
+    } else {
+        buf.put_slice(b"\r\ncontent-length: ");
+    }
+
+    buf.put_slice(buffer.format(n).as_bytes());
+    buf.put_slice(b"\r\n");
+}
+
+/// An `io::Write`r that only requires mutable reference and assumes that there is space available
+/// in the buffer for every write operation or that it can be extended implicitly (like
+/// `bytes::BytesMut`, for example).
+///
+/// This is slightly faster (~10%) than `bytes::buf::Writer` in such cases because it does not
+/// perform a remaining length check before writing.
+pub(crate) struct MutWriter<'a, B>(pub(crate) &'a mut B);
+
+impl<'a, B> io::Write for MutWriter<'a, B>
+where
+    B: BufMut,
+{
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.0.put_slice(buf);
+        Ok(buf.len())
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::str::from_utf8;
+
+    use bytes::BytesMut;
+
+    use super::*;
+
+    #[test]
+    fn test_status_line() {
+        let mut bytes = BytesMut::new();
+        bytes.reserve(50);
+        write_status_line(Version::HTTP_11, 200, &mut bytes);
+        assert_eq!(from_utf8(&bytes.split().freeze()).unwrap(), "HTTP/1.1 200 ");
+
+        let mut bytes = BytesMut::new();
+        bytes.reserve(50);
+        write_status_line(Version::HTTP_09, 404, &mut bytes);
+        assert_eq!(from_utf8(&bytes.split().freeze()).unwrap(), "HTTP/0.9 404 ");
+
+        let mut bytes = BytesMut::new();
+        bytes.reserve(50);
+        write_status_line(Version::HTTP_09, 515, &mut bytes);
+        assert_eq!(from_utf8(&bytes.split().freeze()).unwrap(), "HTTP/0.9 515 ");
+    }
+
+    #[test]
+    fn test_write_content_length() {
+        let mut bytes = BytesMut::new();
+        bytes.reserve(50);
+        write_content_length(0, &mut bytes, false);
+        assert_eq!(bytes.split().freeze(), b"\r\ncontent-length: 0\r\n"[..]);
+        bytes.reserve(50);
+        write_content_length(9, &mut bytes, false);
+        assert_eq!(bytes.split().freeze(), b"\r\ncontent-length: 9\r\n"[..]);
+        bytes.reserve(50);
+        write_content_length(10, &mut bytes, false);
+        assert_eq!(bytes.split().freeze(), b"\r\ncontent-length: 10\r\n"[..]);
+        bytes.reserve(50);
+        write_content_length(99, &mut bytes, false);
+        assert_eq!(bytes.split().freeze(), b"\r\ncontent-length: 99\r\n"[..]);
+        bytes.reserve(50);
+        write_content_length(100, &mut bytes, false);
+        assert_eq!(bytes.split().freeze(), b"\r\ncontent-length: 100\r\n"[..]);
+        bytes.reserve(50);
+        write_content_length(101, &mut bytes, false);
+        assert_eq!(bytes.split().freeze(), b"\r\ncontent-length: 101\r\n"[..]);
+        bytes.reserve(50);
+        write_content_length(998, &mut bytes, false);
+        assert_eq!(bytes.split().freeze(), b"\r\ncontent-length: 998\r\n"[..]);
+        bytes.reserve(50);
+        write_content_length(1000, &mut bytes, false);
+        assert_eq!(bytes.split().freeze(), b"\r\ncontent-length: 1000\r\n"[..]);
+        bytes.reserve(50);
+        write_content_length(1001, &mut bytes, false);
+        assert_eq!(bytes.split().freeze(), b"\r\ncontent-length: 1001\r\n"[..]);
+        bytes.reserve(50);
+        write_content_length(5909, &mut bytes, false);
+        assert_eq!(bytes.split().freeze(), b"\r\ncontent-length: 5909\r\n"[..]);
+        bytes.reserve(50);
+        write_content_length(9999, &mut bytes, false);
+        assert_eq!(bytes.split().freeze(), b"\r\ncontent-length: 9999\r\n"[..]);
+        bytes.reserve(50);
+        write_content_length(10001, &mut bytes, false);
+        assert_eq!(bytes.split().freeze(), b"\r\ncontent-length: 10001\r\n"[..]);
+        bytes.reserve(50);
+        write_content_length(59094, &mut bytes, false);
+        assert_eq!(bytes.split().freeze(), b"\r\ncontent-length: 59094\r\n"[..]);
+        bytes.reserve(50);
+        write_content_length(99999, &mut bytes, false);
+        assert_eq!(bytes.split().freeze(), b"\r\ncontent-length: 99999\r\n"[..]);
+
+        bytes.reserve(50);
+        write_content_length(590947, &mut bytes, false);
+        assert_eq!(
+            bytes.split().freeze(),
+            b"\r\ncontent-length: 590947\r\n"[..]
+        );
+        bytes.reserve(50);
+        write_content_length(999999, &mut bytes, false);
+        assert_eq!(
+            bytes.split().freeze(),
+            b"\r\ncontent-length: 999999\r\n"[..]
+        );
+        bytes.reserve(50);
+        write_content_length(5909471, &mut bytes, false);
+        assert_eq!(
+            bytes.split().freeze(),
+            b"\r\ncontent-length: 5909471\r\n"[..]
+        );
+        bytes.reserve(50);
+        write_content_length(59094718, &mut bytes, false);
+        assert_eq!(
+            bytes.split().freeze(),
+            b"\r\ncontent-length: 59094718\r\n"[..]
+        );
+        bytes.reserve(50);
+        write_content_length(4294973728, &mut bytes, false);
+        assert_eq!(
+            bytes.split().freeze(),
+            b"\r\ncontent-length: 4294973728\r\n"[..]
+        );
+    }
+
+    #[test]
+    fn write_content_length_camel_case() {
+        let mut bytes = BytesMut::new();
+        write_content_length(0, &mut bytes, false);
+        assert_eq!(bytes.split().freeze(), b"\r\ncontent-length: 0\r\n"[..]);
+
+        let mut bytes = BytesMut::new();
+        write_content_length(0, &mut bytes, true);
+        assert_eq!(bytes.split().freeze(), b"\r\nContent-Length: 0\r\n"[..]);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/http_message.rs.html b/src/actix_http/http_message.rs.html new file mode 100644 index 000000000..c3d7a4104 --- /dev/null +++ b/src/actix_http/http_message.rs.html @@ -0,0 +1,459 @@ +http_message.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
+
use std::{
+    cell::{Ref, RefMut},
+    str,
+};
+
+use encoding_rs::{Encoding, UTF_8};
+use http::header;
+use mime::Mime;
+
+use crate::{
+    error::{ContentTypeError, ParseError},
+    header::{Header, HeaderMap},
+    payload::Payload,
+    Extensions,
+};
+
+/// Trait that implements general purpose operations on HTTP messages.
+pub trait HttpMessage: Sized {
+    /// Type of message payload stream
+    type Stream;
+
+    /// Read the message headers.
+    fn headers(&self) -> &HeaderMap;
+
+    /// Message payload stream
+    fn take_payload(&mut self) -> Payload<Self::Stream>;
+
+    /// Returns a reference to the request-local data/extensions container.
+    fn extensions(&self) -> Ref<'_, Extensions>;
+
+    /// Returns a mutable reference to the request-local data/extensions container.
+    fn extensions_mut(&self) -> RefMut<'_, Extensions>;
+
+    /// Get a header.
+    #[doc(hidden)]
+    fn get_header<H: Header>(&self) -> Option<H>
+    where
+        Self: Sized,
+    {
+        if self.headers().contains_key(H::name()) {
+            H::parse(self).ok()
+        } else {
+            None
+        }
+    }
+
+    /// Read the request content type. If request did not contain a *Content-Type* header, an empty
+    /// string is returned.
+    fn content_type(&self) -> &str {
+        if let Some(content_type) = self.headers().get(header::CONTENT_TYPE) {
+            if let Ok(content_type) = content_type.to_str() {
+                return content_type.split(';').next().unwrap().trim();
+            }
+        }
+        ""
+    }
+
+    /// Get content type encoding.
+    ///
+    /// UTF-8 is used by default, If request charset is not set.
+    fn encoding(&self) -> Result<&'static Encoding, ContentTypeError> {
+        if let Some(mime_type) = self.mime_type()? {
+            if let Some(charset) = mime_type.get_param("charset") {
+                if let Some(enc) = Encoding::for_label_no_replacement(charset.as_str().as_bytes()) {
+                    Ok(enc)
+                } else {
+                    Err(ContentTypeError::UnknownEncoding)
+                }
+            } else {
+                Ok(UTF_8)
+            }
+        } else {
+            Ok(UTF_8)
+        }
+    }
+
+    /// Convert the request content type to a known mime type.
+    fn mime_type(&self) -> Result<Option<Mime>, ContentTypeError> {
+        if let Some(content_type) = self.headers().get(header::CONTENT_TYPE) {
+            if let Ok(content_type) = content_type.to_str() {
+                return match content_type.parse() {
+                    Ok(mt) => Ok(Some(mt)),
+                    Err(_) => Err(ContentTypeError::ParseError),
+                };
+            } else {
+                return Err(ContentTypeError::ParseError);
+            }
+        }
+        Ok(None)
+    }
+
+    /// Check if request has chunked transfer encoding.
+    fn chunked(&self) -> Result<bool, ParseError> {
+        if let Some(encodings) = self.headers().get(header::TRANSFER_ENCODING) {
+            if let Ok(s) = encodings.to_str() {
+                Ok(s.to_lowercase().contains("chunked"))
+            } else {
+                Err(ParseError::Header)
+            }
+        } else {
+            Ok(false)
+        }
+    }
+}
+
+impl<'a, T> HttpMessage for &'a mut T
+where
+    T: HttpMessage,
+{
+    type Stream = T::Stream;
+
+    fn headers(&self) -> &HeaderMap {
+        (**self).headers()
+    }
+
+    /// Message payload stream
+    fn take_payload(&mut self) -> Payload<Self::Stream> {
+        (**self).take_payload()
+    }
+
+    /// Request's extensions container
+    fn extensions(&self) -> Ref<'_, Extensions> {
+        (**self).extensions()
+    }
+
+    /// Mutable reference to a the request's extensions container
+    fn extensions_mut(&self) -> RefMut<'_, Extensions> {
+        (**self).extensions_mut()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use bytes::Bytes;
+    use encoding_rs::ISO_8859_2;
+
+    use super::*;
+    use crate::test::TestRequest;
+
+    #[test]
+    fn test_content_type() {
+        let req = TestRequest::default()
+            .insert_header(("content-type", "text/plain"))
+            .finish();
+        assert_eq!(req.content_type(), "text/plain");
+        let req = TestRequest::default()
+            .insert_header(("content-type", "application/json; charset=utf-8"))
+            .finish();
+        assert_eq!(req.content_type(), "application/json");
+        let req = TestRequest::default().finish();
+        assert_eq!(req.content_type(), "");
+    }
+
+    #[test]
+    fn test_mime_type() {
+        let req = TestRequest::default()
+            .insert_header(("content-type", "application/json"))
+            .finish();
+        assert_eq!(req.mime_type().unwrap(), Some(mime::APPLICATION_JSON));
+        let req = TestRequest::default().finish();
+        assert_eq!(req.mime_type().unwrap(), None);
+        let req = TestRequest::default()
+            .insert_header(("content-type", "application/json; charset=utf-8"))
+            .finish();
+        let mt = req.mime_type().unwrap().unwrap();
+        assert_eq!(mt.get_param(mime::CHARSET), Some(mime::UTF_8));
+        assert_eq!(mt.type_(), mime::APPLICATION);
+        assert_eq!(mt.subtype(), mime::JSON);
+    }
+
+    #[test]
+    fn test_mime_type_error() {
+        let req = TestRequest::default()
+            .insert_header(("content-type", "applicationadfadsfasdflknadsfklnadsfjson"))
+            .finish();
+        assert_eq!(Err(ContentTypeError::ParseError), req.mime_type());
+    }
+
+    #[test]
+    fn test_encoding() {
+        let req = TestRequest::default().finish();
+        assert_eq!(UTF_8.name(), req.encoding().unwrap().name());
+
+        let req = TestRequest::default()
+            .insert_header(("content-type", "application/json"))
+            .finish();
+        assert_eq!(UTF_8.name(), req.encoding().unwrap().name());
+
+        let req = TestRequest::default()
+            .insert_header(("content-type", "application/json; charset=ISO-8859-2"))
+            .finish();
+        assert_eq!(ISO_8859_2, req.encoding().unwrap());
+    }
+
+    #[test]
+    fn test_encoding_error() {
+        let req = TestRequest::default()
+            .insert_header(("content-type", "applicatjson"))
+            .finish();
+        assert_eq!(Some(ContentTypeError::ParseError), req.encoding().err());
+
+        let req = TestRequest::default()
+            .insert_header(("content-type", "application/json; charset=kkkttktk"))
+            .finish();
+        assert_eq!(
+            Some(ContentTypeError::UnknownEncoding),
+            req.encoding().err()
+        );
+    }
+
+    #[test]
+    fn test_chunked() {
+        let req = TestRequest::default().finish();
+        assert!(!req.chunked().unwrap());
+
+        let req = TestRequest::default()
+            .insert_header((header::TRANSFER_ENCODING, "chunked"))
+            .finish();
+        assert!(req.chunked().unwrap());
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::TRANSFER_ENCODING,
+                Bytes::from_static(b"some va\xadscc\xacas0xsdasdlue"),
+            ))
+            .finish();
+        assert!(req.chunked().is_err());
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/keep_alive.rs.html b/src/actix_http/keep_alive.rs.html new file mode 100644 index 000000000..4a5613f53 --- /dev/null +++ b/src/actix_http/keep_alive.rs.html @@ -0,0 +1,169 @@ +keep_alive.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
+
use std::time::Duration;
+
+/// Connection keep-alive config.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum KeepAlive {
+    /// Keep-alive duration.
+    ///
+    /// `KeepAlive::Timeout(Duration::ZERO)` is mapped to `KeepAlive::Disabled`.
+    Timeout(Duration),
+
+    /// Rely on OS to shutdown TCP connection.
+    ///
+    /// Some defaults can be very long, check your OS documentation.
+    Os,
+
+    /// Keep-alive is disabled.
+    ///
+    /// Connections will be closed immediately.
+    Disabled,
+}
+
+impl KeepAlive {
+    pub(crate) fn enabled(&self) -> bool {
+        !matches!(self, Self::Disabled)
+    }
+
+    #[allow(unused)] // used with `http2` feature flag
+    pub(crate) fn duration(&self) -> Option<Duration> {
+        match self {
+            KeepAlive::Timeout(dur) => Some(*dur),
+            _ => None,
+        }
+    }
+
+    /// Map zero duration to disabled.
+    pub(crate) fn normalize(self) -> KeepAlive {
+        match self {
+            KeepAlive::Timeout(Duration::ZERO) => KeepAlive::Disabled,
+            ka => ka,
+        }
+    }
+}
+
+impl Default for KeepAlive {
+    fn default() -> Self {
+        Self::Timeout(Duration::from_secs(5))
+    }
+}
+
+impl From<Duration> for KeepAlive {
+    fn from(dur: Duration) -> Self {
+        KeepAlive::Timeout(dur).normalize()
+    }
+}
+
+impl From<Option<Duration>> for KeepAlive {
+    fn from(ka_dur: Option<Duration>) -> Self {
+        match ka_dur {
+            Some(dur) => KeepAlive::from(dur),
+            None => KeepAlive::Disabled,
+        }
+        .normalize()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn from_impls() {
+        let test: KeepAlive = Duration::from_secs(1).into();
+        assert_eq!(test, KeepAlive::Timeout(Duration::from_secs(1)));
+
+        let test: KeepAlive = Duration::from_secs(0).into();
+        assert_eq!(test, KeepAlive::Disabled);
+
+        let test: KeepAlive = Some(Duration::from_secs(0)).into();
+        assert_eq!(test, KeepAlive::Disabled);
+
+        let test: KeepAlive = None.into();
+        assert_eq!(test, KeepAlive::Disabled);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/lib.rs.html b/src/actix_http/lib.rs.html new file mode 100644 index 000000000..8ddba2728 --- /dev/null +++ b/src/actix_http/lib.rs.html @@ -0,0 +1,233 @@ +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
+
//! HTTP types and services for the Actix ecosystem.
+//!
+//! ## Crate Features
+//!
+//! | Feature             | Functionality                               |
+//! | ------------------- | ------------------------------------------- |
+//! | `http2`             | HTTP/2 support via [h2].                    |
+//! | `openssl`           | TLS support via [OpenSSL].                  |
+//! | `rustls`            | TLS support via [rustls]  0.20.             |
+//! | `rustls-0_21`       | TLS support via [rustls]  0.21.             |
+//! | `rustls-0_22`       | TLS support via [rustls]  0.22.             |
+//! | `rustls-0_23`       | TLS support via [rustls]  0.23.             |
+//! | `compress-brotli`   | Payload compression support: Brotli.        |
+//! | `compress-gzip`     | Payload compression support: Deflate, Gzip. |
+//! | `compress-zstd`     | Payload compression support: Zstd.          |
+//! | `trust-dns`         | Use [trust-dns] as the client DNS resolver. |
+//!
+//! [h2]: https://crates.io/crates/h2
+//! [OpenSSL]: https://crates.io/crates/openssl
+//! [rustls]: https://crates.io/crates/rustls
+//! [trust-dns]: https://crates.io/crates/trust-dns
+
+#![deny(rust_2018_idioms, nonstandard_style)]
+#![warn(future_incompatible)]
+#![allow(
+    clippy::type_complexity,
+    clippy::too_many_arguments,
+    clippy::borrow_interior_mutable_const
+)]
+#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
+#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+
+pub use http::{uri, uri::Uri, Method, StatusCode, Version};
+
+pub mod body;
+mod builder;
+mod config;
+mod date;
+#[cfg(feature = "__compress")]
+pub mod encoding;
+pub mod error;
+mod extensions;
+pub mod h1;
+#[cfg(feature = "http2")]
+pub mod h2;
+pub mod header;
+mod helpers;
+mod http_message;
+mod keep_alive;
+mod message;
+#[cfg(test)]
+mod notify_on_drop;
+mod payload;
+mod requests;
+mod responses;
+mod service;
+pub mod test;
+#[cfg(feature = "ws")]
+pub mod ws;
+
+#[allow(deprecated)]
+pub use self::payload::PayloadStream;
+#[cfg(any(
+    feature = "openssl",
+    feature = "rustls-0_20",
+    feature = "rustls-0_21",
+    feature = "rustls-0_22",
+    feature = "rustls-0_23",
+))]
+pub use self::service::TlsAcceptorConfig;
+pub use self::{
+    builder::HttpServiceBuilder,
+    config::ServiceConfig,
+    error::Error,
+    extensions::Extensions,
+    header::ContentEncoding,
+    http_message::HttpMessage,
+    keep_alive::KeepAlive,
+    message::{ConnectionType, Message},
+    payload::{BoxedPayloadStream, Payload},
+    requests::{Request, RequestHead, RequestHeadType},
+    responses::{Response, ResponseBuilder, ResponseHead},
+    service::HttpService,
+};
+
+/// A major HTTP protocol version.
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[non_exhaustive]
+pub enum Protocol {
+    Http1,
+    Http2,
+    Http3,
+}
+
+type ConnectCallback<IO> = dyn Fn(&IO, &mut Extensions);
+
+/// Container for data that extract with ConnectCallback.
+///
+/// # Implementation Details
+/// Uses Option to reduce necessary allocations when merging with request extensions.
+#[derive(Default)]
+pub(crate) struct OnConnectData(Option<Extensions>);
+
+impl OnConnectData {
+    /// Construct by calling the on-connect callback with the underlying transport I/O.
+    pub(crate) fn from_io<T>(io: &T, on_connect_ext: Option<&ConnectCallback<T>>) -> Self {
+        let ext = on_connect_ext.map(|handler| {
+            let mut extensions = Extensions::default();
+            handler(io, &mut extensions);
+            extensions
+        });
+
+        Self(ext)
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/message.rs.html b/src/actix_http/message.rs.html new file mode 100644 index 000000000..1dca12c90 --- /dev/null +++ b/src/actix_http/message.rs.html @@ -0,0 +1,215 @@ +message.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
+
use std::{cell::RefCell, ops, rc::Rc};
+
+use bitflags::bitflags;
+
+/// Represents various types of connection
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum ConnectionType {
+    /// Close connection after response.
+    Close,
+
+    /// Keep connection alive after response.
+    KeepAlive,
+
+    /// Connection is upgraded to different type.
+    Upgrade,
+}
+
+bitflags! {
+    #[derive(Debug, Clone, Copy)]
+    pub(crate) struct Flags: u8 {
+        const CLOSE       = 0b0000_0001;
+        const KEEP_ALIVE  = 0b0000_0010;
+        const UPGRADE     = 0b0000_0100;
+        const EXPECT      = 0b0000_1000;
+        const NO_CHUNKING = 0b0001_0000;
+        const CAMEL_CASE  = 0b0010_0000;
+    }
+}
+
+#[doc(hidden)]
+pub trait Head: Default + 'static {
+    fn clear(&mut self);
+
+    fn with_pool<F, R>(f: F) -> R
+    where
+        F: FnOnce(&MessagePool<Self>) -> R;
+}
+
+pub struct Message<T: Head> {
+    /// Rc here should not be cloned by anyone.
+    /// It's used to reuse allocation of T and no shared ownership is allowed.
+    head: Rc<T>,
+}
+
+impl<T: Head> Message<T> {
+    /// Get new message from the pool of objects
+    #[allow(clippy::new_without_default)]
+    pub fn new() -> Self {
+        T::with_pool(MessagePool::get_message)
+    }
+}
+
+impl<T: Head> ops::Deref for Message<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        self.head.as_ref()
+    }
+}
+
+impl<T: Head> ops::DerefMut for Message<T> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        Rc::get_mut(&mut self.head).expect("Multiple copies exist")
+    }
+}
+
+impl<T: Head> Drop for Message<T> {
+    fn drop(&mut self) {
+        T::with_pool(|p| p.release(self.head.clone()))
+    }
+}
+
+/// Generic `Head` object pool.
+#[doc(hidden)]
+pub struct MessagePool<T: Head>(RefCell<Vec<Rc<T>>>);
+
+impl<T: Head> MessagePool<T> {
+    pub(crate) fn create() -> MessagePool<T> {
+        MessagePool(RefCell::new(Vec::with_capacity(128)))
+    }
+
+    /// Get message from the pool
+    #[inline]
+    fn get_message(&self) -> Message<T> {
+        if let Some(mut msg) = self.0.borrow_mut().pop() {
+            // Message is put in pool only when it's the last copy.
+            // which means it's guaranteed to be unique when popped out.
+            Rc::get_mut(&mut msg)
+                .expect("Multiple copies exist")
+                .clear();
+            Message { head: msg }
+        } else {
+            Message {
+                head: Rc::new(T::default()),
+            }
+        }
+    }
+
+    #[inline]
+    /// Release message instance
+    fn release(&self, msg: Rc<T>) {
+        let pool = &mut self.0.borrow_mut();
+        if pool.len() < 128 {
+            pool.push(msg);
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/payload.rs.html b/src/actix_http/payload.rs.html new file mode 100644 index 000000000..7d7bbe5a3 --- /dev/null +++ b/src/actix_http/payload.rs.html @@ -0,0 +1,213 @@ +payload.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
+
use std::{
+    mem,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use bytes::Bytes;
+use futures_core::Stream;
+use pin_project_lite::pin_project;
+
+use crate::error::PayloadError;
+
+/// A boxed payload stream.
+pub type BoxedPayloadStream = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>;
+
+#[doc(hidden)]
+#[deprecated(since = "3.0.0", note = "Renamed to `BoxedPayloadStream`.")]
+pub type PayloadStream = BoxedPayloadStream;
+
+#[cfg(not(feature = "http2"))]
+pin_project! {
+    /// A streaming payload.
+    #[project = PayloadProj]
+    pub enum Payload<S = BoxedPayloadStream> {
+        None,
+        H1 { payload: crate::h1::Payload },
+        Stream { #[pin] payload: S },
+    }
+}
+
+#[cfg(feature = "http2")]
+pin_project! {
+    /// A streaming payload.
+    #[project = PayloadProj]
+    pub enum Payload<S = BoxedPayloadStream> {
+        None,
+        H1 { payload: crate::h1::Payload },
+        H2 { payload: crate::h2::Payload },
+        Stream { #[pin] payload: S },
+    }
+}
+
+impl<S> From<crate::h1::Payload> for Payload<S> {
+    fn from(payload: crate::h1::Payload) -> Self {
+        Payload::H1 { payload }
+    }
+}
+
+#[cfg(feature = "http2")]
+impl<S> From<crate::h2::Payload> for Payload<S> {
+    fn from(payload: crate::h2::Payload) -> Self {
+        Payload::H2 { payload }
+    }
+}
+
+#[cfg(feature = "http2")]
+impl<S> From<::h2::RecvStream> for Payload<S> {
+    fn from(stream: ::h2::RecvStream) -> Self {
+        Payload::H2 {
+            payload: crate::h2::Payload::new(stream),
+        }
+    }
+}
+
+impl From<BoxedPayloadStream> for Payload {
+    fn from(payload: BoxedPayloadStream) -> Self {
+        Payload::Stream { payload }
+    }
+}
+
+impl<S> Payload<S> {
+    /// Takes current payload and replaces it with `None` value
+    pub fn take(&mut self) -> Payload<S> {
+        mem::replace(self, Payload::None)
+    }
+}
+
+impl<S> Stream for Payload<S>
+where
+    S: Stream<Item = Result<Bytes, PayloadError>>,
+{
+    type Item = Result<Bytes, PayloadError>;
+
+    #[inline]
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        match self.project() {
+            PayloadProj::None => Poll::Ready(None),
+            PayloadProj::H1 { payload } => Pin::new(payload).poll_next(cx),
+
+            #[cfg(feature = "http2")]
+            PayloadProj::H2 { payload } => Pin::new(payload).poll_next(cx),
+
+            PayloadProj::Stream { payload } => payload.poll_next(cx),
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use static_assertions::{assert_impl_all, assert_not_impl_any};
+
+    use super::*;
+
+    assert_impl_all!(Payload: Unpin);
+    assert_not_impl_any!(Payload: Send, Sync);
+}
+
\ No newline at end of file diff --git a/src/actix_http/requests/head.rs.html b/src/actix_http/requests/head.rs.html new file mode 100644 index 000000000..4ba2aa327 --- /dev/null +++ b/src/actix_http/requests/head.rs.html @@ -0,0 +1,355 @@ +head.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
+
use std::{net, rc::Rc};
+
+use crate::{
+    header::{self, HeaderMap},
+    message::{Flags, Head, MessagePool},
+    ConnectionType, Method, Uri, Version,
+};
+
+thread_local! {
+    static REQUEST_POOL: MessagePool<RequestHead> = MessagePool::<RequestHead>::create()
+}
+
+#[derive(Debug, Clone)]
+pub struct RequestHead {
+    pub method: Method,
+    pub uri: Uri,
+    pub version: Version,
+    pub headers: HeaderMap,
+
+    /// Will only be None when called in unit tests unless set manually.
+    pub peer_addr: Option<net::SocketAddr>,
+
+    flags: Flags,
+}
+
+impl Default for RequestHead {
+    fn default() -> RequestHead {
+        RequestHead {
+            method: Method::default(),
+            uri: Uri::default(),
+            version: Version::HTTP_11,
+            headers: HeaderMap::with_capacity(16),
+            peer_addr: None,
+            flags: Flags::empty(),
+        }
+    }
+}
+
+impl Head for RequestHead {
+    fn clear(&mut self) {
+        self.flags = Flags::empty();
+        self.headers.clear();
+    }
+
+    fn with_pool<F, R>(f: F) -> R
+    where
+        F: FnOnce(&MessagePool<Self>) -> R,
+    {
+        REQUEST_POOL.with(|p| f(p))
+    }
+}
+
+impl RequestHead {
+    /// Read the message headers.
+    pub fn headers(&self) -> &HeaderMap {
+        &self.headers
+    }
+
+    /// Mutable reference to the message headers.
+    pub fn headers_mut(&mut self) -> &mut HeaderMap {
+        &mut self.headers
+    }
+
+    /// Is to uppercase headers with Camel-Case.
+    /// Default is `false`
+    #[inline]
+    pub fn camel_case_headers(&self) -> bool {
+        self.flags.contains(Flags::CAMEL_CASE)
+    }
+
+    /// Set `true` to send headers which are formatted as Camel-Case.
+    #[inline]
+    pub fn set_camel_case_headers(&mut self, val: bool) {
+        if val {
+            self.flags.insert(Flags::CAMEL_CASE);
+        } else {
+            self.flags.remove(Flags::CAMEL_CASE);
+        }
+    }
+
+    #[inline]
+    /// Set connection type of the message
+    pub fn set_connection_type(&mut self, ctype: ConnectionType) {
+        match ctype {
+            ConnectionType::Close => self.flags.insert(Flags::CLOSE),
+            ConnectionType::KeepAlive => self.flags.insert(Flags::KEEP_ALIVE),
+            ConnectionType::Upgrade => self.flags.insert(Flags::UPGRADE),
+        }
+    }
+
+    #[inline]
+    /// Connection type
+    pub fn connection_type(&self) -> ConnectionType {
+        if self.flags.contains(Flags::CLOSE) {
+            ConnectionType::Close
+        } else if self.flags.contains(Flags::KEEP_ALIVE) {
+            ConnectionType::KeepAlive
+        } else if self.flags.contains(Flags::UPGRADE) {
+            ConnectionType::Upgrade
+        } else if self.version < Version::HTTP_11 {
+            ConnectionType::Close
+        } else {
+            ConnectionType::KeepAlive
+        }
+    }
+
+    /// Connection upgrade status
+    pub fn upgrade(&self) -> bool {
+        self.headers()
+            .get(header::CONNECTION)
+            .map(|hdr| {
+                if let Ok(s) = hdr.to_str() {
+                    s.to_ascii_lowercase().contains("upgrade")
+                } else {
+                    false
+                }
+            })
+            .unwrap_or(false)
+    }
+
+    #[inline]
+    /// Get response body chunking state
+    pub fn chunked(&self) -> bool {
+        !self.flags.contains(Flags::NO_CHUNKING)
+    }
+
+    #[inline]
+    pub fn no_chunking(&mut self, val: bool) {
+        if val {
+            self.flags.insert(Flags::NO_CHUNKING);
+        } else {
+            self.flags.remove(Flags::NO_CHUNKING);
+        }
+    }
+
+    /// Request contains `EXPECT` header.
+    #[inline]
+    pub fn expect(&self) -> bool {
+        self.flags.contains(Flags::EXPECT)
+    }
+
+    #[inline]
+    pub(crate) fn set_expect(&mut self) {
+        self.flags.insert(Flags::EXPECT);
+    }
+}
+
+#[allow(clippy::large_enum_variant)]
+#[derive(Debug)]
+pub enum RequestHeadType {
+    Owned(RequestHead),
+    Rc(Rc<RequestHead>, Option<HeaderMap>),
+}
+
+impl RequestHeadType {
+    pub fn extra_headers(&self) -> Option<&HeaderMap> {
+        match self {
+            RequestHeadType::Owned(_) => None,
+            RequestHeadType::Rc(_, headers) => headers.as_ref(),
+        }
+    }
+}
+
+impl AsRef<RequestHead> for RequestHeadType {
+    fn as_ref(&self) -> &RequestHead {
+        match self {
+            RequestHeadType::Owned(head) => head,
+            RequestHeadType::Rc(head, _) => head.as_ref(),
+        }
+    }
+}
+
+impl From<RequestHead> for RequestHeadType {
+    fn from(head: RequestHead) -> Self {
+        RequestHeadType::Owned(head)
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/requests/mod.rs.html b/src/actix_http/requests/mod.rs.html new file mode 100644 index 000000000..9e815c57d --- /dev/null +++ b/src/actix_http/requests/mod.rs.html @@ -0,0 +1,19 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+
//! HTTP requests.
+
+mod head;
+mod request;
+
+pub use self::{
+    head::{RequestHead, RequestHeadType},
+    request::Request,
+};
+
\ No newline at end of file diff --git a/src/actix_http/requests/request.rs.html b/src/actix_http/requests/request.rs.html new file mode 100644 index 000000000..535d749d4 --- /dev/null +++ b/src/actix_http/requests/request.rs.html @@ -0,0 +1,509 @@ +request.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
+
//! HTTP requests.
+
+use std::{
+    cell::{Ref, RefCell, RefMut},
+    fmt, mem, net,
+    rc::Rc,
+    str,
+};
+
+use http::{header, Method, Uri, Version};
+
+use crate::{
+    header::HeaderMap, BoxedPayloadStream, Extensions, HttpMessage, Message, Payload, RequestHead,
+};
+
+/// An HTTP request.
+pub struct Request<P = BoxedPayloadStream> {
+    pub(crate) payload: Payload<P>,
+    pub(crate) head: Message<RequestHead>,
+    pub(crate) conn_data: Option<Rc<Extensions>>,
+    pub(crate) extensions: RefCell<Extensions>,
+}
+
+impl<P> HttpMessage for Request<P> {
+    type Stream = P;
+
+    #[inline]
+    fn headers(&self) -> &HeaderMap {
+        &self.head().headers
+    }
+
+    fn take_payload(&mut self) -> Payload<P> {
+        mem::replace(&mut self.payload, Payload::None)
+    }
+
+    #[inline]
+    fn extensions(&self) -> Ref<'_, Extensions> {
+        self.extensions.borrow()
+    }
+
+    #[inline]
+    fn extensions_mut(&self) -> RefMut<'_, Extensions> {
+        self.extensions.borrow_mut()
+    }
+}
+
+impl From<Message<RequestHead>> for Request<BoxedPayloadStream> {
+    fn from(head: Message<RequestHead>) -> Self {
+        Request {
+            head,
+            payload: Payload::None,
+            extensions: RefCell::new(Extensions::default()),
+            conn_data: None,
+        }
+    }
+}
+
+impl Request<BoxedPayloadStream> {
+    /// Create new Request instance
+    #[allow(clippy::new_without_default)]
+    pub fn new() -> Request<BoxedPayloadStream> {
+        Request {
+            head: Message::new(),
+            payload: Payload::None,
+            extensions: RefCell::new(Extensions::default()),
+            conn_data: None,
+        }
+    }
+}
+
+impl<P> Request<P> {
+    /// Create new Request instance
+    pub fn with_payload(payload: Payload<P>) -> Request<P> {
+        Request {
+            payload,
+            head: Message::new(),
+            extensions: RefCell::new(Extensions::default()),
+            conn_data: None,
+        }
+    }
+
+    /// Create new Request instance
+    pub fn replace_payload<P1>(self, payload: Payload<P1>) -> (Request<P1>, Payload<P>) {
+        let pl = self.payload;
+
+        (
+            Request {
+                payload,
+                head: self.head,
+                extensions: self.extensions,
+                conn_data: self.conn_data,
+            },
+            pl,
+        )
+    }
+
+    /// Get request's payload
+    pub fn payload(&mut self) -> &mut Payload<P> {
+        &mut self.payload
+    }
+
+    /// Get request's payload
+    pub fn take_payload(&mut self) -> Payload<P> {
+        mem::replace(&mut self.payload, Payload::None)
+    }
+
+    /// Split request into request head and payload
+    pub fn into_parts(self) -> (Message<RequestHead>, Payload<P>) {
+        (self.head, self.payload)
+    }
+
+    #[inline]
+    /// Http message part of the request
+    pub fn head(&self) -> &RequestHead {
+        &self.head
+    }
+
+    #[inline]
+    #[doc(hidden)]
+    /// Mutable reference to a HTTP message part of the request
+    pub fn head_mut(&mut self) -> &mut RequestHead {
+        &mut self.head
+    }
+
+    /// Mutable reference to the message's headers.
+    pub fn headers_mut(&mut self) -> &mut HeaderMap {
+        &mut self.head.headers
+    }
+
+    /// Request's uri.
+    #[inline]
+    pub fn uri(&self) -> &Uri {
+        &self.head().uri
+    }
+
+    /// Mutable reference to the request's uri.
+    #[inline]
+    pub fn uri_mut(&mut self) -> &mut Uri {
+        &mut self.head.uri
+    }
+
+    /// Read the Request method.
+    #[inline]
+    pub fn method(&self) -> &Method {
+        &self.head().method
+    }
+
+    /// Read the Request Version.
+    #[inline]
+    pub fn version(&self) -> Version {
+        self.head().version
+    }
+
+    /// The target path of this Request.
+    #[inline]
+    pub fn path(&self) -> &str {
+        self.head().uri.path()
+    }
+
+    /// Check if request requires connection upgrade
+    #[inline]
+    pub fn upgrade(&self) -> bool {
+        if let Some(conn) = self.head().headers.get(header::CONNECTION) {
+            if let Ok(s) = conn.to_str() {
+                return s.to_lowercase().contains("upgrade");
+            }
+        }
+        self.head().method == Method::CONNECT
+    }
+
+    /// Peer socket address.
+    ///
+    /// Peer address is the directly connected peer's socket address. If a proxy is used in front of
+    /// the Actix Web server, then it would be address of this proxy.
+    ///
+    /// Will only return None when called in unit tests unless set manually.
+    #[inline]
+    pub fn peer_addr(&self) -> Option<net::SocketAddr> {
+        self.head().peer_addr
+    }
+
+    /// Returns a reference a piece of connection data set in an [on-connect] callback.
+    ///
+    /// ```ignore
+    /// let opt_t = req.conn_data::<PeerCertificate>();
+    /// ```
+    ///
+    /// [on-connect]: crate::HttpServiceBuilder::on_connect_ext
+    pub fn conn_data<T: 'static>(&self) -> Option<&T> {
+        self.conn_data
+            .as_deref()
+            .and_then(|container| container.get::<T>())
+    }
+
+    /// Returns the connection-level data/extensions container if an [on-connect] callback was
+    /// registered, leaving an empty one in its place.
+    ///
+    /// [on-connect]: crate::HttpServiceBuilder::on_connect_ext
+    pub fn take_conn_data(&mut self) -> Option<Rc<Extensions>> {
+        self.conn_data.take()
+    }
+
+    /// Returns the request-local data/extensions container, leaving an empty one in its place.
+    pub fn take_req_data(&mut self) -> Extensions {
+        mem::take(self.extensions.get_mut())
+    }
+}
+
+impl<P> fmt::Debug for Request<P> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        writeln!(
+            f,
+            "\nRequest {:?} {}:{}",
+            self.version(),
+            self.method(),
+            self.path()
+        )?;
+
+        if let Some(q) = self.uri().query().as_ref() {
+            writeln!(f, "  query: ?{:?}", q)?;
+        }
+
+        writeln!(f, "  headers:")?;
+
+        for (key, val) in self.headers().iter() {
+            writeln!(f, "    {:?}: {:?}", key, val)?;
+        }
+
+        Ok(())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_basics() {
+        let msg = Message::new();
+        let mut req = Request::from(msg);
+        req.headers_mut().insert(
+            header::CONTENT_TYPE,
+            header::HeaderValue::from_static("text/plain"),
+        );
+        assert!(req.headers().contains_key(header::CONTENT_TYPE));
+
+        *req.uri_mut() = Uri::try_from("/index.html?q=1").unwrap();
+        assert_eq!(req.uri().path(), "/index.html");
+        assert_eq!(req.uri().query(), Some("q=1"));
+
+        let s = format!("{:?}", req);
+        assert!(s.contains("Request HTTP/1.1 GET:/index.html"));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/responses/builder.rs.html b/src/actix_http/responses/builder.rs.html new file mode 100644 index 000000000..86cbaef8a --- /dev/null +++ b/src/actix_http/responses/builder.rs.html @@ -0,0 +1,859 @@ +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
+
//! HTTP response builder.
+
+use std::{cell::RefCell, fmt, str};
+
+use crate::{
+    body::{EitherBody, MessageBody},
+    error::{Error, HttpError},
+    header::{self, TryIntoHeaderPair, TryIntoHeaderValue},
+    responses::{BoxedResponseHead, ResponseHead},
+    ConnectionType, Extensions, Response, StatusCode,
+};
+
+/// An HTTP response builder.
+///
+/// Used to construct an instance of `Response` using a builder pattern. Response builders are often
+/// created using [`Response::build`].
+///
+/// # Examples
+/// ```
+/// use actix_http::{Response, ResponseBuilder, StatusCode, body, header};
+///
+/// # actix_rt::System::new().block_on(async {
+/// let mut res: Response<_> = Response::build(StatusCode::OK)
+///     .content_type(mime::APPLICATION_JSON)
+///     .insert_header((header::SERVER, "my-app/1.0"))
+///     .append_header((header::SET_COOKIE, "a=1"))
+///     .append_header((header::SET_COOKIE, "b=2"))
+///     .body("1234");
+///
+/// assert_eq!(res.status(), StatusCode::OK);
+///
+/// assert!(res.headers().contains_key("server"));
+/// assert_eq!(res.headers().get_all("set-cookie").count(), 2);
+///
+/// assert_eq!(body::to_bytes(res.into_body()).await.unwrap(), &b"1234"[..]);
+/// # })
+/// ```
+pub struct ResponseBuilder {
+    head: Option<BoxedResponseHead>,
+    err: Option<HttpError>,
+}
+
+impl ResponseBuilder {
+    /// Create response builder
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_http::{Response, ResponseBuilder, StatusCode};
+    /// let res: Response<_> = ResponseBuilder::default().finish();
+    /// assert_eq!(res.status(), StatusCode::OK);
+    /// ```
+    #[inline]
+    pub fn new(status: StatusCode) -> Self {
+        ResponseBuilder {
+            head: Some(BoxedResponseHead::new(status)),
+            err: None,
+        }
+    }
+
+    /// Set HTTP status code of this response.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_http::{ResponseBuilder, StatusCode};
+    /// let res = ResponseBuilder::default().status(StatusCode::NOT_FOUND).finish();
+    /// assert_eq!(res.status(), StatusCode::NOT_FOUND);
+    /// ```
+    #[inline]
+    pub fn status(&mut self, status: StatusCode) -> &mut Self {
+        if let Some(parts) = self.inner() {
+            parts.status = status;
+        }
+        self
+    }
+
+    /// Insert a header, replacing any that were set with an equivalent field name.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_http::{ResponseBuilder, header};
+    ///
+    /// let res = ResponseBuilder::default()
+    ///     .insert_header((header::CONTENT_TYPE, mime::APPLICATION_JSON))
+    ///     .insert_header(("X-TEST", "value"))
+    ///     .finish();
+    ///
+    /// assert!(res.headers().contains_key("content-type"));
+    /// assert!(res.headers().contains_key("x-test"));
+    /// ```
+    pub fn insert_header(&mut self, header: impl TryIntoHeaderPair) -> &mut Self {
+        if let Some(parts) = self.inner() {
+            match header.try_into_pair() {
+                Ok((key, value)) => {
+                    parts.headers.insert(key, value);
+                }
+                Err(err) => self.err = Some(err.into()),
+            };
+        }
+
+        self
+    }
+
+    /// Append a header, keeping any that were set with an equivalent field name.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_http::{ResponseBuilder, header};
+    ///
+    /// let res = ResponseBuilder::default()
+    ///     .append_header((header::CONTENT_TYPE, mime::APPLICATION_JSON))
+    ///     .append_header(("X-TEST", "value1"))
+    ///     .append_header(("X-TEST", "value2"))
+    ///     .finish();
+    ///
+    /// assert_eq!(res.headers().get_all("content-type").count(), 1);
+    /// assert_eq!(res.headers().get_all("x-test").count(), 2);
+    /// ```
+    pub fn append_header(&mut self, header: impl TryIntoHeaderPair) -> &mut Self {
+        if let Some(parts) = self.inner() {
+            match header.try_into_pair() {
+                Ok((key, value)) => parts.headers.append(key, value),
+                Err(err) => self.err = Some(err.into()),
+            };
+        }
+
+        self
+    }
+
+    /// Set the custom reason for the response.
+    #[inline]
+    pub fn reason(&mut self, reason: &'static str) -> &mut Self {
+        if let Some(parts) = self.inner() {
+            parts.reason = Some(reason);
+        }
+        self
+    }
+
+    /// Set connection type to KeepAlive
+    #[inline]
+    pub fn keep_alive(&mut self) -> &mut Self {
+        if let Some(parts) = self.inner() {
+            parts.set_connection_type(ConnectionType::KeepAlive);
+        }
+        self
+    }
+
+    /// Set connection type to `Upgrade`.
+    #[inline]
+    pub fn upgrade<V>(&mut self, value: V) -> &mut Self
+    where
+        V: TryIntoHeaderValue,
+    {
+        if let Some(parts) = self.inner() {
+            parts.set_connection_type(ConnectionType::Upgrade);
+        }
+
+        if let Ok(value) = value.try_into_value() {
+            self.insert_header((header::UPGRADE, value));
+        }
+
+        self
+    }
+
+    /// Force-close connection, even if it is marked as keep-alive.
+    #[inline]
+    pub fn force_close(&mut self) -> &mut Self {
+        if let Some(parts) = self.inner() {
+            parts.set_connection_type(ConnectionType::Close);
+        }
+        self
+    }
+
+    /// Disable chunked transfer encoding for HTTP/1.1 streaming responses.
+    #[inline]
+    pub fn no_chunking(&mut self, len: u64) -> &mut Self {
+        let mut buf = itoa::Buffer::new();
+        self.insert_header((header::CONTENT_LENGTH, buf.format(len)));
+
+        if let Some(parts) = self.inner() {
+            parts.no_chunking(true);
+        }
+        self
+    }
+
+    /// Set response content type.
+    #[inline]
+    pub fn content_type<V>(&mut self, value: V) -> &mut Self
+    where
+        V: TryIntoHeaderValue,
+    {
+        if let Some(parts) = self.inner() {
+            match value.try_into_value() {
+                Ok(value) => {
+                    parts.headers.insert(header::CONTENT_TYPE, value);
+                }
+                Err(err) => self.err = Some(err.into()),
+            };
+        }
+        self
+    }
+
+    /// Generate response with a wrapped body.
+    ///
+    /// This `ResponseBuilder` will be left in a useless state.
+    pub fn body<B>(&mut self, body: B) -> Response<EitherBody<B>>
+    where
+        B: MessageBody + 'static,
+    {
+        match self.message_body(body) {
+            Ok(res) => res.map_body(|_, body| EitherBody::left(body)),
+            Err(err) => Response::from(err).map_body(|_, body| EitherBody::right(body)),
+        }
+    }
+
+    /// Generate response with a body.
+    ///
+    /// This `ResponseBuilder` will be left in a useless state.
+    pub fn message_body<B>(&mut self, body: B) -> Result<Response<B>, Error> {
+        if let Some(err) = self.err.take() {
+            return Err(Error::new_http().with_cause(err));
+        }
+
+        let head = self.head.take().expect("cannot reuse response builder");
+
+        Ok(Response {
+            head,
+            body,
+            extensions: RefCell::new(Extensions::new()),
+        })
+    }
+
+    /// Generate response with an empty body.
+    ///
+    /// This `ResponseBuilder` will be left in a useless state.
+    #[inline]
+    pub fn finish(&mut self) -> Response<EitherBody<()>> {
+        self.body(())
+    }
+
+    /// Create an owned `ResponseBuilder`, leaving the original in a useless state.
+    pub fn take(&mut self) -> ResponseBuilder {
+        ResponseBuilder {
+            head: self.head.take(),
+            err: self.err.take(),
+        }
+    }
+
+    /// Get access to the inner response head if there has been no error.
+    fn inner(&mut self) -> Option<&mut ResponseHead> {
+        if self.err.is_some() {
+            return None;
+        }
+
+        self.head.as_deref_mut()
+    }
+}
+
+impl Default for ResponseBuilder {
+    fn default() -> Self {
+        Self::new(StatusCode::OK)
+    }
+}
+
+/// Convert `Response` to a `ResponseBuilder`. Body get dropped.
+impl<B> From<Response<B>> for ResponseBuilder {
+    fn from(res: Response<B>) -> ResponseBuilder {
+        ResponseBuilder {
+            head: Some(res.head),
+            err: None,
+        }
+    }
+}
+
+/// Convert `ResponseHead` to a `ResponseBuilder`
+impl<'a> From<&'a ResponseHead> for ResponseBuilder {
+    fn from(head: &'a ResponseHead) -> ResponseBuilder {
+        let mut msg = BoxedResponseHead::new(head.status);
+        msg.version = head.version;
+        msg.reason = head.reason;
+
+        for (k, v) in head.headers.iter() {
+            msg.headers.append(k.clone(), v.clone());
+        }
+
+        msg.no_chunking(!head.chunked());
+
+        ResponseBuilder {
+            head: Some(msg),
+            err: None,
+        }
+    }
+}
+
+impl fmt::Debug for ResponseBuilder {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let head = self.head.as_ref().unwrap();
+
+        let res = writeln!(
+            f,
+            "\nResponseBuilder {:?} {}{}",
+            head.version,
+            head.status,
+            head.reason.unwrap_or(""),
+        );
+        let _ = writeln!(f, "  headers:");
+        for (key, val) in head.headers.iter() {
+            let _ = writeln!(f, "    {:?}: {:?}", key, val);
+        }
+        res
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use bytes::Bytes;
+
+    use super::*;
+    use crate::header::{HeaderName, HeaderValue, CONTENT_TYPE};
+
+    #[test]
+    fn test_basic_builder() {
+        let resp = Response::build(StatusCode::OK)
+            .insert_header(("X-TEST", "value"))
+            .finish();
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[test]
+    fn test_upgrade() {
+        let resp = Response::build(StatusCode::OK)
+            .upgrade("websocket")
+            .finish();
+        assert!(resp.upgrade());
+        assert_eq!(
+            resp.headers().get(header::UPGRADE).unwrap(),
+            HeaderValue::from_static("websocket")
+        );
+    }
+
+    #[test]
+    fn test_force_close() {
+        let resp = Response::build(StatusCode::OK).force_close().finish();
+        assert!(!resp.keep_alive());
+    }
+
+    #[test]
+    fn test_content_type() {
+        let resp = Response::build(StatusCode::OK)
+            .content_type("text/plain")
+            .body(Bytes::new());
+        assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "text/plain");
+
+        let resp = Response::build(StatusCode::OK)
+            .content_type(mime::APPLICATION_JAVASCRIPT_UTF_8)
+            .body(Bytes::new());
+        assert_eq!(
+            resp.headers().get(CONTENT_TYPE).unwrap(),
+            "application/javascript; charset=utf-8"
+        );
+    }
+
+    #[test]
+    fn test_into_builder() {
+        let mut resp: Response<_> = "test".into();
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        resp.headers_mut().insert(
+            HeaderName::from_static("cookie"),
+            HeaderValue::from_static("cookie1=val100"),
+        );
+
+        let mut builder: ResponseBuilder = resp.into();
+        let resp = builder.status(StatusCode::BAD_REQUEST).finish();
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+
+        let cookie = resp.headers().get_all("Cookie").next().unwrap();
+        assert_eq!(cookie.to_str().unwrap(), "cookie1=val100");
+    }
+
+    #[test]
+    fn response_builder_header_insert_kv() {
+        let mut res = Response::build(StatusCode::OK);
+        res.insert_header(("Content-Type", "application/octet-stream"));
+        let res = res.finish();
+
+        assert_eq!(
+            res.headers().get("Content-Type"),
+            Some(&HeaderValue::from_static("application/octet-stream"))
+        );
+    }
+
+    #[test]
+    fn response_builder_header_insert_typed() {
+        let mut res = Response::build(StatusCode::OK);
+        res.insert_header((header::CONTENT_TYPE, mime::APPLICATION_OCTET_STREAM));
+        let res = res.finish();
+
+        assert_eq!(
+            res.headers().get("Content-Type"),
+            Some(&HeaderValue::from_static("application/octet-stream"))
+        );
+    }
+
+    #[test]
+    fn response_builder_header_append_kv() {
+        let mut res = Response::build(StatusCode::OK);
+        res.append_header(("Content-Type", "application/octet-stream"));
+        res.append_header(("Content-Type", "application/json"));
+        let res = res.finish();
+
+        let headers: Vec<_> = res.headers().get_all("Content-Type").cloned().collect();
+        assert_eq!(headers.len(), 2);
+        assert!(headers.contains(&HeaderValue::from_static("application/octet-stream")));
+        assert!(headers.contains(&HeaderValue::from_static("application/json")));
+    }
+
+    #[test]
+    fn response_builder_header_append_typed() {
+        let mut res = Response::build(StatusCode::OK);
+        res.append_header((header::CONTENT_TYPE, mime::APPLICATION_OCTET_STREAM));
+        res.append_header((header::CONTENT_TYPE, mime::APPLICATION_JSON));
+        let res = res.finish();
+
+        let headers: Vec<_> = res.headers().get_all("Content-Type").cloned().collect();
+        assert_eq!(headers.len(), 2);
+        assert!(headers.contains(&HeaderValue::from_static("application/octet-stream")));
+        assert!(headers.contains(&HeaderValue::from_static("application/json")));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/responses/head.rs.html b/src/actix_http/responses/head.rs.html new file mode 100644 index 000000000..6baaba71a --- /dev/null +++ b/src/actix_http/responses/head.rs.html @@ -0,0 +1,539 @@ +head.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
+
//! Response head type and caching pool.
+
+use std::{cell::RefCell, ops};
+
+use crate::{header::HeaderMap, message::Flags, ConnectionType, StatusCode, Version};
+
+thread_local! {
+    static RESPONSE_POOL: BoxedResponsePool = BoxedResponsePool::create();
+}
+
+#[derive(Debug, Clone)]
+pub struct ResponseHead {
+    pub version: Version,
+    pub status: StatusCode,
+    pub headers: HeaderMap,
+    pub reason: Option<&'static str>,
+    pub(crate) flags: Flags,
+}
+
+impl ResponseHead {
+    /// Create new instance of `ResponseHead` type
+    #[inline]
+    pub fn new(status: StatusCode) -> ResponseHead {
+        ResponseHead {
+            status,
+            version: Version::HTTP_11,
+            headers: HeaderMap::with_capacity(12),
+            reason: None,
+            flags: Flags::empty(),
+        }
+    }
+
+    /// Read the message headers.
+    #[inline]
+    pub fn headers(&self) -> &HeaderMap {
+        &self.headers
+    }
+
+    /// Mutable reference to the message headers.
+    #[inline]
+    pub fn headers_mut(&mut self) -> &mut HeaderMap {
+        &mut self.headers
+    }
+
+    /// Sets the flag that controls whether to send headers formatted as Camel-Case.
+    ///
+    /// Only applicable to HTTP/1.x responses; HTTP/2 header names are always lowercase.
+    #[inline]
+    pub fn set_camel_case_headers(&mut self, camel_case: bool) {
+        if camel_case {
+            self.flags.insert(Flags::CAMEL_CASE);
+        } else {
+            self.flags.remove(Flags::CAMEL_CASE);
+        }
+    }
+
+    /// Set connection type of the message
+    #[inline]
+    pub fn set_connection_type(&mut self, ctype: ConnectionType) {
+        match ctype {
+            ConnectionType::Close => self.flags.insert(Flags::CLOSE),
+            ConnectionType::KeepAlive => self.flags.insert(Flags::KEEP_ALIVE),
+            ConnectionType::Upgrade => self.flags.insert(Flags::UPGRADE),
+        }
+    }
+
+    #[inline]
+    pub fn connection_type(&self) -> ConnectionType {
+        if self.flags.contains(Flags::CLOSE) {
+            ConnectionType::Close
+        } else if self.flags.contains(Flags::KEEP_ALIVE) {
+            ConnectionType::KeepAlive
+        } else if self.flags.contains(Flags::UPGRADE) {
+            ConnectionType::Upgrade
+        } else if self.version < Version::HTTP_11 {
+            ConnectionType::Close
+        } else {
+            ConnectionType::KeepAlive
+        }
+    }
+
+    /// Check if keep-alive is enabled
+    #[inline]
+    pub fn keep_alive(&self) -> bool {
+        self.connection_type() == ConnectionType::KeepAlive
+    }
+
+    /// Check upgrade status of this message
+    #[inline]
+    pub fn upgrade(&self) -> bool {
+        self.connection_type() == ConnectionType::Upgrade
+    }
+
+    /// Get custom reason for the response
+    #[inline]
+    pub fn reason(&self) -> &str {
+        self.reason.unwrap_or_else(|| {
+            self.status
+                .canonical_reason()
+                .unwrap_or("<unknown status code>")
+        })
+    }
+
+    #[inline]
+    pub(crate) fn conn_type(&self) -> Option<ConnectionType> {
+        if self.flags.contains(Flags::CLOSE) {
+            Some(ConnectionType::Close)
+        } else if self.flags.contains(Flags::KEEP_ALIVE) {
+            Some(ConnectionType::KeepAlive)
+        } else if self.flags.contains(Flags::UPGRADE) {
+            Some(ConnectionType::Upgrade)
+        } else {
+            None
+        }
+    }
+
+    /// Get response body chunking state
+    #[inline]
+    pub fn chunked(&self) -> bool {
+        !self.flags.contains(Flags::NO_CHUNKING)
+    }
+
+    /// Set no chunking for payload
+    #[inline]
+    pub fn no_chunking(&mut self, val: bool) {
+        if val {
+            self.flags.insert(Flags::NO_CHUNKING);
+        } else {
+            self.flags.remove(Flags::NO_CHUNKING);
+        }
+    }
+}
+
+pub(crate) struct BoxedResponseHead {
+    head: Option<Box<ResponseHead>>,
+}
+
+impl BoxedResponseHead {
+    /// Get new message from the pool of objects
+    pub fn new(status: StatusCode) -> Self {
+        RESPONSE_POOL.with(|p| p.get_message(status))
+    }
+}
+
+impl ops::Deref for BoxedResponseHead {
+    type Target = ResponseHead;
+
+    fn deref(&self) -> &Self::Target {
+        self.head.as_ref().unwrap()
+    }
+}
+
+impl ops::DerefMut for BoxedResponseHead {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        self.head.as_mut().unwrap()
+    }
+}
+
+impl Drop for BoxedResponseHead {
+    fn drop(&mut self) {
+        if let Some(head) = self.head.take() {
+            RESPONSE_POOL.with(move |p| p.release(head))
+        }
+    }
+}
+
+/// Response head object pool.
+#[doc(hidden)]
+pub struct BoxedResponsePool(#[allow(clippy::vec_box)] RefCell<Vec<Box<ResponseHead>>>);
+
+impl BoxedResponsePool {
+    fn create() -> BoxedResponsePool {
+        BoxedResponsePool(RefCell::new(Vec::with_capacity(128)))
+    }
+
+    /// Get message from the pool.
+    #[inline]
+    fn get_message(&self, status: StatusCode) -> BoxedResponseHead {
+        if let Some(mut head) = self.0.borrow_mut().pop() {
+            head.reason = None;
+            head.status = status;
+            head.headers.clear();
+            head.flags = Flags::empty();
+            BoxedResponseHead { head: Some(head) }
+        } else {
+            BoxedResponseHead {
+                head: Some(Box::new(ResponseHead::new(status))),
+            }
+        }
+    }
+
+    /// Release request instance.
+    #[inline]
+    fn release(&self, msg: Box<ResponseHead>) {
+        let pool = &mut self.0.borrow_mut();
+
+        if pool.len() < 128 {
+            pool.push(msg);
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::{
+        io::{Read as _, Write as _},
+        net,
+    };
+
+    use memchr::memmem;
+
+    use crate::{
+        h1::H1Service,
+        header::{HeaderName, HeaderValue},
+        Error, Request, Response, ServiceConfig,
+    };
+
+    #[actix_rt::test]
+    async fn camel_case_headers() {
+        let mut srv = actix_http_test::test_server(|| {
+            H1Service::with_config(ServiceConfig::default(), |req: Request| async move {
+                let mut res = Response::ok();
+
+                if req.path().contains("camel") {
+                    res.head_mut().set_camel_case_headers(true);
+                }
+
+                res.headers_mut().insert(
+                    HeaderName::from_static("foo-bar"),
+                    HeaderValue::from_static("baz"),
+                );
+
+                Ok::<_, Error>(res)
+            })
+            .tcp()
+        })
+        .await;
+
+        let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
+        stream
+            .write_all(b"GET /camel HTTP/1.1\r\nConnection: Close\r\n\r\n")
+            .unwrap();
+        let mut data = vec![];
+        let _ = stream.read_to_end(&mut data).unwrap();
+        assert_eq!(&data[..17], b"HTTP/1.1 200 OK\r\n");
+        assert!(memmem::find(&data, b"Foo-Bar").is_some());
+        assert!(memmem::find(&data, b"foo-bar").is_none());
+        assert!(memmem::find(&data, b"Date").is_some());
+        assert!(memmem::find(&data, b"date").is_none());
+        assert!(memmem::find(&data, b"Content-Length").is_some());
+        assert!(memmem::find(&data, b"content-length").is_none());
+
+        let mut stream = net::TcpStream::connect(srv.addr()).unwrap();
+        stream
+            .write_all(b"GET /lower HTTP/1.1\r\nConnection: Close\r\n\r\n")
+            .unwrap();
+        let mut data = vec![];
+        let _ = stream.read_to_end(&mut data).unwrap();
+        assert_eq!(&data[..17], b"HTTP/1.1 200 OK\r\n");
+        assert!(memmem::find(&data, b"Foo-Bar").is_none());
+        assert!(memmem::find(&data, b"foo-bar").is_some());
+        assert!(memmem::find(&data, b"Date").is_none());
+        assert!(memmem::find(&data, b"date").is_some());
+        assert!(memmem::find(&data, b"Content-Length").is_none());
+        assert!(memmem::find(&data, b"content-length").is_some());
+
+        srv.stop().await;
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/responses/mod.rs.html b/src/actix_http/responses/mod.rs.html new file mode 100644 index 000000000..32f95fb6b --- /dev/null +++ b/src/actix_http/responses/mod.rs.html @@ -0,0 +1,19 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+
//! HTTP response.
+
+mod builder;
+mod head;
+#[allow(clippy::module_inception)]
+mod response;
+
+pub(crate) use self::head::BoxedResponseHead;
+pub use self::{builder::ResponseBuilder, head::ResponseHead, response::Response};
+
\ No newline at end of file diff --git a/src/actix_http/responses/response.rs.html b/src/actix_http/responses/response.rs.html new file mode 100644 index 000000000..b3aabd496 --- /dev/null +++ b/src/actix_http/responses/response.rs.html @@ -0,0 +1,877 @@ +response.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
+
//! HTTP response.
+
+use std::{
+    cell::{Ref, RefCell, RefMut},
+    fmt, str,
+};
+
+use bytes::{Bytes, BytesMut};
+use bytestring::ByteString;
+
+use crate::{
+    body::{BoxBody, EitherBody, MessageBody},
+    header::{self, HeaderMap, TryIntoHeaderValue},
+    responses::BoxedResponseHead,
+    Error, Extensions, ResponseBuilder, ResponseHead, StatusCode,
+};
+
+/// An HTTP response.
+pub struct Response<B> {
+    pub(crate) head: BoxedResponseHead,
+    pub(crate) body: B,
+    pub(crate) extensions: RefCell<Extensions>,
+}
+
+impl Response<BoxBody> {
+    /// Constructs a new response with default body.
+    #[inline]
+    pub fn new(status: StatusCode) -> Self {
+        Response {
+            head: BoxedResponseHead::new(status),
+            body: BoxBody::new(()),
+            extensions: RefCell::new(Extensions::new()),
+        }
+    }
+
+    /// Constructs a new response builder.
+    #[inline]
+    pub fn build(status: StatusCode) -> ResponseBuilder {
+        ResponseBuilder::new(status)
+    }
+
+    // just a couple frequently used shortcuts
+    // this list should not grow larger than a few
+
+    /// Constructs a new response with status 200 OK.
+    #[inline]
+    pub fn ok() -> Self {
+        Response::new(StatusCode::OK)
+    }
+
+    /// Constructs a new response with status 400 Bad Request.
+    #[inline]
+    pub fn bad_request() -> Self {
+        Response::new(StatusCode::BAD_REQUEST)
+    }
+
+    /// Constructs a new response with status 404 Not Found.
+    #[inline]
+    pub fn not_found() -> Self {
+        Response::new(StatusCode::NOT_FOUND)
+    }
+
+    /// Constructs a new response with status 500 Internal Server Error.
+    #[inline]
+    pub fn internal_server_error() -> Self {
+        Response::new(StatusCode::INTERNAL_SERVER_ERROR)
+    }
+
+    // end shortcuts
+}
+
+impl<B> Response<B> {
+    /// Constructs a new response with given body.
+    #[inline]
+    pub fn with_body(status: StatusCode, body: B) -> Response<B> {
+        Response {
+            head: BoxedResponseHead::new(status),
+            body,
+            extensions: RefCell::new(Extensions::new()),
+        }
+    }
+
+    /// Returns a reference to the head of this response.
+    #[inline]
+    pub fn head(&self) -> &ResponseHead {
+        &self.head
+    }
+
+    /// Returns a mutable reference to the head of this response.
+    #[inline]
+    pub fn head_mut(&mut self) -> &mut ResponseHead {
+        &mut self.head
+    }
+
+    /// Returns the status code of this response.
+    #[inline]
+    pub fn status(&self) -> StatusCode {
+        self.head.status
+    }
+
+    /// Returns a mutable reference the status code of this response.
+    #[inline]
+    pub fn status_mut(&mut self) -> &mut StatusCode {
+        &mut self.head.status
+    }
+
+    /// Returns a reference to response headers.
+    #[inline]
+    pub fn headers(&self) -> &HeaderMap {
+        &self.head.headers
+    }
+
+    /// Returns a mutable reference to response headers.
+    #[inline]
+    pub fn headers_mut(&mut self) -> &mut HeaderMap {
+        &mut self.head.headers
+    }
+
+    /// Returns true if connection upgrade is enabled.
+    #[inline]
+    pub fn upgrade(&self) -> bool {
+        self.head.upgrade()
+    }
+
+    /// Returns true if keep-alive is enabled.
+    #[inline]
+    pub fn keep_alive(&self) -> bool {
+        self.head.keep_alive()
+    }
+
+    /// Returns a reference to the request-local data/extensions container.
+    #[inline]
+    pub fn extensions(&self) -> Ref<'_, Extensions> {
+        self.extensions.borrow()
+    }
+
+    /// Returns a mutable reference to the request-local data/extensions container.
+    #[inline]
+    pub fn extensions_mut(&mut self) -> RefMut<'_, Extensions> {
+        self.extensions.borrow_mut()
+    }
+
+    /// Returns a reference to the body of this response.
+    #[inline]
+    pub fn body(&self) -> &B {
+        &self.body
+    }
+
+    /// Sets new body.
+    #[inline]
+    pub fn set_body<B2>(self, body: B2) -> Response<B2> {
+        Response {
+            head: self.head,
+            body,
+            extensions: self.extensions,
+        }
+    }
+
+    /// Drops body and returns new response.
+    #[inline]
+    pub fn drop_body(self) -> Response<()> {
+        self.set_body(())
+    }
+
+    /// Sets new body, returning new response and previous body value.
+    #[inline]
+    pub(crate) fn replace_body<B2>(self, body: B2) -> (Response<B2>, B) {
+        (
+            Response {
+                head: self.head,
+                body,
+                extensions: self.extensions,
+            },
+            self.body,
+        )
+    }
+
+    /// Returns split head and body.
+    ///
+    /// # Implementation Notes
+    /// Due to internal performance optimizations, the first element of the returned tuple is a
+    /// `Response` as well but only contains the head of the response this was called on.
+    #[inline]
+    pub fn into_parts(self) -> (Response<()>, B) {
+        self.replace_body(())
+    }
+
+    /// Map the current body type to another using a closure, returning a new response.
+    ///
+    /// Closure receives the response head and the current body type.
+    #[inline]
+    pub fn map_body<F, B2>(mut self, f: F) -> Response<B2>
+    where
+        F: FnOnce(&mut ResponseHead, B) -> B2,
+    {
+        let body = f(&mut self.head, self.body);
+
+        Response {
+            head: self.head,
+            body,
+            extensions: self.extensions,
+        }
+    }
+
+    /// Map the current body to a type-erased `BoxBody`.
+    #[inline]
+    pub fn map_into_boxed_body(self) -> Response<BoxBody>
+    where
+        B: MessageBody + 'static,
+    {
+        self.map_body(|_, body| body.boxed())
+    }
+
+    /// Returns the response body, dropping all other parts.
+    #[inline]
+    pub fn into_body(self) -> B {
+        self.body
+    }
+}
+
+impl<B> fmt::Debug for Response<B>
+where
+    B: MessageBody,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let res = writeln!(
+            f,
+            "\nResponse {:?} {}{}",
+            self.head.version,
+            self.head.status,
+            self.head.reason.unwrap_or(""),
+        );
+        let _ = writeln!(f, "  headers:");
+        for (key, val) in self.head.headers.iter() {
+            let _ = writeln!(f, "    {:?}: {:?}", key, val);
+        }
+        let _ = writeln!(f, "  body: {:?}", self.body.size());
+        res
+    }
+}
+
+impl<B: Default> Default for Response<B> {
+    #[inline]
+    fn default() -> Response<B> {
+        Response::with_body(StatusCode::default(), B::default())
+    }
+}
+
+impl<I: Into<Response<BoxBody>>, E: Into<Error>> From<Result<I, E>> for Response<BoxBody> {
+    fn from(res: Result<I, E>) -> Self {
+        match res {
+            Ok(val) => val.into(),
+            Err(err) => Response::from(err.into()),
+        }
+    }
+}
+
+impl From<ResponseBuilder> for Response<EitherBody<()>> {
+    fn from(mut builder: ResponseBuilder) -> Self {
+        builder.finish()
+    }
+}
+
+impl From<std::convert::Infallible> for Response<BoxBody> {
+    fn from(val: std::convert::Infallible) -> Self {
+        match val {}
+    }
+}
+
+impl From<&'static str> for Response<&'static str> {
+    fn from(val: &'static str) -> Self {
+        let mut res = Response::with_body(StatusCode::OK, val);
+        let mime = mime::TEXT_PLAIN_UTF_8.try_into_value().unwrap();
+        res.headers_mut().insert(header::CONTENT_TYPE, mime);
+        res
+    }
+}
+
+impl From<&'static [u8]> for Response<&'static [u8]> {
+    fn from(val: &'static [u8]) -> Self {
+        let mut res = Response::with_body(StatusCode::OK, val);
+        let mime = mime::APPLICATION_OCTET_STREAM.try_into_value().unwrap();
+        res.headers_mut().insert(header::CONTENT_TYPE, mime);
+        res
+    }
+}
+
+impl From<Vec<u8>> for Response<Vec<u8>> {
+    fn from(val: Vec<u8>) -> Self {
+        let mut res = Response::with_body(StatusCode::OK, val);
+        let mime = mime::APPLICATION_OCTET_STREAM.try_into_value().unwrap();
+        res.headers_mut().insert(header::CONTENT_TYPE, mime);
+        res
+    }
+}
+
+impl From<&Vec<u8>> for Response<Vec<u8>> {
+    fn from(val: &Vec<u8>) -> Self {
+        let mut res = Response::with_body(StatusCode::OK, val.clone());
+        let mime = mime::APPLICATION_OCTET_STREAM.try_into_value().unwrap();
+        res.headers_mut().insert(header::CONTENT_TYPE, mime);
+        res
+    }
+}
+
+impl From<String> for Response<String> {
+    fn from(val: String) -> Self {
+        let mut res = Response::with_body(StatusCode::OK, val);
+        let mime = mime::TEXT_PLAIN_UTF_8.try_into_value().unwrap();
+        res.headers_mut().insert(header::CONTENT_TYPE, mime);
+        res
+    }
+}
+
+impl From<&String> for Response<String> {
+    fn from(val: &String) -> Self {
+        let mut res = Response::with_body(StatusCode::OK, val.clone());
+        let mime = mime::TEXT_PLAIN_UTF_8.try_into_value().unwrap();
+        res.headers_mut().insert(header::CONTENT_TYPE, mime);
+        res
+    }
+}
+
+impl From<Bytes> for Response<Bytes> {
+    fn from(val: Bytes) -> Self {
+        let mut res = Response::with_body(StatusCode::OK, val);
+        let mime = mime::APPLICATION_OCTET_STREAM.try_into_value().unwrap();
+        res.headers_mut().insert(header::CONTENT_TYPE, mime);
+        res
+    }
+}
+
+impl From<BytesMut> for Response<BytesMut> {
+    fn from(val: BytesMut) -> Self {
+        let mut res = Response::with_body(StatusCode::OK, val);
+        let mime = mime::APPLICATION_OCTET_STREAM.try_into_value().unwrap();
+        res.headers_mut().insert(header::CONTENT_TYPE, mime);
+        res
+    }
+}
+
+impl From<ByteString> for Response<ByteString> {
+    fn from(val: ByteString) -> Self {
+        let mut res = Response::with_body(StatusCode::OK, val);
+        let mime = mime::TEXT_PLAIN_UTF_8.try_into_value().unwrap();
+        res.headers_mut().insert(header::CONTENT_TYPE, mime);
+        res
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::{
+        body::to_bytes,
+        header::{HeaderValue, CONTENT_TYPE, COOKIE},
+    };
+
+    #[test]
+    fn test_debug() {
+        let resp = Response::build(StatusCode::OK)
+            .append_header((COOKIE, HeaderValue::from_static("cookie1=value1; ")))
+            .append_header((COOKIE, HeaderValue::from_static("cookie2=value2; ")))
+            .finish();
+        let dbg = format!("{:?}", resp);
+        assert!(dbg.contains("Response"));
+    }
+
+    #[actix_rt::test]
+    async fn test_into_response() {
+        let res = Response::from("test");
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("text/plain; charset=utf-8")
+        );
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(to_bytes(res.into_body()).await.unwrap(), &b"test"[..]);
+
+        let res = Response::from(b"test".as_ref());
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("application/octet-stream")
+        );
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(to_bytes(res.into_body()).await.unwrap(), &b"test"[..]);
+
+        let res = Response::from("test".to_owned());
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("text/plain; charset=utf-8")
+        );
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(to_bytes(res.into_body()).await.unwrap(), &b"test"[..]);
+
+        let res = Response::from("test".to_owned());
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("text/plain; charset=utf-8")
+        );
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(to_bytes(res.into_body()).await.unwrap(), &b"test"[..]);
+
+        let b = Bytes::from_static(b"test");
+        let res = Response::from(b);
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("application/octet-stream")
+        );
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(to_bytes(res.into_body()).await.unwrap(), &b"test"[..]);
+
+        let b = Bytes::from_static(b"test");
+        let res = Response::from(b);
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("application/octet-stream")
+        );
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(to_bytes(res.into_body()).await.unwrap(), &b"test"[..]);
+
+        let b = BytesMut::from("test");
+        let res = Response::from(b);
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("application/octet-stream")
+        );
+
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(to_bytes(res.into_body()).await.unwrap(), &b"test"[..]);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/service.rs.html b/src/actix_http/service.rs.html new file mode 100644 index 000000000..500d5deed --- /dev/null +++ b/src/actix_http/service.rs.html @@ -0,0 +1,2181 @@ +service.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
+
use std::{
+    fmt,
+    future::Future,
+    marker::PhantomData,
+    net,
+    pin::Pin,
+    rc::Rc,
+    task::{Context, Poll},
+};
+
+use actix_codec::{AsyncRead, AsyncWrite, Framed};
+use actix_rt::net::TcpStream;
+use actix_service::{
+    fn_service, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt as _,
+};
+use futures_core::{future::LocalBoxFuture, ready};
+use pin_project_lite::pin_project;
+use tracing::error;
+
+use crate::{
+    body::{BoxBody, MessageBody},
+    builder::HttpServiceBuilder,
+    error::DispatchError,
+    h1, ConnectCallback, OnConnectData, Protocol, Request, Response, ServiceConfig,
+};
+
+/// A [`ServiceFactory`] for HTTP/1.1 and HTTP/2 connections.
+///
+/// Use [`build`](Self::build) to begin constructing service. Also see [`HttpServiceBuilder`].
+///
+/// # Automatic HTTP Version Selection
+/// There are two ways to select the HTTP version of an incoming connection:
+/// - One is to rely on the ALPN information that is provided when using TLS (HTTPS); both versions
+///   are supported automatically when using either of the `.rustls()` or `.openssl()` finalizing
+///   methods.
+/// - The other is to read the first few bytes of the TCP stream. This is the only viable approach
+///   for supporting H2C, which allows the HTTP/2 protocol to work over plaintext connections. Use
+///   the `.tcp_auto_h2c()` finalizing method to enable this behavior.
+///
+/// # Examples
+/// ```
+/// # use std::convert::Infallible;
+/// use actix_http::{HttpService, Request, Response, StatusCode};
+///
+/// // this service would constructed in an actix_server::Server
+///
+/// # actix_rt::System::new().block_on(async {
+/// HttpService::build()
+///     // the builder finalizing method, other finalizers would not return an `HttpService`
+///     .finish(|_req: Request| async move {
+///         Ok::<_, Infallible>(
+///             Response::build(StatusCode::OK).body("Hello!")
+///         )
+///     })
+///     // the service finalizing method method
+///     // you can use `.tcp_auto_h2c()`, `.rustls()`, or `.openssl()` instead of `.tcp()`
+///     .tcp();
+/// # })
+/// ```
+pub struct HttpService<T, S, B, X = h1::ExpectHandler, U = h1::UpgradeHandler> {
+    srv: S,
+    cfg: ServiceConfig,
+    expect: X,
+    upgrade: Option<U>,
+    on_connect_ext: Option<Rc<ConnectCallback<T>>>,
+    _phantom: PhantomData<B>,
+}
+
+impl<T, S, B> HttpService<T, S, B>
+where
+    S: ServiceFactory<Request, Config = ()>,
+    S::Error: Into<Response<BoxBody>> + 'static,
+    S::InitError: fmt::Debug,
+    S::Response: Into<Response<B>> + 'static,
+    <S::Service as Service<Request>>::Future: 'static,
+    B: MessageBody + 'static,
+{
+    /// Constructs builder for `HttpService` instance.
+    pub fn build() -> HttpServiceBuilder<T, S> {
+        HttpServiceBuilder::default()
+    }
+}
+
+impl<T, S, B> HttpService<T, S, B>
+where
+    S: ServiceFactory<Request, Config = ()>,
+    S::Error: Into<Response<BoxBody>> + 'static,
+    S::InitError: fmt::Debug,
+    S::Response: Into<Response<B>> + 'static,
+    <S::Service as Service<Request>>::Future: 'static,
+    B: MessageBody + 'static,
+{
+    /// Constructs new `HttpService` instance from service with default config.
+    pub fn new<F: IntoServiceFactory<S, Request>>(service: F) -> Self {
+        HttpService {
+            cfg: ServiceConfig::default(),
+            srv: service.into_factory(),
+            expect: h1::ExpectHandler,
+            upgrade: None,
+            on_connect_ext: None,
+            _phantom: PhantomData,
+        }
+    }
+
+    /// Constructs new `HttpService` instance from config and service.
+    pub(crate) fn with_config<F: IntoServiceFactory<S, Request>>(
+        cfg: ServiceConfig,
+        service: F,
+    ) -> Self {
+        HttpService {
+            cfg,
+            srv: service.into_factory(),
+            expect: h1::ExpectHandler,
+            upgrade: None,
+            on_connect_ext: None,
+            _phantom: PhantomData,
+        }
+    }
+}
+
+impl<T, S, B, X, U> HttpService<T, S, B, X, U>
+where
+    S: ServiceFactory<Request, Config = ()>,
+    S::Error: Into<Response<BoxBody>> + 'static,
+    S::InitError: fmt::Debug,
+    S::Response: Into<Response<B>> + 'static,
+    <S::Service as Service<Request>>::Future: 'static,
+    B: MessageBody,
+{
+    /// Sets service for `Expect: 100-Continue` handling.
+    ///
+    /// An expect service is called with requests that contain an `Expect` header. A successful
+    /// response type is also a request which will be forwarded to the main service.
+    pub fn expect<X1>(self, expect: X1) -> HttpService<T, S, B, X1, U>
+    where
+        X1: ServiceFactory<Request, Config = (), Response = Request>,
+        X1::Error: Into<Response<BoxBody>>,
+        X1::InitError: fmt::Debug,
+    {
+        HttpService {
+            expect,
+            cfg: self.cfg,
+            srv: self.srv,
+            upgrade: self.upgrade,
+            on_connect_ext: self.on_connect_ext,
+            _phantom: PhantomData,
+        }
+    }
+
+    /// Sets service for custom `Connection: Upgrade` handling.
+    ///
+    /// If service is provided then normal requests handling get halted and this service get called
+    /// with original request and framed object.
+    pub fn upgrade<U1>(self, upgrade: Option<U1>) -> HttpService<T, S, B, X, U1>
+    where
+        U1: ServiceFactory<(Request, Framed<T, h1::Codec>), Config = (), Response = ()>,
+        U1::Error: fmt::Display,
+        U1::InitError: fmt::Debug,
+    {
+        HttpService {
+            upgrade,
+            cfg: self.cfg,
+            srv: self.srv,
+            expect: self.expect,
+            on_connect_ext: self.on_connect_ext,
+            _phantom: PhantomData,
+        }
+    }
+
+    /// Set connect callback with mutable access to request data container.
+    pub(crate) fn on_connect_ext(mut self, f: Option<Rc<ConnectCallback<T>>>) -> Self {
+        self.on_connect_ext = f;
+        self
+    }
+}
+
+impl<S, B, X, U> HttpService<TcpStream, S, B, X, U>
+where
+    S: ServiceFactory<Request, Config = ()>,
+    S::Future: 'static,
+    S::Error: Into<Response<BoxBody>> + 'static,
+    S::InitError: fmt::Debug,
+    S::Response: Into<Response<B>> + 'static,
+    <S::Service as Service<Request>>::Future: 'static,
+
+    B: MessageBody + 'static,
+
+    X: ServiceFactory<Request, Config = (), Response = Request>,
+    X::Future: 'static,
+    X::Error: Into<Response<BoxBody>>,
+    X::InitError: fmt::Debug,
+
+    U: ServiceFactory<(Request, Framed<TcpStream, h1::Codec>), Config = (), Response = ()>,
+    U::Future: 'static,
+    U::Error: fmt::Display + Into<Response<BoxBody>>,
+    U::InitError: fmt::Debug,
+{
+    /// Creates TCP stream service from HTTP service.
+    ///
+    /// The resulting service only supports HTTP/1.x.
+    pub fn tcp(
+        self,
+    ) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = DispatchError, InitError = ()>
+    {
+        fn_service(|io: TcpStream| async {
+            let peer_addr = io.peer_addr().ok();
+            Ok((io, Protocol::Http1, peer_addr))
+        })
+        .and_then(self)
+    }
+
+    /// Creates TCP stream service from HTTP service that automatically selects HTTP/1.x or HTTP/2
+    /// on plaintext connections.
+    #[cfg(feature = "http2")]
+    pub fn tcp_auto_h2c(
+        self,
+    ) -> impl ServiceFactory<TcpStream, Config = (), Response = (), Error = DispatchError, InitError = ()>
+    {
+        fn_service(move |io: TcpStream| async move {
+            // subset of HTTP/2 preface defined by RFC 9113 §3.4
+            // this subset was chosen to maximize likelihood that peeking only once will allow us to
+            // reliably determine version or else it should fallback to h1 and fail quickly if data
+            // on the wire is junk
+            const H2_PREFACE: &[u8] = b"PRI * HTTP/2";
+
+            let mut buf = [0; 12];
+
+            io.peek(&mut buf).await?;
+
+            let proto = if buf == H2_PREFACE {
+                Protocol::Http2
+            } else {
+                Protocol::Http1
+            };
+
+            let peer_addr = io.peer_addr().ok();
+            Ok((io, proto, peer_addr))
+        })
+        .and_then(self)
+    }
+}
+
+/// Configuration options used when accepting TLS connection.
+#[cfg(any(
+    feature = "openssl",
+    feature = "rustls-0_20",
+    feature = "rustls-0_21",
+    feature = "rustls-0_22",
+    feature = "rustls-0_23",
+))]
+#[derive(Debug, Default)]
+pub struct TlsAcceptorConfig {
+    pub(crate) handshake_timeout: Option<std::time::Duration>,
+}
+
+#[cfg(any(
+    feature = "openssl",
+    feature = "rustls-0_20",
+    feature = "rustls-0_21",
+    feature = "rustls-0_22",
+    feature = "rustls-0_23",
+))]
+impl TlsAcceptorConfig {
+    /// Set TLS handshake timeout duration.
+    pub fn handshake_timeout(self, dur: std::time::Duration) -> Self {
+        Self {
+            handshake_timeout: Some(dur),
+            // ..self
+        }
+    }
+}
+
+#[cfg(feature = "openssl")]
+mod openssl {
+    use actix_service::ServiceFactoryExt as _;
+    use actix_tls::accept::{
+        openssl::{
+            reexports::{Error as SslError, SslAcceptor},
+            Acceptor, TlsStream,
+        },
+        TlsError,
+    };
+
+    use super::*;
+
+    impl<S, B, X, U> HttpService<TlsStream<TcpStream>, S, B, X, U>
+    where
+        S: ServiceFactory<Request, Config = ()>,
+        S::Future: 'static,
+        S::Error: Into<Response<BoxBody>> + 'static,
+        S::InitError: fmt::Debug,
+        S::Response: Into<Response<B>> + 'static,
+        <S::Service as Service<Request>>::Future: 'static,
+
+        B: MessageBody + 'static,
+
+        X: ServiceFactory<Request, Config = (), Response = Request>,
+        X::Future: 'static,
+        X::Error: Into<Response<BoxBody>>,
+        X::InitError: fmt::Debug,
+
+        U: ServiceFactory<
+            (Request, Framed<TlsStream<TcpStream>, h1::Codec>),
+            Config = (),
+            Response = (),
+        >,
+        U::Future: 'static,
+        U::Error: fmt::Display + Into<Response<BoxBody>>,
+        U::InitError: fmt::Debug,
+    {
+        /// Create OpenSSL based service.
+        pub fn openssl(
+            self,
+            acceptor: SslAcceptor,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<SslError, DispatchError>,
+            InitError = (),
+        > {
+            self.openssl_with_config(acceptor, TlsAcceptorConfig::default())
+        }
+
+        /// Create OpenSSL based service with custom TLS acceptor configuration.
+        pub fn openssl_with_config(
+            self,
+            acceptor: SslAcceptor,
+            tls_acceptor_config: TlsAcceptorConfig,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<SslError, DispatchError>,
+            InitError = (),
+        > {
+            let mut acceptor = Acceptor::new(acceptor);
+
+            if let Some(handshake_timeout) = tls_acceptor_config.handshake_timeout {
+                acceptor.set_handshake_timeout(handshake_timeout);
+            }
+
+            acceptor
+                .map_init_err(|_| {
+                    unreachable!("TLS acceptor service factory does not error on init")
+                })
+                .map_err(TlsError::into_service_error)
+                .map(|io: TlsStream<TcpStream>| {
+                    let proto = if let Some(protos) = io.ssl().selected_alpn_protocol() {
+                        if protos.windows(2).any(|window| window == b"h2") {
+                            Protocol::Http2
+                        } else {
+                            Protocol::Http1
+                        }
+                    } else {
+                        Protocol::Http1
+                    };
+
+                    let peer_addr = io.get_ref().peer_addr().ok();
+                    (io, proto, peer_addr)
+                })
+                .and_then(self.map_err(TlsError::Service))
+        }
+    }
+}
+
+#[cfg(feature = "rustls-0_20")]
+mod rustls_0_20 {
+    use std::io;
+
+    use actix_service::ServiceFactoryExt as _;
+    use actix_tls::accept::{
+        rustls_0_20::{reexports::ServerConfig, Acceptor, TlsStream},
+        TlsError,
+    };
+
+    use super::*;
+
+    impl<S, B, X, U> HttpService<TlsStream<TcpStream>, S, B, X, U>
+    where
+        S: ServiceFactory<Request, Config = ()>,
+        S::Future: 'static,
+        S::Error: Into<Response<BoxBody>> + 'static,
+        S::InitError: fmt::Debug,
+        S::Response: Into<Response<B>> + 'static,
+        <S::Service as Service<Request>>::Future: 'static,
+
+        B: MessageBody + 'static,
+
+        X: ServiceFactory<Request, Config = (), Response = Request>,
+        X::Future: 'static,
+        X::Error: Into<Response<BoxBody>>,
+        X::InitError: fmt::Debug,
+
+        U: ServiceFactory<
+            (Request, Framed<TlsStream<TcpStream>, h1::Codec>),
+            Config = (),
+            Response = (),
+        >,
+        U::Future: 'static,
+        U::Error: fmt::Display + Into<Response<BoxBody>>,
+        U::InitError: fmt::Debug,
+    {
+        /// Create Rustls v0.20 based service.
+        pub fn rustls(
+            self,
+            config: ServerConfig,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<io::Error, DispatchError>,
+            InitError = (),
+        > {
+            self.rustls_with_config(config, TlsAcceptorConfig::default())
+        }
+
+        /// Create Rustls v0.20 based service with custom TLS acceptor configuration.
+        pub fn rustls_with_config(
+            self,
+            mut config: ServerConfig,
+            tls_acceptor_config: TlsAcceptorConfig,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<io::Error, DispatchError>,
+            InitError = (),
+        > {
+            let mut protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
+            protos.extend_from_slice(&config.alpn_protocols);
+            config.alpn_protocols = protos;
+
+            let mut acceptor = Acceptor::new(config);
+
+            if let Some(handshake_timeout) = tls_acceptor_config.handshake_timeout {
+                acceptor.set_handshake_timeout(handshake_timeout);
+            }
+
+            acceptor
+                .map_init_err(|_| {
+                    unreachable!("TLS acceptor service factory does not error on init")
+                })
+                .map_err(TlsError::into_service_error)
+                .and_then(|io: TlsStream<TcpStream>| async {
+                    let proto = if let Some(protos) = io.get_ref().1.alpn_protocol() {
+                        if protos.windows(2).any(|window| window == b"h2") {
+                            Protocol::Http2
+                        } else {
+                            Protocol::Http1
+                        }
+                    } else {
+                        Protocol::Http1
+                    };
+                    let peer_addr = io.get_ref().0.peer_addr().ok();
+                    Ok((io, proto, peer_addr))
+                })
+                .and_then(self.map_err(TlsError::Service))
+        }
+    }
+}
+
+#[cfg(feature = "rustls-0_21")]
+mod rustls_0_21 {
+    use std::io;
+
+    use actix_service::ServiceFactoryExt as _;
+    use actix_tls::accept::{
+        rustls_0_21::{reexports::ServerConfig, Acceptor, TlsStream},
+        TlsError,
+    };
+
+    use super::*;
+
+    impl<S, B, X, U> HttpService<TlsStream<TcpStream>, S, B, X, U>
+    where
+        S: ServiceFactory<Request, Config = ()>,
+        S::Future: 'static,
+        S::Error: Into<Response<BoxBody>> + 'static,
+        S::InitError: fmt::Debug,
+        S::Response: Into<Response<B>> + 'static,
+        <S::Service as Service<Request>>::Future: 'static,
+
+        B: MessageBody + 'static,
+
+        X: ServiceFactory<Request, Config = (), Response = Request>,
+        X::Future: 'static,
+        X::Error: Into<Response<BoxBody>>,
+        X::InitError: fmt::Debug,
+
+        U: ServiceFactory<
+            (Request, Framed<TlsStream<TcpStream>, h1::Codec>),
+            Config = (),
+            Response = (),
+        >,
+        U::Future: 'static,
+        U::Error: fmt::Display + Into<Response<BoxBody>>,
+        U::InitError: fmt::Debug,
+    {
+        /// Create Rustls v0.21 based service.
+        pub fn rustls_021(
+            self,
+            config: ServerConfig,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<io::Error, DispatchError>,
+            InitError = (),
+        > {
+            self.rustls_021_with_config(config, TlsAcceptorConfig::default())
+        }
+
+        /// Create Rustls v0.21 based service with custom TLS acceptor configuration.
+        pub fn rustls_021_with_config(
+            self,
+            mut config: ServerConfig,
+            tls_acceptor_config: TlsAcceptorConfig,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<io::Error, DispatchError>,
+            InitError = (),
+        > {
+            let mut protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
+            protos.extend_from_slice(&config.alpn_protocols);
+            config.alpn_protocols = protos;
+
+            let mut acceptor = Acceptor::new(config);
+
+            if let Some(handshake_timeout) = tls_acceptor_config.handshake_timeout {
+                acceptor.set_handshake_timeout(handshake_timeout);
+            }
+
+            acceptor
+                .map_init_err(|_| {
+                    unreachable!("TLS acceptor service factory does not error on init")
+                })
+                .map_err(TlsError::into_service_error)
+                .and_then(|io: TlsStream<TcpStream>| async {
+                    let proto = if let Some(protos) = io.get_ref().1.alpn_protocol() {
+                        if protos.windows(2).any(|window| window == b"h2") {
+                            Protocol::Http2
+                        } else {
+                            Protocol::Http1
+                        }
+                    } else {
+                        Protocol::Http1
+                    };
+                    let peer_addr = io.get_ref().0.peer_addr().ok();
+                    Ok((io, proto, peer_addr))
+                })
+                .and_then(self.map_err(TlsError::Service))
+        }
+    }
+}
+
+#[cfg(feature = "rustls-0_22")]
+mod rustls_0_22 {
+    use std::io;
+
+    use actix_service::ServiceFactoryExt as _;
+    use actix_tls::accept::{
+        rustls_0_22::{reexports::ServerConfig, Acceptor, TlsStream},
+        TlsError,
+    };
+
+    use super::*;
+
+    impl<S, B, X, U> HttpService<TlsStream<TcpStream>, S, B, X, U>
+    where
+        S: ServiceFactory<Request, Config = ()>,
+        S::Future: 'static,
+        S::Error: Into<Response<BoxBody>> + 'static,
+        S::InitError: fmt::Debug,
+        S::Response: Into<Response<B>> + 'static,
+        <S::Service as Service<Request>>::Future: 'static,
+
+        B: MessageBody + 'static,
+
+        X: ServiceFactory<Request, Config = (), Response = Request>,
+        X::Future: 'static,
+        X::Error: Into<Response<BoxBody>>,
+        X::InitError: fmt::Debug,
+
+        U: ServiceFactory<
+            (Request, Framed<TlsStream<TcpStream>, h1::Codec>),
+            Config = (),
+            Response = (),
+        >,
+        U::Future: 'static,
+        U::Error: fmt::Display + Into<Response<BoxBody>>,
+        U::InitError: fmt::Debug,
+    {
+        /// Create Rustls v0.22 based service.
+        pub fn rustls_0_22(
+            self,
+            config: ServerConfig,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<io::Error, DispatchError>,
+            InitError = (),
+        > {
+            self.rustls_0_22_with_config(config, TlsAcceptorConfig::default())
+        }
+
+        /// Create Rustls v0.22 based service with custom TLS acceptor configuration.
+        pub fn rustls_0_22_with_config(
+            self,
+            mut config: ServerConfig,
+            tls_acceptor_config: TlsAcceptorConfig,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<io::Error, DispatchError>,
+            InitError = (),
+        > {
+            let mut protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
+            protos.extend_from_slice(&config.alpn_protocols);
+            config.alpn_protocols = protos;
+
+            let mut acceptor = Acceptor::new(config);
+
+            if let Some(handshake_timeout) = tls_acceptor_config.handshake_timeout {
+                acceptor.set_handshake_timeout(handshake_timeout);
+            }
+
+            acceptor
+                .map_init_err(|_| {
+                    unreachable!("TLS acceptor service factory does not error on init")
+                })
+                .map_err(TlsError::into_service_error)
+                .and_then(|io: TlsStream<TcpStream>| async {
+                    let proto = if let Some(protos) = io.get_ref().1.alpn_protocol() {
+                        if protos.windows(2).any(|window| window == b"h2") {
+                            Protocol::Http2
+                        } else {
+                            Protocol::Http1
+                        }
+                    } else {
+                        Protocol::Http1
+                    };
+                    let peer_addr = io.get_ref().0.peer_addr().ok();
+                    Ok((io, proto, peer_addr))
+                })
+                .and_then(self.map_err(TlsError::Service))
+        }
+    }
+}
+
+#[cfg(feature = "rustls-0_23")]
+mod rustls_0_23 {
+    use std::io;
+
+    use actix_service::ServiceFactoryExt as _;
+    use actix_tls::accept::{
+        rustls_0_23::{reexports::ServerConfig, Acceptor, TlsStream},
+        TlsError,
+    };
+
+    use super::*;
+
+    impl<S, B, X, U> HttpService<TlsStream<TcpStream>, S, B, X, U>
+    where
+        S: ServiceFactory<Request, Config = ()>,
+        S::Future: 'static,
+        S::Error: Into<Response<BoxBody>> + 'static,
+        S::InitError: fmt::Debug,
+        S::Response: Into<Response<B>> + 'static,
+        <S::Service as Service<Request>>::Future: 'static,
+
+        B: MessageBody + 'static,
+
+        X: ServiceFactory<Request, Config = (), Response = Request>,
+        X::Future: 'static,
+        X::Error: Into<Response<BoxBody>>,
+        X::InitError: fmt::Debug,
+
+        U: ServiceFactory<
+            (Request, Framed<TlsStream<TcpStream>, h1::Codec>),
+            Config = (),
+            Response = (),
+        >,
+        U::Future: 'static,
+        U::Error: fmt::Display + Into<Response<BoxBody>>,
+        U::InitError: fmt::Debug,
+    {
+        /// Create Rustls v0.23 based service.
+        pub fn rustls_0_23(
+            self,
+            config: ServerConfig,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<io::Error, DispatchError>,
+            InitError = (),
+        > {
+            self.rustls_0_23_with_config(config, TlsAcceptorConfig::default())
+        }
+
+        /// Create Rustls v0.23 based service with custom TLS acceptor configuration.
+        pub fn rustls_0_23_with_config(
+            self,
+            mut config: ServerConfig,
+            tls_acceptor_config: TlsAcceptorConfig,
+        ) -> impl ServiceFactory<
+            TcpStream,
+            Config = (),
+            Response = (),
+            Error = TlsError<io::Error, DispatchError>,
+            InitError = (),
+        > {
+            let mut protos = vec![b"h2".to_vec(), b"http/1.1".to_vec()];
+            protos.extend_from_slice(&config.alpn_protocols);
+            config.alpn_protocols = protos;
+
+            let mut acceptor = Acceptor::new(config);
+
+            if let Some(handshake_timeout) = tls_acceptor_config.handshake_timeout {
+                acceptor.set_handshake_timeout(handshake_timeout);
+            }
+
+            acceptor
+                .map_init_err(|_| {
+                    unreachable!("TLS acceptor service factory does not error on init")
+                })
+                .map_err(TlsError::into_service_error)
+                .and_then(|io: TlsStream<TcpStream>| async {
+                    let proto = if let Some(protos) = io.get_ref().1.alpn_protocol() {
+                        if protos.windows(2).any(|window| window == b"h2") {
+                            Protocol::Http2
+                        } else {
+                            Protocol::Http1
+                        }
+                    } else {
+                        Protocol::Http1
+                    };
+                    let peer_addr = io.get_ref().0.peer_addr().ok();
+                    Ok((io, proto, peer_addr))
+                })
+                .and_then(self.map_err(TlsError::Service))
+        }
+    }
+}
+
+impl<T, S, B, X, U> ServiceFactory<(T, Protocol, Option<net::SocketAddr>)>
+    for HttpService<T, S, B, X, U>
+where
+    T: AsyncRead + AsyncWrite + Unpin + 'static,
+
+    S: ServiceFactory<Request, Config = ()>,
+    S::Future: 'static,
+    S::Error: Into<Response<BoxBody>> + 'static,
+    S::InitError: fmt::Debug,
+    S::Response: Into<Response<B>> + 'static,
+    <S::Service as Service<Request>>::Future: 'static,
+
+    B: MessageBody + 'static,
+
+    X: ServiceFactory<Request, Config = (), Response = Request>,
+    X::Future: 'static,
+    X::Error: Into<Response<BoxBody>>,
+    X::InitError: fmt::Debug,
+
+    U: ServiceFactory<(Request, Framed<T, h1::Codec>), Config = (), Response = ()>,
+    U::Future: 'static,
+    U::Error: fmt::Display + Into<Response<BoxBody>>,
+    U::InitError: fmt::Debug,
+{
+    type Response = ();
+    type Error = DispatchError;
+    type Config = ();
+    type Service = HttpServiceHandler<T, S::Service, B, X::Service, U::Service>;
+    type InitError = ();
+    type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
+
+    fn new_service(&self, _: ()) -> Self::Future {
+        let service = self.srv.new_service(());
+        let expect = self.expect.new_service(());
+        let upgrade = self.upgrade.as_ref().map(|s| s.new_service(()));
+        let on_connect_ext = self.on_connect_ext.clone();
+        let cfg = self.cfg.clone();
+
+        Box::pin(async move {
+            let expect = expect
+                .await
+                .map_err(|e| error!("Init http expect service error: {:?}", e))?;
+
+            let upgrade = match upgrade {
+                Some(upgrade) => {
+                    let upgrade = upgrade
+                        .await
+                        .map_err(|e| error!("Init http upgrade service error: {:?}", e))?;
+                    Some(upgrade)
+                }
+                None => None,
+            };
+
+            let service = service
+                .await
+                .map_err(|e| error!("Init http service error: {:?}", e))?;
+
+            Ok(HttpServiceHandler::new(
+                cfg,
+                service,
+                expect,
+                upgrade,
+                on_connect_ext,
+            ))
+        })
+    }
+}
+
+/// `Service` implementation for HTTP/1 and HTTP/2 transport
+pub struct HttpServiceHandler<T, S, B, X, U>
+where
+    S: Service<Request>,
+    X: Service<Request>,
+    U: Service<(Request, Framed<T, h1::Codec>)>,
+{
+    pub(super) flow: Rc<HttpFlow<S, X, U>>,
+    pub(super) cfg: ServiceConfig,
+    pub(super) on_connect_ext: Option<Rc<ConnectCallback<T>>>,
+    _phantom: PhantomData<B>,
+}
+
+impl<T, S, B, X, U> HttpServiceHandler<T, S, B, X, U>
+where
+    S: Service<Request>,
+    S::Error: Into<Response<BoxBody>>,
+    X: Service<Request>,
+    X::Error: Into<Response<BoxBody>>,
+    U: Service<(Request, Framed<T, h1::Codec>)>,
+    U::Error: Into<Response<BoxBody>>,
+{
+    pub(super) fn new(
+        cfg: ServiceConfig,
+        service: S,
+        expect: X,
+        upgrade: Option<U>,
+        on_connect_ext: Option<Rc<ConnectCallback<T>>>,
+    ) -> HttpServiceHandler<T, S, B, X, U> {
+        HttpServiceHandler {
+            cfg,
+            on_connect_ext,
+            flow: HttpFlow::new(service, expect, upgrade),
+            _phantom: PhantomData,
+        }
+    }
+
+    pub(super) fn _poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Response<BoxBody>>> {
+        ready!(self.flow.expect.poll_ready(cx).map_err(Into::into))?;
+
+        ready!(self.flow.service.poll_ready(cx).map_err(Into::into))?;
+
+        if let Some(ref upg) = self.flow.upgrade {
+            ready!(upg.poll_ready(cx).map_err(Into::into))?;
+        };
+
+        Poll::Ready(Ok(()))
+    }
+}
+
+/// A collection of services that describe an HTTP request flow.
+pub(super) struct HttpFlow<S, X, U> {
+    pub(super) service: S,
+    pub(super) expect: X,
+    pub(super) upgrade: Option<U>,
+}
+
+impl<S, X, U> HttpFlow<S, X, U> {
+    pub(super) fn new(service: S, expect: X, upgrade: Option<U>) -> Rc<Self> {
+        Rc::new(Self {
+            service,
+            expect,
+            upgrade,
+        })
+    }
+}
+
+impl<T, S, B, X, U> Service<(T, Protocol, Option<net::SocketAddr>)>
+    for HttpServiceHandler<T, S, B, X, U>
+where
+    T: AsyncRead + AsyncWrite + Unpin,
+
+    S: Service<Request>,
+    S::Error: Into<Response<BoxBody>> + 'static,
+    S::Future: 'static,
+    S::Response: Into<Response<B>> + 'static,
+
+    B: MessageBody + 'static,
+
+    X: Service<Request, Response = Request>,
+    X::Error: Into<Response<BoxBody>>,
+
+    U: Service<(Request, Framed<T, h1::Codec>), Response = ()>,
+    U::Error: fmt::Display + Into<Response<BoxBody>>,
+{
+    type Response = ();
+    type Error = DispatchError;
+    type Future = HttpServiceHandlerResponse<T, S, B, X, U>;
+
+    fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        self._poll_ready(cx).map_err(|err| {
+            error!("HTTP service readiness error: {:?}", err);
+            DispatchError::Service(err)
+        })
+    }
+
+    fn call(&self, (io, proto, peer_addr): (T, Protocol, Option<net::SocketAddr>)) -> Self::Future {
+        let conn_data = OnConnectData::from_io(&io, self.on_connect_ext.as_deref());
+
+        match proto {
+            #[cfg(feature = "http2")]
+            Protocol::Http2 => HttpServiceHandlerResponse {
+                state: State::H2Handshake {
+                    handshake: Some((
+                        crate::h2::handshake_with_timeout(io, &self.cfg),
+                        self.cfg.clone(),
+                        self.flow.clone(),
+                        conn_data,
+                        peer_addr,
+                    )),
+                },
+            },
+
+            #[cfg(not(feature = "http2"))]
+            Protocol::Http2 => {
+                panic!("HTTP/2 support is disabled (enable with the `http2` feature flag)")
+            }
+
+            Protocol::Http1 => HttpServiceHandlerResponse {
+                state: State::H1 {
+                    dispatcher: h1::Dispatcher::new(
+                        io,
+                        self.flow.clone(),
+                        self.cfg.clone(),
+                        peer_addr,
+                        conn_data,
+                    ),
+                },
+            },
+
+            proto => unimplemented!("Unsupported HTTP version: {:?}.", proto),
+        }
+    }
+}
+
+#[cfg(not(feature = "http2"))]
+pin_project! {
+    #[project = StateProj]
+    enum State<T, S, B, X, U>
+    where
+        T: AsyncRead,
+        T: AsyncWrite,
+        T: Unpin,
+
+        S: Service<Request>,
+        S::Future: 'static,
+        S::Error: Into<Response<BoxBody>>,
+
+        B: MessageBody,
+
+        X: Service<Request, Response = Request>,
+        X::Error: Into<Response<BoxBody>>,
+
+        U: Service<(Request, Framed<T, h1::Codec>), Response = ()>,
+        U::Error: fmt::Display,
+    {
+        H1 { #[pin] dispatcher: h1::Dispatcher<T, S, B, X, U> },
+    }
+}
+
+#[cfg(feature = "http2")]
+pin_project! {
+    #[project = StateProj]
+    enum State<T, S, B, X, U>
+    where
+        T: AsyncRead,
+        T: AsyncWrite,
+        T: Unpin,
+
+        S: Service<Request>,
+        S::Future: 'static,
+        S::Error: Into<Response<BoxBody>>,
+
+        B: MessageBody,
+
+        X: Service<Request, Response = Request>,
+        X::Error: Into<Response<BoxBody>>,
+
+        U: Service<(Request, Framed<T, h1::Codec>), Response = ()>,
+        U::Error: fmt::Display,
+    {
+        H1 { #[pin] dispatcher: h1::Dispatcher<T, S, B, X, U> },
+
+        H2 { #[pin] dispatcher: crate::h2::Dispatcher<T, S, B, X, U> },
+
+        H2Handshake {
+            handshake: Option<(
+                crate::h2::HandshakeWithTimeout<T>,
+                ServiceConfig,
+                Rc<HttpFlow<S, X, U>>,
+                OnConnectData,
+                Option<net::SocketAddr>,
+            )>,
+        },
+    }
+}
+
+pin_project! {
+    pub struct HttpServiceHandlerResponse<T, S, B, X, U>
+    where
+        T: AsyncRead,
+        T: AsyncWrite,
+        T: Unpin,
+
+        S: Service<Request>,
+        S::Error: Into<Response<BoxBody>>,
+        S::Error: 'static,
+        S::Future: 'static,
+        S::Response: Into<Response<B>>,
+        S::Response: 'static,
+
+        B: MessageBody,
+
+        X: Service<Request, Response = Request>,
+        X::Error: Into<Response<BoxBody>>,
+
+        U: Service<(Request, Framed<T, h1::Codec>), Response = ()>,
+        U::Error: fmt::Display,
+    {
+        #[pin]
+        state: State<T, S, B, X, U>,
+    }
+}
+
+impl<T, S, B, X, U> Future for HttpServiceHandlerResponse<T, S, B, X, U>
+where
+    T: AsyncRead + AsyncWrite + Unpin,
+
+    S: Service<Request>,
+    S::Error: Into<Response<BoxBody>> + 'static,
+    S::Future: 'static,
+    S::Response: Into<Response<B>> + 'static,
+
+    B: MessageBody + 'static,
+
+    X: Service<Request, Response = Request>,
+    X::Error: Into<Response<BoxBody>>,
+
+    U: Service<(Request, Framed<T, h1::Codec>), Response = ()>,
+    U::Error: fmt::Display,
+{
+    type Output = Result<(), DispatchError>;
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        match self.as_mut().project().state.project() {
+            StateProj::H1 { dispatcher } => dispatcher.poll(cx),
+
+            #[cfg(feature = "http2")]
+            StateProj::H2 { dispatcher } => dispatcher.poll(cx),
+
+            #[cfg(feature = "http2")]
+            StateProj::H2Handshake { handshake: data } => {
+                match ready!(Pin::new(&mut data.as_mut().unwrap().0).poll(cx)) {
+                    Ok((conn, timer)) => {
+                        let (_, config, flow, conn_data, peer_addr) = data.take().unwrap();
+
+                        self.as_mut().project().state.set(State::H2 {
+                            dispatcher: crate::h2::Dispatcher::new(
+                                conn, flow, config, peer_addr, conn_data, timer,
+                            ),
+                        });
+                        self.poll(cx)
+                    }
+                    Err(err) => {
+                        tracing::trace!("H2 handshake error: {}", err);
+                        Poll::Ready(Err(err))
+                    }
+                }
+            }
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/test.rs.html b/src/actix_http/test.rs.html new file mode 100644 index 000000000..e10104f74 --- /dev/null +++ b/src/actix_http/test.rs.html @@ -0,0 +1,749 @@ +test.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
+
//! Various testing helpers for use in internal and app tests.
+
+use std::{
+    cell::{Ref, RefCell, RefMut},
+    io::{self, Read, Write},
+    pin::Pin,
+    rc::Rc,
+    str::FromStr,
+    task::{Context, Poll},
+};
+
+use actix_codec::{AsyncRead, AsyncWrite, ReadBuf};
+use bytes::{Bytes, BytesMut};
+use http::{Method, Uri, Version};
+
+use crate::{
+    header::{HeaderMap, TryIntoHeaderPair},
+    payload::Payload,
+    Request,
+};
+
+/// Test `Request` builder.
+pub struct TestRequest(Option<Inner>);
+
+struct Inner {
+    version: Version,
+    method: Method,
+    uri: Uri,
+    headers: HeaderMap,
+    payload: Option<Payload>,
+}
+
+impl Default for TestRequest {
+    fn default() -> TestRequest {
+        TestRequest(Some(Inner {
+            method: Method::GET,
+            uri: Uri::from_str("/").unwrap(),
+            version: Version::HTTP_11,
+            headers: HeaderMap::new(),
+            payload: None,
+        }))
+    }
+}
+
+impl TestRequest {
+    /// Create a default TestRequest and then set its URI.
+    pub fn with_uri(path: &str) -> TestRequest {
+        TestRequest::default().uri(path).take()
+    }
+
+    /// Set HTTP version of this request.
+    pub fn version(&mut self, ver: Version) -> &mut Self {
+        parts(&mut self.0).version = ver;
+        self
+    }
+
+    /// Set HTTP method of this request.
+    pub fn method(&mut self, meth: Method) -> &mut Self {
+        parts(&mut self.0).method = meth;
+        self
+    }
+
+    /// Set URI of this request.
+    ///
+    /// # Panics
+    /// If provided URI is invalid.
+    pub fn uri(&mut self, path: &str) -> &mut Self {
+        parts(&mut self.0).uri = Uri::from_str(path).unwrap();
+        self
+    }
+
+    /// Insert a header, replacing any that were set with an equivalent field name.
+    pub fn insert_header(&mut self, header: impl TryIntoHeaderPair) -> &mut Self {
+        match header.try_into_pair() {
+            Ok((key, value)) => {
+                parts(&mut self.0).headers.insert(key, value);
+            }
+            Err(err) => {
+                panic!("Error inserting test header: {}.", err.into());
+            }
+        }
+
+        self
+    }
+
+    /// Append a header, keeping any that were set with an equivalent field name.
+    pub fn append_header(&mut self, header: impl TryIntoHeaderPair) -> &mut Self {
+        match header.try_into_pair() {
+            Ok((key, value)) => {
+                parts(&mut self.0).headers.append(key, value);
+            }
+            Err(err) => {
+                panic!("Error inserting test header: {}.", err.into());
+            }
+        }
+
+        self
+    }
+
+    /// Set request payload.
+    pub fn set_payload(&mut self, data: impl Into<Bytes>) -> &mut Self {
+        let mut payload = crate::h1::Payload::empty();
+        payload.unread_data(data.into());
+        parts(&mut self.0).payload = Some(payload.into());
+        self
+    }
+
+    pub fn take(&mut self) -> TestRequest {
+        TestRequest(self.0.take())
+    }
+
+    /// Complete request creation and generate `Request` instance.
+    pub fn finish(&mut self) -> Request {
+        let inner = self.0.take().expect("cannot reuse test request builder");
+
+        let mut req = if let Some(pl) = inner.payload {
+            Request::with_payload(pl)
+        } else {
+            Request::with_payload(crate::h1::Payload::empty().into())
+        };
+
+        let head = req.head_mut();
+        head.uri = inner.uri;
+        head.method = inner.method;
+        head.version = inner.version;
+        head.headers = inner.headers;
+
+        req
+    }
+}
+
+#[inline]
+fn parts(parts: &mut Option<Inner>) -> &mut Inner {
+    parts.as_mut().expect("cannot reuse test request builder")
+}
+
+/// Async I/O test buffer.
+#[derive(Debug)]
+pub struct TestBuffer {
+    pub read_buf: Rc<RefCell<BytesMut>>,
+    pub write_buf: Rc<RefCell<BytesMut>>,
+    pub err: Option<Rc<io::Error>>,
+}
+
+impl TestBuffer {
+    /// Create new `TestBuffer` instance with initial read buffer.
+    pub fn new<T>(data: T) -> Self
+    where
+        T: Into<BytesMut>,
+    {
+        Self {
+            read_buf: Rc::new(RefCell::new(data.into())),
+            write_buf: Rc::new(RefCell::new(BytesMut::new())),
+            err: None,
+        }
+    }
+
+    // intentionally not using Clone trait
+    #[allow(dead_code)]
+    pub(crate) fn clone(&self) -> Self {
+        Self {
+            read_buf: self.read_buf.clone(),
+            write_buf: self.write_buf.clone(),
+            err: self.err.clone(),
+        }
+    }
+
+    /// Create new empty `TestBuffer` instance.
+    pub fn empty() -> Self {
+        Self::new("")
+    }
+
+    #[allow(dead_code)]
+    pub(crate) fn read_buf_slice(&self) -> Ref<'_, [u8]> {
+        Ref::map(self.read_buf.borrow(), |b| b.as_ref())
+    }
+
+    #[allow(dead_code)]
+    pub(crate) fn read_buf_slice_mut(&self) -> RefMut<'_, [u8]> {
+        RefMut::map(self.read_buf.borrow_mut(), |b| b.as_mut())
+    }
+
+    #[allow(dead_code)]
+    pub(crate) fn write_buf_slice(&self) -> Ref<'_, [u8]> {
+        Ref::map(self.write_buf.borrow(), |b| b.as_ref())
+    }
+
+    #[allow(dead_code)]
+    pub(crate) fn write_buf_slice_mut(&self) -> RefMut<'_, [u8]> {
+        RefMut::map(self.write_buf.borrow_mut(), |b| b.as_mut())
+    }
+
+    #[allow(dead_code)]
+    pub(crate) fn take_write_buf(&self) -> Bytes {
+        self.write_buf.borrow_mut().split().freeze()
+    }
+
+    /// Add data to read buffer.
+    pub fn extend_read_buf<T: AsRef<[u8]>>(&mut self, data: T) {
+        self.read_buf.borrow_mut().extend_from_slice(data.as_ref())
+    }
+}
+
+impl io::Read for TestBuffer {
+    fn read(&mut self, dst: &mut [u8]) -> Result<usize, io::Error> {
+        if self.read_buf.borrow().is_empty() {
+            if self.err.is_some() {
+                Err(Rc::try_unwrap(self.err.take().unwrap()).unwrap())
+            } else {
+                Err(io::Error::new(io::ErrorKind::WouldBlock, ""))
+            }
+        } else {
+            let size = std::cmp::min(self.read_buf.borrow().len(), dst.len());
+            let b = self.read_buf.borrow_mut().split_to(size);
+            dst[..size].copy_from_slice(&b);
+            Ok(size)
+        }
+    }
+}
+
+impl io::Write for TestBuffer {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.write_buf.borrow_mut().extend(buf);
+        Ok(buf.len())
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+impl AsyncRead for TestBuffer {
+    fn poll_read(
+        self: Pin<&mut Self>,
+        _: &mut Context<'_>,
+        buf: &mut ReadBuf<'_>,
+    ) -> Poll<io::Result<()>> {
+        let dst = buf.initialize_unfilled();
+        let res = self.get_mut().read(dst).map(|n| buf.advance(n));
+        Poll::Ready(res)
+    }
+}
+
+impl AsyncWrite for TestBuffer {
+    fn poll_write(
+        self: Pin<&mut Self>,
+        _: &mut Context<'_>,
+        buf: &[u8],
+    ) -> Poll<io::Result<usize>> {
+        Poll::Ready(self.get_mut().write(buf))
+    }
+
+    fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
+        Poll::Ready(Ok(()))
+    }
+
+    fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
+        Poll::Ready(Ok(()))
+    }
+}
+
+/// Async I/O test buffer with ability to incrementally add to the read buffer.
+#[derive(Clone)]
+pub struct TestSeqBuffer(Rc<RefCell<TestSeqInner>>);
+
+impl TestSeqBuffer {
+    /// Create new `TestBuffer` instance with initial read buffer.
+    pub fn new<T>(data: T) -> Self
+    where
+        T: Into<BytesMut>,
+    {
+        Self(Rc::new(RefCell::new(TestSeqInner {
+            read_buf: data.into(),
+            write_buf: BytesMut::new(),
+            err: None,
+        })))
+    }
+
+    /// Create new empty `TestBuffer` instance.
+    pub fn empty() -> Self {
+        Self::new(BytesMut::new())
+    }
+
+    pub fn read_buf(&self) -> Ref<'_, BytesMut> {
+        Ref::map(self.0.borrow(), |inner| &inner.read_buf)
+    }
+
+    pub fn write_buf(&self) -> Ref<'_, BytesMut> {
+        Ref::map(self.0.borrow(), |inner| &inner.write_buf)
+    }
+
+    pub fn err(&self) -> Ref<'_, Option<io::Error>> {
+        Ref::map(self.0.borrow(), |inner| &inner.err)
+    }
+
+    /// Add data to read buffer.
+    pub fn extend_read_buf<T: AsRef<[u8]>>(&mut self, data: T) {
+        self.0
+            .borrow_mut()
+            .read_buf
+            .extend_from_slice(data.as_ref())
+    }
+}
+
+pub struct TestSeqInner {
+    read_buf: BytesMut,
+    write_buf: BytesMut,
+    err: Option<io::Error>,
+}
+
+impl io::Read for TestSeqBuffer {
+    fn read(&mut self, dst: &mut [u8]) -> Result<usize, io::Error> {
+        if self.0.borrow().read_buf.is_empty() {
+            if self.0.borrow().err.is_some() {
+                Err(self.0.borrow_mut().err.take().unwrap())
+            } else {
+                Err(io::Error::new(io::ErrorKind::WouldBlock, ""))
+            }
+        } else {
+            let size = std::cmp::min(self.0.borrow().read_buf.len(), dst.len());
+            let b = self.0.borrow_mut().read_buf.split_to(size);
+            dst[..size].copy_from_slice(&b);
+            Ok(size)
+        }
+    }
+}
+
+impl io::Write for TestSeqBuffer {
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.0.borrow_mut().write_buf.extend(buf);
+        Ok(buf.len())
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
+impl AsyncRead for TestSeqBuffer {
+    fn poll_read(
+        self: Pin<&mut Self>,
+        _: &mut Context<'_>,
+        buf: &mut ReadBuf<'_>,
+    ) -> Poll<io::Result<()>> {
+        let dst = buf.initialize_unfilled();
+        let r = self.get_mut().read(dst);
+        match r {
+            Ok(n) => {
+                buf.advance(n);
+                Poll::Ready(Ok(()))
+            }
+            Err(err) if err.kind() == io::ErrorKind::WouldBlock => Poll::Pending,
+            Err(err) => Poll::Ready(Err(err)),
+        }
+    }
+}
+
+impl AsyncWrite for TestSeqBuffer {
+    fn poll_write(
+        self: Pin<&mut Self>,
+        _: &mut Context<'_>,
+        buf: &[u8],
+    ) -> Poll<io::Result<usize>> {
+        Poll::Ready(self.get_mut().write(buf))
+    }
+
+    fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
+        Poll::Ready(Ok(()))
+    }
+
+    fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
+        Poll::Ready(Ok(()))
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/ws/codec.rs.html b/src/actix_http/ws/codec.rs.html new file mode 100644 index 000000000..33f7f50d6 --- /dev/null +++ b/src/actix_http/ws/codec.rs.html @@ -0,0 +1,605 @@ +codec.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
+
use bitflags::bitflags;
+use bytes::{Bytes, BytesMut};
+use bytestring::ByteString;
+use tokio_util::codec::{Decoder, Encoder};
+use tracing::error;
+
+use super::{
+    frame::Parser,
+    proto::{CloseReason, OpCode},
+    ProtocolError,
+};
+
+/// A WebSocket message.
+#[derive(Debug, PartialEq, Eq)]
+pub enum Message {
+    /// Text message.
+    Text(ByteString),
+
+    /// Binary message.
+    Binary(Bytes),
+
+    /// Continuation.
+    Continuation(Item),
+
+    /// Ping message.
+    Ping(Bytes),
+
+    /// Pong message.
+    Pong(Bytes),
+
+    /// Close message with optional reason.
+    Close(Option<CloseReason>),
+
+    /// No-op. Useful for low-level services.
+    Nop,
+}
+
+/// A WebSocket frame.
+#[derive(Debug, PartialEq, Eq)]
+pub enum Frame {
+    /// Text frame. Note that the codec does not validate UTF-8 encoding.
+    Text(Bytes),
+
+    /// Binary frame.
+    Binary(Bytes),
+
+    /// Continuation.
+    Continuation(Item),
+
+    /// Ping message.
+    Ping(Bytes),
+
+    /// Pong message.
+    Pong(Bytes),
+
+    /// Close message with optional reason.
+    Close(Option<CloseReason>),
+}
+
+/// A WebSocket continuation item.
+#[derive(Debug, PartialEq, Eq)]
+pub enum Item {
+    FirstText(Bytes),
+    FirstBinary(Bytes),
+    Continue(Bytes),
+    Last(Bytes),
+}
+
+/// WebSocket protocol codec.
+#[derive(Debug, Clone)]
+pub struct Codec {
+    flags: Flags,
+    max_size: usize,
+}
+
+bitflags! {
+    #[derive(Debug, Clone, Copy)]
+    struct Flags: u8 {
+        const SERVER         = 0b0000_0001;
+        const CONTINUATION   = 0b0000_0010;
+        const W_CONTINUATION = 0b0000_0100;
+    }
+}
+
+impl Codec {
+    /// Create new WebSocket frames decoder.
+    pub const fn new() -> Codec {
+        Codec {
+            max_size: 65_536,
+            flags: Flags::SERVER,
+        }
+    }
+
+    /// Set max frame size.
+    ///
+    /// By default max size is set to 64KiB.
+    #[must_use = "This returns the a new Codec, without modifying the original."]
+    pub fn max_size(mut self, size: usize) -> Self {
+        self.max_size = size;
+        self
+    }
+
+    /// Set decoder to client mode.
+    ///
+    /// By default decoder works in server mode.
+    #[must_use = "This returns the a new Codec, without modifying the original."]
+    pub fn client_mode(mut self) -> Self {
+        self.flags.remove(Flags::SERVER);
+        self
+    }
+}
+
+impl Default for Codec {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl Encoder<Message> for Codec {
+    type Error = ProtocolError;
+
+    fn encode(&mut self, item: Message, dst: &mut BytesMut) -> Result<(), Self::Error> {
+        match item {
+            Message::Text(txt) => Parser::write_message(
+                dst,
+                txt,
+                OpCode::Text,
+                true,
+                !self.flags.contains(Flags::SERVER),
+            ),
+            Message::Binary(bin) => Parser::write_message(
+                dst,
+                bin,
+                OpCode::Binary,
+                true,
+                !self.flags.contains(Flags::SERVER),
+            ),
+            Message::Ping(txt) => Parser::write_message(
+                dst,
+                txt,
+                OpCode::Ping,
+                true,
+                !self.flags.contains(Flags::SERVER),
+            ),
+            Message::Pong(txt) => Parser::write_message(
+                dst,
+                txt,
+                OpCode::Pong,
+                true,
+                !self.flags.contains(Flags::SERVER),
+            ),
+            Message::Close(reason) => {
+                Parser::write_close(dst, reason, !self.flags.contains(Flags::SERVER))
+            }
+            Message::Continuation(cont) => match cont {
+                Item::FirstText(data) => {
+                    if self.flags.contains(Flags::W_CONTINUATION) {
+                        return Err(ProtocolError::ContinuationStarted);
+                    } else {
+                        self.flags.insert(Flags::W_CONTINUATION);
+                        Parser::write_message(
+                            dst,
+                            &data[..],
+                            OpCode::Text,
+                            false,
+                            !self.flags.contains(Flags::SERVER),
+                        )
+                    }
+                }
+                Item::FirstBinary(data) => {
+                    if self.flags.contains(Flags::W_CONTINUATION) {
+                        return Err(ProtocolError::ContinuationStarted);
+                    } else {
+                        self.flags.insert(Flags::W_CONTINUATION);
+                        Parser::write_message(
+                            dst,
+                            &data[..],
+                            OpCode::Binary,
+                            false,
+                            !self.flags.contains(Flags::SERVER),
+                        )
+                    }
+                }
+                Item::Continue(data) => {
+                    if self.flags.contains(Flags::W_CONTINUATION) {
+                        Parser::write_message(
+                            dst,
+                            &data[..],
+                            OpCode::Continue,
+                            false,
+                            !self.flags.contains(Flags::SERVER),
+                        )
+                    } else {
+                        return Err(ProtocolError::ContinuationNotStarted);
+                    }
+                }
+                Item::Last(data) => {
+                    if self.flags.contains(Flags::W_CONTINUATION) {
+                        self.flags.remove(Flags::W_CONTINUATION);
+                        Parser::write_message(
+                            dst,
+                            &data[..],
+                            OpCode::Continue,
+                            true,
+                            !self.flags.contains(Flags::SERVER),
+                        )
+                    } else {
+                        return Err(ProtocolError::ContinuationNotStarted);
+                    }
+                }
+            },
+            Message::Nop => {}
+        }
+        Ok(())
+    }
+}
+
+impl Decoder for Codec {
+    type Item = Frame;
+    type Error = ProtocolError;
+
+    fn decode(&mut self, src: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
+        match Parser::parse(src, self.flags.contains(Flags::SERVER), self.max_size) {
+            Ok(Some((finished, opcode, payload))) => {
+                // continuation is not supported
+                if !finished {
+                    return match opcode {
+                        OpCode::Continue => {
+                            if self.flags.contains(Flags::CONTINUATION) {
+                                Ok(Some(Frame::Continuation(Item::Continue(
+                                    payload.map(|pl| pl.freeze()).unwrap_or_else(Bytes::new),
+                                ))))
+                            } else {
+                                Err(ProtocolError::ContinuationNotStarted)
+                            }
+                        }
+                        OpCode::Binary => {
+                            if !self.flags.contains(Flags::CONTINUATION) {
+                                self.flags.insert(Flags::CONTINUATION);
+                                Ok(Some(Frame::Continuation(Item::FirstBinary(
+                                    payload.map(|pl| pl.freeze()).unwrap_or_else(Bytes::new),
+                                ))))
+                            } else {
+                                Err(ProtocolError::ContinuationStarted)
+                            }
+                        }
+                        OpCode::Text => {
+                            if !self.flags.contains(Flags::CONTINUATION) {
+                                self.flags.insert(Flags::CONTINUATION);
+                                Ok(Some(Frame::Continuation(Item::FirstText(
+                                    payload.map(|pl| pl.freeze()).unwrap_or_else(Bytes::new),
+                                ))))
+                            } else {
+                                Err(ProtocolError::ContinuationStarted)
+                            }
+                        }
+                        _ => {
+                            error!("Unfinished fragment {:?}", opcode);
+                            Err(ProtocolError::ContinuationFragment(opcode))
+                        }
+                    };
+                }
+
+                match opcode {
+                    OpCode::Continue => {
+                        if self.flags.contains(Flags::CONTINUATION) {
+                            self.flags.remove(Flags::CONTINUATION);
+                            Ok(Some(Frame::Continuation(Item::Last(
+                                payload.map(|pl| pl.freeze()).unwrap_or_else(Bytes::new),
+                            ))))
+                        } else {
+                            Err(ProtocolError::ContinuationNotStarted)
+                        }
+                    }
+                    OpCode::Bad => Err(ProtocolError::BadOpCode),
+                    OpCode::Close => {
+                        if let Some(ref pl) = payload {
+                            let close_reason = Parser::parse_close_payload(pl);
+                            Ok(Some(Frame::Close(close_reason)))
+                        } else {
+                            Ok(Some(Frame::Close(None)))
+                        }
+                    }
+                    OpCode::Ping => Ok(Some(Frame::Ping(
+                        payload.map(|pl| pl.freeze()).unwrap_or_else(Bytes::new),
+                    ))),
+                    OpCode::Pong => Ok(Some(Frame::Pong(
+                        payload.map(|pl| pl.freeze()).unwrap_or_else(Bytes::new),
+                    ))),
+                    OpCode::Binary => Ok(Some(Frame::Binary(
+                        payload.map(|pl| pl.freeze()).unwrap_or_else(Bytes::new),
+                    ))),
+                    OpCode::Text => Ok(Some(Frame::Text(
+                        payload.map(|pl| pl.freeze()).unwrap_or_else(Bytes::new),
+                    ))),
+                }
+            }
+            Ok(None) => Ok(None),
+            Err(err) => Err(err),
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/ws/dispatcher.rs.html b/src/actix_http/ws/dispatcher.rs.html new file mode 100644 index 000000000..572f8c7d6 --- /dev/null +++ b/src/actix_http/ws/dispatcher.rs.html @@ -0,0 +1,879 @@ +dispatcher.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
+
use std::{
+    future::Future,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use actix_codec::{AsyncRead, AsyncWrite, Framed};
+use actix_service::{IntoService, Service};
+use pin_project_lite::pin_project;
+
+use super::{Codec, Frame, Message};
+
+pin_project! {
+    pub struct Dispatcher<S, T>
+    where
+        S: Service<Frame, Response = Message>,
+        S: 'static,
+        T: AsyncRead,
+        T: AsyncWrite,
+    {
+        #[pin]
+        inner: inner::Dispatcher<S, T, Codec, Message>,
+    }
+}
+
+impl<S, T> Dispatcher<S, T>
+where
+    T: AsyncRead + AsyncWrite,
+    S: Service<Frame, Response = Message>,
+    S::Future: 'static,
+    S::Error: 'static,
+{
+    pub fn new<F: IntoService<S, Frame>>(io: T, service: F) -> Self {
+        Dispatcher {
+            inner: inner::Dispatcher::new(Framed::new(io, Codec::new()), service),
+        }
+    }
+
+    pub fn with<F: IntoService<S, Frame>>(framed: Framed<T, Codec>, service: F) -> Self {
+        Dispatcher {
+            inner: inner::Dispatcher::new(framed, service),
+        }
+    }
+}
+
+impl<S, T> Future for Dispatcher<S, T>
+where
+    T: AsyncRead + AsyncWrite,
+    S: Service<Frame, Response = Message>,
+    S::Future: 'static,
+    S::Error: 'static,
+{
+    type Output = Result<(), inner::DispatcherError<S::Error, Codec, Message>>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        self.project().inner.poll(cx)
+    }
+}
+
+/// Framed dispatcher service and related utilities.
+mod inner {
+    // allow dead code since this mod was ripped from actix-utils
+    #![allow(dead_code)]
+
+    use core::{
+        fmt,
+        future::Future,
+        mem,
+        pin::Pin,
+        task::{Context, Poll},
+    };
+
+    use actix_codec::Framed;
+    use actix_service::{IntoService, Service};
+    use futures_core::stream::Stream;
+    use local_channel::mpsc;
+    use pin_project_lite::pin_project;
+    use tokio::io::{AsyncRead, AsyncWrite};
+    use tokio_util::codec::{Decoder, Encoder};
+    use tracing::debug;
+
+    use crate::{body::BoxBody, Response};
+
+    /// Framed transport errors
+    pub enum DispatcherError<E, U, I>
+    where
+        U: Encoder<I> + Decoder,
+    {
+        /// Inner service error.
+        Service(E),
+
+        /// Frame encoding error.
+        Encoder(<U as Encoder<I>>::Error),
+
+        /// Frame decoding error.
+        Decoder(<U as Decoder>::Error),
+    }
+
+    impl<E, U, I> From<E> for DispatcherError<E, U, I>
+    where
+        U: Encoder<I> + Decoder,
+    {
+        fn from(err: E) -> Self {
+            DispatcherError::Service(err)
+        }
+    }
+
+    impl<E, U, I> fmt::Debug for DispatcherError<E, U, I>
+    where
+        E: fmt::Debug,
+        U: Encoder<I> + Decoder,
+        <U as Encoder<I>>::Error: fmt::Debug,
+        <U as Decoder>::Error: fmt::Debug,
+    {
+        fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+            match *self {
+                DispatcherError::Service(ref e) => {
+                    write!(fmt, "DispatcherError::Service({:?})", e)
+                }
+                DispatcherError::Encoder(ref e) => {
+                    write!(fmt, "DispatcherError::Encoder({:?})", e)
+                }
+                DispatcherError::Decoder(ref e) => {
+                    write!(fmt, "DispatcherError::Decoder({:?})", e)
+                }
+            }
+        }
+    }
+
+    impl<E, U, I> fmt::Display for DispatcherError<E, U, I>
+    where
+        E: fmt::Display,
+        U: Encoder<I> + Decoder,
+        <U as Encoder<I>>::Error: fmt::Debug,
+        <U as Decoder>::Error: fmt::Debug,
+    {
+        fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+            match *self {
+                DispatcherError::Service(ref e) => write!(fmt, "{}", e),
+                DispatcherError::Encoder(ref e) => write!(fmt, "{:?}", e),
+                DispatcherError::Decoder(ref e) => write!(fmt, "{:?}", e),
+            }
+        }
+    }
+
+    impl<E, U, I> From<DispatcherError<E, U, I>> for Response<BoxBody>
+    where
+        E: fmt::Debug + fmt::Display,
+        U: Encoder<I> + Decoder,
+        <U as Encoder<I>>::Error: fmt::Debug,
+        <U as Decoder>::Error: fmt::Debug,
+    {
+        fn from(err: DispatcherError<E, U, I>) -> Self {
+            Response::internal_server_error().set_body(BoxBody::new(err.to_string()))
+        }
+    }
+
+    /// Message type wrapper for signalling end of message stream.
+    pub enum Message<T> {
+        /// Message item.
+        Item(T),
+
+        /// Signal from service to flush all messages and stop processing.
+        Close,
+    }
+
+    pin_project! {
+        /// A future that reads frames from a [`Framed`] object and passes them to a [`Service`].
+        pub struct Dispatcher<S, T, U, I>
+        where
+            S: Service<<U as Decoder>::Item, Response = I>,
+            S::Error: 'static,
+            S::Future: 'static,
+            T: AsyncRead,
+            T: AsyncWrite,
+            U: Encoder<I>,
+            U: Decoder,
+            I: 'static,
+            <U as Encoder<I>>::Error: fmt::Debug,
+        {
+            service: S,
+            state: State<S, U, I>,
+            #[pin]
+            framed: Framed<T, U>,
+            rx: mpsc::Receiver<Result<Message<I>, S::Error>>,
+            tx: mpsc::Sender<Result<Message<I>, S::Error>>,
+        }
+    }
+
+    enum State<S, U, I>
+    where
+        S: Service<<U as Decoder>::Item>,
+        U: Encoder<I> + Decoder,
+    {
+        Processing,
+        Error(DispatcherError<S::Error, U, I>),
+        FramedError(DispatcherError<S::Error, U, I>),
+        FlushAndStop,
+        Stopping,
+    }
+
+    impl<S, U, I> State<S, U, I>
+    where
+        S: Service<<U as Decoder>::Item>,
+        U: Encoder<I> + Decoder,
+    {
+        fn take_error(&mut self) -> DispatcherError<S::Error, U, I> {
+            match mem::replace(self, State::Processing) {
+                State::Error(err) => err,
+                _ => panic!(),
+            }
+        }
+
+        fn take_framed_error(&mut self) -> DispatcherError<S::Error, U, I> {
+            match mem::replace(self, State::Processing) {
+                State::FramedError(err) => err,
+                _ => panic!(),
+            }
+        }
+    }
+
+    impl<S, T, U, I> Dispatcher<S, T, U, I>
+    where
+        S: Service<<U as Decoder>::Item, Response = I>,
+        S::Error: 'static,
+        S::Future: 'static,
+        T: AsyncRead + AsyncWrite,
+        U: Decoder + Encoder<I>,
+        I: 'static,
+        <U as Decoder>::Error: fmt::Debug,
+        <U as Encoder<I>>::Error: fmt::Debug,
+    {
+        /// Create new `Dispatcher`.
+        pub fn new<F>(framed: Framed<T, U>, service: F) -> Self
+        where
+            F: IntoService<S, <U as Decoder>::Item>,
+        {
+            let (tx, rx) = mpsc::channel();
+            Dispatcher {
+                framed,
+                rx,
+                tx,
+                service: service.into_service(),
+                state: State::Processing,
+            }
+        }
+
+        /// Construct new `Dispatcher` instance with customer `mpsc::Receiver`
+        pub fn with_rx<F>(
+            framed: Framed<T, U>,
+            service: F,
+            rx: mpsc::Receiver<Result<Message<I>, S::Error>>,
+        ) -> Self
+        where
+            F: IntoService<S, <U as Decoder>::Item>,
+        {
+            let tx = rx.sender();
+            Dispatcher {
+                framed,
+                rx,
+                tx,
+                service: service.into_service(),
+                state: State::Processing,
+            }
+        }
+
+        /// Get sender handle.
+        pub fn tx(&self) -> mpsc::Sender<Result<Message<I>, S::Error>> {
+            self.tx.clone()
+        }
+
+        /// Get reference to a service wrapped by `Dispatcher` instance.
+        pub fn service(&self) -> &S {
+            &self.service
+        }
+
+        /// Get mutable reference to a service wrapped by `Dispatcher` instance.
+        pub fn service_mut(&mut self) -> &mut S {
+            &mut self.service
+        }
+
+        /// Get reference to a framed instance wrapped by `Dispatcher` instance.
+        pub fn framed(&self) -> &Framed<T, U> {
+            &self.framed
+        }
+
+        /// Get mutable reference to a framed instance wrapped by `Dispatcher` instance.
+        pub fn framed_mut(&mut self) -> &mut Framed<T, U> {
+            &mut self.framed
+        }
+
+        /// Read from framed object.
+        fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> bool
+        where
+            S: Service<<U as Decoder>::Item, Response = I>,
+            S::Error: 'static,
+            S::Future: 'static,
+            T: AsyncRead + AsyncWrite,
+            U: Decoder + Encoder<I>,
+            I: 'static,
+            <U as Encoder<I>>::Error: fmt::Debug,
+        {
+            loop {
+                let this = self.as_mut().project();
+                match this.service.poll_ready(cx) {
+                    Poll::Ready(Ok(_)) => {
+                        let item = match this.framed.next_item(cx) {
+                            Poll::Ready(Some(Ok(el))) => el,
+                            Poll::Ready(Some(Err(err))) => {
+                                *this.state = State::FramedError(DispatcherError::Decoder(err));
+                                return true;
+                            }
+                            Poll::Pending => return false,
+                            Poll::Ready(None) => {
+                                *this.state = State::Stopping;
+                                return true;
+                            }
+                        };
+
+                        let tx = this.tx.clone();
+                        let fut = this.service.call(item);
+                        actix_rt::spawn(async move {
+                            let item = fut.await;
+                            let _ = tx.send(item.map(Message::Item));
+                        });
+                    }
+                    Poll::Pending => return false,
+                    Poll::Ready(Err(err)) => {
+                        *this.state = State::Error(DispatcherError::Service(err));
+                        return true;
+                    }
+                }
+            }
+        }
+
+        /// Write to framed object.
+        fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> bool
+        where
+            S: Service<<U as Decoder>::Item, Response = I>,
+            S::Error: 'static,
+            S::Future: 'static,
+            T: AsyncRead + AsyncWrite,
+            U: Decoder + Encoder<I>,
+            I: 'static,
+            <U as Encoder<I>>::Error: fmt::Debug,
+        {
+            loop {
+                let mut this = self.as_mut().project();
+                while !this.framed.is_write_buf_full() {
+                    match Pin::new(&mut this.rx).poll_next(cx) {
+                        Poll::Ready(Some(Ok(Message::Item(msg)))) => {
+                            if let Err(err) = this.framed.as_mut().write(msg) {
+                                *this.state = State::FramedError(DispatcherError::Encoder(err));
+                                return true;
+                            }
+                        }
+                        Poll::Ready(Some(Ok(Message::Close))) => {
+                            *this.state = State::FlushAndStop;
+                            return true;
+                        }
+                        Poll::Ready(Some(Err(err))) => {
+                            *this.state = State::Error(DispatcherError::Service(err));
+                            return true;
+                        }
+                        Poll::Ready(None) | Poll::Pending => break,
+                    }
+                }
+
+                if !this.framed.is_write_buf_empty() {
+                    match this.framed.flush(cx) {
+                        Poll::Pending => break,
+                        Poll::Ready(Ok(_)) => {}
+                        Poll::Ready(Err(err)) => {
+                            debug!("Error sending data: {:?}", err);
+                            *this.state = State::FramedError(DispatcherError::Encoder(err));
+                            return true;
+                        }
+                    }
+                } else {
+                    break;
+                }
+            }
+
+            false
+        }
+    }
+
+    impl<S, T, U, I> Future for Dispatcher<S, T, U, I>
+    where
+        S: Service<<U as Decoder>::Item, Response = I>,
+        S::Error: 'static,
+        S::Future: 'static,
+        T: AsyncRead + AsyncWrite,
+        U: Decoder + Encoder<I>,
+        I: 'static,
+        <U as Encoder<I>>::Error: fmt::Debug,
+        <U as Decoder>::Error: fmt::Debug,
+    {
+        type Output = Result<(), DispatcherError<S::Error, U, I>>;
+
+        fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+            loop {
+                let this = self.as_mut().project();
+
+                return match this.state {
+                    State::Processing => {
+                        if self.as_mut().poll_read(cx) || self.as_mut().poll_write(cx) {
+                            continue;
+                        } else {
+                            Poll::Pending
+                        }
+                    }
+                    State::Error(_) => {
+                        // flush write buffer
+                        if !this.framed.is_write_buf_empty() && this.framed.flush(cx).is_pending() {
+                            return Poll::Pending;
+                        }
+                        Poll::Ready(Err(this.state.take_error()))
+                    }
+                    State::FlushAndStop => {
+                        if !this.framed.is_write_buf_empty() {
+                            this.framed.flush(cx).map(|res| {
+                                if let Err(err) = res {
+                                    debug!("Error sending data: {:?}", err);
+                                }
+
+                                Ok(())
+                            })
+                        } else {
+                            Poll::Ready(Ok(()))
+                        }
+                    }
+                    State::FramedError(_) => Poll::Ready(Err(this.state.take_framed_error())),
+                    State::Stopping => Poll::Ready(Ok(())),
+                };
+            }
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/ws/frame.rs.html b/src/actix_http/ws/frame.rs.html new file mode 100644 index 000000000..834584295 --- /dev/null +++ b/src/actix_http/ws/frame.rs.html @@ -0,0 +1,811 @@ +frame.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
+
use std::cmp::min;
+
+use bytes::{Buf, BufMut, BytesMut};
+use tracing::debug;
+
+use super::{
+    mask::apply_mask,
+    proto::{CloseCode, CloseReason, OpCode},
+    ProtocolError,
+};
+
+/// A struct representing a WebSocket frame.
+#[derive(Debug)]
+pub struct Parser;
+
+impl Parser {
+    fn parse_metadata(
+        src: &[u8],
+        server: bool,
+    ) -> Result<Option<(usize, bool, OpCode, usize, Option<[u8; 4]>)>, ProtocolError> {
+        let chunk_len = src.len();
+
+        let mut idx = 2;
+        if chunk_len < 2 {
+            return Ok(None);
+        }
+
+        let first = src[0];
+        let second = src[1];
+        let finished = first & 0x80 != 0;
+
+        // check masking
+        let masked = second & 0x80 != 0;
+        if !masked && server {
+            return Err(ProtocolError::UnmaskedFrame);
+        } else if masked && !server {
+            return Err(ProtocolError::MaskedFrame);
+        }
+
+        // Op code
+        let opcode = OpCode::from(first & 0x0F);
+
+        if let OpCode::Bad = opcode {
+            return Err(ProtocolError::InvalidOpcode(first & 0x0F));
+        }
+
+        let len = second & 0x7F;
+        let length = if len == 126 {
+            if chunk_len < 4 {
+                return Ok(None);
+            }
+            let len = usize::from(u16::from_be_bytes(
+                TryFrom::try_from(&src[idx..idx + 2]).unwrap(),
+            ));
+            idx += 2;
+            len
+        } else if len == 127 {
+            if chunk_len < 10 {
+                return Ok(None);
+            }
+            let len = u64::from_be_bytes(TryFrom::try_from(&src[idx..idx + 8]).unwrap());
+            idx += 8;
+            len as usize
+        } else {
+            len as usize
+        };
+
+        let mask = if server {
+            if chunk_len < idx + 4 {
+                return Ok(None);
+            }
+
+            let mask = TryFrom::try_from(&src[idx..idx + 4]).unwrap();
+
+            idx += 4;
+
+            Some(mask)
+        } else {
+            None
+        };
+
+        Ok(Some((idx, finished, opcode, length, mask)))
+    }
+
+    /// Parse the input stream into a frame.
+    pub fn parse(
+        src: &mut BytesMut,
+        server: bool,
+        max_size: usize,
+    ) -> Result<Option<(bool, OpCode, Option<BytesMut>)>, ProtocolError> {
+        // try to parse ws frame metadata
+        let (idx, finished, opcode, length, mask) = match Parser::parse_metadata(src, server)? {
+            None => return Ok(None),
+            Some(res) => res,
+        };
+
+        // not enough data
+        if src.len() < idx + length {
+            let min_length = min(length, max_size);
+            if src.capacity() < idx + min_length {
+                src.reserve(idx + min_length - src.capacity());
+            }
+            return Ok(None);
+        }
+
+        // remove prefix
+        src.advance(idx);
+
+        // check for max allowed size
+        if length > max_size {
+            // drop the payload
+            src.advance(length);
+            return Err(ProtocolError::Overflow);
+        }
+
+        // no need for body
+        if length == 0 {
+            return Ok(Some((finished, opcode, None)));
+        }
+
+        let mut data = src.split_to(length);
+
+        // control frames must have length <= 125
+        match opcode {
+            OpCode::Ping | OpCode::Pong if length > 125 => {
+                return Err(ProtocolError::InvalidLength(length));
+            }
+            OpCode::Close if length > 125 => {
+                debug!("Received close frame with payload length exceeding 125. Morphing to protocol close frame.");
+                return Ok(Some((true, OpCode::Close, None)));
+            }
+            _ => {}
+        }
+
+        // unmask
+        if let Some(mask) = mask {
+            apply_mask(&mut data, mask);
+        }
+
+        Ok(Some((finished, opcode, Some(data))))
+    }
+
+    /// Parse the payload of a close frame.
+    pub fn parse_close_payload(payload: &[u8]) -> Option<CloseReason> {
+        if payload.len() >= 2 {
+            let raw_code = u16::from_be_bytes(TryFrom::try_from(&payload[..2]).unwrap());
+            let code = CloseCode::from(raw_code);
+            let description = if payload.len() > 2 {
+                Some(String::from_utf8_lossy(&payload[2..]).into())
+            } else {
+                None
+            };
+            Some(CloseReason { code, description })
+        } else {
+            None
+        }
+    }
+
+    /// Generate binary representation
+    pub fn write_message<B: AsRef<[u8]>>(
+        dst: &mut BytesMut,
+        pl: B,
+        op: OpCode,
+        fin: bool,
+        mask: bool,
+    ) {
+        let payload = pl.as_ref();
+        let one: u8 = if fin {
+            0x80 | Into::<u8>::into(op)
+        } else {
+            op.into()
+        };
+        let payload_len = payload.len();
+        let (two, p_len) = if mask {
+            (0x80, payload_len + 4)
+        } else {
+            (0, payload_len)
+        };
+
+        if payload_len < 126 {
+            dst.reserve(p_len + 2 + if mask { 4 } else { 0 });
+            dst.put_slice(&[one, two | payload_len as u8]);
+        } else if payload_len <= 65_535 {
+            dst.reserve(p_len + 4 + if mask { 4 } else { 0 });
+            dst.put_slice(&[one, two | 126]);
+            dst.put_u16(payload_len as u16);
+        } else {
+            dst.reserve(p_len + 10 + if mask { 4 } else { 0 });
+            dst.put_slice(&[one, two | 127]);
+            dst.put_u64(payload_len as u64);
+        };
+
+        if mask {
+            let mask = rand::random::<[u8; 4]>();
+            dst.put_slice(mask.as_ref());
+            dst.put_slice(payload.as_ref());
+            let pos = dst.len() - payload_len;
+            apply_mask(&mut dst[pos..], mask);
+        } else {
+            dst.put_slice(payload.as_ref());
+        }
+    }
+
+    /// Create a new Close control frame.
+    #[inline]
+    pub fn write_close(dst: &mut BytesMut, reason: Option<CloseReason>, mask: bool) {
+        let payload = match reason {
+            None => Vec::new(),
+            Some(reason) => {
+                let mut payload = Into::<u16>::into(reason.code).to_be_bytes().to_vec();
+                if let Some(description) = reason.description {
+                    payload.extend(description.as_bytes());
+                }
+                payload
+            }
+        };
+
+        Parser::write_message(dst, payload, OpCode::Close, true, mask)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use bytes::Bytes;
+
+    use super::*;
+
+    struct F {
+        finished: bool,
+        opcode: OpCode,
+        payload: Bytes,
+    }
+
+    fn is_none(frm: &Result<Option<(bool, OpCode, Option<BytesMut>)>, ProtocolError>) -> bool {
+        matches!(*frm, Ok(None))
+    }
+
+    fn extract(frm: Result<Option<(bool, OpCode, Option<BytesMut>)>, ProtocolError>) -> F {
+        match frm {
+            Ok(Some((finished, opcode, payload))) => F {
+                finished,
+                opcode,
+                payload: payload
+                    .map(|b| b.freeze())
+                    .unwrap_or_else(|| Bytes::from("")),
+            },
+            _ => unreachable!("error"),
+        }
+    }
+
+    #[test]
+    fn test_parse() {
+        let mut buf = BytesMut::from(&[0b0000_0001u8, 0b0000_0001u8][..]);
+        assert!(is_none(&Parser::parse(&mut buf, false, 1024)));
+
+        let mut buf = BytesMut::from(&[0b0000_0001u8, 0b0000_0001u8][..]);
+        buf.extend(b"1");
+
+        let frame = extract(Parser::parse(&mut buf, false, 1024));
+        assert!(!frame.finished);
+        assert_eq!(frame.opcode, OpCode::Text);
+        assert_eq!(frame.payload.as_ref(), &b"1"[..]);
+    }
+
+    #[test]
+    fn test_parse_length0() {
+        let mut buf = BytesMut::from(&[0b0000_0001u8, 0b0000_0000u8][..]);
+        let frame = extract(Parser::parse(&mut buf, false, 1024));
+        assert!(!frame.finished);
+        assert_eq!(frame.opcode, OpCode::Text);
+        assert!(frame.payload.is_empty());
+    }
+
+    #[test]
+    fn test_parse_length2() {
+        let mut buf = BytesMut::from(&[0b0000_0001u8, 126u8][..]);
+        assert!(is_none(&Parser::parse(&mut buf, false, 1024)));
+
+        let mut buf = BytesMut::from(&[0b0000_0001u8, 126u8][..]);
+        buf.extend(&[0u8, 4u8][..]);
+        buf.extend(b"1234");
+
+        let frame = extract(Parser::parse(&mut buf, false, 1024));
+        assert!(!frame.finished);
+        assert_eq!(frame.opcode, OpCode::Text);
+        assert_eq!(frame.payload.as_ref(), &b"1234"[..]);
+    }
+
+    #[test]
+    fn test_parse_length4() {
+        let mut buf = BytesMut::from(&[0b0000_0001u8, 127u8][..]);
+        assert!(is_none(&Parser::parse(&mut buf, false, 1024)));
+
+        let mut buf = BytesMut::from(&[0b0000_0001u8, 127u8][..]);
+        buf.extend(&[0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 4u8][..]);
+        buf.extend(b"1234");
+
+        let frame = extract(Parser::parse(&mut buf, false, 1024));
+        assert!(!frame.finished);
+        assert_eq!(frame.opcode, OpCode::Text);
+        assert_eq!(frame.payload.as_ref(), &b"1234"[..]);
+    }
+
+    #[test]
+    fn test_parse_frame_mask() {
+        let mut buf = BytesMut::from(&[0b0000_0001u8, 0b1000_0001u8][..]);
+        buf.extend(b"0001");
+        buf.extend(b"1");
+
+        assert!(Parser::parse(&mut buf, false, 1024).is_err());
+
+        let frame = extract(Parser::parse(&mut buf, true, 1024));
+        assert!(!frame.finished);
+        assert_eq!(frame.opcode, OpCode::Text);
+        assert_eq!(frame.payload, Bytes::from(vec![1u8]));
+    }
+
+    #[test]
+    fn test_parse_frame_no_mask() {
+        let mut buf = BytesMut::from(&[0b0000_0001u8, 0b0000_0001u8][..]);
+        buf.extend([1u8]);
+
+        assert!(Parser::parse(&mut buf, true, 1024).is_err());
+
+        let frame = extract(Parser::parse(&mut buf, false, 1024));
+        assert!(!frame.finished);
+        assert_eq!(frame.opcode, OpCode::Text);
+        assert_eq!(frame.payload, Bytes::from(vec![1u8]));
+    }
+
+    #[test]
+    fn test_parse_frame_max_size() {
+        let mut buf = BytesMut::from(&[0b0000_0001u8, 0b0000_0010u8][..]);
+        buf.extend([1u8, 1u8]);
+
+        assert!(Parser::parse(&mut buf, true, 1).is_err());
+
+        if let Err(ProtocolError::Overflow) = Parser::parse(&mut buf, false, 0) {
+        } else {
+            unreachable!("error");
+        }
+    }
+
+    #[test]
+    fn test_parse_frame_max_size_recoverability() {
+        let mut buf = BytesMut::new();
+        // The first text frame with length == 2, payload doesn't matter.
+        buf.extend([0b0000_0001u8, 0b0000_0010u8, 0b0000_0000u8, 0b0000_0000u8]);
+        // Next binary frame with length == 2 and payload == `[0x1111_1111u8, 0x1111_1111u8]`.
+        buf.extend([0b0000_0010u8, 0b0000_0010u8, 0b1111_1111u8, 0b1111_1111u8]);
+
+        assert_eq!(buf.len(), 8);
+        assert!(matches!(
+            Parser::parse(&mut buf, false, 1),
+            Err(ProtocolError::Overflow)
+        ));
+        assert_eq!(buf.len(), 4);
+        let frame = extract(Parser::parse(&mut buf, false, 2));
+        assert!(!frame.finished);
+        assert_eq!(frame.opcode, OpCode::Binary);
+        assert_eq!(
+            frame.payload,
+            Bytes::from(vec![0b1111_1111u8, 0b1111_1111u8])
+        );
+        assert_eq!(buf.len(), 0);
+    }
+
+    #[test]
+    fn test_ping_frame() {
+        let mut buf = BytesMut::new();
+        Parser::write_message(&mut buf, Vec::from("data"), OpCode::Ping, true, false);
+
+        let mut v = vec![137u8, 4u8];
+        v.extend(b"data");
+        assert_eq!(&buf[..], &v[..]);
+    }
+
+    #[test]
+    fn test_pong_frame() {
+        let mut buf = BytesMut::new();
+        Parser::write_message(&mut buf, Vec::from("data"), OpCode::Pong, true, false);
+
+        let mut v = vec![138u8, 4u8];
+        v.extend(b"data");
+        assert_eq!(&buf[..], &v[..]);
+    }
+
+    #[test]
+    fn test_close_frame() {
+        let mut buf = BytesMut::new();
+        let reason = (CloseCode::Normal, "data");
+        Parser::write_close(&mut buf, Some(reason.into()), false);
+
+        let mut v = vec![136u8, 6u8, 3u8, 232u8];
+        v.extend(b"data");
+        assert_eq!(&buf[..], &v[..]);
+    }
+
+    #[test]
+    fn test_empty_close_frame() {
+        let mut buf = BytesMut::new();
+        Parser::write_close(&mut buf, None, false);
+        assert_eq!(&buf[..], &vec![0x88, 0x00][..]);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/ws/mask.rs.html b/src/actix_http/ws/mask.rs.html new file mode 100644 index 000000000..c39e6af38 --- /dev/null +++ b/src/actix_http/ws/mask.rs.html @@ -0,0 +1,151 @@ +mask.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
+
//! This is code from [Tungstenite project](https://github.com/snapview/tungstenite-rs)
+
+/// Mask/unmask a frame.
+#[inline]
+pub fn apply_mask(buf: &mut [u8], mask: [u8; 4]) {
+    apply_mask_fast32(buf, mask)
+}
+
+/// A safe unoptimized mask application.
+#[inline]
+fn apply_mask_fallback(buf: &mut [u8], mask: [u8; 4]) {
+    for (i, byte) in buf.iter_mut().enumerate() {
+        *byte ^= mask[i & 3];
+    }
+}
+
+/// Faster version of `apply_mask()` which operates on 4-byte blocks.
+#[inline]
+pub fn apply_mask_fast32(buf: &mut [u8], mask: [u8; 4]) {
+    let mask_u32 = u32::from_ne_bytes(mask);
+
+    // SAFETY:
+    //
+    // buf is a valid slice borrowed mutably from bytes::BytesMut.
+    //
+    // un aligned prefix and suffix would be mask/unmask per byte.
+    // proper aligned middle slice goes into fast path and operates on 4-byte blocks.
+    let (prefix, words, suffix) = unsafe { buf.align_to_mut::<u32>() };
+    apply_mask_fallback(prefix, mask);
+    let head = prefix.len() & 3;
+    let mask_u32 = if head > 0 {
+        if cfg!(target_endian = "big") {
+            mask_u32.rotate_left(8 * head as u32)
+        } else {
+            mask_u32.rotate_right(8 * head as u32)
+        }
+    } else {
+        mask_u32
+    };
+    for word in words.iter_mut() {
+        *word ^= mask_u32;
+    }
+    apply_mask_fallback(suffix, mask_u32.to_ne_bytes());
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_apply_mask() {
+        let mask = [0x6d, 0xb6, 0xb2, 0x80];
+        let unmasked = [
+            0xf3, 0x00, 0x01, 0x02, 0x03, 0x80, 0x81, 0x82, 0xff, 0xfe, 0x00, 0x17, 0x74, 0xf9,
+            0x12, 0x03,
+        ];
+
+        for data_len in 0..=unmasked.len() {
+            let unmasked = &unmasked[0..data_len];
+            // Check masking with different alignment.
+            for off in 0..=3 {
+                if unmasked.len() < off {
+                    continue;
+                }
+                let mut masked = unmasked.to_vec();
+                apply_mask_fallback(&mut masked[off..], mask);
+
+                let mut masked_fast = unmasked.to_vec();
+                apply_mask_fast32(&mut masked_fast[off..], mask);
+
+                assert_eq!(masked, masked_fast);
+            }
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/ws/mod.rs.html b/src/actix_http/ws/mod.rs.html new file mode 100644 index 000000000..cb1f81387 --- /dev/null +++ b/src/actix_http/ws/mod.rs.html @@ -0,0 +1,703 @@ +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
+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
+
//! WebSocket protocol implementation.
+//!
+//! To setup a WebSocket, first perform the WebSocket handshake then on success convert `Payload` into a
+//! `WsStream` stream and then use `WsWriter` to communicate with the peer.
+
+use std::io;
+
+use derive_more::{Display, Error, From};
+use http::{header, Method, StatusCode};
+
+use crate::{body::BoxBody, header::HeaderValue, RequestHead, Response, ResponseBuilder};
+
+mod codec;
+mod dispatcher;
+mod frame;
+mod mask;
+mod proto;
+
+pub use self::{
+    codec::{Codec, Frame, Item, Message},
+    dispatcher::Dispatcher,
+    frame::Parser,
+    proto::{hash_key, CloseCode, CloseReason, OpCode},
+};
+
+/// WebSocket protocol errors.
+#[derive(Debug, Display, Error, From)]
+pub enum ProtocolError {
+    /// Received an unmasked frame from client.
+    #[display(fmt = "received an unmasked frame from client")]
+    UnmaskedFrame,
+
+    /// Received a masked frame from server.
+    #[display(fmt = "received a masked frame from server")]
+    MaskedFrame,
+
+    /// Encountered invalid opcode.
+    #[display(fmt = "invalid opcode ({})", _0)]
+    InvalidOpcode(#[error(not(source))] u8),
+
+    /// Invalid control frame length
+    #[display(fmt = "invalid control frame length ({})", _0)]
+    InvalidLength(#[error(not(source))] usize),
+
+    /// Bad opcode.
+    #[display(fmt = "bad opcode")]
+    BadOpCode,
+
+    /// A payload reached size limit.
+    #[display(fmt = "payload reached size limit")]
+    Overflow,
+
+    /// Continuation has not started.
+    #[display(fmt = "continuation has not started")]
+    ContinuationNotStarted,
+
+    /// Received new continuation but it is already started.
+    #[display(fmt = "received new continuation but it has already started")]
+    ContinuationStarted,
+
+    /// Unknown continuation fragment.
+    #[display(fmt = "unknown continuation fragment: {}", _0)]
+    ContinuationFragment(#[error(not(source))] OpCode),
+
+    /// I/O error.
+    #[display(fmt = "I/O error: {}", _0)]
+    Io(io::Error),
+}
+
+/// WebSocket handshake errors
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Display, Error)]
+pub enum HandshakeError {
+    /// Only get method is allowed.
+    #[display(fmt = "method not allowed")]
+    GetMethodRequired,
+
+    /// Upgrade header if not set to WebSocket.
+    #[display(fmt = "WebSocket upgrade is expected")]
+    NoWebsocketUpgrade,
+
+    /// Connection header is not set to upgrade.
+    #[display(fmt = "connection upgrade is expected")]
+    NoConnectionUpgrade,
+
+    /// WebSocket version header is not set.
+    #[display(fmt = "WebSocket version header is required")]
+    NoVersionHeader,
+
+    /// Unsupported WebSocket version.
+    #[display(fmt = "unsupported WebSocket version")]
+    UnsupportedVersion,
+
+    /// WebSocket key is not set or wrong.
+    #[display(fmt = "unknown WebSocket key")]
+    BadWebsocketKey,
+}
+
+impl From<HandshakeError> for Response<BoxBody> {
+    fn from(err: HandshakeError) -> Self {
+        match err {
+            HandshakeError::GetMethodRequired => {
+                let mut res = Response::new(StatusCode::METHOD_NOT_ALLOWED);
+                #[allow(clippy::declare_interior_mutable_const)]
+                const HV_GET: HeaderValue = HeaderValue::from_static("GET");
+                res.headers_mut().insert(header::ALLOW, HV_GET);
+                res
+            }
+
+            HandshakeError::NoWebsocketUpgrade => {
+                let mut res = Response::bad_request();
+                res.head_mut().reason = Some("No WebSocket Upgrade header found");
+                res
+            }
+
+            HandshakeError::NoConnectionUpgrade => {
+                let mut res = Response::bad_request();
+                res.head_mut().reason = Some("No Connection upgrade");
+                res
+            }
+
+            HandshakeError::NoVersionHeader => {
+                let mut res = Response::bad_request();
+                res.head_mut().reason = Some("WebSocket version header is required");
+                res
+            }
+
+            HandshakeError::UnsupportedVersion => {
+                let mut res = Response::bad_request();
+                res.head_mut().reason = Some("Unsupported WebSocket version");
+                res
+            }
+
+            HandshakeError::BadWebsocketKey => {
+                let mut res = Response::bad_request();
+                res.head_mut().reason = Some("Handshake error");
+                res
+            }
+        }
+    }
+}
+
+impl From<&HandshakeError> for Response<BoxBody> {
+    fn from(err: &HandshakeError) -> Self {
+        (*err).into()
+    }
+}
+
+/// Verify WebSocket handshake request and create handshake response.
+pub fn handshake(req: &RequestHead) -> Result<ResponseBuilder, HandshakeError> {
+    verify_handshake(req)?;
+    Ok(handshake_response(req))
+}
+
+/// Verify WebSocket handshake request.
+pub fn verify_handshake(req: &RequestHead) -> Result<(), HandshakeError> {
+    // WebSocket accepts only GET
+    if req.method != Method::GET {
+        return Err(HandshakeError::GetMethodRequired);
+    }
+
+    // Check for "UPGRADE" to WebSocket header
+    let has_hdr = if let Some(hdr) = req.headers().get(header::UPGRADE) {
+        if let Ok(s) = hdr.to_str() {
+            s.to_ascii_lowercase().contains("websocket")
+        } else {
+            false
+        }
+    } else {
+        false
+    };
+    if !has_hdr {
+        return Err(HandshakeError::NoWebsocketUpgrade);
+    }
+
+    // Upgrade connection
+    if !req.upgrade() {
+        return Err(HandshakeError::NoConnectionUpgrade);
+    }
+
+    // check supported version
+    if !req.headers().contains_key(header::SEC_WEBSOCKET_VERSION) {
+        return Err(HandshakeError::NoVersionHeader);
+    }
+    let supported_ver = {
+        if let Some(hdr) = req.headers().get(header::SEC_WEBSOCKET_VERSION) {
+            hdr == "13" || hdr == "8" || hdr == "7"
+        } else {
+            false
+        }
+    };
+    if !supported_ver {
+        return Err(HandshakeError::UnsupportedVersion);
+    }
+
+    // check client handshake for validity
+    if !req.headers().contains_key(header::SEC_WEBSOCKET_KEY) {
+        return Err(HandshakeError::BadWebsocketKey);
+    }
+    Ok(())
+}
+
+/// Create WebSocket handshake response.
+///
+/// This function returns handshake `Response`, ready to send to peer.
+pub fn handshake_response(req: &RequestHead) -> ResponseBuilder {
+    let key = {
+        let key = req.headers().get(header::SEC_WEBSOCKET_KEY).unwrap();
+        proto::hash_key(key.as_ref())
+    };
+
+    Response::build(StatusCode::SWITCHING_PROTOCOLS)
+        .upgrade("websocket")
+        .insert_header((
+            header::SEC_WEBSOCKET_ACCEPT,
+            // key is known to be header value safe ascii
+            HeaderValue::from_bytes(&key).unwrap(),
+        ))
+        .take()
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::{header, test::TestRequest};
+
+    #[test]
+    fn test_handshake() {
+        let req = TestRequest::default().method(Method::POST).finish();
+        assert_eq!(
+            HandshakeError::GetMethodRequired,
+            verify_handshake(req.head()).unwrap_err(),
+        );
+
+        let req = TestRequest::default().finish();
+        assert_eq!(
+            HandshakeError::NoWebsocketUpgrade,
+            verify_handshake(req.head()).unwrap_err(),
+        );
+
+        let req = TestRequest::default()
+            .insert_header((header::UPGRADE, header::HeaderValue::from_static("test")))
+            .finish();
+        assert_eq!(
+            HandshakeError::NoWebsocketUpgrade,
+            verify_handshake(req.head()).unwrap_err(),
+        );
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::UPGRADE,
+                header::HeaderValue::from_static("websocket"),
+            ))
+            .finish();
+        assert_eq!(
+            HandshakeError::NoConnectionUpgrade,
+            verify_handshake(req.head()).unwrap_err(),
+        );
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::UPGRADE,
+                header::HeaderValue::from_static("websocket"),
+            ))
+            .insert_header((
+                header::CONNECTION,
+                header::HeaderValue::from_static("upgrade"),
+            ))
+            .finish();
+        assert_eq!(
+            HandshakeError::NoVersionHeader,
+            verify_handshake(req.head()).unwrap_err(),
+        );
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::UPGRADE,
+                header::HeaderValue::from_static("websocket"),
+            ))
+            .insert_header((
+                header::CONNECTION,
+                header::HeaderValue::from_static("upgrade"),
+            ))
+            .insert_header((
+                header::SEC_WEBSOCKET_VERSION,
+                header::HeaderValue::from_static("5"),
+            ))
+            .finish();
+        assert_eq!(
+            HandshakeError::UnsupportedVersion,
+            verify_handshake(req.head()).unwrap_err(),
+        );
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::UPGRADE,
+                header::HeaderValue::from_static("websocket"),
+            ))
+            .insert_header((
+                header::CONNECTION,
+                header::HeaderValue::from_static("upgrade"),
+            ))
+            .insert_header((
+                header::SEC_WEBSOCKET_VERSION,
+                header::HeaderValue::from_static("13"),
+            ))
+            .finish();
+        assert_eq!(
+            HandshakeError::BadWebsocketKey,
+            verify_handshake(req.head()).unwrap_err(),
+        );
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::UPGRADE,
+                header::HeaderValue::from_static("websocket"),
+            ))
+            .insert_header((
+                header::CONNECTION,
+                header::HeaderValue::from_static("upgrade"),
+            ))
+            .insert_header((
+                header::SEC_WEBSOCKET_VERSION,
+                header::HeaderValue::from_static("13"),
+            ))
+            .insert_header((
+                header::SEC_WEBSOCKET_KEY,
+                header::HeaderValue::from_static("13"),
+            ))
+            .finish();
+        assert_eq!(
+            StatusCode::SWITCHING_PROTOCOLS,
+            handshake_response(req.head()).finish().status()
+        );
+    }
+
+    #[test]
+    fn test_ws_error_http_response() {
+        let resp: Response<BoxBody> = HandshakeError::GetMethodRequired.into();
+        assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
+        let resp: Response<BoxBody> = HandshakeError::NoWebsocketUpgrade.into();
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+        let resp: Response<BoxBody> = HandshakeError::NoConnectionUpgrade.into();
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+        let resp: Response<BoxBody> = HandshakeError::NoVersionHeader.into();
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+        let resp: Response<BoxBody> = HandshakeError::UnsupportedVersion.into();
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+        let resp: Response<BoxBody> = HandshakeError::BadWebsocketKey.into();
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http/ws/proto.rs.html b/src/actix_http/ws/proto.rs.html new file mode 100644 index 000000000..1041936ac --- /dev/null +++ b/src/actix_http/ws/proto.rs.html @@ -0,0 +1,709 @@ +proto.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
+
use std::fmt;
+
+use base64::prelude::*;
+use tracing::error;
+
+/// Operation codes defined in [RFC 6455 §11.8].
+///
+/// [RFC 6455]: https://datatracker.ietf.org/doc/html/rfc6455#section-11.8
+#[derive(Debug, Eq, PartialEq, Clone, Copy)]
+pub enum OpCode {
+    /// Indicates a continuation frame of a fragmented message.
+    Continue,
+
+    /// Indicates a text data frame.
+    Text,
+
+    /// Indicates a binary data frame.
+    Binary,
+
+    /// Indicates a close control frame.
+    Close,
+
+    /// Indicates a ping control frame.
+    Ping,
+
+    /// Indicates a pong control frame.
+    Pong,
+
+    /// Indicates an invalid opcode was received.
+    Bad,
+}
+
+impl fmt::Display for OpCode {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        use OpCode::*;
+
+        match self {
+            Continue => write!(f, "CONTINUE"),
+            Text => write!(f, "TEXT"),
+            Binary => write!(f, "BINARY"),
+            Close => write!(f, "CLOSE"),
+            Ping => write!(f, "PING"),
+            Pong => write!(f, "PONG"),
+            Bad => write!(f, "BAD"),
+        }
+    }
+}
+
+impl From<OpCode> for u8 {
+    fn from(op: OpCode) -> u8 {
+        use self::OpCode::*;
+
+        match op {
+            Continue => 0,
+            Text => 1,
+            Binary => 2,
+            Close => 8,
+            Ping => 9,
+            Pong => 10,
+            Bad => {
+                error!("Attempted to convert invalid opcode to u8. This is a bug.");
+                8 // if this somehow happens, a close frame will help us tear down quickly
+            }
+        }
+    }
+}
+
+impl From<u8> for OpCode {
+    fn from(byte: u8) -> OpCode {
+        use self::OpCode::*;
+
+        match byte {
+            0 => Continue,
+            1 => Text,
+            2 => Binary,
+            8 => Close,
+            9 => Ping,
+            10 => Pong,
+            _ => Bad,
+        }
+    }
+}
+
+/// Status code used to indicate why an endpoint is closing the WebSocket connection.
+#[derive(Debug, Eq, PartialEq, Clone, Copy)]
+pub enum CloseCode {
+    /// Indicates a normal closure, meaning that the purpose for which the connection was
+    /// established has been fulfilled.
+    Normal,
+
+    /// Indicates that an endpoint is "going away", such as a server going down or a browser having
+    /// navigated away from a page.
+    Away,
+
+    /// Indicates that an endpoint is terminating the connection due to a protocol error.
+    Protocol,
+
+    /// Indicates that an endpoint is terminating the connection because it has received a type of
+    /// data it cannot accept (e.g., an endpoint that understands only text data MAY send this if it
+    /// receives a binary message).
+    Unsupported,
+
+    /// Indicates an abnormal closure. If the abnormal closure was due to an error, this close code
+    /// will not be used. Instead, the `on_error` method of the handler will be called with
+    /// the error. However, if the connection is simply dropped, without an error, this close code
+    /// will be sent to the handler.
+    Abnormal,
+
+    /// Indicates that an endpoint is terminating the connection because it has received data within
+    /// a message that was not consistent with the type of the message (e.g., non-UTF-8 \[RFC 3629\]
+    /// data within a text message).
+    Invalid,
+
+    /// Indicates that an endpoint is terminating the connection because it has received a message
+    /// that violates its policy. This is a generic status code that can be returned when there is
+    /// no other more suitable status code (e.g., Unsupported or Size) or if there is a need to hide
+    /// specific details about the policy.
+    Policy,
+
+    /// Indicates that an endpoint is terminating the connection because it has received a message
+    /// that is too big for it to process.
+    Size,
+
+    /// Indicates that an endpoint (client) is terminating the connection because it has expected
+    /// the server to negotiate one or more extension, but the server didn't return them in the
+    /// response message of the WebSocket handshake.  The list of extensions that are needed should
+    /// be given as the reason for closing. Note that this status code is not used by the server,
+    /// because it can fail the WebSocket handshake instead.
+    Extension,
+
+    /// Indicates that a server is terminating the connection because it encountered an unexpected
+    /// condition that prevented it from fulfilling the request.
+    Error,
+
+    /// Indicates that the server is restarting. A client may choose to reconnect, and if it does,
+    /// it should use a randomized delay of 5-30 seconds between attempts.
+    Restart,
+
+    /// Indicates that the server is overloaded and the client should either connect to a different
+    /// IP (when multiple targets exist), or reconnect to the same IP when a user has performed
+    /// an action.
+    Again,
+
+    #[doc(hidden)]
+    Tls,
+
+    #[doc(hidden)]
+    Other(u16),
+}
+
+impl From<CloseCode> for u16 {
+    fn from(code: CloseCode) -> u16 {
+        use self::CloseCode::*;
+
+        match code {
+            Normal => 1000,
+            Away => 1001,
+            Protocol => 1002,
+            Unsupported => 1003,
+            Abnormal => 1006,
+            Invalid => 1007,
+            Policy => 1008,
+            Size => 1009,
+            Extension => 1010,
+            Error => 1011,
+            Restart => 1012,
+            Again => 1013,
+            Tls => 1015,
+            Other(code) => code,
+        }
+    }
+}
+
+impl From<u16> for CloseCode {
+    fn from(code: u16) -> CloseCode {
+        use self::CloseCode::*;
+
+        match code {
+            1000 => Normal,
+            1001 => Away,
+            1002 => Protocol,
+            1003 => Unsupported,
+            1006 => Abnormal,
+            1007 => Invalid,
+            1008 => Policy,
+            1009 => Size,
+            1010 => Extension,
+            1011 => Error,
+            1012 => Restart,
+            1013 => Again,
+            1015 => Tls,
+            _ => Other(code),
+        }
+    }
+}
+
+#[derive(Debug, Eq, PartialEq, Clone)]
+/// Reason for closing the connection
+pub struct CloseReason {
+    /// Exit code
+    pub code: CloseCode,
+
+    /// Optional description of the exit code
+    pub description: Option<String>,
+}
+
+impl From<CloseCode> for CloseReason {
+    fn from(code: CloseCode) -> Self {
+        CloseReason {
+            code,
+            description: None,
+        }
+    }
+}
+
+impl<T: Into<String>> From<(CloseCode, T)> for CloseReason {
+    fn from(info: (CloseCode, T)) -> Self {
+        CloseReason {
+            code: info.0,
+            description: Some(info.1.into()),
+        }
+    }
+}
+
+/// The WebSocket GUID as stated in the spec.
+/// See <https://datatracker.ietf.org/doc/html/rfc6455#section-1.3>.
+static WS_GUID: &[u8] = b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
+
+/// Hashes the `Sec-WebSocket-Key` header according to the WebSocket spec.
+///
+/// Result is a Base64 encoded byte array. `base64(sha1(input))` is always 28 bytes.
+pub fn hash_key(key: &[u8]) -> [u8; 28] {
+    let hash = {
+        use sha1::Digest as _;
+
+        let mut hasher = sha1::Sha1::new();
+
+        hasher.update(key);
+        hasher.update(WS_GUID);
+
+        hasher.finalize()
+    };
+
+    let mut hash_b64 = [0; 28];
+    let n = BASE64_STANDARD.encode_slice(hash, &mut hash_b64).unwrap();
+    assert_eq!(n, 28);
+
+    hash_b64
+}
+
+#[cfg(test)]
+mod test {
+    #![allow(unused_imports, unused_variables, dead_code)]
+    use super::*;
+
+    macro_rules! opcode_into {
+        ($from:expr => $opcode:pat) => {
+            match OpCode::from($from) {
+                e @ $opcode => {}
+                e => unreachable!("{:?}", e),
+            }
+        };
+    }
+
+    macro_rules! opcode_from {
+        ($from:expr => $opcode:pat) => {
+            let res: u8 = $from.into();
+            match res {
+                e @ $opcode => {}
+                e => unreachable!("{:?}", e),
+            }
+        };
+    }
+
+    #[test]
+    fn test_to_opcode() {
+        opcode_into!(0 => OpCode::Continue);
+        opcode_into!(1 => OpCode::Text);
+        opcode_into!(2 => OpCode::Binary);
+        opcode_into!(8 => OpCode::Close);
+        opcode_into!(9 => OpCode::Ping);
+        opcode_into!(10 => OpCode::Pong);
+        opcode_into!(99 => OpCode::Bad);
+    }
+
+    #[test]
+    fn test_from_opcode() {
+        opcode_from!(OpCode::Continue => 0);
+        opcode_from!(OpCode::Text => 1);
+        opcode_from!(OpCode::Binary => 2);
+        opcode_from!(OpCode::Close => 8);
+        opcode_from!(OpCode::Ping => 9);
+        opcode_from!(OpCode::Pong => 10);
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_from_opcode_debug() {
+        opcode_from!(OpCode::Bad => 99);
+    }
+
+    #[test]
+    fn test_from_opcode_display() {
+        assert_eq!(format!("{}", OpCode::Continue), "CONTINUE");
+        assert_eq!(format!("{}", OpCode::Text), "TEXT");
+        assert_eq!(format!("{}", OpCode::Binary), "BINARY");
+        assert_eq!(format!("{}", OpCode::Close), "CLOSE");
+        assert_eq!(format!("{}", OpCode::Ping), "PING");
+        assert_eq!(format!("{}", OpCode::Pong), "PONG");
+        assert_eq!(format!("{}", OpCode::Bad), "BAD");
+    }
+
+    #[test]
+    fn test_hash_key() {
+        let hash = hash_key(b"hello actix-web");
+        assert_eq!(&hash, b"cR1dlyUUJKp0s/Bel25u5TgvC3E=");
+    }
+
+    #[test]
+    fn close_code_from_u16() {
+        assert_eq!(CloseCode::from(1000u16), CloseCode::Normal);
+        assert_eq!(CloseCode::from(1001u16), CloseCode::Away);
+        assert_eq!(CloseCode::from(1002u16), CloseCode::Protocol);
+        assert_eq!(CloseCode::from(1003u16), CloseCode::Unsupported);
+        assert_eq!(CloseCode::from(1006u16), CloseCode::Abnormal);
+        assert_eq!(CloseCode::from(1007u16), CloseCode::Invalid);
+        assert_eq!(CloseCode::from(1008u16), CloseCode::Policy);
+        assert_eq!(CloseCode::from(1009u16), CloseCode::Size);
+        assert_eq!(CloseCode::from(1010u16), CloseCode::Extension);
+        assert_eq!(CloseCode::from(1011u16), CloseCode::Error);
+        assert_eq!(CloseCode::from(1012u16), CloseCode::Restart);
+        assert_eq!(CloseCode::from(1013u16), CloseCode::Again);
+        assert_eq!(CloseCode::from(1015u16), CloseCode::Tls);
+        assert_eq!(CloseCode::from(2000u16), CloseCode::Other(2000));
+    }
+
+    #[test]
+    fn close_code_into_u16() {
+        assert_eq!(1000u16, Into::<u16>::into(CloseCode::Normal));
+        assert_eq!(1001u16, Into::<u16>::into(CloseCode::Away));
+        assert_eq!(1002u16, Into::<u16>::into(CloseCode::Protocol));
+        assert_eq!(1003u16, Into::<u16>::into(CloseCode::Unsupported));
+        assert_eq!(1006u16, Into::<u16>::into(CloseCode::Abnormal));
+        assert_eq!(1007u16, Into::<u16>::into(CloseCode::Invalid));
+        assert_eq!(1008u16, Into::<u16>::into(CloseCode::Policy));
+        assert_eq!(1009u16, Into::<u16>::into(CloseCode::Size));
+        assert_eq!(1010u16, Into::<u16>::into(CloseCode::Extension));
+        assert_eq!(1011u16, Into::<u16>::into(CloseCode::Error));
+        assert_eq!(1012u16, Into::<u16>::into(CloseCode::Restart));
+        assert_eq!(1013u16, Into::<u16>::into(CloseCode::Again));
+        assert_eq!(1015u16, Into::<u16>::into(CloseCode::Tls));
+        assert_eq!(2000u16, Into::<u16>::into(CloseCode::Other(2000)));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_http_test/lib.rs.html b/src/actix_http_test/lib.rs.html new file mode 100644 index 000000000..6e913696e --- /dev/null +++ b/src/actix_http_test/lib.rs.html @@ -0,0 +1,639 @@ +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
+
//! Various helpers for Actix applications to use during testing.
+
+#![deny(rust_2018_idioms, nonstandard_style)]
+#![warn(future_incompatible)]
+#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
+#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+
+#[cfg(feature = "openssl")]
+extern crate tls_openssl as openssl;
+
+use std::{net, thread, time::Duration};
+
+use actix_codec::{AsyncRead, AsyncWrite, Framed};
+use actix_rt::{net::TcpStream, System};
+use actix_server::{Server, ServerServiceFactory};
+use awc::{
+    error::PayloadError, http::header::HeaderMap, ws, Client, ClientRequest, ClientResponse,
+    Connector,
+};
+use bytes::Bytes;
+use futures_core::stream::Stream;
+use http::Method;
+use socket2::{Domain, Protocol, Socket, Type};
+use tokio::sync::mpsc;
+
+/// Start test server.
+///
+/// `TestServer` is very simple test server that simplify process of writing integration tests cases
+/// for HTTP applications.
+///
+/// # Examples
+///
+/// ```
+/// use actix_http::{HttpService, Response, Error, StatusCode};
+/// use actix_http_test::test_server;
+/// use actix_service::{fn_service, map_config, ServiceFactoryExt as _};
+///
+/// #[actix_rt::test]
+/// # async fn hidden_test() {}
+/// async fn test_example() {
+///     let srv = test_server(|| {
+///         HttpService::build()
+///             .h1(fn_service(|req| async move {
+///                 Ok::<_, Error>(Response::ok())
+///             }))
+///             .tcp()
+///             .map_err(|_| ())
+///     })
+///     .await;
+///
+///     let req = srv.get("/");
+///     let response = req.send().await.unwrap();
+///
+///     assert_eq!(response.status(), StatusCode::OK);
+/// }
+/// # actix_rt::System::new().block_on(test_example());
+/// ```
+pub async fn test_server<F: ServerServiceFactory<TcpStream>>(factory: F) -> TestServer {
+    let tcp = net::TcpListener::bind("127.0.0.1:0").unwrap();
+    test_server_with_addr(tcp, factory).await
+}
+
+/// Start [`test server`](test_server()) on an existing address binding.
+pub async fn test_server_with_addr<F: ServerServiceFactory<TcpStream>>(
+    tcp: net::TcpListener,
+    factory: F,
+) -> TestServer {
+    let (started_tx, started_rx) = std::sync::mpsc::channel();
+    let (thread_stop_tx, thread_stop_rx) = mpsc::channel(1);
+
+    // run server in separate thread
+    thread::spawn(move || {
+        System::new().block_on(async move {
+            let local_addr = tcp.local_addr().unwrap();
+
+            let srv = Server::build()
+                .workers(1)
+                .disable_signals()
+                .system_exit()
+                .listen("test", tcp, factory)
+                .expect("test server could not be created");
+
+            let srv = srv.run();
+            started_tx
+                .send((System::current(), srv.handle(), local_addr))
+                .unwrap();
+
+            // drive server loop
+            srv.await.unwrap();
+        });
+
+        // notify TestServer that server and system have shut down
+        // all thread managed resources should be dropped at this point
+        #[allow(clippy::let_underscore_future)]
+        let _ = thread_stop_tx.send(());
+    });
+
+    let (system, server, addr) = started_rx.recv().unwrap();
+
+    let client = {
+        #[cfg(feature = "openssl")]
+        let connector = {
+            use openssl::ssl::{SslConnector, SslMethod, SslVerifyMode};
+
+            let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
+
+            builder.set_verify(SslVerifyMode::NONE);
+            let _ = builder
+                .set_alpn_protos(b"\x02h2\x08http/1.1")
+                .map_err(|e| log::error!("Can not set alpn protocol: {:?}", e));
+
+            Connector::new()
+                .conn_lifetime(Duration::from_secs(0))
+                .timeout(Duration::from_millis(30000))
+                .openssl(builder.build())
+        };
+
+        #[cfg(not(feature = "openssl"))]
+        let connector = {
+            Connector::new()
+                .conn_lifetime(Duration::from_secs(0))
+                .timeout(Duration::from_millis(30000))
+        };
+
+        Client::builder().connector(connector).finish()
+    };
+
+    TestServer {
+        server,
+        client,
+        system,
+        addr,
+        thread_stop_rx,
+    }
+}
+
+/// Test server controller
+pub struct TestServer {
+    server: actix_server::ServerHandle,
+    client: awc::Client,
+    system: actix_rt::System,
+    addr: net::SocketAddr,
+    thread_stop_rx: mpsc::Receiver<()>,
+}
+
+impl TestServer {
+    /// Construct test server url
+    pub fn addr(&self) -> net::SocketAddr {
+        self.addr
+    }
+
+    /// Construct test server url
+    pub fn url(&self, uri: &str) -> String {
+        if uri.starts_with('/') {
+            format!("http://localhost:{}{}", self.addr.port(), uri)
+        } else {
+            format!("http://localhost:{}/{}", self.addr.port(), uri)
+        }
+    }
+
+    /// Construct test HTTPS server URL.
+    pub fn surl(&self, uri: &str) -> String {
+        if uri.starts_with('/') {
+            format!("https://localhost:{}{}", self.addr.port(), uri)
+        } else {
+            format!("https://localhost:{}/{}", self.addr.port(), uri)
+        }
+    }
+
+    /// Create `GET` request
+    pub fn get<S: AsRef<str>>(&self, path: S) -> ClientRequest {
+        self.client.get(self.url(path.as_ref()).as_str())
+    }
+
+    /// Create HTTPS `GET` request
+    pub fn sget<S: AsRef<str>>(&self, path: S) -> ClientRequest {
+        self.client.get(self.surl(path.as_ref()).as_str())
+    }
+
+    /// Create `POST` request
+    pub fn post<S: AsRef<str>>(&self, path: S) -> ClientRequest {
+        self.client.post(self.url(path.as_ref()).as_str())
+    }
+
+    /// Create HTTPS `POST` request
+    pub fn spost<S: AsRef<str>>(&self, path: S) -> ClientRequest {
+        self.client.post(self.surl(path.as_ref()).as_str())
+    }
+
+    /// Create `HEAD` request
+    pub fn head<S: AsRef<str>>(&self, path: S) -> ClientRequest {
+        self.client.head(self.url(path.as_ref()).as_str())
+    }
+
+    /// Create HTTPS `HEAD` request
+    pub fn shead<S: AsRef<str>>(&self, path: S) -> ClientRequest {
+        self.client.head(self.surl(path.as_ref()).as_str())
+    }
+
+    /// Create `PUT` request
+    pub fn put<S: AsRef<str>>(&self, path: S) -> ClientRequest {
+        self.client.put(self.url(path.as_ref()).as_str())
+    }
+
+    /// Create HTTPS `PUT` request
+    pub fn sput<S: AsRef<str>>(&self, path: S) -> ClientRequest {
+        self.client.put(self.surl(path.as_ref()).as_str())
+    }
+
+    /// Create `PATCH` request
+    pub fn patch<S: AsRef<str>>(&self, path: S) -> ClientRequest {
+        self.client.patch(self.url(path.as_ref()).as_str())
+    }
+
+    /// Create HTTPS `PATCH` request
+    pub fn spatch<S: AsRef<str>>(&self, path: S) -> ClientRequest {
+        self.client.patch(self.surl(path.as_ref()).as_str())
+    }
+
+    /// Create `DELETE` request
+    pub fn delete<S: AsRef<str>>(&self, path: S) -> ClientRequest {
+        self.client.delete(self.url(path.as_ref()).as_str())
+    }
+
+    /// Create HTTPS `DELETE` request
+    pub fn sdelete<S: AsRef<str>>(&self, path: S) -> ClientRequest {
+        self.client.delete(self.surl(path.as_ref()).as_str())
+    }
+
+    /// Create `OPTIONS` request
+    pub fn options<S: AsRef<str>>(&self, path: S) -> ClientRequest {
+        self.client.options(self.url(path.as_ref()).as_str())
+    }
+
+    /// Create HTTPS `OPTIONS` request
+    pub fn soptions<S: AsRef<str>>(&self, path: S) -> ClientRequest {
+        self.client.options(self.surl(path.as_ref()).as_str())
+    }
+
+    /// Connect to test HTTP server
+    pub fn request<S: AsRef<str>>(&self, method: Method, path: S) -> ClientRequest {
+        self.client.request(method, path.as_ref())
+    }
+
+    pub async fn load_body<S>(
+        &mut self,
+        mut response: ClientResponse<S>,
+    ) -> Result<Bytes, PayloadError>
+    where
+        S: Stream<Item = Result<Bytes, PayloadError>> + Unpin + 'static,
+    {
+        response.body().limit(10_485_760).await
+    }
+
+    /// Connect to WebSocket server at a given path.
+    pub async fn ws_at(
+        &mut self,
+        path: &str,
+    ) -> Result<Framed<impl AsyncRead + AsyncWrite, ws::Codec>, awc::error::WsClientError> {
+        let url = self.url(path);
+        let connect = self.client.ws(url).connect();
+        connect.await.map(|(_, framed)| framed)
+    }
+
+    /// Connect to a WebSocket server.
+    pub async fn ws(
+        &mut self,
+    ) -> Result<Framed<impl AsyncRead + AsyncWrite, ws::Codec>, awc::error::WsClientError> {
+        self.ws_at("/").await
+    }
+
+    /// Get default HeaderMap of Client.
+    ///
+    /// Returns Some(&mut HeaderMap) when Client object is unique
+    /// (No other clone of client exists at the same time).
+    pub fn client_headers(&mut self) -> Option<&mut HeaderMap> {
+        self.client.headers()
+    }
+
+    /// Stop HTTP server.
+    ///
+    /// Waits for spawned `Server` and `System` to (force) shutdown.
+    pub async fn stop(&mut self) {
+        // signal server to stop
+        self.server.stop(false).await;
+
+        // also signal system to stop
+        // though this is handled by `ServerBuilder::exit_system` too
+        self.system.stop();
+
+        // wait for thread to be stopped but don't care about result
+        let _ = self.thread_stop_rx.recv().await;
+    }
+}
+
+impl Drop for TestServer {
+    fn drop(&mut self) {
+        // calls in this Drop impl should be enough to shut down the server, system, and thread
+        // without needing to await anything
+
+        // signal server to stop
+        #[allow(clippy::let_underscore_future)]
+        let _ = self.server.stop(true);
+
+        // signal system to stop
+        self.system.stop();
+    }
+}
+
+/// Get a localhost socket address with random, unused port.
+pub fn unused_addr() -> net::SocketAddr {
+    let addr: net::SocketAddr = "127.0.0.1:0".parse().unwrap();
+    let socket = Socket::new(Domain::IPV4, Type::STREAM, Some(Protocol::TCP)).unwrap();
+    socket.bind(&addr.into()).unwrap();
+    socket.set_reuse_address(true).unwrap();
+    let tcp = net::TcpListener::from(socket);
+    tcp.local_addr().unwrap()
+}
+
\ No newline at end of file diff --git a/src/actix_multipart/error.rs.html b/src/actix_multipart/error.rs.html new file mode 100644 index 000000000..079af85af --- /dev/null +++ b/src/actix_multipart/error.rs.html @@ -0,0 +1,199 @@ +error.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+
//! Error and Result module
+
+use actix_web::{
+    error::{ParseError, PayloadError},
+    http::StatusCode,
+    ResponseError,
+};
+use derive_more::{Display, Error, From};
+
+/// A set of errors that can occur during parsing multipart streams.
+#[derive(Debug, Display, From, Error)]
+#[non_exhaustive]
+pub enum MultipartError {
+    /// Content-Disposition header is not found or is not equal to "form-data".
+    ///
+    /// According to [RFC 7578 §4.2](https://datatracker.ietf.org/doc/html/rfc7578#section-4.2) a
+    /// Content-Disposition header must always be present and equal to "form-data".
+    #[display(fmt = "No Content-Disposition `form-data` header")]
+    NoContentDisposition,
+
+    /// Content-Type header is not found
+    #[display(fmt = "No Content-Type header found")]
+    NoContentType,
+
+    /// Can not parse Content-Type header
+    #[display(fmt = "Can not parse Content-Type header")]
+    ParseContentType,
+
+    /// Multipart boundary is not found
+    #[display(fmt = "Multipart boundary is not found")]
+    Boundary,
+
+    /// Nested multipart is not supported
+    #[display(fmt = "Nested multipart is not supported")]
+    Nested,
+
+    /// Multipart stream is incomplete
+    #[display(fmt = "Multipart stream is incomplete")]
+    Incomplete,
+
+    /// Error during field parsing
+    #[display(fmt = "{}", _0)]
+    Parse(ParseError),
+
+    /// Payload error
+    #[display(fmt = "{}", _0)]
+    Payload(PayloadError),
+
+    /// Not consumed
+    #[display(fmt = "Multipart stream is not consumed")]
+    NotConsumed,
+
+    /// An error from a field handler in a form
+    #[display(
+        fmt = "An error occurred processing field `{}`: {}",
+        field_name,
+        source
+    )]
+    Field {
+        field_name: String,
+        source: actix_web::Error,
+    },
+
+    /// Duplicate field
+    #[display(fmt = "Duplicate field found for: `{}`", _0)]
+    #[from(ignore)]
+    DuplicateField(#[error(not(source))] String),
+
+    /// Missing field
+    #[display(fmt = "Field with name `{}` is required", _0)]
+    #[from(ignore)]
+    MissingField(#[error(not(source))] String),
+
+    /// Unknown field
+    #[display(fmt = "Unsupported field `{}`", _0)]
+    #[from(ignore)]
+    UnsupportedField(#[error(not(source))] String),
+}
+
+/// Return `BadRequest` for `MultipartError`
+impl ResponseError for MultipartError {
+    fn status_code(&self) -> StatusCode {
+        match &self {
+            MultipartError::Field { source, .. } => source.as_response_error().status_code(),
+            _ => StatusCode::BAD_REQUEST,
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_multipart_error() {
+        let resp = MultipartError::Boundary.error_response();
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_multipart/extractor.rs.html b/src/actix_multipart/extractor.rs.html new file mode 100644 index 000000000..65d8a8c30 --- /dev/null +++ b/src/actix_multipart/extractor.rs.html @@ -0,0 +1,87 @@ +extractor.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
+
//! Multipart payload support
+
+use actix_utils::future::{ready, Ready};
+use actix_web::{dev::Payload, Error, FromRequest, HttpRequest};
+
+use crate::server::Multipart;
+
+/// Get request's payload as multipart stream.
+///
+/// Content-type: multipart/form-data;
+///
+/// # Examples
+/// ```
+/// use actix_web::{web, HttpResponse, Error};
+/// use actix_multipart::Multipart;
+/// use futures_util::StreamExt as _;
+///
+/// async fn index(mut payload: Multipart) -> Result<HttpResponse, Error> {
+///     // iterate over multipart stream
+///     while let Some(item) = payload.next().await {
+///            let mut field = item?;
+///
+///            // Field in turn is stream of *Bytes* object
+///            while let Some(chunk) = field.next().await {
+///                println!("-- CHUNK: \n{:?}", std::str::from_utf8(&chunk?));
+///            }
+///     }
+///
+///     Ok(HttpResponse::Ok().into())
+/// }
+/// ```
+impl FromRequest for Multipart {
+    type Error = Error;
+    type Future = Ready<Result<Multipart, Error>>;
+
+    #[inline]
+    fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
+        ready(Ok(match Multipart::boundary(req.headers()) {
+            Ok(boundary) => Multipart::from_boundary(boundary, payload.take()),
+            Err(err) => Multipart::from_error(err),
+        }))
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_multipart/form/bytes.rs.html b/src/actix_multipart/form/bytes.rs.html new file mode 100644 index 000000000..091cb97e9 --- /dev/null +++ b/src/actix_multipart/form/bytes.rs.html @@ -0,0 +1,99 @@ +bytes.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
+
//! Reads a field into memory.
+
+use actix_web::HttpRequest;
+use bytes::BytesMut;
+use futures_core::future::LocalBoxFuture;
+use futures_util::TryStreamExt as _;
+use mime::Mime;
+
+use crate::{
+    form::{FieldReader, Limits},
+    Field, MultipartError,
+};
+
+/// Read the field into memory.
+#[derive(Debug)]
+pub struct Bytes {
+    /// The data.
+    pub data: bytes::Bytes,
+
+    /// The value of the `Content-Type` header.
+    pub content_type: Option<Mime>,
+
+    /// The `filename` value in the `Content-Disposition` header.
+    pub file_name: Option<String>,
+}
+
+impl<'t> FieldReader<'t> for Bytes {
+    type Future = LocalBoxFuture<'t, Result<Self, MultipartError>>;
+
+    fn read_field(_: &'t HttpRequest, mut field: Field, limits: &'t mut Limits) -> Self::Future {
+        Box::pin(async move {
+            let mut buf = BytesMut::with_capacity(131_072);
+
+            while let Some(chunk) = field.try_next().await? {
+                limits.try_consume_limits(chunk.len(), true)?;
+                buf.extend(chunk);
+            }
+
+            Ok(Bytes {
+                data: buf.freeze(),
+                content_type: field.content_type().map(ToOwned::to_owned),
+                file_name: field
+                    .content_disposition()
+                    .get_filename()
+                    .map(str::to_owned),
+            })
+        })
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_multipart/form/json.rs.html b/src/actix_multipart/form/json.rs.html new file mode 100644 index 000000000..339d19c23 --- /dev/null +++ b/src/actix_multipart/form/json.rs.html @@ -0,0 +1,423 @@ +json.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
+
//! Deserializes a field as JSON.
+
+use std::sync::Arc;
+
+use actix_web::{http::StatusCode, web, Error, HttpRequest, ResponseError};
+use derive_more::{Deref, DerefMut, Display, Error};
+use futures_core::future::LocalBoxFuture;
+use serde::de::DeserializeOwned;
+
+use super::FieldErrorHandler;
+use crate::{
+    form::{bytes::Bytes, FieldReader, Limits},
+    Field, MultipartError,
+};
+
+/// Deserialize from JSON.
+#[derive(Debug, Deref, DerefMut)]
+pub struct Json<T: DeserializeOwned>(pub T);
+
+impl<T: DeserializeOwned> Json<T> {
+    pub fn into_inner(self) -> T {
+        self.0
+    }
+}
+
+impl<'t, T> FieldReader<'t> for Json<T>
+where
+    T: DeserializeOwned + 'static,
+{
+    type Future = LocalBoxFuture<'t, Result<Self, MultipartError>>;
+
+    fn read_field(req: &'t HttpRequest, field: Field, limits: &'t mut Limits) -> Self::Future {
+        Box::pin(async move {
+            let config = JsonConfig::from_req(req);
+            let field_name = field.name().to_owned();
+
+            if config.validate_content_type {
+                let valid = if let Some(mime) = field.content_type() {
+                    mime.subtype() == mime::JSON || mime.suffix() == Some(mime::JSON)
+                } else {
+                    false
+                };
+
+                if !valid {
+                    return Err(MultipartError::Field {
+                        field_name,
+                        source: config.map_error(req, JsonFieldError::ContentType),
+                    });
+                }
+            }
+
+            let bytes = Bytes::read_field(req, field, limits).await?;
+
+            Ok(Json(serde_json::from_slice(bytes.data.as_ref()).map_err(
+                |err| MultipartError::Field {
+                    field_name,
+                    source: config.map_error(req, JsonFieldError::Deserialize(err)),
+                },
+            )?))
+        })
+    }
+}
+
+#[derive(Debug, Display, Error)]
+#[non_exhaustive]
+pub enum JsonFieldError {
+    /// Deserialize error.
+    #[display(fmt = "Json deserialize error: {}", _0)]
+    Deserialize(serde_json::Error),
+
+    /// Content type error.
+    #[display(fmt = "Content type error")]
+    ContentType,
+}
+
+impl ResponseError for JsonFieldError {
+    fn status_code(&self) -> StatusCode {
+        StatusCode::BAD_REQUEST
+    }
+}
+
+/// Configuration for the [`Json`] field reader.
+#[derive(Clone)]
+pub struct JsonConfig {
+    err_handler: FieldErrorHandler<JsonFieldError>,
+    validate_content_type: bool,
+}
+
+const DEFAULT_CONFIG: JsonConfig = JsonConfig {
+    err_handler: None,
+    validate_content_type: true,
+};
+
+impl JsonConfig {
+    pub fn error_handler<F>(mut self, f: F) -> Self
+    where
+        F: Fn(JsonFieldError, &HttpRequest) -> Error + Send + Sync + 'static,
+    {
+        self.err_handler = Some(Arc::new(f));
+        self
+    }
+
+    /// Extract payload config from app data. Check both `T` and `Data<T>`, in that order, and fall
+    /// back to the default payload config.
+    fn from_req(req: &HttpRequest) -> &Self {
+        req.app_data::<Self>()
+            .or_else(|| req.app_data::<web::Data<Self>>().map(|d| d.as_ref()))
+            .unwrap_or(&DEFAULT_CONFIG)
+    }
+
+    fn map_error(&self, req: &HttpRequest, err: JsonFieldError) -> Error {
+        if let Some(err_handler) = self.err_handler.as_ref() {
+            (*err_handler)(err, req)
+        } else {
+            err.into()
+        }
+    }
+
+    /// Sets whether or not the field must have a valid `Content-Type` header to be parsed.
+    pub fn validate_content_type(mut self, validate_content_type: bool) -> Self {
+        self.validate_content_type = validate_content_type;
+        self
+    }
+}
+
+impl Default for JsonConfig {
+    fn default() -> Self {
+        DEFAULT_CONFIG
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::collections::HashMap;
+
+    use actix_web::{http::StatusCode, web, App, HttpResponse, Responder};
+    use bytes::Bytes;
+
+    use crate::form::{
+        json::{Json, JsonConfig},
+        MultipartForm,
+    };
+
+    #[derive(MultipartForm)]
+    struct JsonForm {
+        json: Json<HashMap<String, String>>,
+    }
+
+    async fn test_json_route(form: MultipartForm<JsonForm>) -> impl Responder {
+        let mut expected = HashMap::new();
+        expected.insert("key1".to_owned(), "value1".to_owned());
+        expected.insert("key2".to_owned(), "value2".to_owned());
+        assert_eq!(&*form.json, &expected);
+        HttpResponse::Ok().finish()
+    }
+
+    const TEST_JSON: &str = r#"{"key1": "value1", "key2": "value2"}"#;
+
+    #[actix_rt::test]
+    async fn test_json_without_content_type() {
+        let srv = actix_test::start(|| {
+            App::new()
+                .route("/", web::post().to(test_json_route))
+                .app_data(JsonConfig::default().validate_content_type(false))
+        });
+
+        let (body, headers) = crate::test::create_form_data_payload_and_headers(
+            "json",
+            None,
+            None,
+            Bytes::from_static(TEST_JSON.as_bytes()),
+        );
+        let mut req = srv.post("/");
+        *req.headers_mut() = headers;
+        let res = req.send_body(body).await.unwrap();
+        assert_eq!(res.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_content_type_validation() {
+        let srv = actix_test::start(|| {
+            App::new()
+                .route("/", web::post().to(test_json_route))
+                .app_data(JsonConfig::default().validate_content_type(true))
+        });
+
+        // Deny because wrong content type
+        let (body, headers) = crate::test::create_form_data_payload_and_headers(
+            "json",
+            None,
+            Some(mime::APPLICATION_OCTET_STREAM),
+            Bytes::from_static(TEST_JSON.as_bytes()),
+        );
+        let mut req = srv.post("/");
+        *req.headers_mut() = headers;
+        let res = req.send_body(body).await.unwrap();
+        assert_eq!(res.status(), StatusCode::BAD_REQUEST);
+
+        // Allow because correct content type
+        let (body, headers) = crate::test::create_form_data_payload_and_headers(
+            "json",
+            None,
+            Some(mime::APPLICATION_JSON),
+            Bytes::from_static(TEST_JSON.as_bytes()),
+        );
+        let mut req = srv.post("/");
+        *req.headers_mut() = headers;
+        let res = req.send_body(body).await.unwrap();
+        assert_eq!(res.status(), StatusCode::OK);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_multipart/form/mod.rs.html b/src/actix_multipart/form/mod.rs.html new file mode 100644 index 000000000..9ff245267 --- /dev/null +++ b/src/actix_multipart/form/mod.rs.html @@ -0,0 +1,1475 @@ +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
+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
+
//! Process and extract typed data from a multipart stream.
+
+use std::{
+    any::Any,
+    collections::HashMap,
+    future::{ready, Future},
+    sync::Arc,
+};
+
+use actix_web::{dev, error::PayloadError, web, Error, FromRequest, HttpRequest};
+use derive_more::{Deref, DerefMut};
+use futures_core::future::LocalBoxFuture;
+use futures_util::{TryFutureExt as _, TryStreamExt as _};
+
+use crate::{Field, Multipart, MultipartError};
+
+pub mod bytes;
+pub mod json;
+#[cfg(feature = "tempfile")]
+pub mod tempfile;
+pub mod text;
+
+#[cfg(feature = "derive")]
+pub use actix_multipart_derive::MultipartForm;
+
+type FieldErrorHandler<T> = Option<Arc<dyn Fn(T, &HttpRequest) -> Error + Send + Sync>>;
+
+/// Trait that data types to be used in a multipart form struct should implement.
+///
+/// It represents an asynchronous handler that processes a multipart field to produce `Self`.
+pub trait FieldReader<'t>: Sized + Any {
+    /// Future that resolves to a `Self`.
+    type Future: Future<Output = Result<Self, MultipartError>>;
+
+    /// The form will call this function to handle the field.
+    fn read_field(req: &'t HttpRequest, field: Field, limits: &'t mut Limits) -> Self::Future;
+}
+
+/// Used to accumulate the state of the loaded fields.
+#[doc(hidden)]
+#[derive(Default, Deref, DerefMut)]
+pub struct State(pub HashMap<String, Box<dyn Any>>);
+
+/// Trait that the field collection types implement, i.e. `Vec<T>`, `Option<T>`, or `T` itself.
+#[doc(hidden)]
+pub trait FieldGroupReader<'t>: Sized + Any {
+    type Future: Future<Output = Result<(), MultipartError>>;
+
+    /// The form will call this function for each matching field.
+    fn handle_field(
+        req: &'t HttpRequest,
+        field: Field,
+        limits: &'t mut Limits,
+        state: &'t mut State,
+        duplicate_field: DuplicateField,
+    ) -> Self::Future;
+
+    /// Construct `Self` from the group of processed fields.
+    fn from_state(name: &str, state: &'t mut State) -> Result<Self, MultipartError>;
+}
+
+impl<'t, T> FieldGroupReader<'t> for Option<T>
+where
+    T: FieldReader<'t>,
+{
+    type Future = LocalBoxFuture<'t, Result<(), MultipartError>>;
+
+    fn handle_field(
+        req: &'t HttpRequest,
+        field: Field,
+        limits: &'t mut Limits,
+        state: &'t mut State,
+        duplicate_field: DuplicateField,
+    ) -> Self::Future {
+        if state.contains_key(field.name()) {
+            match duplicate_field {
+                DuplicateField::Ignore => return Box::pin(ready(Ok(()))),
+
+                DuplicateField::Deny => {
+                    return Box::pin(ready(Err(MultipartError::DuplicateField(
+                        field.name().to_owned(),
+                    ))))
+                }
+
+                DuplicateField::Replace => {}
+            }
+        }
+
+        Box::pin(async move {
+            let field_name = field.name().to_owned();
+            let t = T::read_field(req, field, limits).await?;
+            state.insert(field_name, Box::new(t));
+            Ok(())
+        })
+    }
+
+    fn from_state(name: &str, state: &'t mut State) -> Result<Self, MultipartError> {
+        Ok(state.remove(name).map(|m| *m.downcast::<T>().unwrap()))
+    }
+}
+
+impl<'t, T> FieldGroupReader<'t> for Vec<T>
+where
+    T: FieldReader<'t>,
+{
+    type Future = LocalBoxFuture<'t, Result<(), MultipartError>>;
+
+    fn handle_field(
+        req: &'t HttpRequest,
+        field: Field,
+        limits: &'t mut Limits,
+        state: &'t mut State,
+        _duplicate_field: DuplicateField,
+    ) -> Self::Future {
+        Box::pin(async move {
+            // Note: Vec GroupReader always allows duplicates
+
+            let field_name = field.name().to_owned();
+
+            let vec = state
+                .entry(field_name)
+                .or_insert_with(|| Box::<Vec<T>>::default())
+                .downcast_mut::<Vec<T>>()
+                .unwrap();
+
+            let item = T::read_field(req, field, limits).await?;
+            vec.push(item);
+
+            Ok(())
+        })
+    }
+
+    fn from_state(name: &str, state: &'t mut State) -> Result<Self, MultipartError> {
+        Ok(state
+            .remove(name)
+            .map(|m| *m.downcast::<Vec<T>>().unwrap())
+            .unwrap_or_default())
+    }
+}
+
+impl<'t, T> FieldGroupReader<'t> for T
+where
+    T: FieldReader<'t>,
+{
+    type Future = LocalBoxFuture<'t, Result<(), MultipartError>>;
+
+    fn handle_field(
+        req: &'t HttpRequest,
+        field: Field,
+        limits: &'t mut Limits,
+        state: &'t mut State,
+        duplicate_field: DuplicateField,
+    ) -> Self::Future {
+        if state.contains_key(field.name()) {
+            match duplicate_field {
+                DuplicateField::Ignore => return Box::pin(ready(Ok(()))),
+
+                DuplicateField::Deny => {
+                    return Box::pin(ready(Err(MultipartError::DuplicateField(
+                        field.name().to_owned(),
+                    ))))
+                }
+
+                DuplicateField::Replace => {}
+            }
+        }
+
+        Box::pin(async move {
+            let field_name = field.name().to_owned();
+            let t = T::read_field(req, field, limits).await?;
+            state.insert(field_name, Box::new(t));
+            Ok(())
+        })
+    }
+
+    fn from_state(name: &str, state: &'t mut State) -> Result<Self, MultipartError> {
+        state
+            .remove(name)
+            .map(|m| *m.downcast::<T>().unwrap())
+            .ok_or_else(|| MultipartError::MissingField(name.to_owned()))
+    }
+}
+
+/// Trait that allows a type to be used in the [`struct@MultipartForm`] extractor.
+///
+/// You should use the [`macro@MultipartForm`] macro to derive this for your struct.
+pub trait MultipartCollect: Sized {
+    /// An optional limit in bytes to be applied a given field name. Note this limit will be shared
+    /// across all fields sharing the same name.
+    fn limit(field_name: &str) -> Option<usize>;
+
+    /// The extractor will call this function for each incoming field, the state can be updated
+    /// with the processed field data.
+    fn handle_field<'t>(
+        req: &'t HttpRequest,
+        field: Field,
+        limits: &'t mut Limits,
+        state: &'t mut State,
+    ) -> LocalBoxFuture<'t, Result<(), MultipartError>>;
+
+    /// Once all the fields have been processed and stored in the state, this is called
+    /// to convert into the struct representation.
+    fn from_state(state: State) -> Result<Self, MultipartError>;
+}
+
+#[doc(hidden)]
+pub enum DuplicateField {
+    /// Additional fields are not processed.
+    Ignore,
+
+    /// An error will be raised.
+    Deny,
+
+    /// All fields will be processed, the last one will replace all previous.
+    Replace,
+}
+
+/// Used to keep track of the remaining limits for the form and current field.
+pub struct Limits {
+    pub total_limit_remaining: usize,
+    pub memory_limit_remaining: usize,
+    pub field_limit_remaining: Option<usize>,
+}
+
+impl Limits {
+    pub fn new(total_limit: usize, memory_limit: usize) -> Self {
+        Self {
+            total_limit_remaining: total_limit,
+            memory_limit_remaining: memory_limit,
+            field_limit_remaining: None,
+        }
+    }
+
+    /// This function should be called within a [`FieldReader`] when reading each chunk of a field
+    /// to ensure that the form limits are not exceeded.
+    ///
+    /// # Arguments
+    ///
+    /// * `bytes` - The number of bytes being read from this chunk
+    /// * `in_memory` - Whether to consume from the memory limits
+    pub fn try_consume_limits(
+        &mut self,
+        bytes: usize,
+        in_memory: bool,
+    ) -> Result<(), MultipartError> {
+        self.total_limit_remaining = self
+            .total_limit_remaining
+            .checked_sub(bytes)
+            .ok_or(MultipartError::Payload(PayloadError::Overflow))?;
+
+        if in_memory {
+            self.memory_limit_remaining = self
+                .memory_limit_remaining
+                .checked_sub(bytes)
+                .ok_or(MultipartError::Payload(PayloadError::Overflow))?;
+        }
+
+        if let Some(field_limit) = self.field_limit_remaining {
+            self.field_limit_remaining = Some(
+                field_limit
+                    .checked_sub(bytes)
+                    .ok_or(MultipartError::Payload(PayloadError::Overflow))?,
+            );
+        }
+
+        Ok(())
+    }
+}
+
+/// Typed `multipart/form-data` extractor.
+///
+/// To extract typed data from a multipart stream, the inner type `T` must implement the
+/// [`MultipartCollect`] trait. You should use the [`macro@MultipartForm`] macro to derive this
+/// for your struct.
+///
+/// Add a [`MultipartFormConfig`] to your app data to configure extraction.
+#[derive(Deref, DerefMut)]
+pub struct MultipartForm<T: MultipartCollect>(pub T);
+
+impl<T: MultipartCollect> MultipartForm<T> {
+    /// Unwrap into inner `T` value.
+    pub fn into_inner(self) -> T {
+        self.0
+    }
+}
+
+impl<T> FromRequest for MultipartForm<T>
+where
+    T: MultipartCollect,
+{
+    type Error = Error;
+    type Future = LocalBoxFuture<'static, Result<Self, Self::Error>>;
+
+    #[inline]
+    fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
+        let mut payload = Multipart::new(req.headers(), payload.take());
+
+        let config = MultipartFormConfig::from_req(req);
+        let mut limits = Limits::new(config.total_limit, config.memory_limit);
+
+        let req = req.clone();
+        let req2 = req.clone();
+        let err_handler = config.err_handler.clone();
+
+        Box::pin(
+            async move {
+                let mut state = State::default();
+                // We need to ensure field limits are shared for all instances of this field name
+                let mut field_limits = HashMap::<String, Option<usize>>::new();
+
+                while let Some(field) = payload.try_next().await? {
+                    // Retrieve the limit for this field
+                    let entry = field_limits
+                        .entry(field.name().to_owned())
+                        .or_insert_with(|| T::limit(field.name()));
+
+                    limits.field_limit_remaining.clone_from(entry);
+
+                    T::handle_field(&req, field, &mut limits, &mut state).await?;
+
+                    // Update the stored limit
+                    *entry = limits.field_limit_remaining;
+                }
+                let inner = T::from_state(state)?;
+                Ok(MultipartForm(inner))
+            }
+            .map_err(move |err| {
+                if let Some(handler) = err_handler {
+                    (*handler)(err, &req2)
+                } else {
+                    err.into()
+                }
+            }),
+        )
+    }
+}
+
+type MultipartFormErrorHandler =
+    Option<Arc<dyn Fn(MultipartError, &HttpRequest) -> Error + Send + Sync>>;
+
+/// [`struct@MultipartForm`] extractor configuration.
+///
+/// Add to your app data to have it picked up by [`struct@MultipartForm`] extractors.
+#[derive(Clone)]
+pub struct MultipartFormConfig {
+    total_limit: usize,
+    memory_limit: usize,
+    err_handler: MultipartFormErrorHandler,
+}
+
+impl MultipartFormConfig {
+    /// Sets maximum accepted payload size for the entire form. By default this limit is 50MiB.
+    pub fn total_limit(mut self, total_limit: usize) -> Self {
+        self.total_limit = total_limit;
+        self
+    }
+
+    /// Sets maximum accepted data that will be read into memory. By default this limit is 2MiB.
+    pub fn memory_limit(mut self, memory_limit: usize) -> Self {
+        self.memory_limit = memory_limit;
+        self
+    }
+
+    /// Sets custom error handler.
+    pub fn error_handler<F>(mut self, f: F) -> Self
+    where
+        F: Fn(MultipartError, &HttpRequest) -> Error + Send + Sync + 'static,
+    {
+        self.err_handler = Some(Arc::new(f));
+        self
+    }
+
+    /// Extracts payload config from app data. Check both `T` and `Data<T>`, in that order, and fall
+    /// back to the default payload config.
+    fn from_req(req: &HttpRequest) -> &Self {
+        req.app_data::<Self>()
+            .or_else(|| req.app_data::<web::Data<Self>>().map(|d| d.as_ref()))
+            .unwrap_or(&DEFAULT_CONFIG)
+    }
+}
+
+const DEFAULT_CONFIG: MultipartFormConfig = MultipartFormConfig {
+    total_limit: 52_428_800, // 50 MiB
+    memory_limit: 2_097_152, // 2 MiB
+    err_handler: None,
+};
+
+impl Default for MultipartFormConfig {
+    fn default() -> Self {
+        DEFAULT_CONFIG
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_http::encoding::Decoder;
+    use actix_multipart_rfc7578::client::multipart;
+    use actix_test::TestServer;
+    use actix_web::{dev::Payload, http::StatusCode, web, App, HttpResponse, Responder};
+    use awc::{Client, ClientResponse};
+
+    use super::MultipartForm;
+    use crate::form::{bytes::Bytes, tempfile::TempFile, text::Text, MultipartFormConfig};
+
+    pub async fn send_form(
+        srv: &TestServer,
+        form: multipart::Form<'static>,
+        uri: &'static str,
+    ) -> ClientResponse<Decoder<Payload>> {
+        Client::default()
+            .post(srv.url(uri))
+            .content_type(form.content_type())
+            .send_body(multipart::Body::from(form))
+            .await
+            .unwrap()
+    }
+
+    /// Test `Option` fields.
+    #[derive(MultipartForm)]
+    struct TestOptions {
+        field1: Option<Text<String>>,
+        field2: Option<Text<String>>,
+    }
+
+    async fn test_options_route(form: MultipartForm<TestOptions>) -> impl Responder {
+        assert!(form.field1.is_some());
+        assert!(form.field2.is_none());
+        HttpResponse::Ok().finish()
+    }
+
+    #[actix_rt::test]
+    async fn test_options() {
+        let srv = actix_test::start(|| App::new().route("/", web::post().to(test_options_route)));
+
+        let mut form = multipart::Form::default();
+        form.add_text("field1", "value");
+
+        let response = send_form(&srv, form, "/").await;
+        assert_eq!(response.status(), StatusCode::OK);
+    }
+
+    /// Test `Vec` fields.
+    #[derive(MultipartForm)]
+    struct TestVec {
+        list1: Vec<Text<String>>,
+        list2: Vec<Text<String>>,
+    }
+
+    async fn test_vec_route(form: MultipartForm<TestVec>) -> impl Responder {
+        let form = form.into_inner();
+        let strings = form
+            .list1
+            .into_iter()
+            .map(|s| s.into_inner())
+            .collect::<Vec<_>>();
+        assert_eq!(strings, vec!["value1", "value2", "value3"]);
+        assert_eq!(form.list2.len(), 0);
+        HttpResponse::Ok().finish()
+    }
+
+    #[actix_rt::test]
+    async fn test_vec() {
+        let srv = actix_test::start(|| App::new().route("/", web::post().to(test_vec_route)));
+
+        let mut form = multipart::Form::default();
+        form.add_text("list1", "value1");
+        form.add_text("list1", "value2");
+        form.add_text("list1", "value3");
+
+        let response = send_form(&srv, form, "/").await;
+        assert_eq!(response.status(), StatusCode::OK);
+    }
+
+    /// Test the `rename` field attribute.
+    #[derive(MultipartForm)]
+    struct TestFieldRenaming {
+        #[multipart(rename = "renamed")]
+        field1: Text<String>,
+        #[multipart(rename = "field1")]
+        field2: Text<String>,
+        field3: Text<String>,
+    }
+
+    async fn test_field_renaming_route(form: MultipartForm<TestFieldRenaming>) -> impl Responder {
+        assert_eq!(&*form.field1, "renamed");
+        assert_eq!(&*form.field2, "field1");
+        assert_eq!(&*form.field3, "field3");
+        HttpResponse::Ok().finish()
+    }
+
+    #[actix_rt::test]
+    async fn test_field_renaming() {
+        let srv =
+            actix_test::start(|| App::new().route("/", web::post().to(test_field_renaming_route)));
+
+        let mut form = multipart::Form::default();
+        form.add_text("renamed", "renamed");
+        form.add_text("field1", "field1");
+        form.add_text("field3", "field3");
+
+        let response = send_form(&srv, form, "/").await;
+        assert_eq!(response.status(), StatusCode::OK);
+    }
+
+    /// Test the `deny_unknown_fields` struct attribute.
+    #[derive(MultipartForm)]
+    #[multipart(deny_unknown_fields)]
+    struct TestDenyUnknown {}
+
+    #[derive(MultipartForm)]
+    struct TestAllowUnknown {}
+
+    async fn test_deny_unknown_route(_: MultipartForm<TestDenyUnknown>) -> impl Responder {
+        HttpResponse::Ok().finish()
+    }
+
+    async fn test_allow_unknown_route(_: MultipartForm<TestAllowUnknown>) -> impl Responder {
+        HttpResponse::Ok().finish()
+    }
+
+    #[actix_rt::test]
+    async fn test_deny_unknown() {
+        let srv = actix_test::start(|| {
+            App::new()
+                .route("/deny", web::post().to(test_deny_unknown_route))
+                .route("/allow", web::post().to(test_allow_unknown_route))
+        });
+
+        let mut form = multipart::Form::default();
+        form.add_text("unknown", "value");
+        let response = send_form(&srv, form, "/deny").await;
+        assert_eq!(response.status(), StatusCode::BAD_REQUEST);
+
+        let mut form = multipart::Form::default();
+        form.add_text("unknown", "value");
+        let response = send_form(&srv, form, "/allow").await;
+        assert_eq!(response.status(), StatusCode::OK);
+    }
+
+    /// Test the `duplicate_field` struct attribute.
+    #[derive(MultipartForm)]
+    #[multipart(duplicate_field = "deny")]
+    struct TestDuplicateDeny {
+        _field: Text<String>,
+    }
+
+    #[derive(MultipartForm)]
+    #[multipart(duplicate_field = "replace")]
+    struct TestDuplicateReplace {
+        field: Text<String>,
+    }
+
+    #[derive(MultipartForm)]
+    #[multipart(duplicate_field = "ignore")]
+    struct TestDuplicateIgnore {
+        field: Text<String>,
+    }
+
+    async fn test_duplicate_deny_route(_: MultipartForm<TestDuplicateDeny>) -> impl Responder {
+        HttpResponse::Ok().finish()
+    }
+
+    async fn test_duplicate_replace_route(
+        form: MultipartForm<TestDuplicateReplace>,
+    ) -> impl Responder {
+        assert_eq!(&*form.field, "second_value");
+        HttpResponse::Ok().finish()
+    }
+
+    async fn test_duplicate_ignore_route(
+        form: MultipartForm<TestDuplicateIgnore>,
+    ) -> impl Responder {
+        assert_eq!(&*form.field, "first_value");
+        HttpResponse::Ok().finish()
+    }
+
+    #[actix_rt::test]
+    async fn test_duplicate_field() {
+        let srv = actix_test::start(|| {
+            App::new()
+                .route("/deny", web::post().to(test_duplicate_deny_route))
+                .route("/replace", web::post().to(test_duplicate_replace_route))
+                .route("/ignore", web::post().to(test_duplicate_ignore_route))
+        });
+
+        let mut form = multipart::Form::default();
+        form.add_text("_field", "first_value");
+        form.add_text("_field", "second_value");
+        let response = send_form(&srv, form, "/deny").await;
+        assert_eq!(response.status(), StatusCode::BAD_REQUEST);
+
+        let mut form = multipart::Form::default();
+        form.add_text("field", "first_value");
+        form.add_text("field", "second_value");
+        let response = send_form(&srv, form, "/replace").await;
+        assert_eq!(response.status(), StatusCode::OK);
+
+        let mut form = multipart::Form::default();
+        form.add_text("field", "first_value");
+        form.add_text("field", "second_value");
+        let response = send_form(&srv, form, "/ignore").await;
+        assert_eq!(response.status(), StatusCode::OK);
+    }
+
+    /// Test the Limits.
+    #[derive(MultipartForm)]
+    struct TestMemoryUploadLimits {
+        field: Bytes,
+    }
+
+    #[derive(MultipartForm)]
+    struct TestFileUploadLimits {
+        field: TempFile,
+    }
+
+    async fn test_upload_limits_memory(
+        form: MultipartForm<TestMemoryUploadLimits>,
+    ) -> impl Responder {
+        assert!(!form.field.data.is_empty());
+        HttpResponse::Ok().finish()
+    }
+
+    async fn test_upload_limits_file(form: MultipartForm<TestFileUploadLimits>) -> impl Responder {
+        assert!(form.field.size > 0);
+        HttpResponse::Ok().finish()
+    }
+
+    #[actix_rt::test]
+    async fn test_memory_limits() {
+        let srv = actix_test::start(|| {
+            App::new()
+                .route("/text", web::post().to(test_upload_limits_memory))
+                .route("/file", web::post().to(test_upload_limits_file))
+                .app_data(
+                    MultipartFormConfig::default()
+                        .memory_limit(20)
+                        .total_limit(usize::MAX),
+                )
+        });
+
+        // Exceeds the 20 byte memory limit
+        let mut form = multipart::Form::default();
+        form.add_text("field", "this string is 28 bytes long");
+        let response = send_form(&srv, form, "/text").await;
+        assert_eq!(response.status(), StatusCode::BAD_REQUEST);
+
+        // Memory limit should not apply when the data is being streamed to disk
+        let mut form = multipart::Form::default();
+        form.add_text("field", "this string is 28 bytes long");
+        let response = send_form(&srv, form, "/file").await;
+        assert_eq!(response.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_total_limit() {
+        let srv = actix_test::start(|| {
+            App::new()
+                .route("/text", web::post().to(test_upload_limits_memory))
+                .route("/file", web::post().to(test_upload_limits_file))
+                .app_data(
+                    MultipartFormConfig::default()
+                        .memory_limit(usize::MAX)
+                        .total_limit(20),
+                )
+        });
+
+        // Within the 20 byte limit
+        let mut form = multipart::Form::default();
+        form.add_text("field", "7 bytes");
+        let response = send_form(&srv, form, "/text").await;
+        assert_eq!(response.status(), StatusCode::OK);
+
+        // Exceeds the 20 byte overall limit
+        let mut form = multipart::Form::default();
+        form.add_text("field", "this string is 28 bytes long");
+        let response = send_form(&srv, form, "/text").await;
+        assert_eq!(response.status(), StatusCode::BAD_REQUEST);
+
+        // Exceeds the 20 byte overall limit
+        let mut form = multipart::Form::default();
+        form.add_text("field", "this string is 28 bytes long");
+        let response = send_form(&srv, form, "/file").await;
+        assert_eq!(response.status(), StatusCode::BAD_REQUEST);
+    }
+
+    #[derive(MultipartForm)]
+    struct TestFieldLevelLimits {
+        #[multipart(limit = "30B")]
+        field: Vec<Bytes>,
+    }
+
+    async fn test_field_level_limits_route(
+        form: MultipartForm<TestFieldLevelLimits>,
+    ) -> impl Responder {
+        assert!(!form.field.is_empty());
+        HttpResponse::Ok().finish()
+    }
+
+    #[actix_rt::test]
+    async fn test_field_level_limits() {
+        let srv = actix_test::start(|| {
+            App::new()
+                .route("/", web::post().to(test_field_level_limits_route))
+                .app_data(
+                    MultipartFormConfig::default()
+                        .memory_limit(usize::MAX)
+                        .total_limit(usize::MAX),
+                )
+        });
+
+        // Within the 30 byte limit
+        let mut form = multipart::Form::default();
+        form.add_text("field", "this string is 28 bytes long");
+        let response = send_form(&srv, form, "/").await;
+        assert_eq!(response.status(), StatusCode::OK);
+
+        // Exceeds the the 30 byte limit
+        let mut form = multipart::Form::default();
+        form.add_text("field", "this string is more than 30 bytes long");
+        let response = send_form(&srv, form, "/").await;
+        assert_eq!(response.status(), StatusCode::BAD_REQUEST);
+
+        // Total of values (14 bytes) is within 30 byte limit for "field"
+        let mut form = multipart::Form::default();
+        form.add_text("field", "7 bytes");
+        form.add_text("field", "7 bytes");
+        let response = send_form(&srv, form, "/").await;
+        assert_eq!(response.status(), StatusCode::OK);
+
+        // Total of values exceeds 30 byte limit for "field"
+        let mut form = multipart::Form::default();
+        form.add_text("field", "this string is 28 bytes long");
+        form.add_text("field", "this string is 28 bytes long");
+        let response = send_form(&srv, form, "/").await;
+        assert_eq!(response.status(), StatusCode::BAD_REQUEST);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_multipart/form/tempfile.rs.html b/src/actix_multipart/form/tempfile.rs.html new file mode 100644 index 000000000..3ac860e03 --- /dev/null +++ b/src/actix_multipart/form/tempfile.rs.html @@ -0,0 +1,399 @@ +tempfile.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
+
//! Writes a field to a temporary file on disk.
+
+use std::{
+    io,
+    path::{Path, PathBuf},
+    sync::Arc,
+};
+
+use actix_web::{http::StatusCode, web, Error, HttpRequest, ResponseError};
+use derive_more::{Display, Error};
+use futures_core::future::LocalBoxFuture;
+use futures_util::TryStreamExt as _;
+use mime::Mime;
+use tempfile::NamedTempFile;
+use tokio::io::AsyncWriteExt;
+
+use super::FieldErrorHandler;
+use crate::{
+    form::{FieldReader, Limits},
+    Field, MultipartError,
+};
+
+/// Write the field to a temporary file on disk.
+#[derive(Debug)]
+pub struct TempFile {
+    /// The temporary file on disk.
+    pub file: NamedTempFile,
+
+    /// The value of the `content-type` header.
+    pub content_type: Option<Mime>,
+
+    /// The `filename` value in the `content-disposition` header.
+    pub file_name: Option<String>,
+
+    /// The size in bytes of the file.
+    pub size: usize,
+}
+
+impl<'t> FieldReader<'t> for TempFile {
+    type Future = LocalBoxFuture<'t, Result<Self, MultipartError>>;
+
+    fn read_field(req: &'t HttpRequest, mut field: Field, limits: &'t mut Limits) -> Self::Future {
+        Box::pin(async move {
+            let config = TempFileConfig::from_req(req);
+            let field_name = field.name().to_owned();
+            let mut size = 0;
+
+            let file = config
+                .create_tempfile()
+                .map_err(|err| config.map_error(req, &field_name, TempFileError::FileIo(err)))?;
+
+            let mut file_async =
+                tokio::fs::File::from_std(file.reopen().map_err(|err| {
+                    config.map_error(req, &field_name, TempFileError::FileIo(err))
+                })?);
+
+            while let Some(chunk) = field.try_next().await? {
+                limits.try_consume_limits(chunk.len(), false)?;
+                size += chunk.len();
+                file_async.write_all(chunk.as_ref()).await.map_err(|err| {
+                    config.map_error(req, &field_name, TempFileError::FileIo(err))
+                })?;
+            }
+
+            file_async
+                .flush()
+                .await
+                .map_err(|err| config.map_error(req, &field_name, TempFileError::FileIo(err)))?;
+
+            Ok(TempFile {
+                file,
+                content_type: field.content_type().map(ToOwned::to_owned),
+                file_name: field
+                    .content_disposition()
+                    .get_filename()
+                    .map(str::to_owned),
+                size,
+            })
+        })
+    }
+}
+
+#[derive(Debug, Display, Error)]
+#[non_exhaustive]
+pub enum TempFileError {
+    /// File I/O Error
+    #[display(fmt = "File I/O error: {}", _0)]
+    FileIo(std::io::Error),
+}
+
+impl ResponseError for TempFileError {
+    fn status_code(&self) -> StatusCode {
+        StatusCode::INTERNAL_SERVER_ERROR
+    }
+}
+
+/// Configuration for the [`TempFile`] field reader.
+#[derive(Clone)]
+pub struct TempFileConfig {
+    err_handler: FieldErrorHandler<TempFileError>,
+    directory: Option<PathBuf>,
+}
+
+impl TempFileConfig {
+    fn create_tempfile(&self) -> io::Result<NamedTempFile> {
+        if let Some(ref dir) = self.directory {
+            NamedTempFile::new_in(dir)
+        } else {
+            NamedTempFile::new()
+        }
+    }
+}
+
+impl TempFileConfig {
+    /// Sets custom error handler.
+    pub fn error_handler<F>(mut self, f: F) -> Self
+    where
+        F: Fn(TempFileError, &HttpRequest) -> Error + Send + Sync + 'static,
+    {
+        self.err_handler = Some(Arc::new(f));
+        self
+    }
+
+    /// Extracts payload config from app data. Check both `T` and `Data<T>`, in that order, and fall
+    /// back to the default payload config.
+    fn from_req(req: &HttpRequest) -> &Self {
+        req.app_data::<Self>()
+            .or_else(|| req.app_data::<web::Data<Self>>().map(|d| d.as_ref()))
+            .unwrap_or(&DEFAULT_CONFIG)
+    }
+
+    fn map_error(&self, req: &HttpRequest, field_name: &str, err: TempFileError) -> MultipartError {
+        let source = if let Some(ref err_handler) = self.err_handler {
+            (err_handler)(err, req)
+        } else {
+            err.into()
+        };
+
+        MultipartError::Field {
+            field_name: field_name.to_owned(),
+            source,
+        }
+    }
+
+    /// Sets the directory that temp files will be created in.
+    ///
+    /// The default temporary file location is platform dependent.
+    pub fn directory(mut self, dir: impl AsRef<Path>) -> Self {
+        self.directory = Some(dir.as_ref().to_owned());
+        self
+    }
+}
+
+const DEFAULT_CONFIG: TempFileConfig = TempFileConfig {
+    err_handler: None,
+    directory: None,
+};
+
+impl Default for TempFileConfig {
+    fn default() -> Self {
+        DEFAULT_CONFIG
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::io::{Cursor, Read};
+
+    use actix_multipart_rfc7578::client::multipart;
+    use actix_web::{http::StatusCode, web, App, HttpResponse, Responder};
+
+    use crate::form::{tempfile::TempFile, tests::send_form, MultipartForm};
+
+    #[derive(MultipartForm)]
+    struct FileForm {
+        file: TempFile,
+    }
+
+    async fn test_file_route(form: MultipartForm<FileForm>) -> impl Responder {
+        let mut form = form.into_inner();
+        let mut contents = String::new();
+        form.file.file.read_to_string(&mut contents).unwrap();
+        assert_eq!(contents, "Hello, world!");
+        assert_eq!(form.file.file_name.unwrap(), "testfile.txt");
+        assert_eq!(form.file.content_type.unwrap(), mime::TEXT_PLAIN);
+        HttpResponse::Ok().finish()
+    }
+
+    #[actix_rt::test]
+    async fn test_file_upload() {
+        let srv = actix_test::start(|| App::new().route("/", web::post().to(test_file_route)));
+
+        let mut form = multipart::Form::default();
+        let bytes = Cursor::new("Hello, world!");
+        form.add_reader_file_with_mime("file", bytes, "testfile.txt", mime::TEXT_PLAIN);
+        let response = send_form(&srv, form, "/").await;
+        assert_eq!(response.status(), StatusCode::OK);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_multipart/form/text.rs.html b/src/actix_multipart/form/text.rs.html new file mode 100644 index 000000000..fbeb8b564 --- /dev/null +++ b/src/actix_multipart/form/text.rs.html @@ -0,0 +1,393 @@ +text.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
+
//! Deserializes a field from plain text.
+
+use std::{str, sync::Arc};
+
+use actix_web::{http::StatusCode, web, Error, HttpRequest, ResponseError};
+use derive_more::{Deref, DerefMut, Display, Error};
+use futures_core::future::LocalBoxFuture;
+use serde::de::DeserializeOwned;
+
+use super::FieldErrorHandler;
+use crate::{
+    form::{bytes::Bytes, FieldReader, Limits},
+    Field, MultipartError,
+};
+
+/// Deserialize from plain text.
+///
+/// Internally this uses [`serde_plain`] for deserialization, which supports primitive types
+/// including strings, numbers, and simple enums.
+#[derive(Debug, Deref, DerefMut)]
+pub struct Text<T: DeserializeOwned>(pub T);
+
+impl<T: DeserializeOwned> Text<T> {
+    /// Unwraps into inner value.
+    pub fn into_inner(self) -> T {
+        self.0
+    }
+}
+
+impl<'t, T> FieldReader<'t> for Text<T>
+where
+    T: DeserializeOwned + 'static,
+{
+    type Future = LocalBoxFuture<'t, Result<Self, MultipartError>>;
+
+    fn read_field(req: &'t HttpRequest, field: Field, limits: &'t mut Limits) -> Self::Future {
+        Box::pin(async move {
+            let config = TextConfig::from_req(req);
+            let field_name = field.name().to_owned();
+
+            if config.validate_content_type {
+                let valid = if let Some(mime) = field.content_type() {
+                    mime.subtype() == mime::PLAIN || mime.suffix() == Some(mime::PLAIN)
+                } else {
+                    // https://datatracker.ietf.org/doc/html/rfc7578#section-4.4
+                    // content type defaults to text/plain, so None should be considered valid
+                    true
+                };
+
+                if !valid {
+                    return Err(MultipartError::Field {
+                        field_name,
+                        source: config.map_error(req, TextError::ContentType),
+                    });
+                }
+            }
+
+            let bytes = Bytes::read_field(req, field, limits).await?;
+
+            let text = str::from_utf8(&bytes.data).map_err(|err| MultipartError::Field {
+                field_name: field_name.clone(),
+                source: config.map_error(req, TextError::Utf8Error(err)),
+            })?;
+
+            Ok(Text(serde_plain::from_str(text).map_err(|err| {
+                MultipartError::Field {
+                    field_name,
+                    source: config.map_error(req, TextError::Deserialize(err)),
+                }
+            })?))
+        })
+    }
+}
+
+#[derive(Debug, Display, Error)]
+#[non_exhaustive]
+pub enum TextError {
+    /// UTF-8 decoding error.
+    #[display(fmt = "UTF-8 decoding error: {}", _0)]
+    Utf8Error(str::Utf8Error),
+
+    /// Deserialize error.
+    #[display(fmt = "Plain text deserialize error: {}", _0)]
+    Deserialize(serde_plain::Error),
+
+    /// Content type error.
+    #[display(fmt = "Content type error")]
+    ContentType,
+}
+
+impl ResponseError for TextError {
+    fn status_code(&self) -> StatusCode {
+        StatusCode::BAD_REQUEST
+    }
+}
+
+/// Configuration for the [`Text`] field reader.
+#[derive(Clone)]
+pub struct TextConfig {
+    err_handler: FieldErrorHandler<TextError>,
+    validate_content_type: bool,
+}
+
+impl TextConfig {
+    /// Sets custom error handler.
+    pub fn error_handler<F>(mut self, f: F) -> Self
+    where
+        F: Fn(TextError, &HttpRequest) -> Error + Send + Sync + 'static,
+    {
+        self.err_handler = Some(Arc::new(f));
+        self
+    }
+
+    /// Extracts payload config from app data. Check both `T` and `Data<T>`, in that order, and fall
+    /// back to the default payload config.
+    fn from_req(req: &HttpRequest) -> &Self {
+        req.app_data::<Self>()
+            .or_else(|| req.app_data::<web::Data<Self>>().map(|d| d.as_ref()))
+            .unwrap_or(&DEFAULT_CONFIG)
+    }
+
+    fn map_error(&self, req: &HttpRequest, err: TextError) -> Error {
+        if let Some(ref err_handler) = self.err_handler {
+            (err_handler)(err, req)
+        } else {
+            err.into()
+        }
+    }
+
+    /// Sets whether or not the field must have a valid `Content-Type` header to be parsed.
+    ///
+    /// Note that an empty `Content-Type` is also accepted, as the multipart specification defines
+    /// `text/plain` as the default for text fields.
+    pub fn validate_content_type(mut self, validate_content_type: bool) -> Self {
+        self.validate_content_type = validate_content_type;
+        self
+    }
+}
+
+const DEFAULT_CONFIG: TextConfig = TextConfig {
+    err_handler: None,
+    validate_content_type: true,
+};
+
+impl Default for TextConfig {
+    fn default() -> Self {
+        DEFAULT_CONFIG
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::io::Cursor;
+
+    use actix_multipart_rfc7578::client::multipart;
+    use actix_web::{http::StatusCode, web, App, HttpResponse, Responder};
+
+    use crate::form::{
+        tests::send_form,
+        text::{Text, TextConfig},
+        MultipartForm,
+    };
+
+    #[derive(MultipartForm)]
+    struct TextForm {
+        number: Text<i32>,
+    }
+
+    async fn test_text_route(form: MultipartForm<TextForm>) -> impl Responder {
+        assert_eq!(*form.number, 1025);
+        HttpResponse::Ok().finish()
+    }
+
+    #[actix_rt::test]
+    async fn test_content_type_validation() {
+        let srv = actix_test::start(|| {
+            App::new()
+                .route("/", web::post().to(test_text_route))
+                .app_data(TextConfig::default().validate_content_type(true))
+        });
+
+        // Deny because wrong content type
+        let bytes = Cursor::new("1025");
+        let mut form = multipart::Form::default();
+        form.add_reader_file_with_mime("number", bytes, "", mime::APPLICATION_OCTET_STREAM);
+        let response = send_form(&srv, form, "/").await;
+        assert_eq!(response.status(), StatusCode::BAD_REQUEST);
+
+        // Allow because correct content type
+        let bytes = Cursor::new("1025");
+        let mut form = multipart::Form::default();
+        form.add_reader_file_with_mime("number", bytes, "", mime::TEXT_PLAIN);
+        let response = send_form(&srv, form, "/").await;
+        assert_eq!(response.status(), StatusCode::OK);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_multipart/lib.rs.html b/src/actix_multipart/lib.rs.html new file mode 100644 index 000000000..4bccd07c3 --- /dev/null +++ b/src/actix_multipart/lib.rs.html @@ -0,0 +1,123 @@ +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
+
//! Multipart form support for Actix Web.
+//! # Examples
+//! ```no_run
+//! use actix_web::{post, App, HttpServer, Responder};
+//!
+//! use actix_multipart::form::{json::Json as MPJson, tempfile::TempFile, MultipartForm};
+//! use serde::Deserialize;
+//!
+//! #[derive(Debug, Deserialize)]
+//! struct Metadata {
+//!     name: String,
+//! }
+//!
+//! #[derive(Debug, MultipartForm)]
+//! struct UploadForm {
+//!     #[multipart(limit = "100MB")]
+//!     file: TempFile,
+//!     json: MPJson<Metadata>,
+//! }
+//!
+//! #[post("/videos")]
+//! pub async fn post_video(MultipartForm(form): MultipartForm<UploadForm>) -> impl Responder {
+//!     format!(
+//!         "Uploaded file {}, with size: {}",
+//!         form.json.name, form.file.size
+//!     )
+//! }
+//!
+//! #[actix_web::main]
+//! async fn main() -> std::io::Result<()> {
+//!     HttpServer::new(move || App::new().service(post_video))
+//!         .bind(("127.0.0.1", 8080))?
+//!         .run()
+//!         .await
+//! }
+//! ```
+
+#![deny(rust_2018_idioms, nonstandard_style)]
+#![warn(future_incompatible)]
+#![allow(clippy::borrow_interior_mutable_const)]
+#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
+#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+
+// This allows us to use the actix_multipart_derive within this crate's tests
+#[cfg(test)]
+extern crate self as actix_multipart;
+
+mod error;
+mod extractor;
+pub mod form;
+mod server;
+pub mod test;
+
+pub use self::{
+    error::MultipartError,
+    server::{Field, Multipart},
+    test::{
+        create_form_data_payload_and_headers, create_form_data_payload_and_headers_with_boundary,
+    },
+};
+
\ No newline at end of file diff --git a/src/actix_multipart/server.rs.html b/src/actix_multipart/server.rs.html new file mode 100644 index 000000000..86e40b82b --- /dev/null +++ b/src/actix_multipart/server.rs.html @@ -0,0 +1,2723 @@ +server.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
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+
//! Multipart response payload support.
+
+use std::{
+    cell::{Cell, RefCell, RefMut},
+    cmp, fmt,
+    marker::PhantomData,
+    pin::Pin,
+    rc::Rc,
+    task::{Context, Poll},
+};
+
+use actix_web::{
+    error::{ParseError, PayloadError},
+    http::header::{self, ContentDisposition, HeaderMap, HeaderName, HeaderValue},
+};
+use bytes::{Bytes, BytesMut};
+use futures_core::stream::{LocalBoxStream, Stream};
+use local_waker::LocalWaker;
+
+use crate::error::MultipartError;
+
+const MAX_HEADERS: usize = 32;
+
+/// The server-side implementation of `multipart/form-data` requests.
+///
+/// This will parse the incoming stream into `MultipartItem` instances via its
+/// Stream implementation.
+/// `MultipartItem::Field` contains multipart field. `MultipartItem::Multipart`
+/// is used for nested multipart streams.
+pub struct Multipart {
+    safety: Safety,
+    error: Option<MultipartError>,
+    inner: Option<InnerMultipart>,
+}
+
+enum InnerMultipartItem {
+    None,
+    Field(Rc<RefCell<InnerField>>),
+}
+
+#[derive(PartialEq, Debug)]
+enum InnerState {
+    /// Stream eof
+    Eof,
+
+    /// Skip data until first boundary
+    FirstBoundary,
+
+    /// Reading boundary
+    Boundary,
+
+    /// Reading Headers,
+    Headers,
+}
+
+struct InnerMultipart {
+    payload: PayloadRef,
+    boundary: String,
+    state: InnerState,
+    item: InnerMultipartItem,
+}
+
+impl Multipart {
+    /// Create multipart instance for boundary.
+    pub fn new<S>(headers: &HeaderMap, stream: S) -> Multipart
+    where
+        S: Stream<Item = Result<Bytes, PayloadError>> + 'static,
+    {
+        match Self::boundary(headers) {
+            Ok(boundary) => Multipart::from_boundary(boundary, stream),
+            Err(err) => Multipart::from_error(err),
+        }
+    }
+
+    /// Extract boundary info from headers.
+    pub(crate) fn boundary(headers: &HeaderMap) -> Result<String, MultipartError> {
+        headers
+            .get(&header::CONTENT_TYPE)
+            .ok_or(MultipartError::NoContentType)?
+            .to_str()
+            .ok()
+            .and_then(|content_type| content_type.parse::<mime::Mime>().ok())
+            .ok_or(MultipartError::ParseContentType)?
+            .get_param(mime::BOUNDARY)
+            .map(|boundary| boundary.as_str().to_owned())
+            .ok_or(MultipartError::Boundary)
+    }
+
+    /// Create multipart instance for given boundary and stream
+    pub(crate) fn from_boundary<S>(boundary: String, stream: S) -> Multipart
+    where
+        S: Stream<Item = Result<Bytes, PayloadError>> + 'static,
+    {
+        Multipart {
+            error: None,
+            safety: Safety::new(),
+            inner: Some(InnerMultipart {
+                boundary,
+                payload: PayloadRef::new(PayloadBuffer::new(stream)),
+                state: InnerState::FirstBoundary,
+                item: InnerMultipartItem::None,
+            }),
+        }
+    }
+
+    /// Create Multipart instance from MultipartError
+    pub(crate) fn from_error(err: MultipartError) -> Multipart {
+        Multipart {
+            error: Some(err),
+            safety: Safety::new(),
+            inner: None,
+        }
+    }
+}
+
+impl Stream for Multipart {
+    type Item = Result<Field, MultipartError>;
+
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        let this = self.get_mut();
+
+        match this.inner.as_mut() {
+            Some(inner) => {
+                if let Some(mut buffer) = inner.payload.get_mut(&this.safety) {
+                    // check safety and poll read payload to buffer.
+                    buffer.poll_stream(cx)?;
+                } else if !this.safety.is_clean() {
+                    // safety violation
+                    return Poll::Ready(Some(Err(MultipartError::NotConsumed)));
+                } else {
+                    return Poll::Pending;
+                }
+
+                inner.poll(&this.safety, cx)
+            }
+            None => Poll::Ready(Some(Err(this
+                .error
+                .take()
+                .expect("Multipart polled after finish")))),
+        }
+    }
+}
+
+impl InnerMultipart {
+    fn read_headers(payload: &mut PayloadBuffer) -> Result<Option<HeaderMap>, MultipartError> {
+        match payload.read_until(b"\r\n\r\n")? {
+            None => {
+                if payload.eof {
+                    Err(MultipartError::Incomplete)
+                } else {
+                    Ok(None)
+                }
+            }
+            Some(bytes) => {
+                let mut hdrs = [httparse::EMPTY_HEADER; MAX_HEADERS];
+                match httparse::parse_headers(&bytes, &mut hdrs) {
+                    Ok(httparse::Status::Complete((_, hdrs))) => {
+                        // convert headers
+                        let mut headers = HeaderMap::with_capacity(hdrs.len());
+
+                        for h in hdrs {
+                            let name =
+                                HeaderName::try_from(h.name).map_err(|_| ParseError::Header)?;
+                            let value =
+                                HeaderValue::try_from(h.value).map_err(|_| ParseError::Header)?;
+                            headers.append(name, value);
+                        }
+
+                        Ok(Some(headers))
+                    }
+                    Ok(httparse::Status::Partial) => Err(ParseError::Header.into()),
+                    Err(err) => Err(ParseError::from(err).into()),
+                }
+            }
+        }
+    }
+
+    fn read_boundary(
+        payload: &mut PayloadBuffer,
+        boundary: &str,
+    ) -> Result<Option<bool>, MultipartError> {
+        // TODO: need to read epilogue
+        match payload.readline_or_eof()? {
+            None => {
+                if payload.eof {
+                    Ok(Some(true))
+                } else {
+                    Ok(None)
+                }
+            }
+            Some(chunk) => {
+                if chunk.len() < boundary.len() + 4
+                    || &chunk[..2] != b"--"
+                    || &chunk[2..boundary.len() + 2] != boundary.as_bytes()
+                {
+                    Err(MultipartError::Boundary)
+                } else if &chunk[boundary.len() + 2..] == b"\r\n" {
+                    Ok(Some(false))
+                } else if &chunk[boundary.len() + 2..boundary.len() + 4] == b"--"
+                    && (chunk.len() == boundary.len() + 4
+                        || &chunk[boundary.len() + 4..] == b"\r\n")
+                {
+                    Ok(Some(true))
+                } else {
+                    Err(MultipartError::Boundary)
+                }
+            }
+        }
+    }
+
+    fn skip_until_boundary(
+        payload: &mut PayloadBuffer,
+        boundary: &str,
+    ) -> Result<Option<bool>, MultipartError> {
+        let mut eof = false;
+        loop {
+            match payload.readline()? {
+                Some(chunk) => {
+                    if chunk.is_empty() {
+                        return Err(MultipartError::Boundary);
+                    }
+                    if chunk.len() < boundary.len() {
+                        continue;
+                    }
+                    if &chunk[..2] == b"--" && &chunk[2..chunk.len() - 2] == boundary.as_bytes() {
+                        break;
+                    } else {
+                        if chunk.len() < boundary.len() + 2 {
+                            continue;
+                        }
+                        let b: &[u8] = boundary.as_ref();
+                        if &chunk[..boundary.len()] == b
+                            && &chunk[boundary.len()..boundary.len() + 2] == b"--"
+                        {
+                            eof = true;
+                            break;
+                        }
+                    }
+                }
+                None => {
+                    return if payload.eof {
+                        Err(MultipartError::Incomplete)
+                    } else {
+                        Ok(None)
+                    };
+                }
+            }
+        }
+        Ok(Some(eof))
+    }
+
+    fn poll(
+        &mut self,
+        safety: &Safety,
+        cx: &Context<'_>,
+    ) -> Poll<Option<Result<Field, MultipartError>>> {
+        if self.state == InnerState::Eof {
+            Poll::Ready(None)
+        } else {
+            // release field
+            loop {
+                // Nested multipart streams of fields has to be consumed
+                // before switching to next
+                if safety.current() {
+                    let stop = match self.item {
+                        InnerMultipartItem::Field(ref mut field) => {
+                            match field.borrow_mut().poll(safety) {
+                                Poll::Pending => return Poll::Pending,
+                                Poll::Ready(Some(Ok(_))) => continue,
+                                Poll::Ready(Some(Err(err))) => return Poll::Ready(Some(Err(err))),
+                                Poll::Ready(None) => true,
+                            }
+                        }
+                        InnerMultipartItem::None => false,
+                    };
+                    if stop {
+                        self.item = InnerMultipartItem::None;
+                    }
+                    if let InnerMultipartItem::None = self.item {
+                        break;
+                    }
+                }
+            }
+
+            let headers = if let Some(mut payload) = self.payload.get_mut(safety) {
+                match self.state {
+                    // read until first boundary
+                    InnerState::FirstBoundary => {
+                        match InnerMultipart::skip_until_boundary(&mut payload, &self.boundary)? {
+                            Some(eof) => {
+                                if eof {
+                                    self.state = InnerState::Eof;
+                                    return Poll::Ready(None);
+                                } else {
+                                    self.state = InnerState::Headers;
+                                }
+                            }
+                            None => return Poll::Pending,
+                        }
+                    }
+                    // read boundary
+                    InnerState::Boundary => {
+                        match InnerMultipart::read_boundary(&mut payload, &self.boundary)? {
+                            None => return Poll::Pending,
+                            Some(eof) => {
+                                if eof {
+                                    self.state = InnerState::Eof;
+                                    return Poll::Ready(None);
+                                } else {
+                                    self.state = InnerState::Headers;
+                                }
+                            }
+                        }
+                    }
+                    _ => {}
+                }
+
+                // read field headers for next field
+                if self.state == InnerState::Headers {
+                    if let Some(headers) = InnerMultipart::read_headers(&mut payload)? {
+                        self.state = InnerState::Boundary;
+                        headers
+                    } else {
+                        return Poll::Pending;
+                    }
+                } else {
+                    unreachable!()
+                }
+            } else {
+                log::debug!("NotReady: field is in flight");
+                return Poll::Pending;
+            };
+
+            // According to RFC 7578 §4.2, a Content-Disposition header must always be present and
+            // set to "form-data".
+
+            let content_disposition = headers
+                .get(&header::CONTENT_DISPOSITION)
+                .and_then(|cd| ContentDisposition::from_raw(cd).ok())
+                .filter(|content_disposition| {
+                    let is_form_data =
+                        content_disposition.disposition == header::DispositionType::FormData;
+
+                    let has_field_name = content_disposition
+                        .parameters
+                        .iter()
+                        .any(|param| matches!(param, header::DispositionParam::Name(_)));
+
+                    is_form_data && has_field_name
+                });
+
+            let cd = if let Some(content_disposition) = content_disposition {
+                content_disposition
+            } else {
+                return Poll::Ready(Some(Err(MultipartError::NoContentDisposition)));
+            };
+
+            let ct: Option<mime::Mime> = headers
+                .get(&header::CONTENT_TYPE)
+                .and_then(|ct| ct.to_str().ok())
+                .and_then(|ct| ct.parse().ok());
+
+            self.state = InnerState::Boundary;
+
+            // nested multipart stream is not supported
+            if let Some(mime) = &ct {
+                if mime.type_() == mime::MULTIPART {
+                    return Poll::Ready(Some(Err(MultipartError::Nested)));
+                }
+            }
+
+            let field =
+                InnerField::new_in_rc(self.payload.clone(), self.boundary.clone(), &headers)?;
+
+            self.item = InnerMultipartItem::Field(Rc::clone(&field));
+
+            Poll::Ready(Some(Ok(Field::new(
+                safety.clone(cx),
+                headers,
+                ct,
+                cd,
+                field,
+            ))))
+        }
+    }
+}
+
+impl Drop for InnerMultipart {
+    fn drop(&mut self) {
+        // InnerMultipartItem::Field has to be dropped first because of Safety.
+        self.item = InnerMultipartItem::None;
+    }
+}
+
+/// A single field in a multipart stream
+pub struct Field {
+    ct: Option<mime::Mime>,
+    cd: ContentDisposition,
+    headers: HeaderMap,
+    inner: Rc<RefCell<InnerField>>,
+    safety: Safety,
+}
+
+impl Field {
+    fn new(
+        safety: Safety,
+        headers: HeaderMap,
+        ct: Option<mime::Mime>,
+        cd: ContentDisposition,
+        inner: Rc<RefCell<InnerField>>,
+    ) -> Self {
+        Field {
+            ct,
+            cd,
+            headers,
+            inner,
+            safety,
+        }
+    }
+
+    /// Returns a reference to the field's header map.
+    pub fn headers(&self) -> &HeaderMap {
+        &self.headers
+    }
+
+    /// Returns a reference to the field's content (mime) type, if it is supplied by the client.
+    ///
+    /// According to [RFC 7578](https://www.rfc-editor.org/rfc/rfc7578#section-4.4), if it is not
+    /// present, it should default to "text/plain". Note it is the responsibility of the client to
+    /// provide the appropriate content type, there is no attempt to validate this by the server.
+    pub fn content_type(&self) -> Option<&mime::Mime> {
+        self.ct.as_ref()
+    }
+
+    /// Returns the field's Content-Disposition.
+    ///
+    /// Per [RFC 7578 §4.2]: "Each part MUST contain a Content-Disposition header field where the
+    /// disposition type is `form-data`. The Content-Disposition header field MUST also contain an
+    /// additional parameter of `name`; the value of the `name` parameter is the original field name
+    /// from the form."
+    ///
+    /// This crate validates that it exists before returning a `Field`. As such, it is safe to
+    /// unwrap `.content_disposition().get_name()`. The [name](Self::name) method is provided as
+    /// a convenience.
+    ///
+    /// [RFC 7578 §4.2]: https://datatracker.ietf.org/doc/html/rfc7578#section-4.2
+    pub fn content_disposition(&self) -> &ContentDisposition {
+        &self.cd
+    }
+
+    /// Returns the field's name.
+    ///
+    /// See [content_disposition](Self::content_disposition) regarding guarantees about existence of
+    /// the name field.
+    pub fn name(&self) -> &str {
+        self.content_disposition()
+            .get_name()
+            .expect("field name should be guaranteed to exist in multipart form-data")
+    }
+}
+
+impl Stream for Field {
+    type Item = Result<Bytes, MultipartError>;
+
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        let this = self.get_mut();
+        let mut inner = this.inner.borrow_mut();
+        if let Some(mut buffer) = inner.payload.as_ref().unwrap().get_mut(&this.safety) {
+            // check safety and poll read payload to buffer.
+            buffer.poll_stream(cx)?;
+        } else if !this.safety.is_clean() {
+            // safety violation
+            return Poll::Ready(Some(Err(MultipartError::NotConsumed)));
+        } else {
+            return Poll::Pending;
+        }
+
+        inner.poll(&this.safety)
+    }
+}
+
+impl fmt::Debug for Field {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        if let Some(ct) = &self.ct {
+            writeln!(f, "\nField: {}", ct)?;
+        } else {
+            writeln!(f, "\nField:")?;
+        }
+        writeln!(f, "  boundary: {}", self.inner.borrow().boundary)?;
+        writeln!(f, "  headers:")?;
+        for (key, val) in self.headers.iter() {
+            writeln!(f, "    {:?}: {:?}", key, val)?;
+        }
+        Ok(())
+    }
+}
+
+struct InnerField {
+    payload: Option<PayloadRef>,
+    boundary: String,
+    eof: bool,
+    length: Option<u64>,
+}
+
+impl InnerField {
+    fn new_in_rc(
+        payload: PayloadRef,
+        boundary: String,
+        headers: &HeaderMap,
+    ) -> Result<Rc<RefCell<InnerField>>, PayloadError> {
+        Self::new(payload, boundary, headers).map(|this| Rc::new(RefCell::new(this)))
+    }
+
+    fn new(
+        payload: PayloadRef,
+        boundary: String,
+        headers: &HeaderMap,
+    ) -> Result<InnerField, PayloadError> {
+        let len = if let Some(len) = headers.get(&header::CONTENT_LENGTH) {
+            match len.to_str().ok().and_then(|len| len.parse::<u64>().ok()) {
+                Some(len) => Some(len),
+                None => return Err(PayloadError::Incomplete(None)),
+            }
+        } else {
+            None
+        };
+
+        Ok(InnerField {
+            boundary,
+            payload: Some(payload),
+            eof: false,
+            length: len,
+        })
+    }
+
+    /// Reads body part content chunk of the specified size.
+    /// The body part must has `Content-Length` header with proper value.
+    fn read_len(
+        payload: &mut PayloadBuffer,
+        size: &mut u64,
+    ) -> Poll<Option<Result<Bytes, MultipartError>>> {
+        if *size == 0 {
+            Poll::Ready(None)
+        } else {
+            match payload.read_max(*size)? {
+                Some(mut chunk) => {
+                    let len = cmp::min(chunk.len() as u64, *size);
+                    *size -= len;
+                    let ch = chunk.split_to(len as usize);
+                    if !chunk.is_empty() {
+                        payload.unprocessed(chunk);
+                    }
+                    Poll::Ready(Some(Ok(ch)))
+                }
+                None => {
+                    if payload.eof && (*size != 0) {
+                        Poll::Ready(Some(Err(MultipartError::Incomplete)))
+                    } else {
+                        Poll::Pending
+                    }
+                }
+            }
+        }
+    }
+
+    /// Reads content chunk of body part with unknown length.
+    /// The `Content-Length` header for body part is not necessary.
+    fn read_stream(
+        payload: &mut PayloadBuffer,
+        boundary: &str,
+    ) -> Poll<Option<Result<Bytes, MultipartError>>> {
+        let mut pos = 0;
+
+        let len = payload.buf.len();
+        if len == 0 {
+            return if payload.eof {
+                Poll::Ready(Some(Err(MultipartError::Incomplete)))
+            } else {
+                Poll::Pending
+            };
+        }
+
+        // check boundary
+        if len > 4 && payload.buf[0] == b'\r' {
+            let b_len = if &payload.buf[..2] == b"\r\n" && &payload.buf[2..4] == b"--" {
+                Some(4)
+            } else if &payload.buf[1..3] == b"--" {
+                Some(3)
+            } else {
+                None
+            };
+
+            if let Some(b_len) = b_len {
+                let b_size = boundary.len() + b_len;
+                if len < b_size {
+                    return Poll::Pending;
+                } else if &payload.buf[b_len..b_size] == boundary.as_bytes() {
+                    // found boundary
+                    return Poll::Ready(None);
+                }
+            }
+        }
+
+        loop {
+            return if let Some(idx) = memchr::memmem::find(&payload.buf[pos..], b"\r") {
+                let cur = pos + idx;
+
+                // check if we have enough data for boundary detection
+                if cur + 4 > len {
+                    if cur > 0 {
+                        Poll::Ready(Some(Ok(payload.buf.split_to(cur).freeze())))
+                    } else {
+                        Poll::Pending
+                    }
+                } else {
+                    // check boundary
+                    if (&payload.buf[cur..cur + 2] == b"\r\n"
+                        && &payload.buf[cur + 2..cur + 4] == b"--")
+                        || (&payload.buf[cur..=cur] == b"\r"
+                            && &payload.buf[cur + 1..cur + 3] == b"--")
+                    {
+                        if cur != 0 {
+                            // return buffer
+                            Poll::Ready(Some(Ok(payload.buf.split_to(cur).freeze())))
+                        } else {
+                            pos = cur + 1;
+                            continue;
+                        }
+                    } else {
+                        // not boundary
+                        pos = cur + 1;
+                        continue;
+                    }
+                }
+            } else {
+                Poll::Ready(Some(Ok(payload.buf.split().freeze())))
+            };
+        }
+    }
+
+    fn poll(&mut self, s: &Safety) -> Poll<Option<Result<Bytes, MultipartError>>> {
+        if self.payload.is_none() {
+            return Poll::Ready(None);
+        }
+
+        let result = if let Some(mut payload) = self.payload.as_ref().unwrap().get_mut(s) {
+            if !self.eof {
+                let res = if let Some(ref mut len) = self.length {
+                    InnerField::read_len(&mut payload, len)
+                } else {
+                    InnerField::read_stream(&mut payload, &self.boundary)
+                };
+
+                match res {
+                    Poll::Pending => return Poll::Pending,
+                    Poll::Ready(Some(Ok(bytes))) => return Poll::Ready(Some(Ok(bytes))),
+                    Poll::Ready(Some(Err(err))) => return Poll::Ready(Some(Err(err))),
+                    Poll::Ready(None) => self.eof = true,
+                }
+            }
+
+            match payload.readline() {
+                Ok(None) => Poll::Pending,
+                Ok(Some(line)) => {
+                    if line.as_ref() != b"\r\n" {
+                        log::warn!("multipart field did not read all the data or it is malformed");
+                    }
+                    Poll::Ready(None)
+                }
+                Err(err) => Poll::Ready(Some(Err(err))),
+            }
+        } else {
+            Poll::Pending
+        };
+
+        if let Poll::Ready(None) = result {
+            self.payload.take();
+        }
+        result
+    }
+}
+
+struct PayloadRef {
+    payload: Rc<RefCell<PayloadBuffer>>,
+}
+
+impl PayloadRef {
+    fn new(payload: PayloadBuffer) -> PayloadRef {
+        PayloadRef {
+            payload: Rc::new(payload.into()),
+        }
+    }
+
+    fn get_mut(&self, s: &Safety) -> Option<RefMut<'_, PayloadBuffer>> {
+        if s.current() {
+            Some(self.payload.borrow_mut())
+        } else {
+            None
+        }
+    }
+}
+
+impl Clone for PayloadRef {
+    fn clone(&self) -> PayloadRef {
+        PayloadRef {
+            payload: Rc::clone(&self.payload),
+        }
+    }
+}
+
+/// Counter. It tracks of number of clones of payloads and give access to payload only to top most.
+/// * When dropped, parent task is awakened. This is to support the case where Field is
+/// dropped in a separate task than Multipart.
+/// * Assumes that parent owners don't move to different tasks; only the top-most is allowed to.
+/// * If dropped and is not top most owner, is_clean flag is set to false.
+#[derive(Debug)]
+struct Safety {
+    task: LocalWaker,
+    level: usize,
+    payload: Rc<PhantomData<bool>>,
+    clean: Rc<Cell<bool>>,
+}
+
+impl Safety {
+    fn new() -> Safety {
+        let payload = Rc::new(PhantomData);
+        Safety {
+            task: LocalWaker::new(),
+            level: Rc::strong_count(&payload),
+            clean: Rc::new(Cell::new(true)),
+            payload,
+        }
+    }
+
+    fn current(&self) -> bool {
+        Rc::strong_count(&self.payload) == self.level && self.clean.get()
+    }
+
+    fn is_clean(&self) -> bool {
+        self.clean.get()
+    }
+
+    fn clone(&self, cx: &Context<'_>) -> Safety {
+        let payload = Rc::clone(&self.payload);
+        let s = Safety {
+            task: LocalWaker::new(),
+            level: Rc::strong_count(&payload),
+            clean: self.clean.clone(),
+            payload,
+        };
+        s.task.register(cx.waker());
+        s
+    }
+}
+
+impl Drop for Safety {
+    fn drop(&mut self) {
+        if Rc::strong_count(&self.payload) != self.level {
+            // Multipart dropped leaving a Field
+            self.clean.set(false);
+        }
+
+        self.task.wake();
+    }
+}
+
+/// Payload buffer.
+struct PayloadBuffer {
+    eof: bool,
+    buf: BytesMut,
+    stream: LocalBoxStream<'static, Result<Bytes, PayloadError>>,
+}
+
+impl PayloadBuffer {
+    /// Constructs new `PayloadBuffer` instance.
+    fn new<S>(stream: S) -> Self
+    where
+        S: Stream<Item = Result<Bytes, PayloadError>> + 'static,
+    {
+        PayloadBuffer {
+            eof: false,
+            buf: BytesMut::new(),
+            stream: Box::pin(stream),
+        }
+    }
+
+    fn poll_stream(&mut self, cx: &mut Context<'_>) -> Result<(), PayloadError> {
+        loop {
+            match Pin::new(&mut self.stream).poll_next(cx) {
+                Poll::Ready(Some(Ok(data))) => self.buf.extend_from_slice(&data),
+                Poll::Ready(Some(Err(err))) => return Err(err),
+                Poll::Ready(None) => {
+                    self.eof = true;
+                    return Ok(());
+                }
+                Poll::Pending => return Ok(()),
+            }
+        }
+    }
+
+    /// Read exact number of bytes
+    #[cfg(test)]
+    fn read_exact(&mut self, size: usize) -> Option<Bytes> {
+        if size <= self.buf.len() {
+            Some(self.buf.split_to(size).freeze())
+        } else {
+            None
+        }
+    }
+
+    fn read_max(&mut self, size: u64) -> Result<Option<Bytes>, MultipartError> {
+        if !self.buf.is_empty() {
+            let size = std::cmp::min(self.buf.len() as u64, size) as usize;
+            Ok(Some(self.buf.split_to(size).freeze()))
+        } else if self.eof {
+            Err(MultipartError::Incomplete)
+        } else {
+            Ok(None)
+        }
+    }
+
+    /// Read until specified ending
+    fn read_until(&mut self, line: &[u8]) -> Result<Option<Bytes>, MultipartError> {
+        let res = memchr::memmem::find(&self.buf, line)
+            .map(|idx| self.buf.split_to(idx + line.len()).freeze());
+
+        if res.is_none() && self.eof {
+            Err(MultipartError::Incomplete)
+        } else {
+            Ok(res)
+        }
+    }
+
+    /// Read bytes until new line delimiter
+    fn readline(&mut self) -> Result<Option<Bytes>, MultipartError> {
+        self.read_until(b"\n")
+    }
+
+    /// Read bytes until new line delimiter or eof
+    fn readline_or_eof(&mut self) -> Result<Option<Bytes>, MultipartError> {
+        match self.readline() {
+            Err(MultipartError::Incomplete) if self.eof => Ok(Some(self.buf.split().freeze())),
+            line => line,
+        }
+    }
+
+    /// Put unprocessed data back to the buffer
+    fn unprocessed(&mut self, data: Bytes) {
+        let buf = BytesMut::from(data.as_ref());
+        let buf = std::mem::replace(&mut self.buf, buf);
+        self.buf.extend_from_slice(&buf);
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::time::Duration;
+
+    use actix_http::h1;
+    use actix_web::{
+        http::header::{DispositionParam, DispositionType},
+        rt,
+        test::TestRequest,
+        FromRequest,
+    };
+    use bytes::BufMut as _;
+    use futures_util::{future::lazy, StreamExt as _};
+    use tokio::sync::mpsc;
+    use tokio_stream::wrappers::UnboundedReceiverStream;
+
+    use super::*;
+
+    const BOUNDARY: &str = "abbc761f78ff4d7cb7573b5a23f96ef0";
+
+    #[actix_rt::test]
+    async fn test_boundary() {
+        let headers = HeaderMap::new();
+        match Multipart::boundary(&headers) {
+            Err(MultipartError::NoContentType) => {}
+            _ => unreachable!("should not happen"),
+        }
+
+        let mut headers = HeaderMap::new();
+        headers.insert(
+            header::CONTENT_TYPE,
+            header::HeaderValue::from_static("test"),
+        );
+
+        match Multipart::boundary(&headers) {
+            Err(MultipartError::ParseContentType) => {}
+            _ => unreachable!("should not happen"),
+        }
+
+        let mut headers = HeaderMap::new();
+        headers.insert(
+            header::CONTENT_TYPE,
+            header::HeaderValue::from_static("multipart/mixed"),
+        );
+        match Multipart::boundary(&headers) {
+            Err(MultipartError::Boundary) => {}
+            _ => unreachable!("should not happen"),
+        }
+
+        let mut headers = HeaderMap::new();
+        headers.insert(
+            header::CONTENT_TYPE,
+            header::HeaderValue::from_static(
+                "multipart/mixed; boundary=\"5c02368e880e436dab70ed54e1c58209\"",
+            ),
+        );
+
+        assert_eq!(
+            Multipart::boundary(&headers).unwrap(),
+            "5c02368e880e436dab70ed54e1c58209"
+        );
+    }
+
+    fn create_stream() -> (
+        mpsc::UnboundedSender<Result<Bytes, PayloadError>>,
+        impl Stream<Item = Result<Bytes, PayloadError>>,
+    ) {
+        let (tx, rx) = mpsc::unbounded_channel();
+
+        (
+            tx,
+            UnboundedReceiverStream::new(rx).map(|res| res.map_err(|_| panic!())),
+        )
+    }
+
+    // Stream that returns from a Bytes, one char at a time and Pending every other poll()
+    struct SlowStream {
+        bytes: Bytes,
+        pos: usize,
+        ready: bool,
+    }
+
+    impl SlowStream {
+        fn new(bytes: Bytes) -> SlowStream {
+            SlowStream {
+                bytes,
+                pos: 0,
+                ready: false,
+            }
+        }
+    }
+
+    impl Stream for SlowStream {
+        type Item = Result<Bytes, PayloadError>;
+
+        fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+            let this = self.get_mut();
+            if !this.ready {
+                this.ready = true;
+                cx.waker().wake_by_ref();
+                return Poll::Pending;
+            }
+
+            if this.pos == this.bytes.len() {
+                return Poll::Ready(None);
+            }
+
+            let res = Poll::Ready(Some(Ok(this.bytes.slice(this.pos..(this.pos + 1)))));
+            this.pos += 1;
+            this.ready = false;
+            res
+        }
+    }
+
+    fn create_simple_request_with_header() -> (Bytes, HeaderMap) {
+        let (body, headers) = crate::test::create_form_data_payload_and_headers_with_boundary(
+            BOUNDARY,
+            "file",
+            Some("fn.txt".to_owned()),
+            Some(mime::TEXT_PLAIN_UTF_8),
+            Bytes::from_static(b"data"),
+        );
+
+        let mut buf = BytesMut::with_capacity(body.len() + 14);
+
+        // add junk before form to test pre-boundary data rejection
+        buf.put("testasdadsad\r\n".as_bytes());
+
+        buf.put(body);
+
+        (buf.freeze(), headers)
+    }
+
+    // TODO: use test utility when multi-file support is introduced
+    fn create_double_request_with_header() -> (Bytes, HeaderMap) {
+        let bytes = Bytes::from(
+            "testasdadsad\r\n\
+             --abbc761f78ff4d7cb7573b5a23f96ef0\r\n\
+             Content-Disposition: form-data; name=\"file\"; filename=\"fn.txt\"\r\n\
+             Content-Type: text/plain; charset=utf-8\r\nContent-Length: 4\r\n\r\n\
+             test\r\n\
+             --abbc761f78ff4d7cb7573b5a23f96ef0\r\n\
+             Content-Disposition: form-data; name=\"file\"; filename=\"fn.txt\"\r\n\
+             Content-Type: text/plain; charset=utf-8\r\nContent-Length: 4\r\n\r\n\
+             data\r\n\
+             --abbc761f78ff4d7cb7573b5a23f96ef0--\r\n",
+        );
+        let mut headers = HeaderMap::new();
+        headers.insert(
+            header::CONTENT_TYPE,
+            header::HeaderValue::from_static(
+                "multipart/mixed; boundary=\"abbc761f78ff4d7cb7573b5a23f96ef0\"",
+            ),
+        );
+        (bytes, headers)
+    }
+
+    #[actix_rt::test]
+    async fn test_multipart_no_end_crlf() {
+        let (sender, payload) = create_stream();
+        let (mut bytes, headers) = create_double_request_with_header();
+        let bytes_stripped = bytes.split_to(bytes.len()); // strip crlf
+
+        sender.send(Ok(bytes_stripped)).unwrap();
+        drop(sender); // eof
+
+        let mut multipart = Multipart::new(&headers, payload);
+
+        match multipart.next().await.unwrap() {
+            Ok(_) => {}
+            _ => unreachable!(),
+        }
+
+        match multipart.next().await.unwrap() {
+            Ok(_) => {}
+            _ => unreachable!(),
+        }
+
+        match multipart.next().await {
+            None => {}
+            _ => unreachable!(),
+        }
+    }
+
+    #[actix_rt::test]
+    async fn test_multipart() {
+        let (sender, payload) = create_stream();
+        let (bytes, headers) = create_double_request_with_header();
+
+        sender.send(Ok(bytes)).unwrap();
+
+        let mut multipart = Multipart::new(&headers, payload);
+        match multipart.next().await {
+            Some(Ok(mut field)) => {
+                let cd = field.content_disposition();
+                assert_eq!(cd.disposition, DispositionType::FormData);
+                assert_eq!(cd.parameters[0], DispositionParam::Name("file".into()));
+
+                assert_eq!(field.content_type().unwrap().type_(), mime::TEXT);
+                assert_eq!(field.content_type().unwrap().subtype(), mime::PLAIN);
+
+                match field.next().await.unwrap() {
+                    Ok(chunk) => assert_eq!(chunk, "test"),
+                    _ => unreachable!(),
+                }
+                match field.next().await {
+                    None => {}
+                    _ => unreachable!(),
+                }
+            }
+            _ => unreachable!(),
+        }
+
+        match multipart.next().await.unwrap() {
+            Ok(mut field) => {
+                assert_eq!(field.content_type().unwrap().type_(), mime::TEXT);
+                assert_eq!(field.content_type().unwrap().subtype(), mime::PLAIN);
+
+                match field.next().await {
+                    Some(Ok(chunk)) => assert_eq!(chunk, "data"),
+                    _ => unreachable!(),
+                }
+                match field.next().await {
+                    None => {}
+                    _ => unreachable!(),
+                }
+            }
+            _ => unreachable!(),
+        }
+
+        match multipart.next().await {
+            None => {}
+            _ => unreachable!(),
+        }
+    }
+
+    // Loops, collecting all bytes until end-of-field
+    async fn get_whole_field(field: &mut Field) -> BytesMut {
+        let mut b = BytesMut::new();
+        loop {
+            match field.next().await {
+                Some(Ok(chunk)) => b.extend_from_slice(&chunk),
+                None => return b,
+                _ => unreachable!(),
+            }
+        }
+    }
+
+    #[actix_rt::test]
+    async fn test_stream() {
+        let (bytes, headers) = create_double_request_with_header();
+        let payload = SlowStream::new(bytes);
+
+        let mut multipart = Multipart::new(&headers, payload);
+        match multipart.next().await.unwrap() {
+            Ok(mut field) => {
+                let cd = field.content_disposition();
+                assert_eq!(cd.disposition, DispositionType::FormData);
+                assert_eq!(cd.parameters[0], DispositionParam::Name("file".into()));
+
+                assert_eq!(field.content_type().unwrap().type_(), mime::TEXT);
+                assert_eq!(field.content_type().unwrap().subtype(), mime::PLAIN);
+
+                assert_eq!(get_whole_field(&mut field).await, "test");
+            }
+            _ => unreachable!(),
+        }
+
+        match multipart.next().await {
+            Some(Ok(mut field)) => {
+                assert_eq!(field.content_type().unwrap().type_(), mime::TEXT);
+                assert_eq!(field.content_type().unwrap().subtype(), mime::PLAIN);
+
+                assert_eq!(get_whole_field(&mut field).await, "data");
+            }
+            _ => unreachable!(),
+        }
+
+        match multipart.next().await {
+            None => {}
+            _ => unreachable!(),
+        }
+    }
+
+    #[actix_rt::test]
+    async fn test_basic() {
+        let (_, payload) = h1::Payload::create(false);
+        let mut payload = PayloadBuffer::new(payload);
+
+        assert_eq!(payload.buf.len(), 0);
+        lazy(|cx| payload.poll_stream(cx)).await.unwrap();
+        assert_eq!(None, payload.read_max(1).unwrap());
+    }
+
+    #[actix_rt::test]
+    async fn test_eof() {
+        let (mut sender, payload) = h1::Payload::create(false);
+        let mut payload = PayloadBuffer::new(payload);
+
+        assert_eq!(None, payload.read_max(4).unwrap());
+        sender.feed_data(Bytes::from("data"));
+        sender.feed_eof();
+        lazy(|cx| payload.poll_stream(cx)).await.unwrap();
+
+        assert_eq!(Some(Bytes::from("data")), payload.read_max(4).unwrap());
+        assert_eq!(payload.buf.len(), 0);
+        assert!(payload.read_max(1).is_err());
+        assert!(payload.eof);
+    }
+
+    #[actix_rt::test]
+    async fn test_err() {
+        let (mut sender, payload) = h1::Payload::create(false);
+        let mut payload = PayloadBuffer::new(payload);
+        assert_eq!(None, payload.read_max(1).unwrap());
+        sender.set_error(PayloadError::Incomplete(None));
+        lazy(|cx| payload.poll_stream(cx)).await.err().unwrap();
+    }
+
+    #[actix_rt::test]
+    async fn test_readmax() {
+        let (mut sender, payload) = h1::Payload::create(false);
+        let mut payload = PayloadBuffer::new(payload);
+
+        sender.feed_data(Bytes::from("line1"));
+        sender.feed_data(Bytes::from("line2"));
+        lazy(|cx| payload.poll_stream(cx)).await.unwrap();
+        assert_eq!(payload.buf.len(), 10);
+
+        assert_eq!(Some(Bytes::from("line1")), payload.read_max(5).unwrap());
+        assert_eq!(payload.buf.len(), 5);
+
+        assert_eq!(Some(Bytes::from("line2")), payload.read_max(5).unwrap());
+        assert_eq!(payload.buf.len(), 0);
+    }
+
+    #[actix_rt::test]
+    async fn test_readexactly() {
+        let (mut sender, payload) = h1::Payload::create(false);
+        let mut payload = PayloadBuffer::new(payload);
+
+        assert_eq!(None, payload.read_exact(2));
+
+        sender.feed_data(Bytes::from("line1"));
+        sender.feed_data(Bytes::from("line2"));
+        lazy(|cx| payload.poll_stream(cx)).await.unwrap();
+
+        assert_eq!(Some(Bytes::from_static(b"li")), payload.read_exact(2));
+        assert_eq!(payload.buf.len(), 8);
+
+        assert_eq!(Some(Bytes::from_static(b"ne1l")), payload.read_exact(4));
+        assert_eq!(payload.buf.len(), 4);
+    }
+
+    #[actix_rt::test]
+    async fn test_readuntil() {
+        let (mut sender, payload) = h1::Payload::create(false);
+        let mut payload = PayloadBuffer::new(payload);
+
+        assert_eq!(None, payload.read_until(b"ne").unwrap());
+
+        sender.feed_data(Bytes::from("line1"));
+        sender.feed_data(Bytes::from("line2"));
+        lazy(|cx| payload.poll_stream(cx)).await.unwrap();
+
+        assert_eq!(
+            Some(Bytes::from("line")),
+            payload.read_until(b"ne").unwrap()
+        );
+        assert_eq!(payload.buf.len(), 6);
+
+        assert_eq!(
+            Some(Bytes::from("1line2")),
+            payload.read_until(b"2").unwrap()
+        );
+        assert_eq!(payload.buf.len(), 0);
+    }
+
+    #[actix_rt::test]
+    async fn test_multipart_from_error() {
+        let err = MultipartError::NoContentType;
+        let mut multipart = Multipart::from_error(err);
+        assert!(multipart.next().await.unwrap().is_err())
+    }
+
+    #[actix_rt::test]
+    async fn test_multipart_from_boundary() {
+        let (_, payload) = create_stream();
+        let (_, headers) = create_simple_request_with_header();
+        let boundary = Multipart::boundary(&headers);
+        assert!(boundary.is_ok());
+        let _ = Multipart::from_boundary(boundary.unwrap(), payload);
+    }
+
+    #[actix_rt::test]
+    async fn test_multipart_payload_consumption() {
+        // with sample payload and HttpRequest with no headers
+        let (_, inner_payload) = h1::Payload::create(false);
+        let mut payload = actix_web::dev::Payload::from(inner_payload);
+        let req = TestRequest::default().to_http_request();
+
+        // multipart should generate an error
+        let mut mp = Multipart::from_request(&req, &mut payload).await.unwrap();
+        assert!(mp.next().await.unwrap().is_err());
+
+        // and should not consume the payload
+        match payload {
+            actix_web::dev::Payload::H1 { .. } => {} //expected
+            _ => unreachable!(),
+        }
+    }
+
+    #[actix_rt::test]
+    async fn no_content_disposition() {
+        let bytes = Bytes::from(
+            "testasdadsad\r\n\
+             --abbc761f78ff4d7cb7573b5a23f96ef0\r\n\
+             Content-Type: text/plain; charset=utf-8\r\nContent-Length: 4\r\n\r\n\
+             test\r\n\
+             --abbc761f78ff4d7cb7573b5a23f96ef0\r\n",
+        );
+        let mut headers = HeaderMap::new();
+        headers.insert(
+            header::CONTENT_TYPE,
+            header::HeaderValue::from_static(
+                "multipart/mixed; boundary=\"abbc761f78ff4d7cb7573b5a23f96ef0\"",
+            ),
+        );
+        let payload = SlowStream::new(bytes);
+
+        let mut multipart = Multipart::new(&headers, payload);
+        let res = multipart.next().await.unwrap();
+        assert!(res.is_err());
+        assert!(matches!(
+            res.unwrap_err(),
+            MultipartError::NoContentDisposition,
+        ));
+    }
+
+    #[actix_rt::test]
+    async fn no_name_in_content_disposition() {
+        let bytes = Bytes::from(
+            "testasdadsad\r\n\
+             --abbc761f78ff4d7cb7573b5a23f96ef0\r\n\
+             Content-Disposition: form-data; filename=\"fn.txt\"\r\n\
+             Content-Type: text/plain; charset=utf-8\r\nContent-Length: 4\r\n\r\n\
+             test\r\n\
+             --abbc761f78ff4d7cb7573b5a23f96ef0\r\n",
+        );
+        let mut headers = HeaderMap::new();
+        headers.insert(
+            header::CONTENT_TYPE,
+            header::HeaderValue::from_static(
+                "multipart/mixed; boundary=\"abbc761f78ff4d7cb7573b5a23f96ef0\"",
+            ),
+        );
+        let payload = SlowStream::new(bytes);
+
+        let mut multipart = Multipart::new(&headers, payload);
+        let res = multipart.next().await.unwrap();
+        assert!(res.is_err());
+        assert!(matches!(
+            res.unwrap_err(),
+            MultipartError::NoContentDisposition,
+        ));
+    }
+
+    #[actix_rt::test]
+    async fn test_drop_multipart_dont_hang() {
+        let (sender, payload) = create_stream();
+        let (bytes, headers) = create_simple_request_with_header();
+        sender.send(Ok(bytes)).unwrap();
+        drop(sender); // eof
+
+        let mut multipart = Multipart::new(&headers, payload);
+        let mut field = multipart.next().await.unwrap().unwrap();
+
+        drop(multipart);
+
+        // should fail immediately
+        match field.next().await {
+            Some(Err(MultipartError::NotConsumed)) => {}
+            _ => panic!(),
+        };
+    }
+
+    #[actix_rt::test]
+    async fn test_drop_field_awaken_multipart() {
+        let (sender, payload) = create_stream();
+        let (bytes, headers) = create_double_request_with_header();
+        sender.send(Ok(bytes)).unwrap();
+        drop(sender); // eof
+
+        let mut multipart = Multipart::new(&headers, payload);
+        let mut field = multipart.next().await.unwrap().unwrap();
+
+        let task = rt::spawn(async move {
+            rt::time::sleep(Duration::from_secs(1)).await;
+            assert_eq!(field.next().await.unwrap().unwrap(), "test");
+            drop(field);
+        });
+
+        // dropping field should awaken current task
+        let _ = multipart.next().await.unwrap().unwrap();
+        task.await.unwrap();
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_multipart/test.rs.html b/src/actix_multipart/test.rs.html new file mode 100644 index 000000000..f89505a58 --- /dev/null +++ b/src/actix_multipart/test.rs.html @@ -0,0 +1,435 @@ +test.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 actix_web::http::header::{self, HeaderMap};
+use bytes::{BufMut as _, Bytes, BytesMut};
+use mime::Mime;
+use rand::{
+    distributions::{Alphanumeric, DistString as _},
+    thread_rng,
+};
+
+const CRLF: &[u8] = b"\r\n";
+const CRLF_CRLF: &[u8] = b"\r\n\r\n";
+const HYPHENS: &[u8] = b"--";
+const BOUNDARY_PREFIX: &str = "------------------------";
+
+/// Constructs a `multipart/form-data` payload from bytes and metadata.
+///
+/// Returned header map can be extended or merged with existing headers.
+///
+/// Multipart boundary used is a random alphanumeric string.
+///
+/// # Examples
+///
+/// ```
+/// use actix_multipart::test::create_form_data_payload_and_headers;
+/// use actix_web::test::TestRequest;
+/// use bytes::Bytes;
+/// use memchr::memmem::find;
+///
+/// let (body, headers) = create_form_data_payload_and_headers(
+///     "foo",
+///     Some("lorem.txt".to_owned()),
+///     Some(mime::TEXT_PLAIN_UTF_8),
+///     Bytes::from_static(b"Lorem ipsum."),
+/// );
+///
+/// assert!(find(&body, b"foo").is_some());
+/// assert!(find(&body, b"lorem.txt").is_some());
+/// assert!(find(&body, b"text/plain; charset=utf-8").is_some());
+/// assert!(find(&body, b"Lorem ipsum.").is_some());
+///
+/// let req = TestRequest::default();
+///
+/// // merge header map into existing test request and set multipart body
+/// let req = headers
+///     .into_iter()
+///     .fold(req, |req, hdr| req.insert_header(hdr))
+///     .set_payload(body)
+///     .to_http_request();
+///
+/// assert!(
+///     req.headers()
+///         .get("content-type")
+///         .unwrap()
+///         .to_str()
+///         .unwrap()
+///         .starts_with("multipart/form-data; boundary=\"")
+/// );
+/// ```
+pub fn create_form_data_payload_and_headers(
+    name: &str,
+    filename: Option<String>,
+    content_type: Option<Mime>,
+    file: Bytes,
+) -> (Bytes, HeaderMap) {
+    let boundary = Alphanumeric.sample_string(&mut thread_rng(), 32);
+
+    create_form_data_payload_and_headers_with_boundary(
+        &boundary,
+        name,
+        filename,
+        content_type,
+        file,
+    )
+}
+
+/// Constructs a `multipart/form-data` payload from bytes and metadata with a fixed boundary.
+///
+/// See [`create_form_data_payload_and_headers`] for more details.
+pub fn create_form_data_payload_and_headers_with_boundary(
+    boundary: &str,
+    name: &str,
+    filename: Option<String>,
+    content_type: Option<Mime>,
+    file: Bytes,
+) -> (Bytes, HeaderMap) {
+    let mut buf = BytesMut::with_capacity(file.len() + 128);
+
+    let boundary_str = [BOUNDARY_PREFIX, boundary].concat();
+    let boundary = boundary_str.as_bytes();
+
+    buf.put(HYPHENS);
+    buf.put(boundary);
+    buf.put(CRLF);
+
+    buf.put(format!("Content-Disposition: form-data; name=\"{name}\"").as_bytes());
+    if let Some(filename) = filename {
+        buf.put(format!("; filename=\"{filename}\"").as_bytes());
+    }
+    buf.put(CRLF);
+
+    if let Some(ct) = content_type {
+        buf.put(format!("Content-Type: {ct}").as_bytes());
+        buf.put(CRLF);
+    }
+
+    buf.put(format!("Content-Length: {}", file.len()).as_bytes());
+    buf.put(CRLF_CRLF);
+
+    buf.put(file);
+    buf.put(CRLF);
+
+    buf.put(HYPHENS);
+    buf.put(boundary);
+    buf.put(HYPHENS);
+    buf.put(CRLF);
+
+    let mut headers = HeaderMap::new();
+    headers.insert(
+        header::CONTENT_TYPE,
+        format!("multipart/form-data; boundary=\"{boundary_str}\"")
+            .parse()
+            .unwrap(),
+    );
+
+    (buf.freeze(), headers)
+}
+
+#[cfg(test)]
+mod tests {
+    use std::convert::Infallible;
+
+    use futures_util::stream;
+
+    use super::*;
+
+    fn find_boundary(headers: &HeaderMap) -> String {
+        headers
+            .get("content-type")
+            .unwrap()
+            .to_str()
+            .unwrap()
+            .parse::<mime::Mime>()
+            .unwrap()
+            .get_param(mime::BOUNDARY)
+            .unwrap()
+            .as_str()
+            .to_owned()
+    }
+
+    #[test]
+    fn wire_format() {
+        let (pl, headers) = create_form_data_payload_and_headers_with_boundary(
+            "qWeRtYuIoP",
+            "foo",
+            None,
+            None,
+            Bytes::from_static(b"Lorem ipsum dolor\nsit ame."),
+        );
+
+        assert_eq!(
+            find_boundary(&headers),
+            "------------------------qWeRtYuIoP",
+        );
+
+        assert_eq!(
+            std::str::from_utf8(&pl).unwrap(),
+            "--------------------------qWeRtYuIoP\r\n\
+            Content-Disposition: form-data; name=\"foo\"\r\n\
+            Content-Length: 26\r\n\
+            \r\n\
+            Lorem ipsum dolor\n\
+            sit ame.\r\n\
+            --------------------------qWeRtYuIoP--\r\n",
+        );
+
+        let (pl, _headers) = create_form_data_payload_and_headers_with_boundary(
+            "qWeRtYuIoP",
+            "foo",
+            Some("Lorem.txt".to_owned()),
+            Some(mime::TEXT_PLAIN_UTF_8),
+            Bytes::from_static(b"Lorem ipsum dolor\nsit ame."),
+        );
+
+        assert_eq!(
+            std::str::from_utf8(&pl).unwrap(),
+            "--------------------------qWeRtYuIoP\r\n\
+            Content-Disposition: form-data; name=\"foo\"; filename=\"Lorem.txt\"\r\n\
+            Content-Type: text/plain; charset=utf-8\r\n\
+            Content-Length: 26\r\n\
+            \r\n\
+            Lorem ipsum dolor\n\
+            sit ame.\r\n\
+            --------------------------qWeRtYuIoP--\r\n",
+        );
+    }
+
+    /// Test using an external library to prevent the two-wrongs-make-a-right class of errors.
+    #[actix_web::test]
+    async fn ecosystem_compat() {
+        let (pl, headers) = create_form_data_payload_and_headers(
+            "foo",
+            None,
+            None,
+            Bytes::from_static(b"Lorem ipsum dolor\nsit ame."),
+        );
+
+        let boundary = find_boundary(&headers);
+
+        let pl = stream::once(async { Ok::<_, Infallible>(pl) });
+
+        let mut form = multer::Multipart::new(pl, boundary);
+        let field = form.next_field().await.unwrap().unwrap();
+        assert_eq!(field.name().unwrap(), "foo");
+        assert_eq!(field.file_name(), None);
+        assert_eq!(field.content_type(), None);
+        assert!(field.bytes().await.unwrap().starts_with(b"Lorem"));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_multipart_derive/lib.rs.html b/src/actix_multipart_derive/lib.rs.html new file mode 100644 index 000000000..e7f54d1b8 --- /dev/null +++ b/src/actix_multipart_derive/lib.rs.html @@ -0,0 +1,631 @@ +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
+
//! Multipart form derive macro for Actix Web.
+//!
+//! See [`macro@MultipartForm`] for usage examples.
+
+#![deny(rust_2018_idioms, nonstandard_style)]
+#![warn(future_incompatible)]
+#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
+#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+
+use std::collections::HashSet;
+
+use darling::{FromDeriveInput, FromField, FromMeta};
+use parse_size::parse_size;
+use proc_macro::TokenStream;
+use proc_macro2::Ident;
+use quote::quote;
+use syn::{parse_macro_input, Type};
+
+#[derive(FromMeta)]
+enum DuplicateField {
+    Ignore,
+    Deny,
+    Replace,
+}
+
+impl Default for DuplicateField {
+    fn default() -> Self {
+        Self::Ignore
+    }
+}
+
+#[derive(FromDeriveInput, Default)]
+#[darling(attributes(multipart), default)]
+struct MultipartFormAttrs {
+    deny_unknown_fields: bool,
+    duplicate_field: DuplicateField,
+}
+
+#[derive(FromField, Default)]
+#[darling(attributes(multipart), default)]
+struct FieldAttrs {
+    rename: Option<String>,
+    limit: Option<String>,
+}
+
+struct ParsedField<'t> {
+    serialization_name: String,
+    rust_name: &'t Ident,
+    limit: Option<usize>,
+    ty: &'t Type,
+}
+
+/// Implements `MultipartCollect` for a struct so that it can be used with the `MultipartForm`
+/// extractor.
+///
+/// # Basic Use
+///
+/// Each field type should implement the `FieldReader` trait:
+///
+/// ```
+/// use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
+///
+/// #[derive(MultipartForm)]
+/// struct ImageUpload {
+///     description: Text<String>,
+///     timestamp: Text<i64>,
+///     image: TempFile,
+/// }
+/// ```
+///
+/// # Optional and List Fields
+///
+/// You can also use `Vec<T>` and `Option<T>` provided that `T: FieldReader`.
+///
+/// A [`Vec`] field corresponds to an upload with multiple parts under the [same field
+/// name](https://www.rfc-editor.org/rfc/rfc7578#section-4.3).
+///
+/// ```
+/// use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
+///
+/// #[derive(MultipartForm)]
+/// struct Form {
+///     category: Option<Text<String>>,
+///     files: Vec<TempFile>,
+/// }
+/// ```
+///
+/// # Field Renaming
+///
+/// You can use the `#[multipart(rename = "foo")]` attribute to receive a field by a different name.
+///
+/// ```
+/// use actix_multipart::form::{tempfile::TempFile, MultipartForm};
+///
+/// #[derive(MultipartForm)]
+/// struct Form {
+///     #[multipart(rename = "files[]")]
+///     files: Vec<TempFile>,
+/// }
+/// ```
+///
+/// # Field Limits
+///
+/// You can use the `#[multipart(limit = "<size>")]` attribute to set field level limits. The limit
+/// string is parsed using [parse_size].
+///
+/// Note: the form is also subject to the global limits configured using `MultipartFormConfig`.
+///
+/// ```
+/// use actix_multipart::form::{tempfile::TempFile, text::Text, MultipartForm};
+///
+/// #[derive(MultipartForm)]
+/// struct Form {
+///     #[multipart(limit = "2 KiB")]
+///     description: Text<String>,
+///
+///     #[multipart(limit = "512 MiB")]
+///     files: Vec<TempFile>,
+/// }
+/// ```
+///
+/// # Unknown Fields
+///
+/// By default fields with an unknown name are ignored. They can be rejected using the
+/// `#[multipart(deny_unknown_fields)]` attribute:
+///
+/// ```
+/// # use actix_multipart::form::MultipartForm;
+/// #[derive(MultipartForm)]
+/// #[multipart(deny_unknown_fields)]
+/// struct Form { }
+/// ```
+///
+/// # Duplicate Fields
+///
+/// The behaviour for when multiple fields with the same name are received can be changed using the
+/// `#[multipart(duplicate_field = "<behavior>")]` attribute:
+///
+/// - "ignore": (default) Extra fields are ignored. I.e., the first one is persisted.
+/// - "deny": A `MultipartError::UnsupportedField` error response is returned.
+/// - "replace": Each field is processed, but only the last one is persisted.
+///
+/// Note that `Vec` fields will ignore this option.
+///
+/// ```
+/// # use actix_multipart::form::MultipartForm;
+/// #[derive(MultipartForm)]
+/// #[multipart(duplicate_field = "deny")]
+/// struct Form { }
+/// ```
+///
+/// [parse_size]: https://docs.rs/parse-size/1/parse_size
+#[proc_macro_derive(MultipartForm, attributes(multipart))]
+pub fn impl_multipart_form(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
+    let input: syn::DeriveInput = parse_macro_input!(input);
+
+    let name = &input.ident;
+
+    let data_struct = match &input.data {
+        syn::Data::Struct(data_struct) => data_struct,
+        _ => {
+            return compile_err(syn::Error::new(
+                input.ident.span(),
+                "`MultipartForm` can only be derived for structs",
+            ))
+        }
+    };
+
+    let fields = match &data_struct.fields {
+        syn::Fields::Named(fields_named) => fields_named,
+        _ => {
+            return compile_err(syn::Error::new(
+                input.ident.span(),
+                "`MultipartForm` can only be derived for a struct with named fields",
+            ))
+        }
+    };
+
+    let attrs = match MultipartFormAttrs::from_derive_input(&input) {
+        Ok(attrs) => attrs,
+        Err(err) => return err.write_errors().into(),
+    };
+
+    // Parse the field attributes
+    let parsed = match fields
+        .named
+        .iter()
+        .map(|field| {
+            let rust_name = field.ident.as_ref().unwrap();
+            let attrs = FieldAttrs::from_field(field).map_err(|err| err.write_errors())?;
+            let serialization_name = attrs.rename.unwrap_or_else(|| rust_name.to_string());
+
+            let limit = match attrs.limit.map(|limit| match parse_size(&limit) {
+                Ok(size) => Ok(usize::try_from(size).unwrap()),
+                Err(err) => Err(syn::Error::new(
+                    field.ident.as_ref().unwrap().span(),
+                    format!("Could not parse size limit `{}`: {}", limit, err),
+                )),
+            }) {
+                Some(Err(err)) => return Err(compile_err(err)),
+                limit => limit.map(Result::unwrap),
+            };
+
+            Ok(ParsedField {
+                serialization_name,
+                rust_name,
+                limit,
+                ty: &field.ty,
+            })
+        })
+        .collect::<Result<Vec<_>, TokenStream>>()
+    {
+        Ok(attrs) => attrs,
+        Err(err) => return err,
+    };
+
+    // Check that field names are unique
+    let mut set = HashSet::new();
+    for field in &parsed {
+        if !set.insert(field.serialization_name.clone()) {
+            return compile_err(syn::Error::new(
+                field.rust_name.span(),
+                format!("Multiple fields named: `{}`", field.serialization_name),
+            ));
+        }
+    }
+
+    // Return value when a field name is not supported by the form
+    let unknown_field_result = if attrs.deny_unknown_fields {
+        quote!(::std::result::Result::Err(
+            ::actix_multipart::MultipartError::UnsupportedField(field.name().to_string())
+        ))
+    } else {
+        quote!(::std::result::Result::Ok(()))
+    };
+
+    // Value for duplicate action
+    let duplicate_field = match attrs.duplicate_field {
+        DuplicateField::Ignore => quote!(::actix_multipart::form::DuplicateField::Ignore),
+        DuplicateField::Deny => quote!(::actix_multipart::form::DuplicateField::Deny),
+        DuplicateField::Replace => quote!(::actix_multipart::form::DuplicateField::Replace),
+    };
+
+    // limit() implementation
+    let mut limit_impl = quote!();
+    for field in &parsed {
+        let name = &field.serialization_name;
+        if let Some(value) = field.limit {
+            limit_impl.extend(quote!(
+                #name => ::std::option::Option::Some(#value),
+            ));
+        }
+    }
+
+    // handle_field() implementation
+    let mut handle_field_impl = quote!();
+    for field in &parsed {
+        let name = &field.serialization_name;
+        let ty = &field.ty;
+
+        handle_field_impl.extend(quote!(
+            #name => ::std::boxed::Box::pin(
+                <#ty as ::actix_multipart::form::FieldGroupReader>::handle_field(req, field, limits, state, #duplicate_field)
+            ),
+        ));
+    }
+
+    // from_state() implementation
+    let mut from_state_impl = quote!();
+    for field in &parsed {
+        let name = &field.serialization_name;
+        let rust_name = &field.rust_name;
+        let ty = &field.ty;
+        from_state_impl.extend(quote!(
+            #rust_name: <#ty as ::actix_multipart::form::FieldGroupReader>::from_state(#name, &mut state)?,
+        ));
+    }
+
+    let gen = quote! {
+        impl ::actix_multipart::form::MultipartCollect for #name {
+            fn limit(field_name: &str) -> ::std::option::Option<usize> {
+                match field_name {
+                    #limit_impl
+                    _ => None,
+                }
+            }
+
+            fn handle_field<'t>(
+                req: &'t ::actix_web::HttpRequest,
+                field: ::actix_multipart::Field,
+                limits: &'t mut ::actix_multipart::form::Limits,
+                state: &'t mut ::actix_multipart::form::State,
+            ) -> ::std::pin::Pin<::std::boxed::Box<dyn ::std::future::Future<Output = ::std::result::Result<(), ::actix_multipart::MultipartError>> + 't>> {
+                match field.name() {
+                    #handle_field_impl
+                    _ => return ::std::boxed::Box::pin(::std::future::ready(#unknown_field_result)),
+                }
+            }
+
+            fn from_state(mut state: ::actix_multipart::form::State) -> ::std::result::Result<Self, ::actix_multipart::MultipartError> {
+                Ok(Self {
+                    #from_state_impl
+                })
+            }
+
+        }
+    };
+    gen.into()
+}
+
+/// Transform a syn error into a token stream for returning.
+fn compile_err(err: syn::Error) -> TokenStream {
+    TokenStream::from(err.to_compile_error())
+}
+
\ No newline at end of file diff --git a/src/actix_router/de.rs.html b/src/actix_router/de.rs.html new file mode 100644 index 000000000..9d58b5058 --- /dev/null +++ b/src/actix_router/de.rs.html @@ -0,0 +1,1603 @@ +de.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
+
use std::borrow::Cow;
+
+use serde::{
+    de::{self, Deserializer, Error as DeError, Visitor},
+    forward_to_deserialize_any,
+};
+
+use crate::{
+    path::{Path, PathIter},
+    Quoter, ResourcePath,
+};
+
+thread_local! {
+    static FULL_QUOTER: Quoter = Quoter::new(b"", b"");
+}
+
+macro_rules! unsupported_type {
+    ($trait_fn:ident, $name:expr) => {
+        fn $trait_fn<V>(self, _: V) -> Result<V::Value, Self::Error>
+        where
+            V: Visitor<'de>,
+        {
+            Err(de::Error::custom(concat!("unsupported type: ", $name)))
+        }
+    };
+}
+
+macro_rules! parse_single_value {
+    ($trait_fn:ident) => {
+        fn $trait_fn<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+        where
+            V: Visitor<'de>,
+        {
+            if self.path.segment_count() != 1 {
+                Err(de::value::Error::custom(
+                    format!(
+                        "wrong number of parameters: {} expected 1",
+                        self.path.segment_count()
+                    )
+                    .as_str(),
+                ))
+            } else {
+                Value {
+                    value: &self.path[0],
+                }
+                .$trait_fn(visitor)
+            }
+        }
+    };
+}
+
+macro_rules! parse_value {
+    ($trait_fn:ident, $visit_fn:ident, $tp:tt) => {
+        fn $trait_fn<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+        where
+            V: Visitor<'de>,
+        {
+            let decoded = FULL_QUOTER
+                .with(|q| q.requote_str_lossy(self.value))
+                .map(Cow::Owned)
+                .unwrap_or(Cow::Borrowed(self.value));
+
+            let v = decoded.parse().map_err(|_| {
+                de::value::Error::custom(format!("can not parse {:?} to a {}", self.value, $tp))
+            })?;
+
+            visitor.$visit_fn(v)
+        }
+    };
+}
+
+pub struct PathDeserializer<'de, T: ResourcePath> {
+    path: &'de Path<T>,
+}
+
+impl<'de, T: ResourcePath + 'de> PathDeserializer<'de, T> {
+    pub fn new(path: &'de Path<T>) -> Self {
+        PathDeserializer { path }
+    }
+}
+
+impl<'de, T: ResourcePath + 'de> Deserializer<'de> for PathDeserializer<'de, T> {
+    type Error = de::value::Error;
+
+    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_map(ParamsDeserializer {
+            params: self.path.iter(),
+            current: None,
+        })
+    }
+
+    fn deserialize_struct<V>(
+        self,
+        _: &'static str,
+        _: &'static [&'static str],
+        visitor: V,
+    ) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        self.deserialize_map(visitor)
+    }
+
+    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_unit()
+    }
+
+    fn deserialize_unit_struct<V>(
+        self,
+        _: &'static str,
+        visitor: V,
+    ) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        self.deserialize_unit(visitor)
+    }
+
+    fn deserialize_newtype_struct<V>(
+        self,
+        _: &'static str,
+        visitor: V,
+    ) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_newtype_struct(self)
+    }
+
+    fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        if self.path.segment_count() < len {
+            Err(de::value::Error::custom(
+                format!(
+                    "wrong number of parameters: {} expected {}",
+                    self.path.segment_count(),
+                    len
+                )
+                .as_str(),
+            ))
+        } else {
+            visitor.visit_seq(ParamsSeq {
+                params: self.path.iter(),
+            })
+        }
+    }
+
+    fn deserialize_tuple_struct<V>(
+        self,
+        _: &'static str,
+        len: usize,
+        visitor: V,
+    ) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        if self.path.segment_count() < len {
+            Err(de::value::Error::custom(
+                format!(
+                    "wrong number of parameters: {} expected {}",
+                    self.path.segment_count(),
+                    len
+                )
+                .as_str(),
+            ))
+        } else {
+            visitor.visit_seq(ParamsSeq {
+                params: self.path.iter(),
+            })
+        }
+    }
+
+    fn deserialize_enum<V>(
+        self,
+        _: &'static str,
+        _: &'static [&'static str],
+        visitor: V,
+    ) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        if self.path.is_empty() {
+            Err(de::value::Error::custom("expected at least one parameters"))
+        } else {
+            visitor.visit_enum(ValueEnum {
+                value: &self.path[0],
+            })
+        }
+    }
+
+    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_seq(ParamsSeq {
+            params: self.path.iter(),
+        })
+    }
+
+    unsupported_type!(deserialize_any, "'any'");
+    unsupported_type!(deserialize_option, "Option<T>");
+    unsupported_type!(deserialize_identifier, "identifier");
+    unsupported_type!(deserialize_ignored_any, "ignored_any");
+
+    parse_single_value!(deserialize_bool);
+    parse_single_value!(deserialize_i8);
+    parse_single_value!(deserialize_i16);
+    parse_single_value!(deserialize_i32);
+    parse_single_value!(deserialize_i64);
+    parse_single_value!(deserialize_u8);
+    parse_single_value!(deserialize_u16);
+    parse_single_value!(deserialize_u32);
+    parse_single_value!(deserialize_u64);
+    parse_single_value!(deserialize_f32);
+    parse_single_value!(deserialize_f64);
+    parse_single_value!(deserialize_str);
+    parse_single_value!(deserialize_string);
+    parse_single_value!(deserialize_bytes);
+    parse_single_value!(deserialize_byte_buf);
+    parse_single_value!(deserialize_char);
+}
+
+struct ParamsDeserializer<'de, T: ResourcePath> {
+    params: PathIter<'de, T>,
+    current: Option<(&'de str, &'de str)>,
+}
+
+impl<'de, T: ResourcePath> de::MapAccess<'de> for ParamsDeserializer<'de, T> {
+    type Error = de::value::Error;
+
+    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
+    where
+        K: de::DeserializeSeed<'de>,
+    {
+        self.current = self.params.next().map(|ref item| (item.0, item.1));
+        match self.current {
+            Some((key, _)) => Ok(Some(seed.deserialize(Key { key })?)),
+            None => Ok(None),
+        }
+    }
+
+    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
+    where
+        V: de::DeserializeSeed<'de>,
+    {
+        if let Some((_, value)) = self.current.take() {
+            seed.deserialize(Value { value })
+        } else {
+            Err(de::value::Error::custom("unexpected item"))
+        }
+    }
+}
+
+struct Key<'de> {
+    key: &'de str,
+}
+
+impl<'de> Deserializer<'de> for Key<'de> {
+    type Error = de::value::Error;
+
+    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_str(self.key)
+    }
+
+    fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        Err(de::value::Error::custom("Unexpected"))
+    }
+
+    forward_to_deserialize_any! {
+        bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
+            byte_buf option unit unit_struct newtype_struct seq tuple
+            tuple_struct map struct enum ignored_any
+    }
+}
+
+struct Value<'de> {
+    value: &'de str,
+}
+
+impl<'de> Deserializer<'de> for Value<'de> {
+    type Error = de::value::Error;
+
+    parse_value!(deserialize_bool, visit_bool, "bool");
+    parse_value!(deserialize_i8, visit_i8, "i8");
+    parse_value!(deserialize_i16, visit_i16, "i16");
+    parse_value!(deserialize_i32, visit_i32, "i32");
+    parse_value!(deserialize_i64, visit_i64, "i64");
+    parse_value!(deserialize_u8, visit_u8, "u8");
+    parse_value!(deserialize_u16, visit_u16, "u16");
+    parse_value!(deserialize_u32, visit_u32, "u32");
+    parse_value!(deserialize_u64, visit_u64, "u64");
+    parse_value!(deserialize_f32, visit_f32, "f32");
+    parse_value!(deserialize_f64, visit_f64, "f64");
+    parse_value!(deserialize_char, visit_char, "char");
+
+    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_unit()
+    }
+
+    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_unit()
+    }
+
+    fn deserialize_unit_struct<V>(
+        self,
+        _: &'static str,
+        visitor: V,
+    ) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_unit()
+    }
+
+    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        match FULL_QUOTER.with(|q| q.requote_str_lossy(self.value)) {
+            Some(s) => visitor.visit_string(s),
+            None => visitor.visit_borrowed_str(self.value),
+        }
+    }
+
+    fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        match FULL_QUOTER.with(|q| q.requote_str_lossy(self.value)) {
+            Some(s) => visitor.visit_byte_buf(s.into()),
+            None => visitor.visit_borrowed_bytes(self.value.as_bytes()),
+        }
+    }
+
+    fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        self.deserialize_bytes(visitor)
+    }
+
+    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        self.deserialize_str(visitor)
+    }
+
+    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_some(self)
+    }
+
+    fn deserialize_enum<V>(
+        self,
+        _: &'static str,
+        _: &'static [&'static str],
+        visitor: V,
+    ) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_enum(ValueEnum { value: self.value })
+    }
+
+    fn deserialize_newtype_struct<V>(
+        self,
+        _: &'static str,
+        visitor: V,
+    ) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        visitor.visit_newtype_struct(self)
+    }
+
+    fn deserialize_tuple<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        Err(de::value::Error::custom("unsupported type: tuple"))
+    }
+
+    fn deserialize_struct<V>(
+        self,
+        _: &'static str,
+        _: &'static [&'static str],
+        _: V,
+    ) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        Err(de::value::Error::custom("unsupported type: struct"))
+    }
+
+    fn deserialize_tuple_struct<V>(
+        self,
+        _: &'static str,
+        _: usize,
+        _: V,
+    ) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        Err(de::value::Error::custom("unsupported type: tuple struct"))
+    }
+
+    unsupported_type!(deserialize_any, "any");
+    unsupported_type!(deserialize_seq, "seq");
+    unsupported_type!(deserialize_map, "map");
+    unsupported_type!(deserialize_identifier, "identifier");
+}
+
+struct ParamsSeq<'de, T: ResourcePath> {
+    params: PathIter<'de, T>,
+}
+
+impl<'de, T: ResourcePath> de::SeqAccess<'de> for ParamsSeq<'de, T> {
+    type Error = de::value::Error;
+
+    fn next_element_seed<U>(&mut self, seed: U) -> Result<Option<U::Value>, Self::Error>
+    where
+        U: de::DeserializeSeed<'de>,
+    {
+        match self.params.next() {
+            Some(item) => Ok(Some(seed.deserialize(Value { value: item.1 })?)),
+            None => Ok(None),
+        }
+    }
+}
+
+struct ValueEnum<'de> {
+    value: &'de str,
+}
+
+impl<'de> de::EnumAccess<'de> for ValueEnum<'de> {
+    type Error = de::value::Error;
+    type Variant = UnitVariant;
+
+    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
+    where
+        V: de::DeserializeSeed<'de>,
+    {
+        Ok((seed.deserialize(Key { key: self.value })?, UnitVariant))
+    }
+}
+
+struct UnitVariant;
+
+impl<'de> de::VariantAccess<'de> for UnitVariant {
+    type Error = de::value::Error;
+
+    fn unit_variant(self) -> Result<(), Self::Error> {
+        Ok(())
+    }
+
+    fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>
+    where
+        T: de::DeserializeSeed<'de>,
+    {
+        Err(de::value::Error::custom("not supported"))
+    }
+
+    fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        Err(de::value::Error::custom("not supported"))
+    }
+
+    fn struct_variant<V>(self, _: &'static [&'static str], _: V) -> Result<V::Value, Self::Error>
+    where
+        V: Visitor<'de>,
+    {
+        Err(de::value::Error::custom("not supported"))
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use serde::Deserialize;
+
+    use super::*;
+    use crate::{router::Router, ResourceDef};
+
+    #[derive(Deserialize)]
+    struct MyStruct {
+        key: String,
+        value: String,
+    }
+
+    #[derive(Deserialize)]
+    struct Id {
+        _id: String,
+    }
+
+    #[derive(Debug, Deserialize)]
+    struct Test1(String, u32);
+
+    #[derive(Debug, Deserialize)]
+    struct Test2 {
+        key: String,
+        value: u32,
+    }
+
+    #[derive(Debug, Deserialize, PartialEq)]
+    #[serde(rename_all = "lowercase")]
+    enum TestEnum {
+        Val1,
+        Val2,
+    }
+
+    #[derive(Debug, Deserialize)]
+    struct Test3 {
+        val: TestEnum,
+    }
+
+    #[test]
+    fn test_request_extract() {
+        let mut router = Router::<()>::build();
+        router.path("/{key}/{value}/", ());
+        let router = router.finish();
+
+        let mut path = Path::new("/name/user1/");
+        assert!(router.recognize(&mut path).is_some());
+
+        let s: MyStruct = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
+        assert_eq!(s.key, "name");
+        assert_eq!(s.value, "user1");
+
+        let s: (String, String) =
+            de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
+        assert_eq!(s.0, "name");
+        assert_eq!(s.1, "user1");
+
+        let mut router = Router::<()>::build();
+        router.path("/{key}/{value}/", ());
+        let router = router.finish();
+
+        let mut path = Path::new("/name/32/");
+        assert!(router.recognize(&mut path).is_some());
+
+        let s: Test1 = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
+        assert_eq!(s.0, "name");
+        assert_eq!(s.1, 32);
+
+        let s: Test2 = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
+        assert_eq!(s.key, "name");
+        assert_eq!(s.value, 32);
+
+        let s: (String, u8) = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
+        assert_eq!(s.0, "name");
+        assert_eq!(s.1, 32);
+
+        let res: Vec<String> = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
+        assert_eq!(res[0], "name".to_owned());
+        assert_eq!(res[1], "32".to_owned());
+    }
+
+    #[test]
+    fn test_extract_path_single() {
+        let mut router = Router::<()>::build();
+        router.path("/{value}/", ());
+        let router = router.finish();
+
+        let mut path = Path::new("/32/");
+        assert!(router.recognize(&mut path).is_some());
+        let i: i8 = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
+        assert_eq!(i, 32);
+    }
+
+    #[test]
+    fn test_extract_enum() {
+        let mut router = Router::<()>::build();
+        router.path("/{val}/", ());
+        let router = router.finish();
+
+        let mut path = Path::new("/val1/");
+        assert!(router.recognize(&mut path).is_some());
+        let i: TestEnum = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
+        assert_eq!(i, TestEnum::Val1);
+
+        let mut router = Router::<()>::build();
+        router.path("/{val1}/{val2}/", ());
+        let router = router.finish();
+
+        let mut path = Path::new("/val1/val2/");
+        assert!(router.recognize(&mut path).is_some());
+        let i: (TestEnum, TestEnum) =
+            de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
+        assert_eq!(i, (TestEnum::Val1, TestEnum::Val2));
+    }
+
+    #[test]
+    fn test_extract_enum_value() {
+        let mut router = Router::<()>::build();
+        router.path("/{val}/", ());
+        let router = router.finish();
+
+        let mut path = Path::new("/val1/");
+        assert!(router.recognize(&mut path).is_some());
+        let i: Test3 = de::Deserialize::deserialize(PathDeserializer::new(&path)).unwrap();
+        assert_eq!(i.val, TestEnum::Val1);
+
+        let mut path = Path::new("/val3/");
+        assert!(router.recognize(&mut path).is_some());
+        let i: Result<Test3, de::value::Error> =
+            de::Deserialize::deserialize(PathDeserializer::new(&path));
+        assert!(i.is_err());
+        assert!(format!("{:?}", i).contains("unknown variant"));
+    }
+
+    #[test]
+    fn test_extract_errors() {
+        let mut router = Router::<()>::build();
+        router.path("/{value}/", ());
+        let router = router.finish();
+
+        let mut path = Path::new("/name/");
+        assert!(router.recognize(&mut path).is_some());
+
+        let s: Result<Test1, de::value::Error> =
+            de::Deserialize::deserialize(PathDeserializer::new(&path));
+        assert!(s.is_err());
+        assert!(format!("{:?}", s).contains("wrong number of parameters"));
+
+        let s: Result<Test2, de::value::Error> =
+            de::Deserialize::deserialize(PathDeserializer::new(&path));
+        assert!(s.is_err());
+        assert!(format!("{:?}", s).contains("can not parse"));
+
+        let s: Result<(String, String), de::value::Error> =
+            de::Deserialize::deserialize(PathDeserializer::new(&path));
+        assert!(s.is_err());
+        assert!(format!("{:?}", s).contains("wrong number of parameters"));
+
+        let s: Result<u32, de::value::Error> =
+            de::Deserialize::deserialize(PathDeserializer::new(&path));
+        assert!(s.is_err());
+        assert!(format!("{:?}", s).contains("can not parse"));
+    }
+
+    #[test]
+    fn deserialize_path_decode_string() {
+        let rdef = ResourceDef::new("/{key}");
+
+        let mut path = Path::new("/%25");
+        rdef.capture_match_info(&mut path);
+        let de = PathDeserializer::new(&path);
+        let segment: String = serde::Deserialize::deserialize(de).unwrap();
+        assert_eq!(segment, "%");
+
+        let mut path = Path::new("/%2F");
+        rdef.capture_match_info(&mut path);
+        let de = PathDeserializer::new(&path);
+        let segment: String = serde::Deserialize::deserialize(de).unwrap();
+        assert_eq!(segment, "/")
+    }
+
+    #[test]
+    fn deserialize_path_decode_seq() {
+        let rdef = ResourceDef::new("/{key}/{value}");
+
+        let mut path = Path::new("/%30%25/%30%2F");
+        rdef.capture_match_info(&mut path);
+        let de = PathDeserializer::new(&path);
+        let segment: (String, String) = serde::Deserialize::deserialize(de).unwrap();
+        assert_eq!(segment.0, "0%");
+        assert_eq!(segment.1, "0/");
+    }
+
+    #[test]
+    fn deserialize_path_decode_map() {
+        #[derive(Deserialize)]
+        struct Vals {
+            key: String,
+            value: String,
+        }
+
+        let rdef = ResourceDef::new("/{key}/{value}");
+
+        let mut path = Path::new("/%25/%2F");
+        rdef.capture_match_info(&mut path);
+        let de = PathDeserializer::new(&path);
+        let vals: Vals = serde::Deserialize::deserialize(de).unwrap();
+        assert_eq!(vals.key, "%");
+        assert_eq!(vals.value, "/");
+    }
+
+    #[test]
+    fn deserialize_borrowed() {
+        #[derive(Debug, Deserialize)]
+        struct Params<'a> {
+            val: &'a str,
+        }
+
+        let rdef = ResourceDef::new("/{val}");
+
+        let mut path = Path::new("/X");
+        rdef.capture_match_info(&mut path);
+        let de = PathDeserializer::new(&path);
+        let params: Params<'_> = serde::Deserialize::deserialize(de).unwrap();
+        assert_eq!(params.val, "X");
+        let de = PathDeserializer::new(&path);
+        let params: &str = serde::Deserialize::deserialize(de).unwrap();
+        assert_eq!(params, "X");
+
+        let mut path = Path::new("/%2F");
+        rdef.capture_match_info(&mut path);
+        let de = PathDeserializer::new(&path);
+        assert!(<Params<'_> as serde::Deserialize>::deserialize(de).is_err());
+        let de = PathDeserializer::new(&path);
+        assert!(<&str as serde::Deserialize>::deserialize(de).is_err());
+    }
+
+    // #[test]
+    // fn test_extract_path_decode() {
+    //     let mut router = Router::<()>::default();
+    //     router.register_resource(Resource::new(ResourceDef::new("/{value}/")));
+
+    //     macro_rules! test_single_value {
+    //         ($value:expr, $expected:expr) => {{
+    //             let req = TestRequest::with_uri($value).finish();
+    //             let info = router.recognize(&req, &(), 0);
+    //             let req = req.with_route_info(info);
+    //             assert_eq!(
+    //                 *Path::<String>::from_request(&req, &PathConfig::default()).unwrap(),
+    //                 $expected
+    //             );
+    //         }};
+    //     }
+
+    //     test_single_value!("/%25/", "%");
+    //     test_single_value!("/%40%C2%A3%24%25%5E%26%2B%3D/", "@£$%^&+=");
+    //     test_single_value!("/%2B/", "+");
+    //     test_single_value!("/%252B/", "%2B");
+    //     test_single_value!("/%2F/", "/");
+    //     test_single_value!("/%252F/", "%2F");
+    //     test_single_value!(
+    //         "/http%3A%2F%2Flocalhost%3A80%2Ffoo/",
+    //         "http://localhost:80/foo"
+    //     );
+    //     test_single_value!("/%2Fvar%2Flog%2Fsyslog/", "/var/log/syslog");
+    //     test_single_value!(
+    //         "/http%3A%2F%2Flocalhost%3A80%2Ffile%2F%252Fvar%252Flog%252Fsyslog/",
+    //         "http://localhost:80/file/%2Fvar%2Flog%2Fsyslog"
+    //     );
+
+    //     let req = TestRequest::with_uri("/%25/7/?id=test").finish();
+
+    //     let mut router = Router::<()>::default();
+    //     router.register_resource(Resource::new(ResourceDef::new("/{key}/{value}/")));
+    //     let info = router.recognize(&req, &(), 0);
+    //     let req = req.with_route_info(info);
+
+    //     let s = Path::<Test2>::from_request(&req, &PathConfig::default()).unwrap();
+    //     assert_eq!(s.key, "%");
+    //     assert_eq!(s.value, 7);
+
+    //     let s = Path::<(String, String)>::from_request(&req, &PathConfig::default()).unwrap();
+    //     assert_eq!(s.0, "%");
+    //     assert_eq!(s.1, "7");
+    // }
+
+    // #[test]
+    // fn test_extract_path_no_decode() {
+    //     let mut router = Router::<()>::default();
+    //     router.register_resource(Resource::new(ResourceDef::new("/{value}/")));
+
+    //     let req = TestRequest::with_uri("/%25/").finish();
+    //     let info = router.recognize(&req, &(), 0);
+    //     let req = req.with_route_info(info);
+    //     assert_eq!(
+    //         *Path::<String>::from_request(&req, &&PathConfig::default().disable_decoding())
+    //             .unwrap(),
+    //         "%25"
+    //     );
+    // }
+}
+
\ No newline at end of file diff --git a/src/actix_router/lib.rs.html b/src/actix_router/lib.rs.html new file mode 100644 index 000000000..d1ea36de5 --- /dev/null +++ b/src/actix_router/lib.rs.html @@ -0,0 +1,63 @@ +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
+
//! Resource path matching and router.
+
+#![deny(rust_2018_idioms, nonstandard_style)]
+#![warn(future_incompatible)]
+#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
+#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+
+mod de;
+mod path;
+mod pattern;
+mod quoter;
+mod regex_set;
+mod resource;
+mod resource_path;
+mod router;
+
+#[cfg(feature = "http")]
+mod url;
+
+#[cfg(feature = "http")]
+pub use self::url::Url;
+pub use self::{
+    de::PathDeserializer,
+    path::Path,
+    pattern::{IntoPatterns, Patterns},
+    quoter::Quoter,
+    resource::ResourceDef,
+    resource_path::{Resource, ResourcePath},
+    router::{ResourceId, Router, RouterBuilder},
+};
+
\ No newline at end of file diff --git a/src/actix_router/path.rs.html b/src/actix_router/path.rs.html new file mode 100644 index 000000000..fe9bd745b --- /dev/null +++ b/src/actix_router/path.rs.html @@ -0,0 +1,523 @@ +path.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
+
use std::{
+    borrow::Cow,
+    ops::{DerefMut, Index},
+};
+
+use serde::{de, Deserialize};
+
+use crate::{de::PathDeserializer, Resource, ResourcePath};
+
+#[derive(Debug, Clone)]
+pub(crate) enum PathItem {
+    Static(Cow<'static, str>),
+    Segment(u16, u16),
+}
+
+impl Default for PathItem {
+    fn default() -> Self {
+        Self::Static(Cow::Borrowed(""))
+    }
+}
+
+/// Resource path match information.
+///
+/// If resource path contains variable patterns, `Path` stores them.
+#[derive(Debug, Clone, Default)]
+pub struct Path<T> {
+    /// Full path representation.
+    path: T,
+
+    /// Number of characters in `path` that have been processed into `segments`.
+    pub(crate) skip: u16,
+
+    /// List of processed dynamic segments; name->value pairs.
+    pub(crate) segments: Vec<(Cow<'static, str>, PathItem)>,
+}
+
+impl<T: ResourcePath> Path<T> {
+    pub fn new(path: T) -> Path<T> {
+        Path {
+            path,
+            skip: 0,
+            segments: Vec::new(),
+        }
+    }
+
+    /// Returns reference to inner path instance.
+    #[inline]
+    pub fn get_ref(&self) -> &T {
+        &self.path
+    }
+
+    /// Returns mutable reference to inner path instance.
+    #[inline]
+    pub fn get_mut(&mut self) -> &mut T {
+        &mut self.path
+    }
+
+    /// Returns full path as a string.
+    #[inline]
+    pub fn as_str(&self) -> &str {
+        self.path.path()
+    }
+
+    /// Returns unprocessed part of the path.
+    ///
+    /// Returns empty string if no more is to be processed.
+    #[inline]
+    pub fn unprocessed(&self) -> &str {
+        // clamp skip to path length
+        let skip = (self.skip as usize).min(self.as_str().len());
+        &self.path.path()[skip..]
+    }
+
+    /// Returns unprocessed part of the path.
+    #[doc(hidden)]
+    #[deprecated(since = "0.6.0", note = "Use `.as_str()` or `.unprocessed()`.")]
+    #[inline]
+    pub fn path(&self) -> &str {
+        let skip = self.skip as usize;
+        let path = self.path.path();
+        if skip <= path.len() {
+            &path[skip..]
+        } else {
+            ""
+        }
+    }
+
+    /// Set new path.
+    #[inline]
+    pub fn set(&mut self, path: T) {
+        self.path = path;
+        self.skip = 0;
+        self.segments.clear();
+    }
+
+    /// Reset state.
+    #[inline]
+    pub fn reset(&mut self) {
+        self.skip = 0;
+        self.segments.clear();
+    }
+
+    /// Skip first `n` chars in path.
+    #[inline]
+    pub fn skip(&mut self, n: u16) {
+        self.skip += n;
+    }
+
+    pub(crate) fn add(&mut self, name: impl Into<Cow<'static, str>>, value: PathItem) {
+        match value {
+            PathItem::Static(seg) => self.segments.push((name.into(), PathItem::Static(seg))),
+            PathItem::Segment(begin, end) => self.segments.push((
+                name.into(),
+                PathItem::Segment(self.skip + begin, self.skip + end),
+            )),
+        }
+    }
+
+    #[doc(hidden)]
+    pub fn add_static(
+        &mut self,
+        name: impl Into<Cow<'static, str>>,
+        value: impl Into<Cow<'static, str>>,
+    ) {
+        self.segments
+            .push((name.into(), PathItem::Static(value.into())));
+    }
+
+    /// Check if there are any matched patterns.
+    #[inline]
+    pub fn is_empty(&self) -> bool {
+        self.segments.is_empty()
+    }
+
+    /// Returns number of interpolated segments.
+    #[inline]
+    pub fn segment_count(&self) -> usize {
+        self.segments.len()
+    }
+
+    /// Get matched parameter by name without type conversion
+    pub fn get(&self, name: &str) -> Option<&str> {
+        for (seg_name, val) in self.segments.iter() {
+            if name == seg_name {
+                return match val {
+                    PathItem::Static(ref s) => Some(s),
+                    PathItem::Segment(s, e) => {
+                        Some(&self.path.path()[(*s as usize)..(*e as usize)])
+                    }
+                };
+            }
+        }
+
+        None
+    }
+
+    /// Returns matched parameter by name.
+    ///
+    /// If keyed parameter is not available empty string is used as default value.
+    pub fn query(&self, key: &str) -> &str {
+        self.get(key).unwrap_or_default()
+    }
+
+    /// Return iterator to items in parameter container.
+    pub fn iter(&self) -> PathIter<'_, T> {
+        PathIter {
+            idx: 0,
+            params: self,
+        }
+    }
+
+    /// Deserializes matching parameters to a specified type `U`.
+    ///
+    /// # Errors
+    ///
+    /// Returns error when dynamic path segments cannot be deserialized into a `U` type.
+    pub fn load<'de, U: Deserialize<'de>>(&'de self) -> Result<U, de::value::Error> {
+        Deserialize::deserialize(PathDeserializer::new(self))
+    }
+}
+
+#[derive(Debug)]
+pub struct PathIter<'a, T> {
+    idx: usize,
+    params: &'a Path<T>,
+}
+
+impl<'a, T: ResourcePath> Iterator for PathIter<'a, T> {
+    type Item = (&'a str, &'a str);
+
+    #[inline]
+    fn next(&mut self) -> Option<(&'a str, &'a str)> {
+        if self.idx < self.params.segment_count() {
+            let idx = self.idx;
+            let res = match self.params.segments[idx].1 {
+                PathItem::Static(ref s) => s,
+                PathItem::Segment(s, e) => &self.params.path.path()[(s as usize)..(e as usize)],
+            };
+            self.idx += 1;
+            return Some((&self.params.segments[idx].0, res));
+        }
+        None
+    }
+}
+
+impl<'a, T: ResourcePath> Index<&'a str> for Path<T> {
+    type Output = str;
+
+    fn index(&self, name: &'a str) -> &str {
+        self.get(name)
+            .expect("Value for parameter is not available")
+    }
+}
+
+impl<T: ResourcePath> Index<usize> for Path<T> {
+    type Output = str;
+
+    fn index(&self, idx: usize) -> &str {
+        match self.segments[idx].1 {
+            PathItem::Static(ref s) => s,
+            PathItem::Segment(s, e) => &self.path.path()[(s as usize)..(e as usize)],
+        }
+    }
+}
+
+impl<T: ResourcePath> Resource for Path<T> {
+    type Path = T;
+
+    fn resource_path(&mut self) -> &mut Path<Self::Path> {
+        self
+    }
+}
+
+impl<T, P> Resource for T
+where
+    T: DerefMut<Target = Path<P>>,
+    P: ResourcePath,
+{
+    type Path = P;
+
+    fn resource_path(&mut self) -> &mut Path<Self::Path> {
+        &mut *self
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::cell::RefCell;
+
+    use super::*;
+
+    #[allow(clippy::needless_borrow)]
+    #[test]
+    fn deref_impls() {
+        let mut foo = Path::new("/foo");
+        let _ = (&mut foo).resource_path();
+
+        let foo = RefCell::new(foo);
+        let _ = foo.borrow_mut().resource_path();
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_router/pattern.rs.html b/src/actix_router/pattern.rs.html new file mode 100644 index 000000000..fdd8e04fe --- /dev/null +++ b/src/actix_router/pattern.rs.html @@ -0,0 +1,185 @@ +pattern.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
+
/// One or many patterns.
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum Patterns {
+    Single(String),
+    List(Vec<String>),
+}
+
+impl Patterns {
+    pub fn is_empty(&self) -> bool {
+        match self {
+            Patterns::Single(_) => false,
+            Patterns::List(pats) => pats.is_empty(),
+        }
+    }
+}
+
+/// Helper trait for type that could be converted to one or more path patterns.
+pub trait IntoPatterns {
+    fn patterns(&self) -> Patterns;
+}
+
+impl IntoPatterns for String {
+    fn patterns(&self) -> Patterns {
+        Patterns::Single(self.clone())
+    }
+}
+
+impl IntoPatterns for &String {
+    fn patterns(&self) -> Patterns {
+        (*self).patterns()
+    }
+}
+
+impl IntoPatterns for str {
+    fn patterns(&self) -> Patterns {
+        Patterns::Single(self.to_owned())
+    }
+}
+
+impl IntoPatterns for &str {
+    fn patterns(&self) -> Patterns {
+        (*self).patterns()
+    }
+}
+
+impl IntoPatterns for bytestring::ByteString {
+    fn patterns(&self) -> Patterns {
+        Patterns::Single(self.to_string())
+    }
+}
+
+impl IntoPatterns for Patterns {
+    fn patterns(&self) -> Patterns {
+        self.clone()
+    }
+}
+
+impl<T: AsRef<str>> IntoPatterns for Vec<T> {
+    fn patterns(&self) -> Patterns {
+        let mut patterns = self.iter().map(|v| v.as_ref().to_owned());
+
+        match patterns.size_hint() {
+            (1, _) => Patterns::Single(patterns.next().unwrap()),
+            _ => Patterns::List(patterns.collect()),
+        }
+    }
+}
+
+macro_rules! array_patterns_single (($tp:ty) => {
+    impl IntoPatterns for [$tp; 1] {
+        fn patterns(&self) -> Patterns {
+            Patterns::Single(self[0].to_owned())
+        }
+    }
+});
+
+macro_rules! array_patterns_multiple (($tp:ty, $str_fn:expr, $($num:tt) +) => {
+    // for each array length specified in space-separated $num
+    $(
+        impl IntoPatterns for [$tp; $num] {
+            fn patterns(&self) -> Patterns {
+                Patterns::List(self.iter().map($str_fn).collect())
+            }
+        }
+    )+
+});
+
+array_patterns_single!(&str);
+array_patterns_multiple!(&str, |&v| v.to_owned(), 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16);
+
+array_patterns_single!(String);
+array_patterns_multiple!(String, |v| v.clone(), 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16);
+
\ No newline at end of file diff --git a/src/actix_router/quoter.rs.html b/src/actix_router/quoter.rs.html new file mode 100644 index 000000000..1d97ff191 --- /dev/null +++ b/src/actix_router/quoter.rs.html @@ -0,0 +1,345 @@ +quoter.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
+
/// Partial percent-decoding.
+///
+/// Performs percent-decoding on a slice but can selectively skip decoding certain sequences.
+///
+/// # Examples
+/// ```
+/// # use actix_router::Quoter;
+/// // + is set as a protected character and will not be decoded...
+/// let q = Quoter::new(&[], b"+");
+///
+/// // ...but the other encoded characters (like the hyphen below) will.
+/// assert_eq!(q.requote(b"/a%2Db%2Bc").unwrap(), b"/a-b%2Bc");
+/// ```
+pub struct Quoter {
+    /// Simple bit-map of protected values in the 0-127 ASCII range.
+    protected_table: AsciiBitmap,
+}
+
+impl Quoter {
+    /// Constructs a new `Quoter` instance given a set of protected ASCII bytes.
+    ///
+    /// The first argument is ignored but is kept for backward compatibility.
+    ///
+    /// # Panics
+    /// Panics if any of the `protected` bytes are not in the 0-127 ASCII range.
+    pub fn new(_: &[u8], protected: &[u8]) -> Quoter {
+        let mut protected_table = AsciiBitmap::default();
+
+        // prepare protected table
+        for &ch in protected {
+            protected_table.set_bit(ch);
+        }
+
+        Quoter { protected_table }
+    }
+
+    /// Decodes the next escape sequence, if any, and advances `val`.
+    #[inline(always)]
+    fn decode_next<'a>(&self, val: &mut &'a [u8]) -> Option<(&'a [u8], u8)> {
+        for i in 0..val.len() {
+            if let (prev, [b'%', p1, p2, rem @ ..]) = val.split_at(i) {
+                if let Some(ch) = hex_pair_to_char(*p1, *p2)
+                    // ignore protected ascii bytes
+                    .filter(|&ch| !(ch < 128 && self.protected_table.bit_at(ch)))
+                {
+                    *val = rem;
+                    return Some((prev, ch));
+                }
+            }
+        }
+
+        None
+    }
+
+    /// Partially percent-decodes the given bytes.
+    ///
+    /// Escape sequences of the protected set are *not* decoded.
+    ///
+    /// Returns `None` when no modification to the original bytes was required.
+    ///
+    /// Invalid/incomplete percent-encoding sequences are passed unmodified.
+    pub fn requote(&self, val: &[u8]) -> Option<Vec<u8>> {
+        let mut remaining = val;
+
+        // early return indicates that no percent-encoded sequences exist and we can skip allocation
+        let (pre, decoded_char) = self.decode_next(&mut remaining)?;
+
+        // decoded output will always be shorter than the input
+        let mut decoded = Vec::<u8>::with_capacity(val.len());
+
+        // push first segment and decoded char
+        decoded.extend_from_slice(pre);
+        decoded.push(decoded_char);
+
+        // decode and push rest of segments and decoded chars
+        while let Some((prev, ch)) = self.decode_next(&mut remaining) {
+            // this ugly conditional achieves +50% perf in cases where this is a tight loop.
+            if !prev.is_empty() {
+                decoded.extend_from_slice(prev);
+            }
+            decoded.push(ch);
+        }
+
+        decoded.extend_from_slice(remaining);
+
+        Some(decoded)
+    }
+
+    pub(crate) fn requote_str_lossy(&self, val: &str) -> Option<String> {
+        self.requote(val.as_bytes())
+            .map(|data| String::from_utf8_lossy(&data).into_owned())
+    }
+}
+
+/// Decode a ASCII hex-encoded pair to an integer.
+///
+/// Returns `None` if either portion of the decoded pair does not evaluate to a valid hex value.
+///
+/// - `0x33 ('3'), 0x30 ('0') => 0x30 ('0')`
+/// - `0x34 ('4'), 0x31 ('1') => 0x41 ('A')`
+/// - `0x36 ('6'), 0x31 ('1') => 0x61 ('a')`
+#[inline(always)]
+fn hex_pair_to_char(d1: u8, d2: u8) -> Option<u8> {
+    let d_high = char::from(d1).to_digit(16)?;
+    let d_low = char::from(d2).to_digit(16)?;
+
+    // left shift high nibble by 4 bits
+    Some((d_high as u8) << 4 | (d_low as u8))
+}
+
+#[derive(Debug, Default, Clone)]
+struct AsciiBitmap {
+    array: [u8; 16],
+}
+
+impl AsciiBitmap {
+    /// Sets bit in given bit-map to 1=true.
+    ///
+    /// # Panics
+    /// Panics if `ch` index is out of bounds.
+    fn set_bit(&mut self, ch: u8) {
+        self.array[(ch >> 3) as usize] |= 0b1 << (ch & 0b111)
+    }
+
+    /// Returns true if bit to true in given bit-map.
+    ///
+    /// # Panics
+    /// Panics if `ch` index is out of bounds.
+    fn bit_at(&self, ch: u8) -> bool {
+        self.array[(ch >> 3) as usize] & (0b1 << (ch & 0b111)) != 0
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn custom_quoter() {
+        let q = Quoter::new(b"", b"+");
+        assert_eq!(q.requote(b"/a%25c").unwrap(), b"/a%c");
+        assert_eq!(q.requote(b"/a%2Bc"), None);
+
+        let q = Quoter::new(b"%+", b"/");
+        assert_eq!(q.requote(b"/a%25b%2Bc").unwrap(), b"/a%b+c");
+        assert_eq!(q.requote(b"/a%2fb"), None);
+        assert_eq!(q.requote(b"/a%2Fb"), None);
+        assert_eq!(q.requote(b"/a%0Ab").unwrap(), b"/a\nb");
+        assert_eq!(q.requote(b"/a%FE\xffb").unwrap(), b"/a\xfe\xffb");
+        assert_eq!(q.requote(b"/a\xfe\xffb"), None);
+    }
+
+    #[test]
+    fn non_ascii() {
+        let q = Quoter::new(b"%+", b"/");
+        assert_eq!(q.requote(b"/a%FE\xffb").unwrap(), b"/a\xfe\xffb");
+        assert_eq!(q.requote(b"/a\xfe\xffb"), None);
+    }
+
+    #[test]
+    fn invalid_sequences() {
+        let q = Quoter::new(b"%+", b"/");
+        assert_eq!(q.requote(b"/a%2x%2X%%"), None);
+        assert_eq!(q.requote(b"/a%20%2X%%").unwrap(), b"/a %2X%%");
+    }
+
+    #[test]
+    fn quoter_no_modification() {
+        let q = Quoter::new(b"", b"");
+        assert_eq!(q.requote(b"/abc/../efg"), None);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_router/regex_set.rs.html b/src/actix_router/regex_set.rs.html new file mode 100644 index 000000000..641cd83cd --- /dev/null +++ b/src/actix_router/regex_set.rs.html @@ -0,0 +1,133 @@ +regex_set.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
+
//! Abstraction over `regex` and `regex-lite` depending on whether we have `unicode` crate feature
+//! enabled.
+
+use cfg_if::cfg_if;
+#[cfg(feature = "unicode")]
+pub(crate) use regex::{escape, Regex};
+#[cfg(not(feature = "unicode"))]
+pub(crate) use regex_lite::{escape, Regex};
+
+#[cfg(feature = "unicode")]
+#[derive(Debug, Clone)]
+pub(crate) struct RegexSet(regex::RegexSet);
+
+#[cfg(not(feature = "unicode"))]
+#[derive(Debug, Clone)]
+pub(crate) struct RegexSet(Vec<regex_lite::Regex>);
+
+impl RegexSet {
+    /// Create a new regex set.
+    ///
+    /// # Panics
+    ///
+    /// Panics if any path patterns are malformed.
+    pub(crate) fn new(re_set: Vec<String>) -> Self {
+        cfg_if! {
+            if #[cfg(feature = "unicode")] {
+                Self(regex::RegexSet::new(re_set).unwrap())
+            } else {
+                Self(re_set.iter().map(|re| Regex::new(re).unwrap()).collect())
+            }
+        }
+    }
+
+    /// Create a new empty regex set.
+    pub(crate) fn empty() -> Self {
+        cfg_if! {
+            if #[cfg(feature = "unicode")] {
+                Self(regex::RegexSet::empty())
+            } else {
+                Self(Vec::new())
+            }
+        }
+    }
+
+    /// Returns true if regex set matches `path`.
+    pub(crate) fn is_match(&self, path: &str) -> bool {
+        cfg_if! {
+            if #[cfg(feature = "unicode")] {
+                self.0.is_match(path)
+            } else {
+                self.0.iter().any(|re| re.is_match(path))
+            }
+        }
+    }
+
+    /// Returns index within `path` of first match.
+    pub(crate) fn first_match_idx(&self, path: &str) -> Option<usize> {
+        cfg_if! {
+            if #[cfg(feature = "unicode")] {
+                self.0.matches(path).into_iter().next()
+            } else {
+                Some(self.0.iter().enumerate().find(|(_, re)| re.is_match(path))?.0)
+            }
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_router/resource.rs.html b/src/actix_router/resource.rs.html new file mode 100644 index 000000000..3d36c3dcc --- /dev/null +++ b/src/actix_router/resource.rs.html @@ -0,0 +1,3557 @@ +resource.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
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+
use std::{
+    borrow::{Borrow, Cow},
+    collections::HashMap,
+    hash::{BuildHasher, Hash, Hasher},
+    mem,
+};
+
+use tracing::error;
+
+use crate::{
+    path::PathItem,
+    regex_set::{escape, Regex, RegexSet},
+    IntoPatterns, Patterns, Resource, ResourcePath,
+};
+
+const MAX_DYNAMIC_SEGMENTS: usize = 16;
+
+/// Regex flags to allow '.' in regex to match '\n'
+///
+/// See the docs under: https://docs.rs/regex/1/regex/#grouping-and-flags
+const REGEX_FLAGS: &str = "(?s-m)";
+
+/// Describes the set of paths that match to a resource.
+///
+/// `ResourceDef`s are effectively a way to transform the a custom resource pattern syntax into
+/// suitable regular expressions from which to check matches with paths and capture portions of a
+/// matched path into variables. Common cases are on a fast path that avoids going through the
+/// regex engine.
+///
+///
+/// # Pattern Format and Matching Behavior
+/// Resource pattern is defined as a string of zero or more _segments_ where each segment is
+/// preceded by a slash `/`.
+///
+/// This means that pattern string __must__ either be empty or begin with a slash (`/`). This also
+/// implies that a trailing slash in pattern defines an empty segment. For example, the pattern
+/// `"/user/"` has two segments: `["user", ""]`
+///
+/// A key point to understand is that `ResourceDef` matches segments, not strings. Segments are
+/// matched individually. For example, the pattern `/user/` is not considered a prefix for the path
+/// `/user/123/456`, because the second segment doesn't match: `["user", ""]`
+/// vs `["user", "123", "456"]`.
+///
+/// This definition is consistent with the definition of absolute URL path in
+/// [RFC 3986 §3.3](https://datatracker.ietf.org/doc/html/rfc3986#section-3.3)
+///
+///
+/// # Static Resources
+/// A static resource is the most basic type of definition. Pass a pattern to [new][Self::new].
+/// Conforming paths must match the pattern exactly.
+///
+/// ## Examples
+/// ```
+/// # use actix_router::ResourceDef;
+/// let resource = ResourceDef::new("/home");
+///
+/// assert!(resource.is_match("/home"));
+///
+/// assert!(!resource.is_match("/home/"));
+/// assert!(!resource.is_match("/home/new"));
+/// assert!(!resource.is_match("/homes"));
+/// assert!(!resource.is_match("/search"));
+/// ```
+///
+/// # Dynamic Segments
+/// Also known as "path parameters". Resources can define sections of a pattern that be extracted
+/// from a conforming path, if it conforms to (one of) the resource pattern(s).
+///
+/// The marker for a dynamic segment is curly braces wrapping an identifier. For example,
+/// `/user/{id}` would match paths like `/user/123` or `/user/james` and be able to extract the user
+/// IDs "123" and "james", respectively.
+///
+/// However, this resource pattern (`/user/{id}`) would, not cover `/user/123/stars` (unless
+/// constructed as a prefix; see next section) since the default pattern for segments matches all
+/// characters until it finds a `/` character (or the end of the path). Custom segment patterns are
+/// covered further down.
+///
+/// Dynamic segments do not need to be delimited by `/` characters, they can be defined within a
+/// path segment. For example, `/rust-is-{opinion}` can match the paths `/rust-is-cool` and
+/// `/rust-is-hard`.
+///
+/// For information on capturing segment values from paths or other custom resource types,
+/// see [`capture_match_info`][Self::capture_match_info]
+/// and [`capture_match_info_fn`][Self::capture_match_info_fn].
+///
+/// A resource definition can contain at most 16 dynamic segments.
+///
+/// ## Examples
+/// ```
+/// use actix_router::{Path, ResourceDef};
+///
+/// let resource = ResourceDef::prefix("/user/{id}");
+///
+/// assert!(resource.is_match("/user/123"));
+/// assert!(!resource.is_match("/user"));
+/// assert!(!resource.is_match("/user/"));
+///
+/// let mut path = Path::new("/user/123");
+/// resource.capture_match_info(&mut path);
+/// assert_eq!(path.get("id").unwrap(), "123");
+/// ```
+///
+/// # Prefix Resources
+/// A prefix resource is defined as pattern that can match just the start of a path, up to a
+/// segment boundary.
+///
+/// Prefix patterns with a trailing slash may have an unexpected, though correct, behavior.
+/// They define and therefore require an empty segment in order to match. It is easier to understand
+/// this behavior after reading the [matching behavior section]. Examples are given below.
+///
+/// The empty pattern (`""`), as a prefix, matches any path.
+///
+/// Prefix resources can contain dynamic segments.
+///
+/// ## Examples
+/// ```
+/// # use actix_router::ResourceDef;
+/// let resource = ResourceDef::prefix("/home");
+/// assert!(resource.is_match("/home"));
+/// assert!(resource.is_match("/home/new"));
+/// assert!(!resource.is_match("/homes"));
+///
+/// // prefix pattern with a trailing slash
+/// let resource = ResourceDef::prefix("/user/{id}/");
+/// assert!(resource.is_match("/user/123/"));
+/// assert!(resource.is_match("/user/123//stars"));
+/// assert!(!resource.is_match("/user/123/stars"));
+/// assert!(!resource.is_match("/user/123"));
+/// ```
+///
+/// # Custom Regex Segments
+/// Dynamic segments can be customised to only match a specific regular expression. It can be
+/// helpful to do this if resource definitions would otherwise conflict and cause one to
+/// be inaccessible.
+///
+/// The regex used when capturing segment values can be specified explicitly using this syntax:
+/// `{name:regex}`. For example, `/user/{id:\d+}` will only match paths where the user ID
+/// is numeric.
+///
+/// The regex could potentially match multiple segments. If this is not wanted, then care must be
+/// taken to avoid matching a slash `/`. It is guaranteed, however, that the match ends at a
+/// segment boundary; the pattern `r"(/|$)` is always appended to the regex.
+///
+/// By default, dynamic segments use this regex: `[^/]+`. This shows why it is the case, as shown in
+/// the earlier section, that segments capture a slice of the path up to the next `/` character.
+///
+/// Custom regex segments can be used in static and prefix resource definition variants.
+///
+/// ## Examples
+/// ```
+/// # use actix_router::ResourceDef;
+/// let resource = ResourceDef::new(r"/user/{id:\d+}");
+/// assert!(resource.is_match("/user/123"));
+/// assert!(resource.is_match("/user/314159"));
+/// assert!(!resource.is_match("/user/abc"));
+/// ```
+///
+/// # Tail Segments
+/// As a shortcut to defining a custom regex for matching _all_ remaining characters (not just those
+/// up until a `/` character), there is a special pattern to match (and capture) the remaining
+/// path portion.
+///
+/// To do this, use the segment pattern: `{name}*`. Since a tail segment also has a name, values are
+/// extracted in the same way as non-tail dynamic segments.
+///
+/// ## Examples
+/// ```
+/// # use actix_router::{Path, ResourceDef};
+/// let resource = ResourceDef::new("/blob/{tail}*");
+/// assert!(resource.is_match("/blob/HEAD/Cargo.toml"));
+/// assert!(resource.is_match("/blob/HEAD/README.md"));
+///
+/// let mut path = Path::new("/blob/main/LICENSE");
+/// resource.capture_match_info(&mut path);
+/// assert_eq!(path.get("tail").unwrap(), "main/LICENSE");
+/// ```
+///
+/// # Multi-Pattern Resources
+/// For resources that can map to multiple distinct paths, it may be suitable to use
+/// multi-pattern resources by passing an array/vec to [`new`][Self::new]. They will be combined
+/// into a regex set which is usually quicker to check matches on than checking each
+/// pattern individually.
+///
+/// Multi-pattern resources can contain dynamic segments just like single pattern ones.
+/// However, take care to use consistent and semantically-equivalent segment names; it could affect
+/// expectations in the router using these definitions and cause runtime panics.
+///
+/// ## Examples
+/// ```
+/// # use actix_router::ResourceDef;
+/// let resource = ResourceDef::new(["/home", "/index"]);
+/// assert!(resource.is_match("/home"));
+/// assert!(resource.is_match("/index"));
+/// ```
+///
+/// # Trailing Slashes
+/// It should be noted that this library takes no steps to normalize intra-path or trailing slashes.
+/// As such, all resource definitions implicitly expect a pre-processing step to normalize paths if
+/// you wish to accommodate "recoverable" path errors. Below are several examples of resource-path
+/// pairs that would not be compatible.
+///
+/// ## Examples
+/// ```
+/// # use actix_router::ResourceDef;
+/// assert!(!ResourceDef::new("/root").is_match("/root/"));
+/// assert!(!ResourceDef::new("/root/").is_match("/root"));
+/// assert!(!ResourceDef::prefix("/root/").is_match("/root"));
+/// ```
+///
+/// [matching behavior section]: #pattern-format-and-matching-behavior
+#[derive(Clone, Debug)]
+pub struct ResourceDef {
+    id: u16,
+
+    /// Optional name of resource.
+    name: Option<String>,
+
+    /// Pattern that generated the resource definition.
+    patterns: Patterns,
+
+    is_prefix: bool,
+
+    /// Pattern type.
+    pat_type: PatternType,
+
+    /// List of segments that compose the pattern, in order.
+    segments: Vec<PatternSegment>,
+}
+
+#[derive(Debug, Clone, PartialEq)]
+enum PatternSegment {
+    /// Literal slice of pattern.
+    Const(String),
+
+    /// Name of dynamic segment.
+    Var(String),
+}
+
+#[derive(Debug, Clone)]
+#[allow(clippy::large_enum_variant)]
+enum PatternType {
+    /// Single constant/literal segment.
+    Static(String),
+
+    /// Single regular expression and list of dynamic segment names.
+    Dynamic(Regex, Vec<&'static str>),
+
+    /// Regular expression set and list of component expressions plus dynamic segment names.
+    DynamicSet(RegexSet, Vec<(Regex, Vec<&'static str>)>),
+}
+
+impl ResourceDef {
+    /// Constructs a new resource definition from patterns.
+    ///
+    /// Multi-pattern resources can be constructed by providing a slice (or vec) of patterns.
+    ///
+    /// # Panics
+    /// Panics if any path patterns are malformed.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_router::ResourceDef;
+    ///
+    /// let resource = ResourceDef::new("/user/{id}");
+    /// assert!(resource.is_match("/user/123"));
+    /// assert!(!resource.is_match("/user/123/stars"));
+    /// assert!(!resource.is_match("user/1234"));
+    /// assert!(!resource.is_match("/foo"));
+    ///
+    /// let resource = ResourceDef::new(["/profile", "/user/{id}"]);
+    /// assert!(resource.is_match("/profile"));
+    /// assert!(resource.is_match("/user/123"));
+    /// assert!(!resource.is_match("user/123"));
+    /// assert!(!resource.is_match("/foo"));
+    /// ```
+    pub fn new<T: IntoPatterns>(paths: T) -> Self {
+        Self::construct(paths, false)
+    }
+
+    /// Constructs a new resource definition using a pattern that performs prefix matching.
+    ///
+    /// More specifically, the regular expressions generated for matching are different when using
+    /// this method vs using `new`; they will not be appended with the `$` meta-character that
+    /// matches the end of an input.
+    ///
+    /// Although it will compile and run correctly, it is meaningless to construct a prefix
+    /// resource definition with a tail segment; use [`new`][Self::new] in this case.
+    ///
+    /// # Panics
+    /// Panics if path pattern is malformed.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_router::ResourceDef;
+    ///
+    /// let resource = ResourceDef::prefix("/user/{id}");
+    /// assert!(resource.is_match("/user/123"));
+    /// assert!(resource.is_match("/user/123/stars"));
+    /// assert!(!resource.is_match("user/123"));
+    /// assert!(!resource.is_match("user/123/stars"));
+    /// assert!(!resource.is_match("/foo"));
+    /// ```
+    pub fn prefix<T: IntoPatterns>(paths: T) -> Self {
+        ResourceDef::construct(paths, true)
+    }
+
+    /// Constructs a new resource definition using a string pattern that performs prefix matching,
+    /// ensuring a leading `/` if pattern is not empty.
+    ///
+    /// # Panics
+    /// Panics if path pattern is malformed.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_router::ResourceDef;
+    ///
+    /// let resource = ResourceDef::root_prefix("user/{id}");
+    ///
+    /// assert_eq!(&resource, &ResourceDef::prefix("/user/{id}"));
+    /// assert_eq!(&resource, &ResourceDef::root_prefix("/user/{id}"));
+    /// assert_ne!(&resource, &ResourceDef::new("user/{id}"));
+    /// assert_ne!(&resource, &ResourceDef::new("/user/{id}"));
+    ///
+    /// assert!(resource.is_match("/user/123"));
+    /// assert!(!resource.is_match("user/123"));
+    /// ```
+    pub fn root_prefix(path: &str) -> Self {
+        ResourceDef::prefix(insert_slash(path).into_owned())
+    }
+
+    /// Returns a numeric resource ID.
+    ///
+    /// If not explicitly set using [`set_id`][Self::set_id], this will return `0`.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_router::ResourceDef;
+    /// let mut resource = ResourceDef::new("/root");
+    /// assert_eq!(resource.id(), 0);
+    ///
+    /// resource.set_id(42);
+    /// assert_eq!(resource.id(), 42);
+    /// ```
+    pub fn id(&self) -> u16 {
+        self.id
+    }
+
+    /// Set numeric resource ID.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_router::ResourceDef;
+    /// let mut resource = ResourceDef::new("/root");
+    /// resource.set_id(42);
+    /// assert_eq!(resource.id(), 42);
+    /// ```
+    pub fn set_id(&mut self, id: u16) {
+        self.id = id;
+    }
+
+    /// Returns resource definition name, if set.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_router::ResourceDef;
+    /// let mut resource = ResourceDef::new("/root");
+    /// assert!(resource.name().is_none());
+    ///
+    /// resource.set_name("root");
+    /// assert_eq!(resource.name().unwrap(), "root");
+    pub fn name(&self) -> Option<&str> {
+        self.name.as_deref()
+    }
+
+    /// Assigns a new name to the resource.
+    ///
+    /// # Panics
+    /// Panics if `name` is an empty string.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_router::ResourceDef;
+    /// let mut resource = ResourceDef::new("/root");
+    /// resource.set_name("root");
+    /// assert_eq!(resource.name().unwrap(), "root");
+    /// ```
+    pub fn set_name(&mut self, name: impl Into<String>) {
+        let name = name.into();
+
+        assert!(!name.is_empty(), "resource name should not be empty");
+
+        self.name = Some(name)
+    }
+
+    /// Returns `true` if pattern type is prefix.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_router::ResourceDef;
+    /// assert!(ResourceDef::prefix("/user").is_prefix());
+    /// assert!(!ResourceDef::new("/user").is_prefix());
+    /// ```
+    pub fn is_prefix(&self) -> bool {
+        self.is_prefix
+    }
+
+    /// Returns the pattern string that generated the resource definition.
+    ///
+    /// If definition is constructed with multiple patterns, the first pattern is returned. To get
+    /// all patterns, use [`patterns_iter`][Self::pattern_iter]. If resource has 0 patterns,
+    /// returns `None`.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_router::ResourceDef;
+    /// let mut resource = ResourceDef::new("/user/{id}");
+    /// assert_eq!(resource.pattern().unwrap(), "/user/{id}");
+    ///
+    /// let mut resource = ResourceDef::new(["/profile", "/user/{id}"]);
+    /// assert_eq!(resource.pattern(), Some("/profile"));
+    pub fn pattern(&self) -> Option<&str> {
+        match &self.patterns {
+            Patterns::Single(pattern) => Some(pattern.as_str()),
+            Patterns::List(patterns) => patterns.first().map(AsRef::as_ref),
+        }
+    }
+
+    /// Returns iterator of pattern strings that generated the resource definition.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_router::ResourceDef;
+    /// let mut resource = ResourceDef::new("/root");
+    /// let mut iter = resource.pattern_iter();
+    /// assert_eq!(iter.next().unwrap(), "/root");
+    /// assert!(iter.next().is_none());
+    ///
+    /// let mut resource = ResourceDef::new(["/root", "/backup"]);
+    /// let mut iter = resource.pattern_iter();
+    /// assert_eq!(iter.next().unwrap(), "/root");
+    /// assert_eq!(iter.next().unwrap(), "/backup");
+    /// assert!(iter.next().is_none());
+    pub fn pattern_iter(&self) -> impl Iterator<Item = &str> {
+        struct PatternIter<'a> {
+            patterns: &'a Patterns,
+            list_idx: usize,
+            done: bool,
+        }
+
+        impl<'a> Iterator for PatternIter<'a> {
+            type Item = &'a str;
+
+            fn next(&mut self) -> Option<Self::Item> {
+                match &self.patterns {
+                    Patterns::Single(pattern) => {
+                        if self.done {
+                            return None;
+                        }
+
+                        self.done = true;
+                        Some(pattern.as_str())
+                    }
+                    Patterns::List(patterns) if patterns.is_empty() => None,
+                    Patterns::List(patterns) => match patterns.get(self.list_idx) {
+                        Some(pattern) => {
+                            self.list_idx += 1;
+                            Some(pattern.as_str())
+                        }
+                        None => {
+                            // fast path future call
+                            self.done = true;
+                            None
+                        }
+                    },
+                }
+            }
+
+            fn size_hint(&self) -> (usize, Option<usize>) {
+                match &self.patterns {
+                    Patterns::Single(_) => (1, Some(1)),
+                    Patterns::List(patterns) => (patterns.len(), Some(patterns.len())),
+                }
+            }
+        }
+
+        PatternIter {
+            patterns: &self.patterns,
+            list_idx: 0,
+            done: false,
+        }
+    }
+
+    /// Joins two resources.
+    ///
+    /// Resulting resource is prefix if `other` is prefix.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_router::ResourceDef;
+    /// let joined = ResourceDef::prefix("/root").join(&ResourceDef::prefix("/seg"));
+    /// assert_eq!(joined, ResourceDef::prefix("/root/seg"));
+    /// ```
+    pub fn join(&self, other: &ResourceDef) -> ResourceDef {
+        let patterns = self
+            .pattern_iter()
+            .flat_map(move |this| other.pattern_iter().map(move |other| (this, other)))
+            .map(|(this, other)| {
+                let mut pattern = String::with_capacity(this.len() + other.len());
+                pattern.push_str(this);
+                pattern.push_str(other);
+                pattern
+            })
+            .collect::<Vec<_>>();
+
+        match patterns.len() {
+            1 => ResourceDef::construct(&patterns[0], other.is_prefix()),
+            _ => ResourceDef::construct(patterns, other.is_prefix()),
+        }
+    }
+
+    /// Returns `true` if `path` matches this resource.
+    ///
+    /// The behavior of this method depends on how the `ResourceDef` was constructed. For example,
+    /// static resources will not be able to match as many paths as dynamic and prefix resources.
+    /// See [`ResourceDef`] struct docs for details on resource definition types.
+    ///
+    /// This method will always agree with [`find_match`][Self::find_match] on whether the path
+    /// matches or not.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_router::ResourceDef;
+    ///
+    /// // static resource
+    /// let resource = ResourceDef::new("/user");
+    /// assert!(resource.is_match("/user"));
+    /// assert!(!resource.is_match("/users"));
+    /// assert!(!resource.is_match("/user/123"));
+    /// assert!(!resource.is_match("/foo"));
+    ///
+    /// // dynamic resource
+    /// let resource = ResourceDef::new("/user/{user_id}");
+    /// assert!(resource.is_match("/user/123"));
+    /// assert!(!resource.is_match("/user/123/stars"));
+    ///
+    /// // prefix resource
+    /// let resource = ResourceDef::prefix("/root");
+    /// assert!(resource.is_match("/root"));
+    /// assert!(resource.is_match("/root/leaf"));
+    /// assert!(!resource.is_match("/roots"));
+    ///
+    /// // more examples are shown in the `ResourceDef` struct docs
+    /// ```
+    #[inline]
+    pub fn is_match(&self, path: &str) -> bool {
+        // this function could be expressed as:
+        // `self.find_match(path).is_some()`
+        // but this skips some checks and uses potentially faster regex methods
+
+        match &self.pat_type {
+            PatternType::Static(pattern) => self.static_match(pattern, path).is_some(),
+            PatternType::Dynamic(re, _) => re.is_match(path),
+            PatternType::DynamicSet(re, _) => re.is_match(path),
+        }
+    }
+
+    /// Tries to match `path` to this resource, returning the position in the path where the
+    /// match ends.
+    ///
+    /// This method will always agree with [`is_match`][Self::is_match] on whether the path matches
+    /// or not.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_router::ResourceDef;
+    ///
+    /// // static resource
+    /// let resource = ResourceDef::new("/user");
+    /// assert_eq!(resource.find_match("/user"), Some(5));
+    /// assert!(resource.find_match("/user/").is_none());
+    /// assert!(resource.find_match("/user/123").is_none());
+    /// assert!(resource.find_match("/foo").is_none());
+    ///
+    /// // constant prefix resource
+    /// let resource = ResourceDef::prefix("/user");
+    /// assert_eq!(resource.find_match("/user"), Some(5));
+    /// assert_eq!(resource.find_match("/user/"), Some(5));
+    /// assert_eq!(resource.find_match("/user/123"), Some(5));
+    ///
+    /// // dynamic prefix resource
+    /// let resource = ResourceDef::prefix("/user/{id}");
+    /// assert_eq!(resource.find_match("/user/123"), Some(9));
+    /// assert_eq!(resource.find_match("/user/1234/"), Some(10));
+    /// assert_eq!(resource.find_match("/user/12345/stars"), Some(11));
+    /// assert!(resource.find_match("/user/").is_none());
+    ///
+    /// // multi-pattern resource
+    /// let resource = ResourceDef::new(["/user/{id}", "/profile/{id}"]);
+    /// assert_eq!(resource.find_match("/user/123"), Some(9));
+    /// assert_eq!(resource.find_match("/profile/1234"), Some(13));
+    /// ```
+    pub fn find_match(&self, path: &str) -> Option<usize> {
+        match &self.pat_type {
+            PatternType::Static(pattern) => self.static_match(pattern, path),
+
+            PatternType::Dynamic(re, _) => Some(re.captures(path)?[1].len()),
+
+            PatternType::DynamicSet(re, params) => {
+                let idx = re.first_match_idx(path)?;
+                let (ref pattern, _) = params[idx];
+                Some(pattern.captures(path)?[1].len())
+            }
+        }
+    }
+
+    /// Collects dynamic segment values into `resource`.
+    ///
+    /// Returns `true` if `path` matches this resource.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_router::{Path, ResourceDef};
+    ///
+    /// let resource = ResourceDef::prefix("/user/{id}");
+    /// let mut path = Path::new("/user/123/stars");
+    /// assert!(resource.capture_match_info(&mut path));
+    /// assert_eq!(path.get("id").unwrap(), "123");
+    /// assert_eq!(path.unprocessed(), "/stars");
+    ///
+    /// let resource = ResourceDef::new("/blob/{path}*");
+    /// let mut path = Path::new("/blob/HEAD/Cargo.toml");
+    /// assert!(resource.capture_match_info(&mut path));
+    /// assert_eq!(path.get("path").unwrap(), "HEAD/Cargo.toml");
+    /// assert_eq!(path.unprocessed(), "");
+    /// ```
+    pub fn capture_match_info<R: Resource>(&self, resource: &mut R) -> bool {
+        self.capture_match_info_fn(resource, |_| true)
+    }
+
+    /// Collects dynamic segment values into `resource` after matching paths and executing
+    /// check function.
+    ///
+    /// The check function is given a reference to the passed resource and optional arbitrary data.
+    /// This is useful if you want to conditionally match on some non-path related aspect of the
+    /// resource type.
+    ///
+    /// Returns `true` if resource path matches this resource definition _and_ satisfies the
+    /// given check function.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_router::{Path, ResourceDef};
+    ///
+    /// fn try_match(resource: &ResourceDef, path: &mut Path<&str>) -> bool {
+    ///     let admin_allowed = std::env::var("ADMIN_ALLOWED").is_ok();
+    ///
+    ///     resource.capture_match_info_fn(
+    ///         path,
+    ///         // when env var is not set, reject when path contains "admin"
+    ///         |path| !(!admin_allowed && path.as_str().contains("admin")),
+    ///     )
+    /// }
+    ///
+    /// let resource = ResourceDef::prefix("/user/{id}");
+    ///
+    /// // path matches; segment values are collected into path
+    /// let mut path = Path::new("/user/james/stars");
+    /// assert!(try_match(&resource, &mut path));
+    /// assert_eq!(path.get("id").unwrap(), "james");
+    /// assert_eq!(path.unprocessed(), "/stars");
+    ///
+    /// // path matches but fails check function; no segments are collected
+    /// let mut path = Path::new("/user/admin/stars");
+    /// assert!(!try_match(&resource, &mut path));
+    /// assert_eq!(path.unprocessed(), "/user/admin/stars");
+    /// ```
+    pub fn capture_match_info_fn<R, F>(&self, resource: &mut R, check_fn: F) -> bool
+    where
+        R: Resource,
+        F: FnOnce(&R) -> bool,
+    {
+        let mut segments = <[PathItem; MAX_DYNAMIC_SEGMENTS]>::default();
+        let path = resource.resource_path();
+        let path_str = path.unprocessed();
+
+        let (matched_len, matched_vars) = match &self.pat_type {
+            PatternType::Static(pattern) => match self.static_match(pattern, path_str) {
+                Some(len) => (len, None),
+                None => return false,
+            },
+
+            PatternType::Dynamic(re, names) => {
+                let captures = match re.captures(path.unprocessed()) {
+                    Some(captures) => captures,
+                    _ => return false,
+                };
+
+                for (no, name) in names.iter().enumerate() {
+                    if let Some(m) = captures.name(name) {
+                        segments[no] = PathItem::Segment(m.start() as u16, m.end() as u16);
+                    } else {
+                        error!("Dynamic path match but not all segments found: {}", name);
+                        return false;
+                    }
+                }
+
+                (captures[1].len(), Some(names))
+            }
+
+            PatternType::DynamicSet(re, params) => {
+                let path = path.unprocessed();
+                let (pattern, names) = match re.first_match_idx(path) {
+                    Some(idx) => &params[idx],
+                    _ => return false,
+                };
+
+                let captures = match pattern.captures(path.path()) {
+                    Some(captures) => captures,
+                    _ => return false,
+                };
+
+                for (no, name) in names.iter().enumerate() {
+                    if let Some(m) = captures.name(name) {
+                        segments[no] = PathItem::Segment(m.start() as u16, m.end() as u16);
+                    } else {
+                        error!("Dynamic path match but not all segments found: {}", name);
+                        return false;
+                    }
+                }
+
+                (captures[1].len(), Some(names))
+            }
+        };
+
+        if !check_fn(resource) {
+            return false;
+        }
+
+        // Modify `path` to skip matched part and store matched segments
+        let path = resource.resource_path();
+
+        if let Some(vars) = matched_vars {
+            for i in 0..vars.len() {
+                path.add(vars[i], mem::take(&mut segments[i]));
+            }
+        }
+
+        path.skip(matched_len as u16);
+
+        true
+    }
+
+    /// Assembles resource path using a closure that maps variable segment names to values.
+    fn build_resource_path<F, I>(&self, path: &mut String, mut vars: F) -> bool
+    where
+        F: FnMut(&str) -> Option<I>,
+        I: AsRef<str>,
+    {
+        for segment in &self.segments {
+            match segment {
+                PatternSegment::Const(val) => path.push_str(val),
+                PatternSegment::Var(name) => match vars(name) {
+                    Some(val) => path.push_str(val.as_ref()),
+                    _ => return false,
+                },
+            }
+        }
+
+        true
+    }
+
+    /// Assembles full resource path from iterator of dynamic segment values.
+    ///
+    /// Returns `true` on success.
+    ///
+    /// For multi-pattern resources, the first pattern is used under the assumption that it would be
+    /// equivalent to any other choice.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_router::ResourceDef;
+    /// let mut s = String::new();
+    /// let resource = ResourceDef::new("/user/{id}/post/{title}");
+    ///
+    /// assert!(resource.resource_path_from_iter(&mut s, &["123", "my-post"]));
+    /// assert_eq!(s, "/user/123/post/my-post");
+    /// ```
+    pub fn resource_path_from_iter<I>(&self, path: &mut String, values: I) -> bool
+    where
+        I: IntoIterator,
+        I::Item: AsRef<str>,
+    {
+        let mut iter = values.into_iter();
+        self.build_resource_path(path, |_| iter.next())
+    }
+
+    /// Assembles resource path from map of dynamic segment values.
+    ///
+    /// Returns `true` on success.
+    ///
+    /// For multi-pattern resources, the first pattern is used under the assumption that it would be
+    /// equivalent to any other choice.
+    ///
+    /// # Examples
+    /// ```
+    /// # use std::collections::HashMap;
+    /// # use actix_router::ResourceDef;
+    /// let mut s = String::new();
+    /// let resource = ResourceDef::new("/user/{id}/post/{title}");
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert("id", "123");
+    /// map.insert("title", "my-post");
+    ///
+    /// assert!(resource.resource_path_from_map(&mut s, &map));
+    /// assert_eq!(s, "/user/123/post/my-post");
+    /// ```
+    pub fn resource_path_from_map<K, V, S>(
+        &self,
+        path: &mut String,
+        values: &HashMap<K, V, S>,
+    ) -> bool
+    where
+        K: Borrow<str> + Eq + Hash,
+        V: AsRef<str>,
+        S: BuildHasher,
+    {
+        self.build_resource_path(path, |name| values.get(name))
+    }
+
+    /// Returns true if `prefix` acts as a proper prefix (i.e., separated by a slash) in `path`.
+    fn static_match(&self, pattern: &str, path: &str) -> Option<usize> {
+        let rem = path.strip_prefix(pattern)?;
+
+        match self.is_prefix {
+            // resource is not a prefix so an exact match is needed
+            false if rem.is_empty() => Some(pattern.len()),
+
+            // resource is a prefix so rem should start with a path delimiter
+            true if rem.is_empty() || rem.starts_with('/') => Some(pattern.len()),
+
+            // otherwise, no match
+            _ => None,
+        }
+    }
+
+    fn construct<T: IntoPatterns>(paths: T, is_prefix: bool) -> Self {
+        let patterns = paths.patterns();
+
+        let (pat_type, segments) = match &patterns {
+            Patterns::Single(pattern) => ResourceDef::parse(pattern, is_prefix, false),
+
+            // since zero length pattern sets are possible
+            // just return a useless `ResourceDef`
+            Patterns::List(patterns) if patterns.is_empty() => (
+                PatternType::DynamicSet(RegexSet::empty(), Vec::new()),
+                Vec::new(),
+            ),
+
+            Patterns::List(patterns) => {
+                let mut re_set = Vec::with_capacity(patterns.len());
+                let mut pattern_data = Vec::new();
+                let mut segments = None;
+
+                for pattern in patterns {
+                    match ResourceDef::parse(pattern, is_prefix, true) {
+                        (PatternType::Dynamic(re, names), segs) => {
+                            re_set.push(re.as_str().to_owned());
+                            pattern_data.push((re, names));
+                            segments.get_or_insert(segs);
+                        }
+                        _ => unreachable!(),
+                    }
+                }
+
+                let pattern_re_set = RegexSet::new(re_set);
+                let segments = segments.unwrap_or_default();
+
+                (
+                    PatternType::DynamicSet(pattern_re_set, pattern_data),
+                    segments,
+                )
+            }
+        };
+
+        ResourceDef {
+            id: 0,
+            name: None,
+            patterns,
+            is_prefix,
+            pat_type,
+            segments,
+        }
+    }
+
+    /// Parses a dynamic segment definition from a pattern.
+    ///
+    /// The returned tuple includes:
+    /// - the segment descriptor, either `Var` or `Tail`
+    /// - the segment's regex to check values against
+    /// - the remaining, unprocessed string slice
+    /// - whether the parsed parameter represents a tail pattern
+    ///
+    /// # Panics
+    /// Panics if given patterns does not contain a dynamic segment.
+    fn parse_param(pattern: &str) -> (PatternSegment, String, &str, bool) {
+        const DEFAULT_PATTERN: &str = "[^/]+";
+        const DEFAULT_PATTERN_TAIL: &str = ".*";
+
+        let mut params_nesting = 0usize;
+        let close_idx = pattern
+            .find(|c| match c {
+                '{' => {
+                    params_nesting += 1;
+                    false
+                }
+                '}' => {
+                    params_nesting -= 1;
+                    params_nesting == 0
+                }
+                _ => false,
+            })
+            .unwrap_or_else(|| {
+                panic!(
+                    r#"pattern "{}" contains malformed dynamic segment"#,
+                    pattern
+                )
+            });
+
+        let (mut param, mut unprocessed) = pattern.split_at(close_idx + 1);
+
+        // remove outer curly brackets
+        param = &param[1..param.len() - 1];
+
+        let tail = unprocessed == "*";
+
+        let (name, pattern) = match param.find(':') {
+            Some(idx) => {
+                assert!(!tail, "custom regex is not supported for tail match");
+
+                let (name, pattern) = param.split_at(idx);
+                (name, &pattern[1..])
+            }
+            None => (
+                param,
+                if tail {
+                    unprocessed = &unprocessed[1..];
+                    DEFAULT_PATTERN_TAIL
+                } else {
+                    DEFAULT_PATTERN
+                },
+            ),
+        };
+
+        let segment = PatternSegment::Var(name.to_string());
+        let regex = format!(r"(?P<{}>{})", &name, &pattern);
+
+        (segment, regex, unprocessed, tail)
+    }
+
+    /// Parse `pattern` using `is_prefix` and `force_dynamic` flags.
+    ///
+    /// Parameters:
+    /// - `is_prefix`: Use `true` if `pattern` should be treated as a prefix; i.e., a conforming
+    ///   path will be a match even if it has parts remaining to process
+    /// - `force_dynamic`: Use `true` to disallow the return of static and prefix segments.
+    ///
+    /// The returned tuple includes:
+    /// - the pattern type detected, either `Static`, `Prefix`, or `Dynamic`
+    /// - a list of segment descriptors from the pattern
+    fn parse(
+        pattern: &str,
+        is_prefix: bool,
+        force_dynamic: bool,
+    ) -> (PatternType, Vec<PatternSegment>) {
+        if !force_dynamic && pattern.find('{').is_none() && !pattern.ends_with('*') {
+            // pattern is static
+            return (
+                PatternType::Static(pattern.to_owned()),
+                vec![PatternSegment::Const(pattern.to_owned())],
+            );
+        }
+
+        let mut unprocessed = pattern;
+        let mut segments = Vec::new();
+        let mut re = format!("{}^", REGEX_FLAGS);
+        let mut dyn_segment_count = 0;
+        let mut has_tail_segment = false;
+
+        while let Some(idx) = unprocessed.find('{') {
+            let (prefix, rem) = unprocessed.split_at(idx);
+
+            segments.push(PatternSegment::Const(prefix.to_owned()));
+            re.push_str(&escape(prefix));
+
+            let (param_pattern, re_part, rem, tail) = Self::parse_param(rem);
+
+            if tail {
+                has_tail_segment = true;
+            }
+
+            segments.push(param_pattern);
+            re.push_str(&re_part);
+
+            unprocessed = rem;
+            dyn_segment_count += 1;
+        }
+
+        if is_prefix && has_tail_segment {
+            // tail segments in prefixes have no defined semantics
+
+            #[cfg(not(test))]
+            tracing::warn!(
+                "Prefix resources should not have tail segments. \
+                Use `ResourceDef::new` constructor. \
+                This may become a panic in the future."
+            );
+
+            // panic in tests to make this case detectable
+            #[cfg(test)]
+            panic!("prefix resource definitions should not have tail segments");
+        }
+
+        if unprocessed.ends_with('*') {
+            // unnamed tail segment
+
+            #[cfg(not(test))]
+            tracing::warn!(
+                "Tail segments must have names. \
+                Consider `.../{{tail}}*`. \
+                This may become a panic in the future."
+            );
+
+            // panic in tests to make this case detectable
+            #[cfg(test)]
+            panic!("tail segments must have names");
+        } else if !has_tail_segment && !unprocessed.is_empty() {
+            // prevent `Const("")` element from being added after last dynamic segment
+
+            segments.push(PatternSegment::Const(unprocessed.to_owned()));
+            re.push_str(&escape(unprocessed));
+        }
+
+        assert!(
+            dyn_segment_count <= MAX_DYNAMIC_SEGMENTS,
+            "Only {} dynamic segments are allowed, provided: {}",
+            MAX_DYNAMIC_SEGMENTS,
+            dyn_segment_count
+        );
+
+        // Store the pattern in capture group #1 to have context info outside it
+        let mut re = format!("({})", re);
+
+        // Ensure the match ends at a segment boundary
+        if !has_tail_segment {
+            if is_prefix {
+                re.push_str(r"(/|$)");
+            } else {
+                re.push('$');
+            }
+        }
+
+        let re = match Regex::new(&re) {
+            Ok(re) => re,
+            Err(err) => panic!("Wrong path pattern: \"{}\" {}", pattern, err),
+        };
+
+        // `Bok::leak(Box::new(name))` is an intentional memory leak. In typical applications the
+        // routing table is only constructed once (per worker) so leak is bounded. If you are
+        // constructing `ResourceDef`s more than once in your application's lifecycle you would
+        // expect a linear increase in leaked memory over time.
+        let names = re
+            .capture_names()
+            .filter_map(|name| name.map(|name| Box::leak(Box::new(name.to_owned())).as_str()))
+            .collect();
+
+        (PatternType::Dynamic(re, names), segments)
+    }
+}
+
+impl Eq for ResourceDef {}
+
+impl PartialEq for ResourceDef {
+    fn eq(&self, other: &ResourceDef) -> bool {
+        self.patterns == other.patterns && self.is_prefix == other.is_prefix
+    }
+}
+
+impl Hash for ResourceDef {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.patterns.hash(state);
+    }
+}
+
+impl<'a> From<&'a str> for ResourceDef {
+    fn from(path: &'a str) -> ResourceDef {
+        ResourceDef::new(path)
+    }
+}
+
+impl From<String> for ResourceDef {
+    fn from(path: String) -> ResourceDef {
+        ResourceDef::new(path)
+    }
+}
+
+pub(crate) fn insert_slash(path: &str) -> Cow<'_, str> {
+    if !path.is_empty() && !path.starts_with('/') {
+        let mut new_path = String::with_capacity(path.len() + 1);
+        new_path.push('/');
+        new_path.push_str(path);
+        Cow::Owned(new_path)
+    } else {
+        Cow::Borrowed(path)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::Path;
+
+    #[test]
+    fn equivalence() {
+        assert_eq!(
+            ResourceDef::root_prefix("/root"),
+            ResourceDef::prefix("/root")
+        );
+        assert_eq!(
+            ResourceDef::root_prefix("root"),
+            ResourceDef::prefix("/root")
+        );
+        assert_eq!(
+            ResourceDef::root_prefix("/{id}"),
+            ResourceDef::prefix("/{id}")
+        );
+        assert_eq!(
+            ResourceDef::root_prefix("{id}"),
+            ResourceDef::prefix("/{id}")
+        );
+
+        assert_eq!(ResourceDef::new("/"), ResourceDef::new(["/"]));
+        assert_eq!(ResourceDef::new("/"), ResourceDef::new(vec!["/"]));
+
+        assert_ne!(ResourceDef::new(""), ResourceDef::prefix(""));
+        assert_ne!(ResourceDef::new("/"), ResourceDef::prefix("/"));
+        assert_ne!(ResourceDef::new("/{id}"), ResourceDef::prefix("/{id}"));
+    }
+
+    #[test]
+    fn parse_static() {
+        let re = ResourceDef::new("");
+
+        assert!(!re.is_prefix());
+
+        assert!(re.is_match(""));
+        assert!(!re.is_match("/"));
+        assert_eq!(re.find_match(""), Some(0));
+        assert_eq!(re.find_match("/"), None);
+
+        let re = ResourceDef::new("/");
+        assert!(re.is_match("/"));
+        assert!(!re.is_match(""));
+        assert!(!re.is_match("/foo"));
+
+        let re = ResourceDef::new("/name");
+        assert!(re.is_match("/name"));
+        assert!(!re.is_match("/name1"));
+        assert!(!re.is_match("/name/"));
+        assert!(!re.is_match("/name~"));
+
+        let mut path = Path::new("/name");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.unprocessed(), "");
+
+        assert_eq!(re.find_match("/name"), Some(5));
+        assert_eq!(re.find_match("/name1"), None);
+        assert_eq!(re.find_match("/name/"), None);
+        assert_eq!(re.find_match("/name~"), None);
+
+        let re = ResourceDef::new("/name/");
+        assert!(re.is_match("/name/"));
+        assert!(!re.is_match("/name"));
+        assert!(!re.is_match("/name/gs"));
+
+        let re = ResourceDef::new("/user/profile");
+        assert!(re.is_match("/user/profile"));
+        assert!(!re.is_match("/user/profile/profile"));
+
+        let mut path = Path::new("/user/profile");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.unprocessed(), "");
+    }
+
+    #[test]
+    fn parse_param() {
+        let re = ResourceDef::new("/user/{id}");
+        assert!(re.is_match("/user/profile"));
+        assert!(re.is_match("/user/2345"));
+        assert!(!re.is_match("/user/2345/"));
+        assert!(!re.is_match("/user/2345/sdg"));
+
+        let mut path = Path::new("/user/profile");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("id").unwrap(), "profile");
+        assert_eq!(path.unprocessed(), "");
+
+        let mut path = Path::new("/user/1245125");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("id").unwrap(), "1245125");
+        assert_eq!(path.unprocessed(), "");
+
+        let re = ResourceDef::new("/v{version}/resource/{id}");
+        assert!(re.is_match("/v1/resource/320120"));
+        assert!(!re.is_match("/v/resource/1"));
+        assert!(!re.is_match("/resource"));
+
+        let mut path = Path::new("/v151/resource/adage32");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("version").unwrap(), "151");
+        assert_eq!(path.get("id").unwrap(), "adage32");
+        assert_eq!(path.unprocessed(), "");
+
+        let re = ResourceDef::new("/{id:[[:digit:]]{6}}");
+        assert!(re.is_match("/012345"));
+        assert!(!re.is_match("/012"));
+        assert!(!re.is_match("/01234567"));
+        assert!(!re.is_match("/XXXXXX"));
+
+        let mut path = Path::new("/012345");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("id").unwrap(), "012345");
+        assert_eq!(path.unprocessed(), "");
+    }
+
+    #[allow(clippy::cognitive_complexity)]
+    #[test]
+    fn dynamic_set() {
+        let re = ResourceDef::new(vec![
+            "/user/{id}",
+            "/v{version}/resource/{id}",
+            "/{id:[[:digit:]]{6}}",
+            "/static",
+        ]);
+        assert!(re.is_match("/user/profile"));
+        assert!(re.is_match("/user/2345"));
+        assert!(!re.is_match("/user/2345/"));
+        assert!(!re.is_match("/user/2345/sdg"));
+
+        let mut path = Path::new("/user/profile");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("id").unwrap(), "profile");
+        assert_eq!(path.unprocessed(), "");
+
+        let mut path = Path::new("/user/1245125");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("id").unwrap(), "1245125");
+        assert_eq!(path.unprocessed(), "");
+
+        assert!(re.is_match("/v1/resource/320120"));
+        assert!(!re.is_match("/v/resource/1"));
+        assert!(!re.is_match("/resource"));
+
+        let mut path = Path::new("/v151/resource/adage32");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("version").unwrap(), "151");
+        assert_eq!(path.get("id").unwrap(), "adage32");
+
+        assert!(re.is_match("/012345"));
+        assert!(!re.is_match("/012"));
+        assert!(!re.is_match("/01234567"));
+        assert!(!re.is_match("/XXXXXX"));
+
+        assert!(re.is_match("/static"));
+        assert!(!re.is_match("/a/static"));
+        assert!(!re.is_match("/static/a"));
+
+        let mut path = Path::new("/012345");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("id").unwrap(), "012345");
+
+        let re = ResourceDef::new([
+            "/user/{id}",
+            "/v{version}/resource/{id}",
+            "/{id:[[:digit:]]{6}}",
+        ]);
+        assert!(re.is_match("/user/profile"));
+        assert!(re.is_match("/user/2345"));
+        assert!(!re.is_match("/user/2345/"));
+        assert!(!re.is_match("/user/2345/sdg"));
+
+        let re = ResourceDef::new([
+            "/user/{id}".to_string(),
+            "/v{version}/resource/{id}".to_string(),
+            "/{id:[[:digit:]]{6}}".to_string(),
+        ]);
+        assert!(re.is_match("/user/profile"));
+        assert!(re.is_match("/user/2345"));
+        assert!(!re.is_match("/user/2345/"));
+        assert!(!re.is_match("/user/2345/sdg"));
+    }
+
+    #[test]
+    fn dynamic_set_prefix() {
+        let re = ResourceDef::prefix(vec!["/u/{id}", "/{id:[[:digit:]]{3}}"]);
+
+        assert_eq!(re.find_match("/u/abc"), Some(6));
+        assert_eq!(re.find_match("/u/abc/123"), Some(6));
+        assert_eq!(re.find_match("/s/user/profile"), None);
+
+        assert_eq!(re.find_match("/123"), Some(4));
+        assert_eq!(re.find_match("/123/456"), Some(4));
+        assert_eq!(re.find_match("/12345"), None);
+
+        let mut path = Path::new("/151/res");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("id").unwrap(), "151");
+        assert_eq!(path.unprocessed(), "/res");
+    }
+
+    #[test]
+    fn parse_tail() {
+        let re = ResourceDef::new("/user/-{id}*");
+
+        let mut path = Path::new("/user/-profile");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("id").unwrap(), "profile");
+
+        let mut path = Path::new("/user/-2345");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("id").unwrap(), "2345");
+
+        let mut path = Path::new("/user/-2345/");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("id").unwrap(), "2345/");
+
+        let mut path = Path::new("/user/-2345/sdg");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("id").unwrap(), "2345/sdg");
+    }
+
+    #[test]
+    fn static_tail() {
+        let re = ResourceDef::new("/user{tail}*");
+        assert!(re.is_match("/users"));
+        assert!(re.is_match("/user-foo"));
+        assert!(re.is_match("/user/profile"));
+        assert!(re.is_match("/user/2345"));
+        assert!(re.is_match("/user/2345/"));
+        assert!(re.is_match("/user/2345/sdg"));
+        assert!(!re.is_match("/foo/profile"));
+
+        let re = ResourceDef::new("/user/{tail}*");
+        assert!(re.is_match("/user/profile"));
+        assert!(re.is_match("/user/2345"));
+        assert!(re.is_match("/user/2345/"));
+        assert!(re.is_match("/user/2345/sdg"));
+        assert!(!re.is_match("/foo/profile"));
+    }
+
+    #[test]
+    fn dynamic_tail() {
+        let re = ResourceDef::new("/user/{id}/{tail}*");
+        assert!(!re.is_match("/user/2345"));
+        let mut path = Path::new("/user/2345/sdg");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("id").unwrap(), "2345");
+        assert_eq!(path.get("tail").unwrap(), "sdg");
+        assert_eq!(path.unprocessed(), "");
+    }
+
+    #[test]
+    fn newline_patterns_and_paths() {
+        let re = ResourceDef::new("/user/a\nb");
+        assert!(re.is_match("/user/a\nb"));
+        assert!(!re.is_match("/user/a\nb/profile"));
+
+        let re = ResourceDef::new("/a{x}b/test/a{y}b");
+        let mut path = Path::new("/a\nb/test/a\nb");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("x").unwrap(), "\n");
+        assert_eq!(path.get("y").unwrap(), "\n");
+
+        let re = ResourceDef::new("/user/{tail}*");
+        assert!(re.is_match("/user/a\nb/"));
+
+        let re = ResourceDef::new("/user/{id}*");
+        let mut path = Path::new("/user/a\nb/a\nb");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("id").unwrap(), "a\nb/a\nb");
+
+        let re = ResourceDef::new("/user/{id:.*}");
+        let mut path = Path::new("/user/a\nb/a\nb");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("id").unwrap(), "a\nb/a\nb");
+    }
+
+    #[cfg(feature = "http")]
+    #[test]
+    fn parse_urlencoded_param() {
+        let re = ResourceDef::new("/user/{id}/test");
+
+        let mut path = Path::new("/user/2345/test");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("id").unwrap(), "2345");
+
+        let mut path = Path::new("/user/qwe%25/test");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("id").unwrap(), "qwe%25");
+
+        let uri = http::Uri::try_from("/user/qwe%25/test").unwrap();
+        let mut path = Path::new(uri);
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.get("id").unwrap(), "qwe%25");
+    }
+
+    #[test]
+    fn prefix_static() {
+        let re = ResourceDef::prefix("/name");
+
+        assert!(re.is_prefix());
+
+        assert!(re.is_match("/name"));
+        assert!(re.is_match("/name/"));
+        assert!(re.is_match("/name/test/test"));
+        assert!(!re.is_match("/name1"));
+        assert!(!re.is_match("/name~"));
+
+        let mut path = Path::new("/name");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.unprocessed(), "");
+
+        let mut path = Path::new("/name/test");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.unprocessed(), "/test");
+
+        assert_eq!(re.find_match("/name"), Some(5));
+        assert_eq!(re.find_match("/name/"), Some(5));
+        assert_eq!(re.find_match("/name/test/test"), Some(5));
+        assert_eq!(re.find_match("/name1"), None);
+        assert_eq!(re.find_match("/name~"), None);
+
+        let re = ResourceDef::prefix("/name/");
+        assert!(re.is_match("/name/"));
+        assert!(re.is_match("/name//gs"));
+        assert!(!re.is_match("/name/gs"));
+        assert!(!re.is_match("/name"));
+
+        let mut path = Path::new("/name/gs");
+        assert!(!re.capture_match_info(&mut path));
+
+        let mut path = Path::new("/name//gs");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(path.unprocessed(), "/gs");
+
+        let re = ResourceDef::root_prefix("name/");
+        assert!(re.is_match("/name/"));
+        assert!(re.is_match("/name//gs"));
+        assert!(!re.is_match("/name/gs"));
+        assert!(!re.is_match("/name"));
+
+        let mut path = Path::new("/name/gs");
+        assert!(!re.capture_match_info(&mut path));
+    }
+
+    #[test]
+    fn prefix_dynamic() {
+        let re = ResourceDef::prefix("/{name}");
+
+        assert!(re.is_prefix());
+
+        assert!(re.is_match("/name/"));
+        assert!(re.is_match("/name/gs"));
+        assert!(re.is_match("/name"));
+
+        assert_eq!(re.find_match("/name/"), Some(5));
+        assert_eq!(re.find_match("/name/gs"), Some(5));
+        assert_eq!(re.find_match("/name"), Some(5));
+        assert_eq!(re.find_match(""), None);
+
+        let mut path = Path::new("/test2/");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(&path["name"], "test2");
+        assert_eq!(&path[0], "test2");
+        assert_eq!(path.unprocessed(), "/");
+
+        let mut path = Path::new("/test2/subpath1/subpath2/index.html");
+        assert!(re.capture_match_info(&mut path));
+        assert_eq!(&path["name"], "test2");
+        assert_eq!(&path[0], "test2");
+        assert_eq!(path.unprocessed(), "/subpath1/subpath2/index.html");
+
+        let resource = ResourceDef::prefix("/user");
+        // input string shorter than prefix
+        assert!(resource.find_match("/foo").is_none());
+    }
+
+    #[test]
+    fn prefix_empty() {
+        let re = ResourceDef::prefix("");
+
+        assert!(re.is_prefix());
+
+        assert!(re.is_match(""));
+        assert!(re.is_match("/"));
+        assert!(re.is_match("/name/test/test"));
+    }
+
+    #[test]
+    fn build_path_list() {
+        let mut s = String::new();
+        let resource = ResourceDef::new("/user/{item1}/test");
+        assert!(resource.resource_path_from_iter(&mut s, &mut ["user1"].iter()));
+        assert_eq!(s, "/user/user1/test");
+
+        let mut s = String::new();
+        let resource = ResourceDef::new("/user/{item1}/{item2}/test");
+        assert!(resource.resource_path_from_iter(&mut s, &mut ["item", "item2"].iter()));
+        assert_eq!(s, "/user/item/item2/test");
+
+        let mut s = String::new();
+        let resource = ResourceDef::new("/user/{item1}/{item2}");
+        assert!(resource.resource_path_from_iter(&mut s, &mut ["item", "item2"].iter()));
+        assert_eq!(s, "/user/item/item2");
+
+        let mut s = String::new();
+        let resource = ResourceDef::new("/user/{item1}/{item2}/");
+        assert!(resource.resource_path_from_iter(&mut s, &mut ["item", "item2"].iter()));
+        assert_eq!(s, "/user/item/item2/");
+
+        let mut s = String::new();
+        assert!(!resource.resource_path_from_iter(&mut s, &mut ["item"].iter()));
+
+        let mut s = String::new();
+        assert!(resource.resource_path_from_iter(&mut s, &mut ["item", "item2"].iter()));
+        assert_eq!(s, "/user/item/item2/");
+        assert!(!resource.resource_path_from_iter(&mut s, &mut ["item"].iter()));
+
+        let mut s = String::new();
+
+        assert!(resource.resource_path_from_iter(
+            &mut s,
+            #[allow(clippy::useless_vec)]
+            &mut vec!["item", "item2"].iter()
+        ));
+        assert_eq!(s, "/user/item/item2/");
+    }
+
+    #[test]
+    fn multi_pattern_build_path() {
+        let resource = ResourceDef::new(["/user/{id}", "/profile/{id}"]);
+        let mut s = String::new();
+        assert!(resource.resource_path_from_iter(&mut s, &mut ["123"].iter()));
+        assert_eq!(s, "/user/123");
+    }
+
+    #[test]
+    fn multi_pattern_capture_segment_values() {
+        let resource = ResourceDef::new(["/user/{id}", "/profile/{id}"]);
+
+        let mut path = Path::new("/user/123");
+        assert!(resource.capture_match_info(&mut path));
+        assert!(path.get("id").is_some());
+
+        let mut path = Path::new("/profile/123");
+        assert!(resource.capture_match_info(&mut path));
+        assert!(path.get("id").is_some());
+
+        let resource = ResourceDef::new(["/user/{id}", "/profile/{uid}"]);
+
+        let mut path = Path::new("/user/123");
+        assert!(resource.capture_match_info(&mut path));
+        assert!(path.get("id").is_some());
+        assert!(path.get("uid").is_none());
+
+        let mut path = Path::new("/profile/123");
+        assert!(resource.capture_match_info(&mut path));
+        assert!(path.get("id").is_none());
+        assert!(path.get("uid").is_some());
+    }
+
+    #[test]
+    fn dynamic_prefix_proper_segmentation() {
+        let resource = ResourceDef::prefix(r"/id/{id:\d{3}}");
+
+        assert!(resource.is_match("/id/123"));
+        assert!(resource.is_match("/id/123/foo"));
+        assert!(!resource.is_match("/id/1234"));
+        assert!(!resource.is_match("/id/123a"));
+
+        assert_eq!(resource.find_match("/id/123"), Some(7));
+        assert_eq!(resource.find_match("/id/123/foo"), Some(7));
+        assert_eq!(resource.find_match("/id/1234"), None);
+        assert_eq!(resource.find_match("/id/123a"), None);
+    }
+
+    #[test]
+    fn build_path_map() {
+        let resource = ResourceDef::new("/user/{item1}/{item2}/");
+
+        let mut map = HashMap::new();
+        map.insert("item1", "item");
+
+        let mut s = String::new();
+        assert!(!resource.resource_path_from_map(&mut s, &map));
+
+        map.insert("item2", "item2");
+
+        let mut s = String::new();
+        assert!(resource.resource_path_from_map(&mut s, &map));
+        assert_eq!(s, "/user/item/item2/");
+    }
+
+    #[test]
+    fn build_path_tail() {
+        let resource = ResourceDef::new("/user/{item1}*");
+
+        let mut s = String::new();
+        assert!(!resource.resource_path_from_iter(&mut s, &mut [""; 0].iter()));
+
+        let mut s = String::new();
+        assert!(resource.resource_path_from_iter(&mut s, &mut ["user1"].iter()));
+        assert_eq!(s, "/user/user1");
+
+        let mut s = String::new();
+        let mut map = HashMap::new();
+        map.insert("item1", "item");
+        assert!(resource.resource_path_from_map(&mut s, &map));
+        assert_eq!(s, "/user/item");
+    }
+
+    #[test]
+    fn prefix_trailing_slash() {
+        // The prefix "/abc/" matches two segments: ["user", ""]
+
+        // These are not prefixes
+        let re = ResourceDef::prefix("/abc/");
+        assert_eq!(re.find_match("/abc/def"), None);
+        assert_eq!(re.find_match("/abc//def"), Some(5));
+
+        let re = ResourceDef::prefix("/{id}/");
+        assert_eq!(re.find_match("/abc/def"), None);
+        assert_eq!(re.find_match("/abc//def"), Some(5));
+    }
+
+    #[test]
+    fn join() {
+        // test joined defs match the same paths as each component separately
+
+        fn seq_find_match(re1: &ResourceDef, re2: &ResourceDef, path: &str) -> Option<usize> {
+            let len1 = re1.find_match(path)?;
+            let len2 = re2.find_match(&path[len1..])?;
+            Some(len1 + len2)
+        }
+
+        macro_rules! join_test {
+            ($pat1:expr, $pat2:expr => $($test:expr),+) => {{
+                let pat1 = $pat1;
+                let pat2 = $pat2;
+                $({
+                    let _path = $test;
+                    let (re1, re2) = (ResourceDef::prefix(pat1), ResourceDef::new(pat2));
+                    let _seq = seq_find_match(&re1, &re2, _path);
+                    let _join = re1.join(&re2).find_match(_path);
+                    assert_eq!(
+                        _seq, _join,
+                        "patterns: prefix {:?}, {:?}; mismatch on \"{}\"; seq={:?}; join={:?}",
+                        pat1, pat2, _path, _seq, _join
+                    );
+                    assert!(!re1.join(&re2).is_prefix());
+
+                    let (re1, re2) = (ResourceDef::prefix(pat1), ResourceDef::prefix(pat2));
+                    let _seq = seq_find_match(&re1, &re2, _path);
+                    let _join = re1.join(&re2).find_match(_path);
+                    assert_eq!(
+                        _seq, _join,
+                        "patterns: prefix {:?}, prefix {:?}; mismatch on \"{}\"; seq={:?}; join={:?}",
+                        pat1, pat2, _path, _seq, _join
+                    );
+                    assert!(re1.join(&re2).is_prefix());
+                })+
+            }}
+        }
+
+        join_test!("", "" => "", "/hello", "/");
+        join_test!("/user", "" => "", "/user", "/user/123", "/user11", "user", "user/123");
+        join_test!("",  "/user" => "", "/user", "foo", "/user11", "user", "user/123");
+        join_test!("/user",  "/xx" => "", "",  "/", "/user", "/xx", "/userxx", "/user/xx");
+
+        join_test!(["/ver/{v}", "/v{v}"], ["/req/{req}", "/{req}"] => "/v1/abc", 
+                   "/ver/1/abc", "/v1/req/abc", "/ver/1/req/abc", "/v1/abc/def",
+                   "/ver1/req/abc/def", "", "/", "/v1/");
+    }
+
+    #[test]
+    fn match_methods_agree() {
+        macro_rules! match_methods_agree {
+            ($pat:expr => $($test:expr),+) => {{
+                match_methods_agree!(finish $pat, ResourceDef::new($pat), $($test),+);
+            }};
+            (prefix $pat:expr => $($test:expr),+) => {{
+                match_methods_agree!(finish $pat, ResourceDef::prefix($pat), $($test),+);
+            }};
+            (finish $pat:expr, $re:expr, $($test:expr),+) => {{
+                let re = $re;
+                $({
+                    let _is = re.is_match($test);
+                    let _find = re.find_match($test).is_some();
+                    assert_eq!(
+                        _is, _find,
+                        "pattern: {:?}; mismatch on \"{}\"; is={}; find={}",
+                        $pat, $test, _is, _find
+                    );
+                })+
+            }}
+        }
+
+        match_methods_agree!("" => "", "/", "/foo");
+        match_methods_agree!("/" => "", "/", "/foo");
+        match_methods_agree!("/user" => "user", "/user", "/users", "/user/123", "/foo");
+        match_methods_agree!("/v{v}" => "v", "/v", "/v1", "/v222", "/foo");
+        match_methods_agree!(["/v{v}", "/version/{v}"] => "/v", "/v1", "/version", "/version/1", "/foo");
+
+        match_methods_agree!("/path{tail}*" => "/path", "/path1", "/path/123");
+        match_methods_agree!("/path/{tail}*" => "/path", "/path1", "/path/123");
+
+        match_methods_agree!(prefix "" => "", "/", "/foo");
+        match_methods_agree!(prefix "/user" => "user", "/user", "/users", "/user/123", "/foo");
+        match_methods_agree!(prefix r"/id/{id:\d{3}}" => "/id/123", "/id/1234");
+        match_methods_agree!(["/v{v}", "/ver/{v}"] => "", "s/v", "/v1", "/v1/xx", "/ver/i3/5", "/ver/1");
+    }
+
+    #[test]
+    #[should_panic]
+    fn duplicate_segment_name() {
+        ResourceDef::new("/user/{id}/post/{id}");
+    }
+
+    #[test]
+    #[should_panic]
+    fn invalid_dynamic_segment_delimiter() {
+        ResourceDef::new("/user/{username");
+    }
+
+    #[test]
+    #[should_panic]
+    fn invalid_dynamic_segment_name() {
+        ResourceDef::new("/user/{}");
+    }
+
+    #[test]
+    #[should_panic]
+    fn invalid_too_many_dynamic_segments() {
+        // valid
+        ResourceDef::new("/{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}/{i}/{j}/{k}/{l}/{m}/{n}/{o}/{p}");
+
+        // panics
+        ResourceDef::new("/{a}/{b}/{c}/{d}/{e}/{f}/{g}/{h}/{i}/{j}/{k}/{l}/{m}/{n}/{o}/{p}/{q}");
+    }
+
+    #[test]
+    #[should_panic]
+    fn invalid_custom_regex_for_tail() {
+        ResourceDef::new(r"/{tail:\d+}*");
+    }
+
+    #[test]
+    #[should_panic]
+    fn invalid_unnamed_tail_segment() {
+        ResourceDef::new("/*");
+    }
+
+    #[test]
+    #[should_panic]
+    fn prefix_plus_tail_match_disallowed() {
+        ResourceDef::prefix("/user/{id}*");
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_router/resource_path.rs.html b/src/actix_router/resource_path.rs.html new file mode 100644 index 000000000..fad3ec8c7 --- /dev/null +++ b/src/actix_router/resource_path.rs.html @@ -0,0 +1,79 @@ +resource_path.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
+
use crate::Path;
+
+// TODO: this trait is necessary, document it
+// see impl Resource for ServiceRequest
+pub trait Resource {
+    /// Type of resource's path returned in `resource_path`.
+    type Path: ResourcePath;
+
+    fn resource_path(&mut self) -> &mut Path<Self::Path>;
+}
+
+pub trait ResourcePath {
+    fn path(&self) -> &str;
+}
+
+impl ResourcePath for String {
+    fn path(&self) -> &str {
+        self.as_str()
+    }
+}
+
+impl<'a> ResourcePath for &'a str {
+    fn path(&self) -> &str {
+        self
+    }
+}
+
+impl ResourcePath for bytestring::ByteString {
+    fn path(&self) -> &str {
+        self
+    }
+}
+
+#[cfg(feature = "http")]
+impl ResourcePath for http::Uri {
+    fn path(&self) -> &str {
+        self.path()
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_router/router.rs.html b/src/actix_router/router.rs.html new file mode 100644 index 000000000..ea713301a --- /dev/null +++ b/src/actix_router/router.rs.html @@ -0,0 +1,565 @@ +router.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
+
use crate::{IntoPatterns, Resource, ResourceDef};
+
+#[derive(Debug, Copy, Clone, PartialEq, Eq)]
+pub struct ResourceId(pub u16);
+
+/// Resource router.
+///
+/// It matches a [routing resource](Resource) to an ordered list of _routes_. Each is defined by a
+/// single [`ResourceDef`] and contains two types of custom data:
+/// 1. The route _value_, of the generic type `T`.
+/// 1. Some _context_ data, of the generic type `U`, which is only provided to the check function in
+///    [`recognize_fn`](Self::recognize_fn). This parameter defaults to `()` and can be omitted if
+///    not required.
+pub struct Router<T, U = ()> {
+    routes: Vec<(ResourceDef, T, U)>,
+}
+
+impl<T, U> Router<T, U> {
+    /// Constructs new `RouterBuilder` with empty route list.
+    pub fn build() -> RouterBuilder<T, U> {
+        RouterBuilder { routes: Vec::new() }
+    }
+
+    /// Finds the value in the router that matches a given [routing resource](Resource).
+    ///
+    /// The match result, including the captured dynamic segments, in the `resource`.
+    pub fn recognize<R>(&self, resource: &mut R) -> Option<(&T, ResourceId)>
+    where
+        R: Resource,
+    {
+        self.recognize_fn(resource, |_, _| true)
+    }
+
+    /// Same as [`recognize`](Self::recognize) but returns a mutable reference to the matched value.
+    pub fn recognize_mut<R>(&mut self, resource: &mut R) -> Option<(&mut T, ResourceId)>
+    where
+        R: Resource,
+    {
+        self.recognize_mut_fn(resource, |_, _| true)
+    }
+
+    /// Finds the value in the router that matches a given [routing resource](Resource) and passes
+    /// an additional predicate check using context data.
+    ///
+    /// Similar to [`recognize`](Self::recognize). However, before accepting the route as matched,
+    /// the `check` closure is executed, passing the resource and each route's context data. If the
+    /// closure returns true then the match result is stored into `resource` and a reference to
+    /// the matched _value_ is returned.
+    pub fn recognize_fn<R, F>(&self, resource: &mut R, mut check: F) -> Option<(&T, ResourceId)>
+    where
+        R: Resource,
+        F: FnMut(&R, &U) -> bool,
+    {
+        for (rdef, val, ctx) in self.routes.iter() {
+            if rdef.capture_match_info_fn(resource, |res| check(res, ctx)) {
+                return Some((val, ResourceId(rdef.id())));
+            }
+        }
+
+        None
+    }
+
+    /// Same as [`recognize_fn`](Self::recognize_fn) but returns a mutable reference to the matched
+    /// value.
+    pub fn recognize_mut_fn<R, F>(
+        &mut self,
+        resource: &mut R,
+        mut check: F,
+    ) -> Option<(&mut T, ResourceId)>
+    where
+        R: Resource,
+        F: FnMut(&R, &U) -> bool,
+    {
+        for (rdef, val, ctx) in self.routes.iter_mut() {
+            if rdef.capture_match_info_fn(resource, |res| check(res, ctx)) {
+                return Some((val, ResourceId(rdef.id())));
+            }
+        }
+
+        None
+    }
+}
+
+/// Builder for an ordered [routing](Router) list.
+pub struct RouterBuilder<T, U = ()> {
+    routes: Vec<(ResourceDef, T, U)>,
+}
+
+impl<T, U> RouterBuilder<T, U> {
+    /// Adds a new route to the end of the routing list.
+    ///
+    /// Returns mutable references to elements of the new route.
+    pub fn push(
+        &mut self,
+        rdef: ResourceDef,
+        val: T,
+        ctx: U,
+    ) -> (&mut ResourceDef, &mut T, &mut U) {
+        self.routes.push((rdef, val, ctx));
+        #[allow(clippy::map_identity)] // map is used to distribute &mut-ness to tuple elements
+        self.routes
+            .last_mut()
+            .map(|(rdef, val, ctx)| (rdef, val, ctx))
+            .unwrap()
+    }
+
+    /// Finish configuration and create router instance.
+    pub fn finish(self) -> Router<T, U> {
+        Router {
+            routes: self.routes,
+        }
+    }
+}
+
+/// Convenience methods provided when context data impls [`Default`]
+impl<T, U> RouterBuilder<T, U>
+where
+    U: Default,
+{
+    /// Registers resource for specified path.
+    pub fn path(&mut self, path: impl IntoPatterns, val: T) -> (&mut ResourceDef, &mut T, &mut U) {
+        self.push(ResourceDef::new(path), val, U::default())
+    }
+
+    /// Registers resource for specified path prefix.
+    pub fn prefix(
+        &mut self,
+        prefix: impl IntoPatterns,
+        val: T,
+    ) -> (&mut ResourceDef, &mut T, &mut U) {
+        self.push(ResourceDef::prefix(prefix), val, U::default())
+    }
+
+    /// Registers resource for [`ResourceDef`].
+    pub fn rdef(&mut self, rdef: ResourceDef, val: T) -> (&mut ResourceDef, &mut T, &mut U) {
+        self.push(rdef, val, U::default())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::{
+        path::Path,
+        router::{ResourceId, Router},
+    };
+
+    #[allow(clippy::cognitive_complexity)]
+    #[test]
+    fn test_recognizer_1() {
+        let mut router = Router::<usize>::build();
+        router.path("/name", 10).0.set_id(0);
+        router.path("/name/{val}", 11).0.set_id(1);
+        router.path("/name/{val}/index.html", 12).0.set_id(2);
+        router.path("/file/{file}.{ext}", 13).0.set_id(3);
+        router.path("/v{val}/{val2}/index.html", 14).0.set_id(4);
+        router.path("/v/{tail:.*}", 15).0.set_id(5);
+        router.path("/test2/{test}.html", 16).0.set_id(6);
+        router.path("/{test}/index.html", 17).0.set_id(7);
+        let mut router = router.finish();
+
+        let mut path = Path::new("/unknown");
+        assert!(router.recognize_mut(&mut path).is_none());
+
+        let mut path = Path::new("/name");
+        let (h, info) = router.recognize_mut(&mut path).unwrap();
+        assert_eq!(*h, 10);
+        assert_eq!(info, ResourceId(0));
+        assert!(path.is_empty());
+
+        let mut path = Path::new("/name/value");
+        let (h, info) = router.recognize_mut(&mut path).unwrap();
+        assert_eq!(*h, 11);
+        assert_eq!(info, ResourceId(1));
+        assert_eq!(path.get("val").unwrap(), "value");
+        assert_eq!(&path["val"], "value");
+
+        let mut path = Path::new("/name/value2/index.html");
+        let (h, info) = router.recognize_mut(&mut path).unwrap();
+        assert_eq!(*h, 12);
+        assert_eq!(info, ResourceId(2));
+        assert_eq!(path.get("val").unwrap(), "value2");
+
+        let mut path = Path::new("/file/file.gz");
+        let (h, info) = router.recognize_mut(&mut path).unwrap();
+        assert_eq!(*h, 13);
+        assert_eq!(info, ResourceId(3));
+        assert_eq!(path.get("file").unwrap(), "file");
+        assert_eq!(path.get("ext").unwrap(), "gz");
+
+        let mut path = Path::new("/v2/ttt/index.html");
+        let (h, info) = router.recognize_mut(&mut path).unwrap();
+        assert_eq!(*h, 14);
+        assert_eq!(info, ResourceId(4));
+        assert_eq!(path.get("val").unwrap(), "2");
+        assert_eq!(path.get("val2").unwrap(), "ttt");
+
+        let mut path = Path::new("/v/blah-blah/index.html");
+        let (h, info) = router.recognize_mut(&mut path).unwrap();
+        assert_eq!(*h, 15);
+        assert_eq!(info, ResourceId(5));
+        assert_eq!(path.get("tail").unwrap(), "blah-blah/index.html");
+
+        let mut path = Path::new("/test2/index.html");
+        let (h, info) = router.recognize_mut(&mut path).unwrap();
+        assert_eq!(*h, 16);
+        assert_eq!(info, ResourceId(6));
+        assert_eq!(path.get("test").unwrap(), "index");
+
+        let mut path = Path::new("/bbb/index.html");
+        let (h, info) = router.recognize_mut(&mut path).unwrap();
+        assert_eq!(*h, 17);
+        assert_eq!(info, ResourceId(7));
+        assert_eq!(path.get("test").unwrap(), "bbb");
+    }
+
+    #[test]
+    fn test_recognizer_2() {
+        let mut router = Router::<usize>::build();
+        router.path("/index.json", 10);
+        router.path("/{source}.json", 11);
+        let mut router = router.finish();
+
+        let mut path = Path::new("/index.json");
+        let (h, _) = router.recognize_mut(&mut path).unwrap();
+        assert_eq!(*h, 10);
+
+        let mut path = Path::new("/test.json");
+        let (h, _) = router.recognize_mut(&mut path).unwrap();
+        assert_eq!(*h, 11);
+    }
+
+    #[test]
+    fn test_recognizer_with_prefix() {
+        let mut router = Router::<usize>::build();
+        router.path("/name", 10).0.set_id(0);
+        router.path("/name/{val}", 11).0.set_id(1);
+        let mut router = router.finish();
+
+        let mut path = Path::new("/name");
+        path.skip(5);
+        assert!(router.recognize_mut(&mut path).is_none());
+
+        let mut path = Path::new("/test/name");
+        path.skip(5);
+        let (h, _) = router.recognize_mut(&mut path).unwrap();
+        assert_eq!(*h, 10);
+
+        let mut path = Path::new("/test/name/value");
+        path.skip(5);
+        let (h, id) = router.recognize_mut(&mut path).unwrap();
+        assert_eq!(*h, 11);
+        assert_eq!(id, ResourceId(1));
+        assert_eq!(path.get("val").unwrap(), "value");
+        assert_eq!(&path["val"], "value");
+
+        // same patterns
+        let mut router = Router::<usize>::build();
+        router.path("/name", 10);
+        router.path("/name/{val}", 11);
+        let mut router = router.finish();
+
+        // test skip beyond path length
+        let mut path = Path::new("/name");
+        path.skip(6);
+        assert!(router.recognize_mut(&mut path).is_none());
+
+        let mut path = Path::new("/test2/name");
+        path.skip(6);
+        let (h, _) = router.recognize_mut(&mut path).unwrap();
+        assert_eq!(*h, 10);
+
+        let mut path = Path::new("/test2/name-test");
+        path.skip(6);
+        assert!(router.recognize_mut(&mut path).is_none());
+
+        let mut path = Path::new("/test2/name/ttt");
+        path.skip(6);
+        let (h, _) = router.recognize_mut(&mut path).unwrap();
+        assert_eq!(*h, 11);
+        assert_eq!(&path["val"], "ttt");
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_router/url.rs.html b/src/actix_router/url.rs.html new file mode 100644 index 000000000..caacd6cd3 --- /dev/null +++ b/src/actix_router/url.rs.html @@ -0,0 +1,287 @@ +url.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
+
use crate::{Quoter, ResourcePath};
+
+thread_local! {
+    static DEFAULT_QUOTER: Quoter = Quoter::new(b"", b"%/+");
+}
+
+#[derive(Debug, Clone, Default)]
+pub struct Url {
+    uri: http::Uri,
+    path: Option<String>,
+}
+
+impl Url {
+    #[inline]
+    pub fn new(uri: http::Uri) -> Url {
+        let path = DEFAULT_QUOTER.with(|q| q.requote_str_lossy(uri.path()));
+        Url { uri, path }
+    }
+
+    #[inline]
+    pub fn new_with_quoter(uri: http::Uri, quoter: &Quoter) -> Url {
+        Url {
+            path: quoter.requote_str_lossy(uri.path()),
+            uri,
+        }
+    }
+
+    /// Returns URI.
+    #[inline]
+    pub fn uri(&self) -> &http::Uri {
+        &self.uri
+    }
+
+    /// Returns path.
+    #[inline]
+    pub fn path(&self) -> &str {
+        match self.path {
+            Some(ref path) => path,
+            _ => self.uri.path(),
+        }
+    }
+
+    #[inline]
+    pub fn update(&mut self, uri: &http::Uri) {
+        self.uri = uri.clone();
+        self.path = DEFAULT_QUOTER.with(|q| q.requote_str_lossy(uri.path()));
+    }
+
+    #[inline]
+    pub fn update_with_quoter(&mut self, uri: &http::Uri, quoter: &Quoter) {
+        self.uri = uri.clone();
+        self.path = quoter.requote_str_lossy(uri.path());
+    }
+}
+
+impl ResourcePath for Url {
+    #[inline]
+    fn path(&self) -> &str {
+        self.path()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::fmt::Write as _;
+
+    use http::Uri;
+
+    use super::*;
+    use crate::{Path, ResourceDef};
+
+    const PROTECTED: &[u8] = b"%/+";
+
+    fn match_url(pattern: &'static str, url: impl AsRef<str>) -> Path<Url> {
+        let re = ResourceDef::new(pattern);
+        let uri = Uri::try_from(url.as_ref()).unwrap();
+        let mut path = Path::new(Url::new(uri));
+        assert!(re.capture_match_info(&mut path));
+        path
+    }
+
+    fn percent_encode(data: &[u8]) -> String {
+        data.iter()
+            .fold(String::with_capacity(data.len() * 3), |mut buf, c| {
+                write!(&mut buf, "%{:02X}", c).unwrap();
+                buf
+            })
+    }
+
+    #[test]
+    fn parse_url() {
+        let re = "/user/{id}/test";
+
+        let path = match_url(re, "/user/2345/test");
+        assert_eq!(path.get("id").unwrap(), "2345");
+    }
+
+    #[test]
+    fn protected_chars() {
+        let re = "/user/{id}/test";
+
+        let encoded = percent_encode(PROTECTED);
+        let path = match_url(re, format!("/user/{}/test", encoded));
+        // characters in captured segment remain unencoded
+        assert_eq!(path.get("id").unwrap(), &encoded);
+
+        // "%25" should never be decoded into '%' to guarantee the output is a valid
+        // percent-encoded format
+        let path = match_url(re, "/user/qwe%25/test");
+        assert_eq!(path.get("id").unwrap(), "qwe%25");
+
+        let path = match_url(re, "/user/qwe%25rty/test");
+        assert_eq!(path.get("id").unwrap(), "qwe%25rty");
+    }
+
+    #[test]
+    fn non_protected_ascii() {
+        let non_protected_ascii = ('\u{0}'..='\u{7F}')
+            .filter(|&c| c.is_ascii() && !PROTECTED.contains(&(c as u8)))
+            .collect::<String>();
+        let encoded = percent_encode(non_protected_ascii.as_bytes());
+        let path = match_url("/user/{id}/test", format!("/user/{}/test", encoded));
+        assert_eq!(path.get("id").unwrap(), &non_protected_ascii);
+    }
+
+    #[test]
+    fn valid_utf8_multi_byte() {
+        let test = ('\u{FF00}'..='\u{FFFF}').collect::<String>();
+        let encoded = percent_encode(test.as_bytes());
+        let path = match_url("/a/{id}/b", format!("/a/{}/b", &encoded));
+        assert_eq!(path.get("id").unwrap(), &test);
+    }
+
+    #[test]
+    fn invalid_utf8() {
+        let invalid_utf8 = percent_encode((0x80..=0xff).collect::<Vec<_>>().as_slice());
+        let uri = Uri::try_from(format!("/{}", invalid_utf8)).unwrap();
+        let path = Path::new(Url::new(uri));
+
+        // We should always get a valid utf8 string
+        assert!(String::from_utf8(path.as_str().as_bytes().to_owned()).is_ok());
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_test/lib.rs.html b/src/actix_test/lib.rs.html new file mode 100644 index 000000000..6936f09cb --- /dev/null +++ b/src/actix_test/lib.rs.html @@ -0,0 +1,1499 @@ +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
+
//! Integration testing tools for Actix Web applications.
+//!
+//! The main integration testing tool is [`TestServer`]. It spawns a real HTTP server on an
+//! unused port and provides methods that use a real HTTP client. Therefore, it is much closer to
+//! real-world cases than using `init_service`, which skips HTTP encoding and decoding.
+//!
+//! # Examples
+//! ```
+//! use actix_web::{get, web, test, App, HttpResponse, Error, Responder};
+//!
+//! #[get("/")]
+//! async fn my_handler() -> Result<impl Responder, Error> {
+//!     Ok(HttpResponse::Ok())
+//! }
+//!
+//! #[actix_rt::test]
+//! async fn test_example() {
+//!     let srv = actix_test::start(||
+//!         App::new().service(my_handler)
+//!     );
+//!
+//!     let req = srv.get("/");
+//!     let res = req.send().await.unwrap();
+//!
+//!     assert!(res.status().is_success());
+//! }
+//! ```
+
+#![deny(rust_2018_idioms, nonstandard_style)]
+#![warn(future_incompatible)]
+#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
+#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+
+#[cfg(feature = "openssl")]
+extern crate tls_openssl as openssl;
+
+use std::{fmt, net, thread, time::Duration};
+
+use actix_codec::{AsyncRead, AsyncWrite, Framed};
+pub use actix_http::{body::to_bytes, test::TestBuffer};
+use actix_http::{header::HeaderMap, ws, HttpService, Method, Request, Response};
+pub use actix_http_test::unused_addr;
+use actix_service::{map_config, IntoServiceFactory, ServiceFactory, ServiceFactoryExt as _};
+pub use actix_web::test::{
+    call_and_read_body, call_and_read_body_json, call_service, init_service, ok_service, read_body,
+    read_body_json, status_service, TestRequest,
+};
+use actix_web::{
+    body::MessageBody,
+    dev::{AppConfig, Server, ServerHandle, Service},
+    rt::{self, System},
+    web, Error,
+};
+pub use awc::{error::PayloadError, Client, ClientRequest, ClientResponse, Connector};
+use futures_core::Stream;
+use tokio::sync::mpsc;
+
+/// Start default [`TestServer`].
+///
+/// # Examples
+/// ```
+/// use actix_web::{get, web, test, App, HttpResponse, Error, Responder};
+///
+/// #[get("/")]
+/// async fn my_handler() -> Result<impl Responder, Error> {
+///     Ok(HttpResponse::Ok())
+/// }
+///
+/// #[actix_web::test]
+/// async fn test_example() {
+///     let srv = actix_test::start(||
+///         App::new().service(my_handler)
+///     );
+///
+///     let req = srv.get("/");
+///     let res = req.send().await.unwrap();
+///
+///     assert!(res.status().is_success());
+/// }
+/// ```
+pub fn start<F, I, S, B>(factory: F) -> TestServer
+where
+    F: Fn() -> I + Send + Clone + 'static,
+    I: IntoServiceFactory<S, Request>,
+    S: ServiceFactory<Request, Config = AppConfig> + 'static,
+    S::Error: Into<Error> + 'static,
+    S::InitError: fmt::Debug,
+    S::Response: Into<Response<B>> + 'static,
+    <S::Service as Service<Request>>::Future: 'static,
+    B: MessageBody + 'static,
+{
+    start_with(TestServerConfig::default(), factory)
+}
+
+/// Start test server with custom configuration
+///
+/// Check [`TestServerConfig`] docs for configuration options.
+///
+/// # Examples
+/// ```
+/// use actix_web::{get, web, test, App, HttpResponse, Error, Responder};
+///
+/// #[get("/")]
+/// async fn my_handler() -> Result<impl Responder, Error> {
+///     Ok(HttpResponse::Ok())
+/// }
+///
+/// #[actix_web::test]
+/// async fn test_example() {
+///     let srv = actix_test::start_with(actix_test::config().h1(), ||
+///         App::new().service(my_handler)
+///     );
+///
+///     let req = srv.get("/");
+///     let res = req.send().await.unwrap();
+///
+///     assert!(res.status().is_success());
+/// }
+/// ```
+pub fn start_with<F, I, S, B>(cfg: TestServerConfig, factory: F) -> TestServer
+where
+    F: Fn() -> I + Send + Clone + 'static,
+    I: IntoServiceFactory<S, Request>,
+    S: ServiceFactory<Request, Config = AppConfig> + 'static,
+    S::Error: Into<Error> + 'static,
+    S::InitError: fmt::Debug,
+    S::Response: Into<Response<B>> + 'static,
+    <S::Service as Service<Request>>::Future: 'static,
+    B: MessageBody + 'static,
+{
+    // for sending handles and server info back from the spawned thread
+    let (started_tx, started_rx) = std::sync::mpsc::channel();
+
+    // for signaling the shutdown of spawned server and system
+    let (thread_stop_tx, thread_stop_rx) = mpsc::channel(1);
+
+    let tls = match cfg.stream {
+        StreamType::Tcp => false,
+        #[cfg(feature = "openssl")]
+        StreamType::Openssl(_) => true,
+        #[cfg(feature = "rustls-0_20")]
+        StreamType::Rustls020(_) => true,
+        #[cfg(feature = "rustls-0_21")]
+        StreamType::Rustls021(_) => true,
+        #[cfg(feature = "rustls-0_22")]
+        StreamType::Rustls022(_) => true,
+        #[cfg(feature = "rustls-0_23")]
+        StreamType::Rustls023(_) => true,
+    };
+
+    // run server in separate orphaned thread
+    thread::spawn(move || {
+        rt::System::new().block_on(async move {
+            let tcp = net::TcpListener::bind(("127.0.0.1", cfg.port)).unwrap();
+            let local_addr = tcp.local_addr().unwrap();
+            let factory = factory.clone();
+            let srv_cfg = cfg.clone();
+            let timeout = cfg.client_request_timeout;
+
+            let builder = Server::build()
+                .workers(cfg.workers)
+                .disable_signals()
+                .system_exit();
+
+            let srv = match srv_cfg.stream {
+                StreamType::Tcp => match srv_cfg.tp {
+                    HttpVer::Http1 => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .h1(map_config(fac, move |_| app_cfg.clone()))
+                            .tcp()
+                    }),
+                    HttpVer::Http2 => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .h2(map_config(fac, move |_| app_cfg.clone()))
+                            .tcp()
+                    }),
+                    HttpVer::Both => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .finish(map_config(fac, move |_| app_cfg.clone()))
+                            .tcp()
+                    }),
+                },
+                #[cfg(feature = "openssl")]
+                StreamType::Openssl(acceptor) => match cfg.tp {
+                    HttpVer::Http1 => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .h1(map_config(fac, move |_| app_cfg.clone()))
+                            .openssl(acceptor.clone())
+                    }),
+                    HttpVer::Http2 => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .h2(map_config(fac, move |_| app_cfg.clone()))
+                            .openssl(acceptor.clone())
+                    }),
+                    HttpVer::Both => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .finish(map_config(fac, move |_| app_cfg.clone()))
+                            .openssl(acceptor.clone())
+                    }),
+                },
+                #[cfg(feature = "rustls-0_20")]
+                StreamType::Rustls020(config) => match cfg.tp {
+                    HttpVer::Http1 => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .h1(map_config(fac, move |_| app_cfg.clone()))
+                            .rustls(config.clone())
+                    }),
+                    HttpVer::Http2 => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .h2(map_config(fac, move |_| app_cfg.clone()))
+                            .rustls(config.clone())
+                    }),
+                    HttpVer::Both => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .finish(map_config(fac, move |_| app_cfg.clone()))
+                            .rustls(config.clone())
+                    }),
+                },
+                #[cfg(feature = "rustls-0_21")]
+                StreamType::Rustls021(config) => match cfg.tp {
+                    HttpVer::Http1 => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .h1(map_config(fac, move |_| app_cfg.clone()))
+                            .rustls_021(config.clone())
+                    }),
+                    HttpVer::Http2 => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .h2(map_config(fac, move |_| app_cfg.clone()))
+                            .rustls_021(config.clone())
+                    }),
+                    HttpVer::Both => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .finish(map_config(fac, move |_| app_cfg.clone()))
+                            .rustls_021(config.clone())
+                    }),
+                },
+                #[cfg(feature = "rustls-0_22")]
+                StreamType::Rustls022(config) => match cfg.tp {
+                    HttpVer::Http1 => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .h1(map_config(fac, move |_| app_cfg.clone()))
+                            .rustls_0_22(config.clone())
+                    }),
+                    HttpVer::Http2 => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .h2(map_config(fac, move |_| app_cfg.clone()))
+                            .rustls_0_22(config.clone())
+                    }),
+                    HttpVer::Both => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .finish(map_config(fac, move |_| app_cfg.clone()))
+                            .rustls_0_22(config.clone())
+                    }),
+                },
+                #[cfg(feature = "rustls-0_23")]
+                StreamType::Rustls023(config) => match cfg.tp {
+                    HttpVer::Http1 => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .h1(map_config(fac, move |_| app_cfg.clone()))
+                            .rustls_0_23(config.clone())
+                    }),
+                    HttpVer::Http2 => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .h2(map_config(fac, move |_| app_cfg.clone()))
+                            .rustls_0_23(config.clone())
+                    }),
+                    HttpVer::Both => builder.listen("test", tcp, move || {
+                        let app_cfg =
+                            AppConfig::__priv_test_new(false, local_addr.to_string(), local_addr);
+
+                        let fac = factory()
+                            .into_factory()
+                            .map_err(|err| err.into().error_response());
+
+                        HttpService::build()
+                            .client_request_timeout(timeout)
+                            .finish(map_config(fac, move |_| app_cfg.clone()))
+                            .rustls_0_23(config.clone())
+                    }),
+                },
+            }
+            .expect("test server could not be created");
+
+            let srv = srv.run();
+            started_tx
+                .send((System::current(), srv.handle(), local_addr))
+                .unwrap();
+
+            // drive server loop
+            srv.await.unwrap();
+
+            // notify TestServer that server and system have shut down
+            // all thread managed resources should be dropped at this point
+        });
+
+        #[allow(clippy::let_underscore_future)]
+        let _ = thread_stop_tx.send(());
+    });
+
+    let (system, server, addr) = started_rx.recv().unwrap();
+
+    let client = {
+        let connector = {
+            #[cfg(feature = "openssl")]
+            {
+                use openssl::ssl::{SslConnector, SslMethod, SslVerifyMode};
+
+                let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
+                builder.set_verify(SslVerifyMode::NONE);
+                let _ = builder
+                    .set_alpn_protos(b"\x02h2\x08http/1.1")
+                    .map_err(|err| log::error!("Can not set alpn protocol: {err:?}"));
+                Connector::new()
+                    .conn_lifetime(Duration::from_secs(0))
+                    .timeout(Duration::from_millis(30000))
+                    .openssl(builder.build())
+            }
+            #[cfg(not(feature = "openssl"))]
+            {
+                Connector::new()
+                    .conn_lifetime(Duration::from_secs(0))
+                    .timeout(Duration::from_millis(30000))
+            }
+        };
+
+        Client::builder().connector(connector).finish()
+    };
+
+    TestServer {
+        server,
+        thread_stop_rx,
+        client,
+        system,
+        addr,
+        tls,
+    }
+}
+
+#[derive(Debug, Clone)]
+enum HttpVer {
+    Http1,
+    Http2,
+    Both,
+}
+
+#[derive(Clone)]
+enum StreamType {
+    Tcp,
+    #[cfg(feature = "openssl")]
+    Openssl(openssl::ssl::SslAcceptor),
+    #[cfg(feature = "rustls-0_20")]
+    Rustls020(tls_rustls_0_20::ServerConfig),
+    #[cfg(feature = "rustls-0_21")]
+    Rustls021(tls_rustls_0_21::ServerConfig),
+    #[cfg(feature = "rustls-0_22")]
+    Rustls022(tls_rustls_0_22::ServerConfig),
+    #[cfg(feature = "rustls-0_23")]
+    Rustls023(tls_rustls_0_23::ServerConfig),
+}
+
+/// Create default test server config.
+pub fn config() -> TestServerConfig {
+    TestServerConfig::default()
+}
+
+#[derive(Clone)]
+pub struct TestServerConfig {
+    tp: HttpVer,
+    stream: StreamType,
+    client_request_timeout: Duration,
+    port: u16,
+    workers: usize,
+}
+
+impl Default for TestServerConfig {
+    fn default() -> Self {
+        TestServerConfig::new()
+    }
+}
+
+impl TestServerConfig {
+    /// Constructs default server configuration.
+    pub(crate) fn new() -> TestServerConfig {
+        TestServerConfig {
+            tp: HttpVer::Both,
+            stream: StreamType::Tcp,
+            client_request_timeout: Duration::from_secs(5),
+            port: 0,
+            workers: 1,
+        }
+    }
+
+    /// Accepts HTTP/1.1 only.
+    pub fn h1(mut self) -> Self {
+        self.tp = HttpVer::Http1;
+        self
+    }
+
+    /// Accepts HTTP/2 only.
+    pub fn h2(mut self) -> Self {
+        self.tp = HttpVer::Http2;
+        self
+    }
+
+    /// Accepts secure connections via OpenSSL.
+    #[cfg(feature = "openssl")]
+    pub fn openssl(mut self, acceptor: openssl::ssl::SslAcceptor) -> Self {
+        self.stream = StreamType::Openssl(acceptor);
+        self
+    }
+
+    #[doc(hidden)]
+    #[deprecated(note = "Renamed to `rustls_0_20()`.")]
+    #[cfg(feature = "rustls-0_20")]
+    pub fn rustls(mut self, config: tls_rustls_0_20::ServerConfig) -> Self {
+        self.stream = StreamType::Rustls020(config);
+        self
+    }
+
+    /// Accepts secure connections via Rustls v0.20.
+    #[cfg(feature = "rustls-0_20")]
+    pub fn rustls_0_20(mut self, config: tls_rustls_0_20::ServerConfig) -> Self {
+        self.stream = StreamType::Rustls020(config);
+        self
+    }
+
+    #[doc(hidden)]
+    #[deprecated(note = "Renamed to `rustls_0_21()`.")]
+    #[cfg(feature = "rustls-0_21")]
+    pub fn rustls_021(mut self, config: tls_rustls_0_21::ServerConfig) -> Self {
+        self.stream = StreamType::Rustls021(config);
+        self
+    }
+
+    /// Accepts secure connections via Rustls v0.21.
+    #[cfg(feature = "rustls-0_21")]
+    pub fn rustls_0_21(mut self, config: tls_rustls_0_21::ServerConfig) -> Self {
+        self.stream = StreamType::Rustls021(config);
+        self
+    }
+
+    /// Accepts secure connections via Rustls v0.22.
+    #[cfg(feature = "rustls-0_22")]
+    pub fn rustls_0_22(mut self, config: tls_rustls_0_22::ServerConfig) -> Self {
+        self.stream = StreamType::Rustls022(config);
+        self
+    }
+
+    /// Accepts secure connections via Rustls v0.23.
+    #[cfg(feature = "rustls-0_23")]
+    pub fn rustls_0_23(mut self, config: tls_rustls_0_23::ServerConfig) -> Self {
+        self.stream = StreamType::Rustls023(config);
+        self
+    }
+
+    /// Sets client timeout for first request.
+    pub fn client_request_timeout(mut self, dur: Duration) -> Self {
+        self.client_request_timeout = dur;
+        self
+    }
+
+    /// Sets test server port.
+    ///
+    /// By default, a random free port is determined by the OS.
+    pub fn port(mut self, port: u16) -> Self {
+        self.port = port;
+        self
+    }
+
+    /// Sets number of workers for the test server.
+    ///
+    /// By default, the server uses 1 worker
+    pub fn workers(mut self, workers: usize) -> Self {
+        self.workers = workers;
+        self
+    }
+}
+
+/// A basic HTTP server controller that simplifies the process of writing integration tests for
+/// Actix Web applications.
+///
+/// See [`start`] for usage example.
+pub struct TestServer {
+    server: ServerHandle,
+    thread_stop_rx: mpsc::Receiver<()>,
+    client: awc::Client,
+    system: rt::System,
+    addr: net::SocketAddr,
+    tls: bool,
+}
+
+impl TestServer {
+    /// Construct test server url
+    pub fn addr(&self) -> net::SocketAddr {
+        self.addr
+    }
+
+    /// Construct test server url
+    pub fn url(&self, uri: &str) -> String {
+        let scheme = if self.tls { "https" } else { "http" };
+
+        if uri.starts_with('/') {
+            format!("{}://localhost:{}{}", scheme, self.addr.port(), uri)
+        } else {
+            format!("{}://localhost:{}/{}", scheme, self.addr.port(), uri)
+        }
+    }
+
+    /// Create `GET` request.
+    pub fn get(&self, path: impl AsRef<str>) -> ClientRequest {
+        self.client.get(self.url(path.as_ref()).as_str())
+    }
+
+    /// Create `POST` request.
+    pub fn post(&self, path: impl AsRef<str>) -> ClientRequest {
+        self.client.post(self.url(path.as_ref()).as_str())
+    }
+
+    /// Create `HEAD` request.
+    pub fn head(&self, path: impl AsRef<str>) -> ClientRequest {
+        self.client.head(self.url(path.as_ref()).as_str())
+    }
+
+    /// Create `PUT` request.
+    pub fn put(&self, path: impl AsRef<str>) -> ClientRequest {
+        self.client.put(self.url(path.as_ref()).as_str())
+    }
+
+    /// Create `PATCH` request.
+    pub fn patch(&self, path: impl AsRef<str>) -> ClientRequest {
+        self.client.patch(self.url(path.as_ref()).as_str())
+    }
+
+    /// Create `DELETE` request.
+    pub fn delete(&self, path: impl AsRef<str>) -> ClientRequest {
+        self.client.delete(self.url(path.as_ref()).as_str())
+    }
+
+    /// Create `OPTIONS` request.
+    pub fn options(&self, path: impl AsRef<str>) -> ClientRequest {
+        self.client.options(self.url(path.as_ref()).as_str())
+    }
+
+    /// Connect request with given method and path.
+    pub fn request(&self, method: Method, path: impl AsRef<str>) -> ClientRequest {
+        self.client.request(method, path.as_ref())
+    }
+
+    pub async fn load_body<S>(
+        &mut self,
+        mut response: ClientResponse<S>,
+    ) -> Result<web::Bytes, PayloadError>
+    where
+        S: Stream<Item = Result<web::Bytes, PayloadError>> + Unpin + 'static,
+    {
+        response.body().limit(10_485_760).await
+    }
+
+    /// Connect to WebSocket server at a given path.
+    pub async fn ws_at(
+        &mut self,
+        path: &str,
+    ) -> Result<Framed<impl AsyncRead + AsyncWrite, ws::Codec>, awc::error::WsClientError> {
+        let url = self.url(path);
+        let connect = self.client.ws(url).connect();
+        connect.await.map(|(_, framed)| framed)
+    }
+
+    /// Connect to a WebSocket server.
+    pub async fn ws(
+        &mut self,
+    ) -> Result<Framed<impl AsyncRead + AsyncWrite, ws::Codec>, awc::error::WsClientError> {
+        self.ws_at("/").await
+    }
+
+    /// Get default HeaderMap of Client.
+    ///
+    /// Returns Some(&mut HeaderMap) when Client object is unique
+    /// (No other clone of client exists at the same time).
+    pub fn client_headers(&mut self) -> Option<&mut HeaderMap> {
+        self.client.headers()
+    }
+
+    /// Stop HTTP server.
+    ///
+    /// Waits for spawned `Server` and `System` to shutdown (force) shutdown.
+    pub async fn stop(mut self) {
+        // signal server to stop
+        self.server.stop(false).await;
+
+        // also signal system to stop
+        // though this is handled by `ServerBuilder::exit_system` too
+        self.system.stop();
+
+        // wait for thread to be stopped but don't care about result
+        let _ = self.thread_stop_rx.recv().await;
+    }
+}
+
+impl Drop for TestServer {
+    fn drop(&mut self) {
+        // calls in this Drop impl should be enough to shut down the server, system, and thread
+        // without needing to await anything
+
+        // signal server to stop
+        #[allow(clippy::let_underscore_future)]
+        let _ = self.server.stop(true);
+
+        // signal system to stop
+        self.system.stop();
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/app.rs.html b/src/actix_web/app.rs.html new file mode 100644 index 000000000..b716a2cd5 --- /dev/null +++ b/src/actix_web/app.rs.html @@ -0,0 +1,1413 @@ +app.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
+
use std::{cell::RefCell, fmt, future::Future, rc::Rc};
+
+use actix_http::{body::MessageBody, Extensions, Request};
+use actix_service::{
+    apply, apply_fn_factory, boxed, IntoServiceFactory, ServiceFactory, ServiceFactoryExt,
+    Transform,
+};
+use futures_util::FutureExt as _;
+
+use crate::{
+    app_service::{AppEntry, AppInit, AppRoutingFactory},
+    config::ServiceConfig,
+    data::{Data, DataFactory, FnDataFactory},
+    dev::ResourceDef,
+    error::Error,
+    resource::Resource,
+    route::Route,
+    service::{
+        AppServiceFactory, BoxedHttpServiceFactory, HttpServiceFactory, ServiceFactoryWrapper,
+        ServiceRequest, ServiceResponse,
+    },
+};
+
+/// The top-level builder for an Actix Web application.
+pub struct App<T> {
+    endpoint: T,
+    services: Vec<Box<dyn AppServiceFactory>>,
+    default: Option<Rc<BoxedHttpServiceFactory>>,
+    factory_ref: Rc<RefCell<Option<AppRoutingFactory>>>,
+    data_factories: Vec<FnDataFactory>,
+    external: Vec<ResourceDef>,
+    extensions: Extensions,
+}
+
+impl App<AppEntry> {
+    /// Create application builder. Application can be configured with a builder-like pattern.
+    #[allow(clippy::new_without_default)]
+    pub fn new() -> Self {
+        let factory_ref = Rc::new(RefCell::new(None));
+
+        App {
+            endpoint: AppEntry::new(factory_ref.clone()),
+            data_factories: Vec::new(),
+            services: Vec::new(),
+            default: None,
+            factory_ref,
+            external: Vec::new(),
+            extensions: Extensions::new(),
+        }
+    }
+}
+
+impl<T> App<T>
+where
+    T: ServiceFactory<ServiceRequest, Config = (), Error = Error, InitError = ()>,
+{
+    /// Set application (root level) data.
+    ///
+    /// Application data stored with `App::app_data()` method is available through the
+    /// [`HttpRequest::app_data`](crate::HttpRequest::app_data) method at runtime.
+    ///
+    /// # [`Data<T>`]
+    /// Any [`Data<T>`] type added here can utilize its extractor implementation in handlers.
+    /// Types not wrapped in `Data<T>` cannot use this extractor. See [its docs](Data<T>) for more
+    /// about its usage and patterns.
+    ///
+    /// ```
+    /// use std::cell::Cell;
+    /// use actix_web::{web, App, HttpRequest, HttpResponse, Responder};
+    ///
+    /// struct MyData {
+    ///     count: std::cell::Cell<usize>,
+    /// }
+    ///
+    /// async fn handler(req: HttpRequest, counter: web::Data<MyData>) -> impl Responder {
+    ///     // note this cannot use the Data<T> extractor because it was not added with it
+    ///     let incr = *req.app_data::<usize>().unwrap();
+    ///     assert_eq!(incr, 3);
+    ///
+    ///     // update counter using other value from app data
+    ///     counter.count.set(counter.count.get() + incr);
+    ///
+    ///     HttpResponse::Ok().body(counter.count.get().to_string())
+    /// }
+    ///
+    /// let app = App::new().service(
+    ///     web::resource("/")
+    ///         .app_data(3usize)
+    ///         .app_data(web::Data::new(MyData { count: Default::default() }))
+    ///         .route(web::get().to(handler))
+    /// );
+    /// ```
+    ///
+    /// # Shared Mutable State
+    /// [`HttpServer::new`](crate::HttpServer::new) accepts an application factory rather than an
+    /// application instance; the factory closure is called on each worker thread independently.
+    /// Therefore, if you want to share a data object between different workers, a shareable object
+    /// needs to be created first, outside the `HttpServer::new` closure and cloned into it.
+    /// [`Data<T>`] is an example of such a sharable object.
+    ///
+    /// ```ignore
+    /// let counter = web::Data::new(AppStateWithCounter {
+    ///     counter: Mutex::new(0),
+    /// });
+    ///
+    /// HttpServer::new(move || {
+    ///     // move counter object into the closure and clone for each worker
+    ///
+    ///     App::new()
+    ///         .app_data(counter.clone())
+    ///         .route("/", web::get().to(handler))
+    /// })
+    /// ```
+    #[doc(alias = "manage")]
+    pub fn app_data<U: 'static>(mut self, ext: U) -> Self {
+        self.extensions.insert(ext);
+        self
+    }
+
+    /// Add application (root) data after wrapping in `Data<T>`.
+    ///
+    /// Deprecated in favor of [`app_data`](Self::app_data).
+    #[deprecated(since = "4.0.0", note = "Use `.app_data(Data::new(val))` instead.")]
+    pub fn data<U: 'static>(self, data: U) -> Self {
+        self.app_data(Data::new(data))
+    }
+
+    /// Add application data factory that resolves asynchronously.
+    ///
+    /// Data items are constructed during application initialization, before the server starts
+    /// accepting requests.
+    ///
+    /// The returned data value `D` is wrapped as [`Data<D>`].
+    pub fn data_factory<F, Out, D, E>(mut self, data: F) -> Self
+    where
+        F: Fn() -> Out + 'static,
+        Out: Future<Output = Result<D, E>> + 'static,
+        D: 'static,
+        E: std::fmt::Debug,
+    {
+        self.data_factories.push(Box::new(move || {
+            {
+                let fut = data();
+                async move {
+                    match fut.await {
+                        Err(err) => {
+                            log::error!("Can not construct data instance: {err:?}");
+                            Err(())
+                        }
+                        Ok(data) => {
+                            let data: Box<dyn DataFactory> = Box::new(Data::new(data));
+                            Ok(data)
+                        }
+                    }
+                }
+            }
+            .boxed_local()
+        }));
+
+        self
+    }
+
+    /// Run external configuration as part of the application building
+    /// process
+    ///
+    /// This function is useful for moving parts of configuration to a
+    /// different module or even library. For example,
+    /// some of the resource's configuration could be moved to different module.
+    ///
+    /// ```
+    /// use actix_web::{web, App, HttpResponse};
+    ///
+    /// // this function could be located in different module
+    /// fn config(cfg: &mut web::ServiceConfig) {
+    ///     cfg.service(web::resource("/test")
+    ///         .route(web::get().to(|| HttpResponse::Ok()))
+    ///         .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
+    ///     );
+    /// }
+    ///
+    /// App::new()
+    ///     .configure(config)  // <- register resources
+    ///     .route("/index.html", web::get().to(|| HttpResponse::Ok()));
+    /// ```
+    pub fn configure<F>(mut self, f: F) -> Self
+    where
+        F: FnOnce(&mut ServiceConfig),
+    {
+        let mut cfg = ServiceConfig::new();
+
+        f(&mut cfg);
+
+        self.services.extend(cfg.services);
+        self.external.extend(cfg.external);
+        self.extensions.extend(cfg.app_data);
+
+        if let Some(default) = cfg.default {
+            self.default = Some(default);
+        }
+
+        self
+    }
+
+    /// Configure route for a specific path.
+    ///
+    /// This is a simplified version of the `App::service()` method.
+    /// This method can be used multiple times with same path, in that case
+    /// multiple resources with one route would be registered for same resource path.
+    ///
+    /// ```
+    /// use actix_web::{web, App, HttpResponse};
+    ///
+    /// async fn index(data: web::Path<(String, String)>) -> &'static str {
+    ///     "Welcome!"
+    /// }
+    ///
+    /// let app = App::new()
+    ///     .route("/test1", web::get().to(index))
+    ///     .route("/test2", web::post().to(|| HttpResponse::MethodNotAllowed()));
+    /// ```
+    pub fn route(self, path: &str, mut route: Route) -> Self {
+        self.service(
+            Resource::new(path)
+                .add_guards(route.take_guards())
+                .route(route),
+        )
+    }
+
+    /// Register HTTP service.
+    ///
+    /// Http service is any type that implements `HttpServiceFactory` trait.
+    ///
+    /// Actix Web provides several services implementations:
+    ///
+    /// * *Resource* is an entry in resource table which corresponds to requested URL.
+    /// * *Scope* is a set of resources with common root path.
+    /// * "StaticFiles" is a service for static files support
+    pub fn service<F>(mut self, factory: F) -> Self
+    where
+        F: HttpServiceFactory + 'static,
+    {
+        self.services
+            .push(Box::new(ServiceFactoryWrapper::new(factory)));
+        self
+    }
+
+    /// Default service that is invoked when no matching resource could be found.
+    ///
+    /// You can use a [`Route`] as default service.
+    ///
+    /// If a default service is not registered, an empty `404 Not Found` response will be sent to
+    /// the client instead.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::{web, App, HttpResponse};
+    ///
+    /// async fn index() -> &'static str {
+    ///     "Welcome!"
+    /// }
+    ///
+    /// let app = App::new()
+    ///     .service(web::resource("/index.html").route(web::get().to(index)))
+    ///     .default_service(web::to(|| HttpResponse::NotFound()));
+    /// ```
+    pub fn default_service<F, U>(mut self, svc: F) -> Self
+    where
+        F: IntoServiceFactory<U, ServiceRequest>,
+        U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error>
+            + 'static,
+        U::InitError: fmt::Debug,
+    {
+        let svc = svc
+            .into_factory()
+            .map_init_err(|e| log::error!("Can not construct default service: {:?}", e));
+
+        self.default = Some(Rc::new(boxed::factory(svc)));
+
+        self
+    }
+
+    /// Register an external resource.
+    ///
+    /// External resources are useful for URL generation purposes only
+    /// and are never considered for matching at request time. Calls to
+    /// `HttpRequest::url_for()` will work as expected.
+    ///
+    /// ```
+    /// use actix_web::{web, App, HttpRequest, HttpResponse, Result};
+    ///
+    /// async fn index(req: HttpRequest) -> Result<HttpResponse> {
+    ///     let url = req.url_for("youtube", &["asdlkjqme"])?;
+    ///     assert_eq!(url.as_str(), "https://youtube.com/watch/asdlkjqme");
+    ///     Ok(HttpResponse::Ok().into())
+    /// }
+    ///
+    /// let app = App::new()
+    ///     .service(web::resource("/index.html").route(
+    ///         web::get().to(index)))
+    ///     .external_resource("youtube", "https://youtube.com/watch/{video_id}");
+    /// ```
+    pub fn external_resource<N, U>(mut self, name: N, url: U) -> Self
+    where
+        N: AsRef<str>,
+        U: AsRef<str>,
+    {
+        let mut rdef = ResourceDef::new(url.as_ref());
+        rdef.set_name(name.as_ref());
+        self.external.push(rdef);
+        self
+    }
+
+    /// Registers an app-wide middleware.
+    ///
+    /// Registers middleware, in the form of a middleware component (type), that runs during
+    /// inbound and/or outbound processing in the request life-cycle (request -> response),
+    /// modifying request/response as necessary, across all requests managed by the `App`.
+    ///
+    /// Use middleware when you need to read or modify *every* request or response in some way.
+    ///
+    /// Middleware can be applied similarly to individual `Scope`s and `Resource`s.
+    /// See [`Scope::wrap`](crate::Scope::wrap) and [`Resource::wrap`].
+    ///
+    /// For more info on middleware take a look at the [`middleware` module][crate::middleware].
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::{middleware, web, App};
+    ///
+    /// async fn index() -> &'static str {
+    ///     "Welcome!"
+    /// }
+    ///
+    /// let app = App::new()
+    ///     .wrap(middleware::Logger::default())
+    ///     .route("/index.html", web::get().to(index));
+    /// ```
+    #[doc(alias = "middleware")]
+    #[doc(alias = "use")] // nodejs terminology
+    pub fn wrap<M, B>(
+        self,
+        mw: M,
+    ) -> App<
+        impl ServiceFactory<
+            ServiceRequest,
+            Config = (),
+            Response = ServiceResponse<B>,
+            Error = Error,
+            InitError = (),
+        >,
+    >
+    where
+        M: Transform<
+                T::Service,
+                ServiceRequest,
+                Response = ServiceResponse<B>,
+                Error = Error,
+                InitError = (),
+            > + 'static,
+        B: MessageBody,
+    {
+        App {
+            endpoint: apply(mw, self.endpoint),
+            data_factories: self.data_factories,
+            services: self.services,
+            default: self.default,
+            factory_ref: self.factory_ref,
+            external: self.external,
+            extensions: self.extensions,
+        }
+    }
+
+    /// Registers an app-wide function middleware.
+    ///
+    /// `mw` is a closure that runs during inbound and/or outbound processing in the request
+    /// life-cycle (request -> response), modifying request/response as necessary, across all
+    /// requests handled by the `App`.
+    ///
+    /// Use middleware when you need to read or modify *every* request or response in some way.
+    ///
+    /// Middleware can also be applied to individual `Scope`s and `Resource`s.
+    ///
+    /// See [`App::wrap`] for details on how middlewares compose with each other.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::{dev::Service as _, middleware, web, App};
+    /// use actix_web::http::header::{CONTENT_TYPE, HeaderValue};
+    ///
+    /// async fn index() -> &'static str {
+    ///     "Welcome!"
+    /// }
+    ///
+    /// let app = App::new()
+    ///     .wrap_fn(|req, srv| {
+    ///         let fut = srv.call(req);
+    ///         async {
+    ///             let mut res = fut.await?;
+    ///             res.headers_mut()
+    ///                 .insert(CONTENT_TYPE, HeaderValue::from_static("text/plain"));
+    ///             Ok(res)
+    ///         }
+    ///     })
+    ///     .route("/index.html", web::get().to(index));
+    /// ```
+    #[doc(alias = "middleware")]
+    #[doc(alias = "use")] // nodejs terminology
+    pub fn wrap_fn<F, R, B>(
+        self,
+        mw: F,
+    ) -> App<
+        impl ServiceFactory<
+            ServiceRequest,
+            Config = (),
+            Response = ServiceResponse<B>,
+            Error = Error,
+            InitError = (),
+        >,
+    >
+    where
+        F: Fn(ServiceRequest, &T::Service) -> R + Clone + 'static,
+        R: Future<Output = Result<ServiceResponse<B>, Error>>,
+        B: MessageBody,
+    {
+        App {
+            endpoint: apply_fn_factory(self.endpoint, mw),
+            data_factories: self.data_factories,
+            services: self.services,
+            default: self.default,
+            factory_ref: self.factory_ref,
+            external: self.external,
+            extensions: self.extensions,
+        }
+    }
+}
+
+impl<T, B> IntoServiceFactory<AppInit<T, B>, Request> for App<T>
+where
+    T: ServiceFactory<
+            ServiceRequest,
+            Config = (),
+            Response = ServiceResponse<B>,
+            Error = Error,
+            InitError = (),
+        > + 'static,
+    B: MessageBody,
+{
+    fn into_factory(self) -> AppInit<T, B> {
+        AppInit {
+            async_data_factories: self.data_factories.into_boxed_slice().into(),
+            endpoint: self.endpoint,
+            services: Rc::new(RefCell::new(self.services)),
+            external: RefCell::new(self.external),
+            default: self.default,
+            factory_ref: self.factory_ref,
+            extensions: RefCell::new(Some(self.extensions)),
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_service::Service as _;
+    use actix_utils::future::{err, ok};
+    use bytes::Bytes;
+
+    use super::*;
+    use crate::{
+        http::{
+            header::{self, HeaderValue},
+            Method, StatusCode,
+        },
+        middleware::DefaultHeaders,
+        test::{call_service, init_service, read_body, try_init_service, TestRequest},
+        web, HttpRequest, HttpResponse,
+    };
+
+    #[actix_rt::test]
+    async fn test_default_resource() {
+        let srv =
+            init_service(App::new().service(web::resource("/test").to(HttpResponse::Ok))).await;
+        let req = TestRequest::with_uri("/test").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/blah").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+
+        let srv = init_service(
+            App::new()
+                .service(web::resource("/test").to(HttpResponse::Ok))
+                .service(
+                    web::resource("/test2")
+                        .default_service(|r: ServiceRequest| {
+                            ok(r.into_response(HttpResponse::Created()))
+                        })
+                        .route(web::get().to(HttpResponse::Ok)),
+                )
+                .default_service(|r: ServiceRequest| {
+                    ok(r.into_response(HttpResponse::MethodNotAllowed()))
+                }),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/blah").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
+
+        let req = TestRequest::with_uri("/test2").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/test2")
+            .method(Method::POST)
+            .to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::CREATED);
+    }
+
+    // allow deprecated App::data
+    #[allow(deprecated)]
+    #[actix_rt::test]
+    async fn test_data_factory() {
+        let srv = init_service(
+            App::new()
+                .data_factory(|| ok::<_, ()>(10usize))
+                .service(web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok())),
+        )
+        .await;
+        let req = TestRequest::default().to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let srv = init_service(
+            App::new()
+                .data_factory(|| ok::<_, ()>(10u32))
+                .service(web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok())),
+        )
+        .await;
+        let req = TestRequest::default().to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
+    }
+
+    // allow deprecated App::data
+    #[allow(deprecated)]
+    #[actix_rt::test]
+    async fn test_data_factory_errors() {
+        let srv = try_init_service(
+            App::new()
+                .data_factory(|| err::<u32, _>(()))
+                .service(web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok())),
+        )
+        .await;
+
+        assert!(srv.is_err());
+    }
+
+    #[actix_rt::test]
+    async fn test_extension() {
+        let srv = init_service(App::new().app_data(10usize).service(web::resource("/").to(
+            |req: HttpRequest| {
+                assert_eq!(*req.app_data::<usize>().unwrap(), 10);
+                HttpResponse::Ok()
+            },
+        )))
+        .await;
+        let req = TestRequest::default().to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_wrap() {
+        let srv = init_service(
+            App::new()
+                .wrap(
+                    DefaultHeaders::new()
+                        .add((header::CONTENT_TYPE, HeaderValue::from_static("0001"))),
+                )
+                .route("/test", web::get().to(HttpResponse::Ok)),
+        )
+        .await;
+        let req = TestRequest::with_uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("0001")
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_router_wrap() {
+        let srv = init_service(
+            App::new()
+                .route("/test", web::get().to(HttpResponse::Ok))
+                .wrap(
+                    DefaultHeaders::new()
+                        .add((header::CONTENT_TYPE, HeaderValue::from_static("0001"))),
+                ),
+        )
+        .await;
+        let req = TestRequest::with_uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("0001")
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_wrap_fn() {
+        let srv = init_service(
+            App::new()
+                .wrap_fn(|req, srv| {
+                    let fut = srv.call(req);
+                    async move {
+                        let mut res = fut.await?;
+                        res.headers_mut()
+                            .insert(header::CONTENT_TYPE, HeaderValue::from_static("0001"));
+                        Ok(res)
+                    }
+                })
+                .service(web::resource("/test").to(HttpResponse::Ok)),
+        )
+        .await;
+        let req = TestRequest::with_uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("0001")
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_router_wrap_fn() {
+        let srv = init_service(
+            App::new()
+                .route("/test", web::get().to(HttpResponse::Ok))
+                .wrap_fn(|req, srv| {
+                    let fut = srv.call(req);
+                    async {
+                        let mut res = fut.await?;
+                        res.headers_mut()
+                            .insert(header::CONTENT_TYPE, HeaderValue::from_static("0001"));
+                        Ok(res)
+                    }
+                }),
+        )
+        .await;
+        let req = TestRequest::with_uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("0001")
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_external_resource() {
+        let srv = init_service(
+            App::new()
+                .external_resource("youtube", "https://youtube.com/watch/{video_id}")
+                .route(
+                    "/test",
+                    web::get().to(|req: HttpRequest| {
+                        HttpResponse::Ok()
+                            .body(req.url_for("youtube", ["12345"]).unwrap().to_string())
+                    }),
+                ),
+        )
+        .await;
+        let req = TestRequest::with_uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        let body = read_body(resp).await;
+        assert_eq!(body, Bytes::from_static(b"https://youtube.com/watch/12345"));
+    }
+
+    #[test]
+    fn can_be_returned_from_fn() {
+        /// compile-only test for returning app type from function
+        pub fn my_app() -> App<
+            impl ServiceFactory<
+                ServiceRequest,
+                Response = ServiceResponse<impl MessageBody>,
+                Config = (),
+                InitError = (),
+                Error = Error,
+            >,
+        > {
+            App::new()
+                // logger can be removed without affecting the return type
+                .wrap(crate::middleware::Logger::default())
+                .route("/", web::to(|| async { "hello" }))
+        }
+
+        #[allow(clippy::let_underscore_future)]
+        let _ = init_service(my_app());
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/app_service.rs.html b/src/actix_web/app_service.rs.html new file mode 100644 index 000000000..b245de5c6 --- /dev/null +++ b/src/actix_web/app_service.rs.html @@ -0,0 +1,773 @@ +app_service.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
+
use std::{cell::RefCell, mem, rc::Rc};
+
+use actix_http::Request;
+use actix_router::{Path, ResourceDef, Router, Url};
+use actix_service::{boxed, fn_service, Service, ServiceFactory};
+use futures_core::future::LocalBoxFuture;
+use futures_util::future::join_all;
+
+use crate::{
+    body::BoxBody,
+    config::{AppConfig, AppService},
+    data::FnDataFactory,
+    dev::Extensions,
+    guard::Guard,
+    request::{HttpRequest, HttpRequestPool},
+    rmap::ResourceMap,
+    service::{
+        AppServiceFactory, BoxedHttpService, BoxedHttpServiceFactory, ServiceRequest,
+        ServiceResponse,
+    },
+    Error, HttpResponse,
+};
+
+/// Service factory to convert [`Request`] to a [`ServiceRequest<S>`].
+///
+/// It also executes data factories.
+pub struct AppInit<T, B>
+where
+    T: ServiceFactory<
+        ServiceRequest,
+        Config = (),
+        Response = ServiceResponse<B>,
+        Error = Error,
+        InitError = (),
+    >,
+{
+    pub(crate) endpoint: T,
+    pub(crate) extensions: RefCell<Option<Extensions>>,
+    pub(crate) async_data_factories: Rc<[FnDataFactory]>,
+    pub(crate) services: Rc<RefCell<Vec<Box<dyn AppServiceFactory>>>>,
+    pub(crate) default: Option<Rc<BoxedHttpServiceFactory>>,
+    pub(crate) factory_ref: Rc<RefCell<Option<AppRoutingFactory>>>,
+    pub(crate) external: RefCell<Vec<ResourceDef>>,
+}
+
+impl<T, B> ServiceFactory<Request> for AppInit<T, B>
+where
+    T: ServiceFactory<
+        ServiceRequest,
+        Config = (),
+        Response = ServiceResponse<B>,
+        Error = Error,
+        InitError = (),
+    >,
+    T::Future: 'static,
+{
+    type Response = ServiceResponse<B>;
+    type Error = T::Error;
+    type Config = AppConfig;
+    type Service = AppInitService<T::Service, B>;
+    type InitError = T::InitError;
+    type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
+
+    fn new_service(&self, config: AppConfig) -> Self::Future {
+        // set AppService's default service to 404 NotFound
+        // if no user defined default service exists.
+        let default = self.default.clone().unwrap_or_else(|| {
+            Rc::new(boxed::factory(fn_service(|req: ServiceRequest| async {
+                Ok(req.into_response(HttpResponse::NotFound()))
+            })))
+        });
+
+        // create App config to pass to child services
+        let mut config = AppService::new(config, default.clone());
+
+        // register services
+        mem::take(&mut *self.services.borrow_mut())
+            .into_iter()
+            .for_each(|mut srv| srv.register(&mut config));
+
+        let mut rmap = ResourceMap::new(ResourceDef::prefix(""));
+
+        let (config, services) = config.into_services();
+
+        // complete pipeline creation.
+        *self.factory_ref.borrow_mut() = Some(AppRoutingFactory {
+            default,
+            services: services
+                .into_iter()
+                .map(|(mut rdef, srv, guards, nested)| {
+                    rmap.add(&mut rdef, nested);
+                    (rdef, srv, RefCell::new(guards))
+                })
+                .collect::<Vec<_>>()
+                .into_boxed_slice()
+                .into(),
+        });
+
+        // external resources
+        for mut rdef in mem::take(&mut *self.external.borrow_mut()) {
+            rmap.add(&mut rdef, None);
+        }
+
+        // complete ResourceMap tree creation
+        let rmap = Rc::new(rmap);
+        ResourceMap::finish(&rmap);
+
+        // construct all async data factory futures
+        let factory_futs = join_all(self.async_data_factories.iter().map(|f| f()));
+
+        // construct app service and middleware service factory future.
+        let endpoint_fut = self.endpoint.new_service(());
+
+        // take extensions or create new one as app data container.
+        let mut app_data = self.extensions.borrow_mut().take().unwrap_or_default();
+
+        Box::pin(async move {
+            // async data factories
+            let async_data_factories = factory_futs
+                .await
+                .into_iter()
+                .collect::<Result<Vec<_>, _>>()
+                .map_err(|_| ())?;
+
+            // app service and middleware
+            let service = endpoint_fut.await?;
+
+            // populate app data container from (async) data factories.
+            for factory in &async_data_factories {
+                factory.create(&mut app_data);
+            }
+
+            Ok(AppInitService {
+                service,
+                app_data: Rc::new(app_data),
+                app_state: AppInitServiceState::new(rmap, config),
+            })
+        })
+    }
+}
+
+/// The [`Service`] that is passed to `actix-http`'s server builder.
+///
+/// Wraps a service receiving a [`ServiceRequest`] into one receiving a [`Request`].
+pub struct AppInitService<T, B>
+where
+    T: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+{
+    service: T,
+    app_data: Rc<Extensions>,
+    app_state: Rc<AppInitServiceState>,
+}
+
+/// A collection of state for [`AppInitService`] that is shared across [`HttpRequest`]s.
+pub(crate) struct AppInitServiceState {
+    rmap: Rc<ResourceMap>,
+    config: AppConfig,
+    pool: HttpRequestPool,
+}
+
+impl AppInitServiceState {
+    /// Constructs state collection from resource map and app config.
+    pub(crate) fn new(rmap: Rc<ResourceMap>, config: AppConfig) -> Rc<Self> {
+        Rc::new(AppInitServiceState {
+            rmap,
+            config,
+            pool: HttpRequestPool::default(),
+        })
+    }
+
+    /// Returns a reference to the application's resource map.
+    #[inline]
+    pub(crate) fn rmap(&self) -> &ResourceMap {
+        &self.rmap
+    }
+
+    /// Returns a reference to the application's configuration.
+    #[inline]
+    pub(crate) fn config(&self) -> &AppConfig {
+        &self.config
+    }
+
+    /// Returns a reference to the application's request pool.
+    #[inline]
+    pub(crate) fn pool(&self) -> &HttpRequestPool {
+        &self.pool
+    }
+}
+
+impl<T, B> Service<Request> for AppInitService<T, B>
+where
+    T: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+{
+    type Response = ServiceResponse<B>;
+    type Error = T::Error;
+    type Future = T::Future;
+
+    actix_service::forward_ready!(service);
+
+    fn call(&self, mut req: Request) -> Self::Future {
+        let extensions = Rc::new(RefCell::new(req.take_req_data()));
+        let conn_data = req.take_conn_data();
+        let (head, payload) = req.into_parts();
+
+        let req = match self.app_state.pool().pop() {
+            Some(mut req) => {
+                let inner = Rc::get_mut(&mut req.inner).unwrap();
+                inner.path.get_mut().update(&head.uri);
+                inner.path.reset();
+                inner.head = head;
+                inner.conn_data = conn_data;
+                inner.extensions = extensions;
+                req
+            }
+
+            None => HttpRequest::new(
+                Path::new(Url::new(head.uri.clone())),
+                head,
+                Rc::clone(&self.app_state),
+                Rc::clone(&self.app_data),
+                conn_data,
+                extensions,
+            ),
+        };
+
+        self.service.call(ServiceRequest::new(req, payload))
+    }
+}
+
+impl<T, B> Drop for AppInitService<T, B>
+where
+    T: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+{
+    fn drop(&mut self) {
+        self.app_state.pool().clear();
+    }
+}
+
+pub struct AppRoutingFactory {
+    #[allow(clippy::type_complexity)]
+    services: Rc<
+        [(
+            ResourceDef,
+            BoxedHttpServiceFactory,
+            RefCell<Option<Vec<Box<dyn Guard>>>>,
+        )],
+    >,
+    default: Rc<BoxedHttpServiceFactory>,
+}
+
+impl ServiceFactory<ServiceRequest> for AppRoutingFactory {
+    type Response = ServiceResponse;
+    type Error = Error;
+    type Config = ();
+    type Service = AppRouting;
+    type InitError = ();
+    type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
+
+    fn new_service(&self, _: ()) -> Self::Future {
+        // construct all services factory future with its resource def and guards.
+        let factory_fut = join_all(self.services.iter().map(|(path, factory, guards)| {
+            let path = path.clone();
+            let guards = guards.borrow_mut().take().unwrap_or_default();
+            let factory_fut = factory.new_service(());
+            async move {
+                factory_fut
+                    .await
+                    .map(move |service| (path, guards, service))
+            }
+        }));
+
+        // construct default service factory future
+        let default_fut = self.default.new_service(());
+
+        Box::pin(async move {
+            let default = default_fut.await?;
+
+            // build router from the factory future result.
+            let router = factory_fut
+                .await
+                .into_iter()
+                .collect::<Result<Vec<_>, _>>()?
+                .drain(..)
+                .fold(Router::build(), |mut router, (path, guards, service)| {
+                    router.push(path, service, guards);
+                    router
+                })
+                .finish();
+
+            Ok(AppRouting { router, default })
+        })
+    }
+}
+
+/// The Actix Web router default entry point.
+pub struct AppRouting {
+    router: Router<BoxedHttpService, Vec<Box<dyn Guard>>>,
+    default: BoxedHttpService,
+}
+
+impl Service<ServiceRequest> for AppRouting {
+    type Response = ServiceResponse<BoxBody>;
+    type Error = Error;
+    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
+
+    actix_service::always_ready!();
+
+    fn call(&self, mut req: ServiceRequest) -> Self::Future {
+        let res = self.router.recognize_fn(&mut req, |req, guards| {
+            let guard_ctx = req.guard_ctx();
+            guards.iter().all(|guard| guard.check(&guard_ctx))
+        });
+
+        if let Some((srv, _info)) = res {
+            srv.call(req)
+        } else {
+            self.default.call(req)
+        }
+    }
+}
+
+/// Wrapper service for routing
+pub struct AppEntry {
+    factory: Rc<RefCell<Option<AppRoutingFactory>>>,
+}
+
+impl AppEntry {
+    pub fn new(factory: Rc<RefCell<Option<AppRoutingFactory>>>) -> Self {
+        AppEntry { factory }
+    }
+}
+
+impl ServiceFactory<ServiceRequest> for AppEntry {
+    type Response = ServiceResponse;
+    type Error = Error;
+    type Config = ();
+    type Service = AppRouting;
+    type InitError = ();
+    type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
+
+    fn new_service(&self, _: ()) -> Self::Future {
+        self.factory.borrow_mut().as_mut().unwrap().new_service(())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::sync::{
+        atomic::{AtomicBool, Ordering},
+        Arc,
+    };
+
+    use actix_service::Service;
+
+    use crate::{
+        test::{init_service, TestRequest},
+        web, App, HttpResponse,
+    };
+
+    struct DropData(Arc<AtomicBool>);
+
+    impl Drop for DropData {
+        fn drop(&mut self) {
+            self.0.store(true, Ordering::Relaxed);
+        }
+    }
+
+    // allow deprecated App::data
+    #[allow(deprecated)]
+    #[actix_rt::test]
+    async fn test_drop_data() {
+        let data = Arc::new(AtomicBool::new(false));
+
+        {
+            let app = init_service(
+                App::new()
+                    .data(DropData(data.clone()))
+                    .service(web::resource("/test").to(HttpResponse::Ok)),
+            )
+            .await;
+            let req = TestRequest::with_uri("/test").to_request();
+            let _ = app.call(req).await.unwrap();
+        }
+        assert!(data.load(Ordering::Relaxed));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/config.rs.html b/src/actix_web/config.rs.html new file mode 100644 index 000000000..0badc211b --- /dev/null +++ b/src/actix_web/config.rs.html @@ -0,0 +1,855 @@ +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
+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
+
use std::{net::SocketAddr, rc::Rc};
+
+use actix_service::{boxed, IntoServiceFactory, ServiceFactory, ServiceFactoryExt as _};
+
+use crate::{
+    data::Data,
+    dev::{Extensions, ResourceDef},
+    error::Error,
+    guard::Guard,
+    resource::Resource,
+    rmap::ResourceMap,
+    route::Route,
+    service::{
+        AppServiceFactory, BoxedHttpServiceFactory, HttpServiceFactory, ServiceFactoryWrapper,
+        ServiceRequest, ServiceResponse,
+    },
+};
+
+type Guards = Vec<Box<dyn Guard>>;
+
+/// Application configuration
+pub struct AppService {
+    config: AppConfig,
+    root: bool,
+    default: Rc<BoxedHttpServiceFactory>,
+    #[allow(clippy::type_complexity)]
+    services: Vec<(
+        ResourceDef,
+        BoxedHttpServiceFactory,
+        Option<Guards>,
+        Option<Rc<ResourceMap>>,
+    )>,
+}
+
+impl AppService {
+    /// Crate server settings instance.
+    pub(crate) fn new(config: AppConfig, default: Rc<BoxedHttpServiceFactory>) -> Self {
+        AppService {
+            config,
+            default,
+            root: true,
+            services: Vec::new(),
+        }
+    }
+
+    /// Check if root is being configured
+    pub fn is_root(&self) -> bool {
+        self.root
+    }
+
+    #[allow(clippy::type_complexity)]
+    pub(crate) fn into_services(
+        self,
+    ) -> (
+        AppConfig,
+        Vec<(
+            ResourceDef,
+            BoxedHttpServiceFactory,
+            Option<Guards>,
+            Option<Rc<ResourceMap>>,
+        )>,
+    ) {
+        (self.config, self.services)
+    }
+
+    /// Clones inner config and default service, returning new `AppService` with empty service list
+    /// marked as non-root.
+    pub(crate) fn clone_config(&self) -> Self {
+        AppService {
+            config: self.config.clone(),
+            default: self.default.clone(),
+            services: Vec::new(),
+            root: false,
+        }
+    }
+
+    /// Returns reference to configuration.
+    pub fn config(&self) -> &AppConfig {
+        &self.config
+    }
+
+    /// Returns default handler factory.
+    pub fn default_service(&self) -> Rc<BoxedHttpServiceFactory> {
+        self.default.clone()
+    }
+
+    /// Register HTTP service.
+    pub fn register_service<F, S>(
+        &mut self,
+        rdef: ResourceDef,
+        guards: Option<Vec<Box<dyn Guard>>>,
+        factory: F,
+        nested: Option<Rc<ResourceMap>>,
+    ) where
+        F: IntoServiceFactory<S, ServiceRequest>,
+        S: ServiceFactory<
+                ServiceRequest,
+                Response = ServiceResponse,
+                Error = Error,
+                Config = (),
+                InitError = (),
+            > + 'static,
+    {
+        self.services
+            .push((rdef, boxed::factory(factory.into_factory()), guards, nested));
+    }
+}
+
+/// Application connection config.
+#[derive(Debug, Clone)]
+pub struct AppConfig {
+    secure: bool,
+    host: String,
+    addr: SocketAddr,
+}
+
+impl AppConfig {
+    pub(crate) fn new(secure: bool, host: String, addr: SocketAddr) -> Self {
+        AppConfig { secure, host, addr }
+    }
+
+    /// Needed in actix-test crate. Semver exempt.
+    #[doc(hidden)]
+    pub fn __priv_test_new(secure: bool, host: String, addr: SocketAddr) -> Self {
+        AppConfig::new(secure, host, addr)
+    }
+
+    /// Server host name.
+    ///
+    /// Host name is used by application router as a hostname for URL generation.
+    /// Check [ConnectionInfo](super::dev::ConnectionInfo::host())
+    /// documentation for more information.
+    ///
+    /// By default host name is set to a "localhost" value.
+    pub fn host(&self) -> &str {
+        &self.host
+    }
+
+    /// Returns true if connection is secure (i.e., running over `https:`).
+    pub fn secure(&self) -> bool {
+        self.secure
+    }
+
+    /// Returns the socket address of the local half of this TCP connection.
+    pub fn local_addr(&self) -> SocketAddr {
+        self.addr
+    }
+
+    #[cfg(test)]
+    pub(crate) fn set_host(&mut self, host: &str) {
+        host.clone_into(&mut self.host);
+    }
+}
+
+impl Default for AppConfig {
+    /// Returns the default AppConfig.
+    /// Note: The included socket address is "127.0.0.1".
+    ///
+    /// 127.0.0.1: non-routable meta address that denotes an unknown, invalid or non-applicable target.
+    /// If you need a service only accessed by itself, use a loopback address.
+    /// A loopback address for IPv4 is any loopback address that begins with "127".
+    /// Loopback addresses should be only used to test your application locally.
+    /// The default configuration provides a loopback address.
+    ///
+    /// 0.0.0.0: if configured to use this special address, the application will listen to any IP address configured on the machine.
+    fn default() -> Self {
+        AppConfig::new(
+            false,
+            "localhost:8080".to_owned(),
+            "127.0.0.1:8080".parse().unwrap(),
+        )
+    }
+}
+
+/// Enables parts of app configuration to be declared separately from the app itself. Helpful for
+/// modularizing large applications.
+///
+/// Merge a `ServiceConfig` into an app using [`App::configure`](crate::App::configure). Scope and
+/// resources services have similar methods.
+///
+/// ```
+/// use actix_web::{web, App, HttpResponse};
+///
+/// // this function could be located in different module
+/// fn config(cfg: &mut web::ServiceConfig) {
+///     cfg.service(web::resource("/test")
+///         .route(web::get().to(|| HttpResponse::Ok()))
+///         .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
+///     );
+/// }
+///
+/// // merge `/test` routes from config function to App
+/// App::new().configure(config);
+/// ```
+pub struct ServiceConfig {
+    pub(crate) services: Vec<Box<dyn AppServiceFactory>>,
+    pub(crate) external: Vec<ResourceDef>,
+    pub(crate) app_data: Extensions,
+    pub(crate) default: Option<Rc<BoxedHttpServiceFactory>>,
+}
+
+impl ServiceConfig {
+    pub(crate) fn new() -> Self {
+        Self {
+            services: Vec::new(),
+            external: Vec::new(),
+            app_data: Extensions::new(),
+            default: None,
+        }
+    }
+
+    /// Add shared app data item.
+    ///
+    /// Counterpart to [`App::data()`](crate::App::data).
+    #[deprecated(since = "4.0.0", note = "Use `.app_data(Data::new(val))` instead.")]
+    pub fn data<U: 'static>(&mut self, data: U) -> &mut Self {
+        self.app_data(Data::new(data));
+        self
+    }
+
+    /// Add arbitrary app data item.
+    ///
+    /// Counterpart to [`App::app_data()`](crate::App::app_data).
+    pub fn app_data<U: 'static>(&mut self, ext: U) -> &mut Self {
+        self.app_data.insert(ext);
+        self
+    }
+
+    /// Default service to be used if no matching resource could be found.
+    ///
+    /// Counterpart to [`App::default_service()`](crate::App::default_service).
+    pub fn default_service<F, U>(&mut self, f: F) -> &mut Self
+    where
+        F: IntoServiceFactory<U, ServiceRequest>,
+        U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error>
+            + 'static,
+        U::InitError: std::fmt::Debug,
+    {
+        let svc = f
+            .into_factory()
+            .map_init_err(|err| log::error!("Can not construct default service: {:?}", err));
+
+        self.default = Some(Rc::new(boxed::factory(svc)));
+
+        self
+    }
+
+    /// Run external configuration as part of the application building process
+    ///
+    /// Counterpart to [`App::configure()`](crate::App::configure) that allows for easy nesting.
+    pub fn configure<F>(&mut self, f: F) -> &mut Self
+    where
+        F: FnOnce(&mut ServiceConfig),
+    {
+        f(self);
+        self
+    }
+
+    /// Configure route for a specific path.
+    ///
+    /// Counterpart to [`App::route()`](crate::App::route).
+    pub fn route(&mut self, path: &str, mut route: Route) -> &mut Self {
+        self.service(
+            Resource::new(path)
+                .add_guards(route.take_guards())
+                .route(route),
+        )
+    }
+
+    /// Register HTTP service factory.
+    ///
+    /// Counterpart to [`App::service()`](crate::App::service).
+    pub fn service<F>(&mut self, factory: F) -> &mut Self
+    where
+        F: HttpServiceFactory + 'static,
+    {
+        self.services
+            .push(Box::new(ServiceFactoryWrapper::new(factory)));
+        self
+    }
+
+    /// Register an external resource.
+    ///
+    /// External resources are useful for URL generation purposes only and are never considered for
+    /// matching at request time. Calls to [`HttpRequest::url_for()`](crate::HttpRequest::url_for)
+    /// will work as expected.
+    ///
+    /// Counterpart to [`App::external_resource()`](crate::App::external_resource).
+    pub fn external_resource<N, U>(&mut self, name: N, url: U) -> &mut Self
+    where
+        N: AsRef<str>,
+        U: AsRef<str>,
+    {
+        let mut rdef = ResourceDef::new(url.as_ref());
+        rdef.set_name(name.as_ref());
+        self.external.push(rdef);
+        self
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_service::Service;
+    use bytes::Bytes;
+
+    use super::*;
+    use crate::{
+        http::{Method, StatusCode},
+        test::{assert_body_eq, call_service, init_service, read_body, TestRequest},
+        web, App, HttpRequest, HttpResponse,
+    };
+
+    // allow deprecated `ServiceConfig::data`
+    #[allow(deprecated)]
+    #[actix_rt::test]
+    async fn test_data() {
+        let cfg = |cfg: &mut ServiceConfig| {
+            cfg.data(10usize);
+            cfg.app_data(15u8);
+        };
+
+        let srv = init_service(App::new().configure(cfg).service(web::resource("/").to(
+            |_: web::Data<usize>, req: HttpRequest| {
+                assert_eq!(*req.app_data::<u8>().unwrap(), 15u8);
+                HttpResponse::Ok()
+            },
+        )))
+        .await;
+        let req = TestRequest::default().to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_external_resource() {
+        let srv = init_service(
+            App::new()
+                .configure(|cfg| {
+                    cfg.external_resource("youtube", "https://youtube.com/watch/{video_id}");
+                })
+                .route(
+                    "/test",
+                    web::get().to(|req: HttpRequest| {
+                        HttpResponse::Ok()
+                            .body(req.url_for("youtube", ["12345"]).unwrap().to_string())
+                    }),
+                ),
+        )
+        .await;
+        let req = TestRequest::with_uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        let body = read_body(resp).await;
+        assert_eq!(body, Bytes::from_static(b"https://youtube.com/watch/12345"));
+    }
+
+    #[actix_rt::test]
+    async fn registers_default_service() {
+        let srv = init_service(
+            App::new()
+                .configure(|cfg| {
+                    cfg.default_service(
+                        web::get().to(|| HttpResponse::NotFound().body("four oh four")),
+                    );
+                })
+                .service(web::scope("/scoped").configure(|cfg| {
+                    cfg.default_service(
+                        web::get().to(|| HttpResponse::NotFound().body("scoped four oh four")),
+                    );
+                })),
+        )
+        .await;
+
+        // app registers default service
+        let req = TestRequest::with_uri("/path/i/did/not-configure").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+        let body = read_body(resp).await;
+        assert_eq!(body, Bytes::from_static(b"four oh four"));
+
+        // scope registers default service
+        let req = TestRequest::with_uri("/scoped/path/i/did/not-configure").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+        let body = read_body(resp).await;
+        assert_eq!(body, Bytes::from_static(b"scoped four oh four"));
+    }
+
+    #[actix_rt::test]
+    async fn test_service() {
+        let srv = init_service(App::new().configure(|cfg| {
+            cfg.service(web::resource("/test").route(web::get().to(HttpResponse::Created)))
+                .route("/index.html", web::get().to(HttpResponse::Ok));
+        }))
+        .await;
+
+        let req = TestRequest::with_uri("/test")
+            .method(Method::GET)
+            .to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::CREATED);
+
+        let req = TestRequest::with_uri("/index.html")
+            .method(Method::GET)
+            .to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn nested_service_configure() {
+        fn cfg_root(cfg: &mut ServiceConfig) {
+            cfg.configure(cfg_sub);
+        }
+
+        fn cfg_sub(cfg: &mut ServiceConfig) {
+            cfg.route("/", web::get().to(|| async { "hello world" }));
+        }
+
+        let srv = init_service(App::new().configure(cfg_root)).await;
+
+        let req = TestRequest::with_uri("/").to_request();
+        let res = call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_body_eq!(res, b"hello world");
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/data.rs.html b/src/actix_web/data.rs.html new file mode 100644 index 000000000..eab060f5e --- /dev/null +++ b/src/actix_web/data.rs.html @@ -0,0 +1,771 @@ +data.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+
use std::{any::type_name, ops::Deref, sync::Arc};
+
+use actix_http::Extensions;
+use actix_utils::future::{err, ok, Ready};
+use futures_core::future::LocalBoxFuture;
+use serde::{de, Serialize};
+
+use crate::{dev::Payload, error, Error, FromRequest, HttpRequest};
+
+/// Data factory.
+pub(crate) trait DataFactory {
+    /// Return true if modifications were made to extensions map.
+    fn create(&self, extensions: &mut Extensions) -> bool;
+}
+
+pub(crate) type FnDataFactory =
+    Box<dyn Fn() -> LocalBoxFuture<'static, Result<Box<dyn DataFactory>, ()>>>;
+
+/// Application data wrapper and extractor.
+///
+/// # Setting Data
+/// Data is set using the `app_data` methods on `App`, `Scope`, and `Resource`. If data is wrapped
+/// in this `Data` type for those calls, it can be used as an extractor.
+///
+/// Note that `Data` should be constructed _outside_ the `HttpServer::new` closure if shared,
+/// potentially mutable state is desired. `Data` is cheap to clone; internally, it uses an `Arc`.
+///
+/// See also [`App::app_data`](crate::App::app_data), [`Scope::app_data`](crate::Scope::app_data),
+/// and [`Resource::app_data`](crate::Resource::app_data).
+///
+/// # Extracting `Data`
+/// Since the Actix Web router layers application data, the returned object will reference the
+/// "closest" instance of the type. For example, if an `App` stores a `u32`, a nested `Scope`
+/// also stores a `u32`, and the delegated request handler falls within that `Scope`, then
+/// extracting a `web::Data<u32>` for that handler will return the `Scope`'s instance. However,
+/// using the same router set up and a request that does not get captured by the `Scope`,
+/// `web::<Data<u32>>` would return the `App`'s instance.
+///
+/// If route data is not set for a handler, using `Data<T>` extractor would cause a `500 Internal
+/// Server Error` response.
+///
+/// See also [`HttpRequest::app_data`]
+/// and [`ServiceRequest::app_data`](crate::dev::ServiceRequest::app_data).
+///
+/// # Unsized Data
+/// For types that are unsized, most commonly `dyn T`, `Data` can wrap these types by first
+/// constructing an `Arc<dyn T>` and using the `From` implementation to convert it.
+///
+/// ```
+/// # use std::{fmt::Display, sync::Arc};
+/// # use actix_web::web::Data;
+/// let displayable_arc: Arc<dyn Display> = Arc::new(42usize);
+/// let displayable_data: Data<dyn Display> = Data::from(displayable_arc);
+/// ```
+///
+/// # Examples
+/// ```
+/// use std::sync::Mutex;
+/// use actix_web::{App, HttpRequest, HttpResponse, Responder, web::{self, Data}};
+///
+/// struct MyData {
+///     counter: usize,
+/// }
+///
+/// /// Use the `Data<T>` extractor to access data in a handler.
+/// async fn index(data: Data<Mutex<MyData>>) -> impl Responder {
+///     let mut my_data = data.lock().unwrap();
+///     my_data.counter += 1;
+///     HttpResponse::Ok()
+/// }
+///
+/// /// Alternatively, use the `HttpRequest::app_data` method to access data in a handler.
+/// async fn index_alt(req: HttpRequest) -> impl Responder {
+///     let data = req.app_data::<Data<Mutex<MyData>>>().unwrap();
+///     let mut my_data = data.lock().unwrap();
+///     my_data.counter += 1;
+///     HttpResponse::Ok()
+/// }
+///
+/// let data = Data::new(Mutex::new(MyData { counter: 0 }));
+///
+/// let app = App::new()
+///     // Store `MyData` in application storage.
+///     .app_data(Data::clone(&data))
+///     .route("/index.html", web::get().to(index))
+///     .route("/index-alt.html", web::get().to(index_alt));
+/// ```
+#[doc(alias = "state")]
+#[derive(Debug)]
+pub struct Data<T: ?Sized>(Arc<T>);
+
+impl<T> Data<T> {
+    /// Create new `Data` instance.
+    pub fn new(state: T) -> Data<T> {
+        Data(Arc::new(state))
+    }
+}
+
+impl<T: ?Sized> Data<T> {
+    /// Returns reference to inner `T`.
+    pub fn get_ref(&self) -> &T {
+        self.0.as_ref()
+    }
+
+    /// Unwraps to the internal `Arc<T>`
+    pub fn into_inner(self) -> Arc<T> {
+        self.0
+    }
+}
+
+impl<T: ?Sized> Deref for Data<T> {
+    type Target = Arc<T>;
+
+    fn deref(&self) -> &Arc<T> {
+        &self.0
+    }
+}
+
+impl<T: ?Sized> Clone for Data<T> {
+    fn clone(&self) -> Data<T> {
+        Data(Arc::clone(&self.0))
+    }
+}
+
+impl<T: ?Sized> From<Arc<T>> for Data<T> {
+    fn from(arc: Arc<T>) -> Self {
+        Data(arc)
+    }
+}
+
+impl<T: Default> Default for Data<T> {
+    fn default() -> Self {
+        Data::new(T::default())
+    }
+}
+
+impl<T> Serialize for Data<T>
+where
+    T: Serialize,
+{
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: serde::Serializer,
+    {
+        self.0.serialize(serializer)
+    }
+}
+impl<'de, T> de::Deserialize<'de> for Data<T>
+where
+    T: de::Deserialize<'de>,
+{
+    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+    where
+        D: de::Deserializer<'de>,
+    {
+        Ok(Data::new(T::deserialize(deserializer)?))
+    }
+}
+
+impl<T: ?Sized + 'static> FromRequest for Data<T> {
+    type Error = Error;
+    type Future = Ready<Result<Self, Error>>;
+
+    #[inline]
+    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
+        if let Some(st) = req.app_data::<Data<T>>() {
+            ok(st.clone())
+        } else {
+            log::debug!(
+                "Failed to extract `Data<{}>` for `{}` handler. For the Data extractor to work \
+                correctly, wrap the data with `Data::new()` and pass it to `App::app_data()`. \
+                Ensure that types align in both the set and retrieve calls.",
+                type_name::<T>(),
+                req.match_name().unwrap_or_else(|| req.path())
+            );
+
+            err(error::ErrorInternalServerError(
+                "Requested application data is not configured correctly. \
+                View/enable debug logs for more details.",
+            ))
+        }
+    }
+}
+
+impl<T: ?Sized + 'static> DataFactory for Data<T> {
+    fn create(&self, extensions: &mut Extensions) -> bool {
+        extensions.insert(Data(self.0.clone()));
+        true
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::{
+        dev::Service,
+        http::StatusCode,
+        test::{init_service, TestRequest},
+        web, App, HttpResponse,
+    };
+
+    // allow deprecated App::data
+    #[allow(deprecated)]
+    #[actix_rt::test]
+    async fn test_data_extractor() {
+        let srv = init_service(
+            App::new()
+                .data("TEST".to_string())
+                .service(web::resource("/").to(|data: web::Data<String>| {
+                    assert_eq!(data.to_lowercase(), "test");
+                    HttpResponse::Ok()
+                })),
+        )
+        .await;
+
+        let req = TestRequest::default().to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let srv = init_service(
+            App::new()
+                .data(10u32)
+                .service(web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok())),
+        )
+        .await;
+        let req = TestRequest::default().to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
+
+        let srv = init_service(
+            App::new()
+                .data(10u32)
+                .data(13u32)
+                .app_data(12u64)
+                .app_data(15u64)
+                .default_service(web::to(|n: web::Data<u32>, req: HttpRequest| {
+                    // in each case, the latter insertion should be preserved
+                    assert_eq!(*req.app_data::<u64>().unwrap(), 15);
+                    assert_eq!(*n.into_inner(), 13);
+                    HttpResponse::Ok()
+                })),
+        )
+        .await;
+        let req = TestRequest::default().to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_app_data_extractor() {
+        let srv = init_service(
+            App::new()
+                .app_data(Data::new(10usize))
+                .service(web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok())),
+        )
+        .await;
+
+        let req = TestRequest::default().to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let srv = init_service(
+            App::new()
+                .app_data(Data::new(10u32))
+                .service(web::resource("/").to(|_: web::Data<usize>| HttpResponse::Ok())),
+        )
+        .await;
+        let req = TestRequest::default().to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
+    }
+
+    // allow deprecated App::data
+    #[allow(deprecated)]
+    #[actix_rt::test]
+    async fn test_route_data_extractor() {
+        let srv = init_service(
+            App::new().service(
+                web::resource("/")
+                    .data(10usize)
+                    .route(web::get().to(|_data: web::Data<usize>| HttpResponse::Ok())),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::default().to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        // different type
+        let srv = init_service(
+            App::new().service(
+                web::resource("/")
+                    .data(10u32)
+                    .route(web::get().to(|_: web::Data<usize>| HttpResponse::Ok())),
+            ),
+        )
+        .await;
+        let req = TestRequest::default().to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
+    }
+
+    // allow deprecated App::data
+    #[allow(deprecated)]
+    #[actix_rt::test]
+    async fn test_override_data() {
+        let srv = init_service(
+            App::new()
+                .data(1usize)
+                .service(web::resource("/").data(10usize).route(web::get().to(
+                    |data: web::Data<usize>| {
+                        assert_eq!(**data, 10);
+                        HttpResponse::Ok()
+                    },
+                ))),
+        )
+        .await;
+
+        let req = TestRequest::default().to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_data_from_arc() {
+        let data_new = Data::new(String::from("test-123"));
+        let data_from_arc = Data::from(Arc::new(String::from("test-123")));
+        assert_eq!(data_new.0, data_from_arc.0);
+    }
+
+    #[actix_rt::test]
+    async fn test_data_from_dyn_arc() {
+        trait TestTrait {
+            fn get_num(&self) -> i32;
+        }
+        struct A {}
+        impl TestTrait for A {
+            fn get_num(&self) -> i32 {
+                42
+            }
+        }
+        // This works when Sized is required
+        let dyn_arc_box: Arc<Box<dyn TestTrait>> = Arc::new(Box::new(A {}));
+        let data_arc_box = Data::from(dyn_arc_box);
+        // This works when Data Sized Bound is removed
+        let dyn_arc: Arc<dyn TestTrait> = Arc::new(A {});
+        let data_arc = Data::from(dyn_arc);
+        assert_eq!(data_arc_box.get_num(), data_arc.get_num())
+    }
+
+    #[actix_rt::test]
+    async fn test_dyn_data_into_arc() {
+        trait TestTrait {
+            fn get_num(&self) -> i32;
+        }
+        struct A {}
+        impl TestTrait for A {
+            fn get_num(&self) -> i32 {
+                42
+            }
+        }
+        let dyn_arc: Arc<dyn TestTrait> = Arc::new(A {});
+        let data_arc = Data::from(dyn_arc);
+        let arc_from_data = data_arc.clone().into_inner();
+        assert_eq!(data_arc.get_num(), arc_from_data.get_num())
+    }
+
+    #[actix_rt::test]
+    async fn test_get_ref_from_dyn_data() {
+        trait TestTrait {
+            fn get_num(&self) -> i32;
+        }
+        struct A {}
+        impl TestTrait for A {
+            fn get_num(&self) -> i32 {
+                42
+            }
+        }
+        let dyn_arc: Arc<dyn TestTrait> = Arc::new(A {});
+        let data_arc = Data::from(dyn_arc);
+        let ref_data = data_arc.get_ref();
+        assert_eq!(data_arc.get_num(), ref_data.get_num())
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/dev.rs.html b/src/actix_web/dev.rs.html new file mode 100644 index 000000000..300e865c9 --- /dev/null +++ b/src/actix_web/dev.rs.html @@ -0,0 +1,95 @@ +dev.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
+
//! Lower-level types and re-exports.
+//!
+//! Most users will not have to interact with the types in this module, but it is useful for those
+//! writing extractors, middleware, libraries, or interacting with the service API directly.
+//!
+//! # Request Extractors
+//! - [`ConnectionInfo`]: Connection information
+//! - [`PeerAddr`]: Connection information
+
+#[cfg(feature = "__compress")]
+pub use actix_http::encoding::Decoder as Decompress;
+pub use actix_http::{Extensions, Payload, RequestHead, Response, ResponseHead};
+use actix_router::Patterns;
+pub use actix_router::{Path, ResourceDef, ResourcePath, Url};
+pub use actix_server::{Server, ServerHandle};
+pub use actix_service::{
+    always_ready, fn_factory, fn_service, forward_ready, Service, ServiceFactory, Transform,
+};
+
+#[doc(hidden)]
+pub use crate::handler::Handler;
+pub use crate::{
+    config::{AppConfig, AppService},
+    info::{ConnectionInfo, PeerAddr},
+    rmap::ResourceMap,
+    service::{HttpServiceFactory, ServiceRequest, ServiceResponse, WebService},
+    types::{JsonBody, Readlines, UrlEncoded},
+};
+
+pub(crate) fn ensure_leading_slash(mut patterns: Patterns) -> Patterns {
+    match &mut patterns {
+        Patterns::Single(pat) => {
+            if !pat.is_empty() && !pat.starts_with('/') {
+                pat.insert(0, '/');
+            };
+        }
+        Patterns::List(pats) => {
+            for pat in pats {
+                if !pat.is_empty() && !pat.starts_with('/') {
+                    pat.insert(0, '/');
+                };
+            }
+        }
+    }
+
+    patterns
+}
+
\ No newline at end of file diff --git a/src/actix_web/error/error.rs.html b/src/actix_web/error/error.rs.html new file mode 100644 index 000000000..b6e10489f --- /dev/null +++ b/src/actix_web/error/error.rs.html @@ -0,0 +1,135 @@ +error.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+
use std::{error::Error as StdError, fmt};
+
+use actix_http::{body::BoxBody, Response};
+
+use crate::{HttpResponse, ResponseError};
+
+/// General purpose Actix Web error.
+///
+/// An Actix Web error is used to carry errors from `std::error` through actix in a convenient way.
+/// It can be created through converting errors with `into()`.
+///
+/// Whenever it is created from an external object a response error is created for it that can be
+/// used to create an HTTP response from it this means that if you have access to an actix `Error`
+/// you can always get a `ResponseError` reference from it.
+pub struct Error {
+    cause: Box<dyn ResponseError>,
+}
+
+impl Error {
+    /// Returns the reference to the underlying `ResponseError`.
+    pub fn as_response_error(&self) -> &dyn ResponseError {
+        self.cause.as_ref()
+    }
+
+    /// Similar to `as_response_error` but downcasts.
+    pub fn as_error<T: ResponseError + 'static>(&self) -> Option<&T> {
+        <dyn ResponseError>::downcast_ref(self.cause.as_ref())
+    }
+
+    /// Shortcut for creating an `HttpResponse`.
+    pub fn error_response(&self) -> HttpResponse {
+        self.cause.error_response()
+    }
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(&self.cause, f)
+    }
+}
+
+impl fmt::Debug for Error {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{:?}", &self.cause)
+    }
+}
+
+impl StdError for Error {
+    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
+        None
+    }
+}
+
+/// `Error` for any error that implements `ResponseError`
+impl<T: ResponseError + 'static> From<T> for Error {
+    fn from(err: T) -> Error {
+        Error {
+            cause: Box::new(err),
+        }
+    }
+}
+
+impl From<Error> for Response<BoxBody> {
+    fn from(err: Error) -> Response<BoxBody> {
+        err.error_response().into()
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/error/internal.rs.html b/src/actix_web/error/internal.rs.html new file mode 100644 index 000000000..8ee98210b --- /dev/null +++ b/src/actix_web/error/internal.rs.html @@ -0,0 +1,633 @@ +internal.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
+
use std::{cell::RefCell, fmt, io::Write as _};
+
+use actix_http::{
+    body::BoxBody,
+    header::{self, TryIntoHeaderValue as _},
+    StatusCode,
+};
+use bytes::{BufMut as _, BytesMut};
+
+use crate::{Error, HttpRequest, HttpResponse, Responder, ResponseError};
+
+/// Wraps errors to alter the generated response status code.
+///
+/// In following example, the `io::Error` is wrapped into `ErrorBadRequest` which will generate a
+/// response with the 400 Bad Request status code instead of the usual status code generated by
+/// an `io::Error`.
+///
+/// # Examples
+/// ```
+/// # use std::io;
+/// # use actix_web::{error, HttpRequest};
+/// async fn handler_error() -> Result<String, actix_web::Error> {
+///     let err = io::Error::new(io::ErrorKind::Other, "error");
+///     Err(error::ErrorBadRequest(err))
+/// }
+/// ```
+pub struct InternalError<T> {
+    cause: T,
+    status: InternalErrorType,
+}
+
+enum InternalErrorType {
+    Status(StatusCode),
+    Response(RefCell<Option<HttpResponse>>),
+}
+
+impl<T> InternalError<T> {
+    /// Constructs an `InternalError` with given status code.
+    pub fn new(cause: T, status: StatusCode) -> Self {
+        InternalError {
+            cause,
+            status: InternalErrorType::Status(status),
+        }
+    }
+
+    /// Constructs an `InternalError` with pre-defined response.
+    pub fn from_response(cause: T, response: HttpResponse) -> Self {
+        InternalError {
+            cause,
+            status: InternalErrorType::Response(RefCell::new(Some(response))),
+        }
+    }
+}
+
+impl<T: fmt::Debug> fmt::Debug for InternalError<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.cause.fmt(f)
+    }
+}
+
+impl<T: fmt::Display> fmt::Display for InternalError<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.cause.fmt(f)
+    }
+}
+
+impl<T> ResponseError for InternalError<T>
+where
+    T: fmt::Debug + fmt::Display,
+{
+    fn status_code(&self) -> StatusCode {
+        match self.status {
+            InternalErrorType::Status(st) => st,
+            InternalErrorType::Response(ref resp) => {
+                if let Some(resp) = resp.borrow().as_ref() {
+                    resp.head().status
+                } else {
+                    StatusCode::INTERNAL_SERVER_ERROR
+                }
+            }
+        }
+    }
+
+    fn error_response(&self) -> HttpResponse {
+        match self.status {
+            InternalErrorType::Status(status) => {
+                let mut res = HttpResponse::new(status);
+                let mut buf = BytesMut::new().writer();
+                let _ = write!(buf, "{}", self);
+
+                let mime = mime::TEXT_PLAIN_UTF_8.try_into_value().unwrap();
+                res.headers_mut().insert(header::CONTENT_TYPE, mime);
+
+                res.set_body(BoxBody::new(buf.into_inner()))
+            }
+
+            InternalErrorType::Response(ref resp) => {
+                if let Some(resp) = resp.borrow_mut().take() {
+                    resp
+                } else {
+                    HttpResponse::new(StatusCode::INTERNAL_SERVER_ERROR)
+                }
+            }
+        }
+    }
+}
+
+impl<T> Responder for InternalError<T>
+where
+    T: fmt::Debug + fmt::Display + 'static,
+{
+    type Body = BoxBody;
+
+    fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body> {
+        HttpResponse::from_error(self)
+    }
+}
+
+macro_rules! error_helper {
+    ($name:ident, $status:ident) => {
+        #[doc = concat!("Helper function that wraps any error and generates a `", stringify!($status), "` response.")]
+        #[allow(non_snake_case)]
+        pub fn $name<T>(err: T) -> Error
+        where
+            T: fmt::Debug + fmt::Display + 'static,
+        {
+            InternalError::new(err, StatusCode::$status).into()
+        }
+    };
+}
+
+error_helper!(ErrorBadRequest, BAD_REQUEST);
+error_helper!(ErrorUnauthorized, UNAUTHORIZED);
+error_helper!(ErrorPaymentRequired, PAYMENT_REQUIRED);
+error_helper!(ErrorForbidden, FORBIDDEN);
+error_helper!(ErrorNotFound, NOT_FOUND);
+error_helper!(ErrorMethodNotAllowed, METHOD_NOT_ALLOWED);
+error_helper!(ErrorNotAcceptable, NOT_ACCEPTABLE);
+error_helper!(
+    ErrorProxyAuthenticationRequired,
+    PROXY_AUTHENTICATION_REQUIRED
+);
+error_helper!(ErrorRequestTimeout, REQUEST_TIMEOUT);
+error_helper!(ErrorConflict, CONFLICT);
+error_helper!(ErrorGone, GONE);
+error_helper!(ErrorLengthRequired, LENGTH_REQUIRED);
+error_helper!(ErrorPayloadTooLarge, PAYLOAD_TOO_LARGE);
+error_helper!(ErrorUriTooLong, URI_TOO_LONG);
+error_helper!(ErrorUnsupportedMediaType, UNSUPPORTED_MEDIA_TYPE);
+error_helper!(ErrorRangeNotSatisfiable, RANGE_NOT_SATISFIABLE);
+error_helper!(ErrorImATeapot, IM_A_TEAPOT);
+error_helper!(ErrorMisdirectedRequest, MISDIRECTED_REQUEST);
+error_helper!(ErrorUnprocessableEntity, UNPROCESSABLE_ENTITY);
+error_helper!(ErrorLocked, LOCKED);
+error_helper!(ErrorFailedDependency, FAILED_DEPENDENCY);
+error_helper!(ErrorUpgradeRequired, UPGRADE_REQUIRED);
+error_helper!(ErrorPreconditionFailed, PRECONDITION_FAILED);
+error_helper!(ErrorPreconditionRequired, PRECONDITION_REQUIRED);
+error_helper!(ErrorTooManyRequests, TOO_MANY_REQUESTS);
+error_helper!(
+    ErrorRequestHeaderFieldsTooLarge,
+    REQUEST_HEADER_FIELDS_TOO_LARGE
+);
+error_helper!(
+    ErrorUnavailableForLegalReasons,
+    UNAVAILABLE_FOR_LEGAL_REASONS
+);
+error_helper!(ErrorExpectationFailed, EXPECTATION_FAILED);
+error_helper!(ErrorInternalServerError, INTERNAL_SERVER_ERROR);
+error_helper!(ErrorNotImplemented, NOT_IMPLEMENTED);
+error_helper!(ErrorBadGateway, BAD_GATEWAY);
+error_helper!(ErrorServiceUnavailable, SERVICE_UNAVAILABLE);
+error_helper!(ErrorGatewayTimeout, GATEWAY_TIMEOUT);
+error_helper!(ErrorHttpVersionNotSupported, HTTP_VERSION_NOT_SUPPORTED);
+error_helper!(ErrorVariantAlsoNegotiates, VARIANT_ALSO_NEGOTIATES);
+error_helper!(ErrorInsufficientStorage, INSUFFICIENT_STORAGE);
+error_helper!(ErrorLoopDetected, LOOP_DETECTED);
+error_helper!(ErrorNotExtended, NOT_EXTENDED);
+error_helper!(
+    ErrorNetworkAuthenticationRequired,
+    NETWORK_AUTHENTICATION_REQUIRED
+);
+
+#[cfg(test)]
+mod tests {
+    use actix_http::error::ParseError;
+
+    use super::*;
+
+    #[test]
+    fn test_internal_error() {
+        let err = InternalError::from_response(ParseError::Method, HttpResponse::Ok().finish());
+        let resp: HttpResponse = err.error_response();
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[test]
+    fn test_error_helpers() {
+        let res: HttpResponse = ErrorBadRequest("err").into();
+        assert_eq!(res.status(), StatusCode::BAD_REQUEST);
+
+        let res: HttpResponse = ErrorUnauthorized("err").into();
+        assert_eq!(res.status(), StatusCode::UNAUTHORIZED);
+
+        let res: HttpResponse = ErrorPaymentRequired("err").into();
+        assert_eq!(res.status(), StatusCode::PAYMENT_REQUIRED);
+
+        let res: HttpResponse = ErrorForbidden("err").into();
+        assert_eq!(res.status(), StatusCode::FORBIDDEN);
+
+        let res: HttpResponse = ErrorNotFound("err").into();
+        assert_eq!(res.status(), StatusCode::NOT_FOUND);
+
+        let res: HttpResponse = ErrorMethodNotAllowed("err").into();
+        assert_eq!(res.status(), StatusCode::METHOD_NOT_ALLOWED);
+
+        let res: HttpResponse = ErrorNotAcceptable("err").into();
+        assert_eq!(res.status(), StatusCode::NOT_ACCEPTABLE);
+
+        let res: HttpResponse = ErrorProxyAuthenticationRequired("err").into();
+        assert_eq!(res.status(), StatusCode::PROXY_AUTHENTICATION_REQUIRED);
+
+        let res: HttpResponse = ErrorRequestTimeout("err").into();
+        assert_eq!(res.status(), StatusCode::REQUEST_TIMEOUT);
+
+        let res: HttpResponse = ErrorConflict("err").into();
+        assert_eq!(res.status(), StatusCode::CONFLICT);
+
+        let res: HttpResponse = ErrorGone("err").into();
+        assert_eq!(res.status(), StatusCode::GONE);
+
+        let res: HttpResponse = ErrorLengthRequired("err").into();
+        assert_eq!(res.status(), StatusCode::LENGTH_REQUIRED);
+
+        let res: HttpResponse = ErrorPreconditionFailed("err").into();
+        assert_eq!(res.status(), StatusCode::PRECONDITION_FAILED);
+
+        let res: HttpResponse = ErrorPayloadTooLarge("err").into();
+        assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);
+
+        let res: HttpResponse = ErrorUriTooLong("err").into();
+        assert_eq!(res.status(), StatusCode::URI_TOO_LONG);
+
+        let res: HttpResponse = ErrorUnsupportedMediaType("err").into();
+        assert_eq!(res.status(), StatusCode::UNSUPPORTED_MEDIA_TYPE);
+
+        let res: HttpResponse = ErrorRangeNotSatisfiable("err").into();
+        assert_eq!(res.status(), StatusCode::RANGE_NOT_SATISFIABLE);
+
+        let res: HttpResponse = ErrorExpectationFailed("err").into();
+        assert_eq!(res.status(), StatusCode::EXPECTATION_FAILED);
+
+        let res: HttpResponse = ErrorImATeapot("err").into();
+        assert_eq!(res.status(), StatusCode::IM_A_TEAPOT);
+
+        let res: HttpResponse = ErrorMisdirectedRequest("err").into();
+        assert_eq!(res.status(), StatusCode::MISDIRECTED_REQUEST);
+
+        let res: HttpResponse = ErrorUnprocessableEntity("err").into();
+        assert_eq!(res.status(), StatusCode::UNPROCESSABLE_ENTITY);
+
+        let res: HttpResponse = ErrorLocked("err").into();
+        assert_eq!(res.status(), StatusCode::LOCKED);
+
+        let res: HttpResponse = ErrorFailedDependency("err").into();
+        assert_eq!(res.status(), StatusCode::FAILED_DEPENDENCY);
+
+        let res: HttpResponse = ErrorUpgradeRequired("err").into();
+        assert_eq!(res.status(), StatusCode::UPGRADE_REQUIRED);
+
+        let res: HttpResponse = ErrorPreconditionRequired("err").into();
+        assert_eq!(res.status(), StatusCode::PRECONDITION_REQUIRED);
+
+        let res: HttpResponse = ErrorTooManyRequests("err").into();
+        assert_eq!(res.status(), StatusCode::TOO_MANY_REQUESTS);
+
+        let res: HttpResponse = ErrorRequestHeaderFieldsTooLarge("err").into();
+        assert_eq!(res.status(), StatusCode::REQUEST_HEADER_FIELDS_TOO_LARGE);
+
+        let res: HttpResponse = ErrorUnavailableForLegalReasons("err").into();
+        assert_eq!(res.status(), StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS);
+
+        let res: HttpResponse = ErrorInternalServerError("err").into();
+        assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);
+
+        let res: HttpResponse = ErrorNotImplemented("err").into();
+        assert_eq!(res.status(), StatusCode::NOT_IMPLEMENTED);
+
+        let res: HttpResponse = ErrorBadGateway("err").into();
+        assert_eq!(res.status(), StatusCode::BAD_GATEWAY);
+
+        let res: HttpResponse = ErrorServiceUnavailable("err").into();
+        assert_eq!(res.status(), StatusCode::SERVICE_UNAVAILABLE);
+
+        let res: HttpResponse = ErrorGatewayTimeout("err").into();
+        assert_eq!(res.status(), StatusCode::GATEWAY_TIMEOUT);
+
+        let res: HttpResponse = ErrorHttpVersionNotSupported("err").into();
+        assert_eq!(res.status(), StatusCode::HTTP_VERSION_NOT_SUPPORTED);
+
+        let res: HttpResponse = ErrorVariantAlsoNegotiates("err").into();
+        assert_eq!(res.status(), StatusCode::VARIANT_ALSO_NEGOTIATES);
+
+        let res: HttpResponse = ErrorInsufficientStorage("err").into();
+        assert_eq!(res.status(), StatusCode::INSUFFICIENT_STORAGE);
+
+        let res: HttpResponse = ErrorLoopDetected("err").into();
+        assert_eq!(res.status(), StatusCode::LOOP_DETECTED);
+
+        let res: HttpResponse = ErrorNotExtended("err").into();
+        assert_eq!(res.status(), StatusCode::NOT_EXTENDED);
+
+        let res: HttpResponse = ErrorNetworkAuthenticationRequired("err").into();
+        assert_eq!(res.status(), StatusCode::NETWORK_AUTHENTICATION_REQUIRED);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/error/macros.rs.html b/src/actix_web/error/macros.rs.html new file mode 100644 index 000000000..abfedfb7c --- /dev/null +++ b/src/actix_web/error/macros.rs.html @@ -0,0 +1,213 @@ +macros.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
+
macro_rules! downcast_get_type_id {
+    () => {
+        /// A helper method to get the type ID of the type
+        /// this trait is implemented on.
+        /// This method is unsafe to *implement*, since `downcast_ref` relies
+        /// on the returned `TypeId` to perform a cast.
+        ///
+        /// Unfortunately, Rust has no notion of a trait method that is
+        /// unsafe to implement (marking it as `unsafe` makes it unsafe
+        /// to *call*). As a workaround, we require this method
+        /// to return a private type along with the `TypeId`. This
+        /// private type (`PrivateHelper`) has a private constructor,
+        /// making it impossible for safe code to construct outside of
+        /// this module. This ensures that safe code cannot violate
+        /// type-safety by implementing this method.
+        ///
+        /// We also take `PrivateHelper` as a parameter, to ensure that
+        /// safe code cannot obtain a `PrivateHelper` instance by
+        /// delegating to an existing implementation of `__private_get_type_id__`
+        #[doc(hidden)]
+        #[allow(dead_code)]
+        fn __private_get_type_id__(&self, _: PrivateHelper) -> (std::any::TypeId, PrivateHelper)
+        where
+            Self: 'static,
+        {
+            (std::any::TypeId::of::<Self>(), PrivateHelper(()))
+        }
+    };
+}
+
+// Generate implementation for dyn $name
+macro_rules! downcast_dyn {
+    ($name:ident) => {
+        /// A struct with a private constructor, for use with
+        /// `__private_get_type_id__`. Its single field is private,
+        /// ensuring that it can only be constructed from this module
+        #[doc(hidden)]
+        #[allow(dead_code)]
+        pub struct PrivateHelper(());
+
+        impl dyn $name + 'static {
+            /// Downcasts generic body to a specific type.
+            #[allow(dead_code)]
+            pub fn downcast_ref<T: $name + 'static>(&self) -> Option<&T> {
+                if self.__private_get_type_id__(PrivateHelper(())).0 == std::any::TypeId::of::<T>()
+                {
+                    // SAFETY: external crates cannot override the default
+                    // implementation of `__private_get_type_id__`, since
+                    // it requires returning a private type. We can therefore
+                    // rely on the returned `TypeId`, which ensures that this
+                    // case is correct.
+                    unsafe { Some(&*(self as *const dyn $name as *const T)) }
+                } else {
+                    None
+                }
+            }
+
+            /// Downcasts a generic body to a mutable specific type.
+            #[allow(dead_code)]
+            pub fn downcast_mut<T: $name + 'static>(&mut self) -> Option<&mut T> {
+                if self.__private_get_type_id__(PrivateHelper(())).0 == std::any::TypeId::of::<T>()
+                {
+                    // SAFETY: external crates cannot override the default
+                    // implementation of `__private_get_type_id__`, since
+                    // it requires returning a private type. We can therefore
+                    // rely on the returned `TypeId`, which ensures that this
+                    // case is correct.
+                    unsafe { Some(&mut *(self as *const dyn $name as *const T as *mut T)) }
+                } else {
+                    None
+                }
+            }
+        }
+    };
+}
+
+pub(crate) use downcast_dyn;
+pub(crate) use downcast_get_type_id;
+
+#[cfg(test)]
+mod tests {
+    #![allow(clippy::upper_case_acronyms)]
+
+    trait MB {
+        downcast_get_type_id!();
+    }
+
+    downcast_dyn!(MB);
+
+    impl MB for String {}
+    impl MB for () {}
+
+    #[actix_rt::test]
+    async fn test_any_casting() {
+        let mut body = String::from("hello cast");
+        let resp_body: &mut dyn MB = &mut body;
+        let body = resp_body.downcast_ref::<String>().unwrap();
+        assert_eq!(body, "hello cast");
+        let body = resp_body.downcast_mut::<String>().unwrap();
+        body.push('!');
+        let body = resp_body.downcast_ref::<String>().unwrap();
+        assert_eq!(body, "hello cast!");
+        let not_body = resp_body.downcast_ref::<()>();
+        assert!(not_body.is_none());
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/error/mod.rs.html b/src/actix_web/error/mod.rs.html new file mode 100644 index 000000000..19fe64dc4 --- /dev/null +++ b/src/actix_web/error/mod.rs.html @@ -0,0 +1,537 @@ +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
+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
+
//! Error and Result module
+
+// This is meant to be a glob import of the whole error module except for `Error`. Rustdoc can't yet
+// correctly resolve the conflicting `Error` type defined in this module, so these re-exports are
+// expanded manually.
+//
+// See <https://github.com/rust-lang/rust/issues/83375>
+pub use actix_http::error::{ContentTypeError, DispatchError, HttpError, ParseError, PayloadError};
+use derive_more::{Display, Error, From};
+use serde_json::error::Error as JsonError;
+use serde_urlencoded::{de::Error as FormDeError, ser::Error as FormError};
+use url::ParseError as UrlParseError;
+
+use crate::http::StatusCode;
+
+#[allow(clippy::module_inception)]
+mod error;
+mod internal;
+mod macros;
+mod response_error;
+
+pub(crate) use self::macros::{downcast_dyn, downcast_get_type_id};
+pub use self::{error::Error, internal::*, response_error::ResponseError};
+
+/// A convenience [`Result`](std::result::Result) for Actix Web operations.
+///
+/// This type alias is generally used to avoid writing out `actix_http::Error` directly.
+pub type Result<T, E = Error> = std::result::Result<T, E>;
+
+/// An error representing a problem running a blocking task on a thread pool.
+#[derive(Debug, Display, Error)]
+#[display(fmt = "Blocking thread pool is shut down unexpectedly")]
+#[non_exhaustive]
+pub struct BlockingError;
+
+impl ResponseError for crate::error::BlockingError {}
+
+/// Errors which can occur when attempting to generate resource uri.
+#[derive(Debug, PartialEq, Eq, Display, Error, From)]
+#[non_exhaustive]
+pub enum UrlGenerationError {
+    /// Resource not found.
+    #[display(fmt = "Resource not found")]
+    ResourceNotFound,
+
+    /// Not all URL parameters covered.
+    #[display(fmt = "Not all URL parameters covered")]
+    NotEnoughElements,
+
+    /// URL parse error.
+    #[display(fmt = "{}", _0)]
+    ParseError(UrlParseError),
+}
+
+impl ResponseError for UrlGenerationError {}
+
+/// A set of errors that can occur during parsing urlencoded payloads
+#[derive(Debug, Display, Error, From)]
+#[non_exhaustive]
+pub enum UrlencodedError {
+    /// Can not decode chunked transfer encoding.
+    #[display(fmt = "Can not decode chunked transfer encoding.")]
+    Chunked,
+
+    /// Payload size is larger than allowed. (default limit: 256kB).
+    #[display(
+        fmt = "URL encoded payload is larger ({} bytes) than allowed (limit: {} bytes).",
+        size,
+        limit
+    )]
+    Overflow { size: usize, limit: usize },
+
+    /// Payload size is now known.
+    #[display(fmt = "Payload size is now known.")]
+    UnknownLength,
+
+    /// Content type error.
+    #[display(fmt = "Content type error.")]
+    ContentType,
+
+    /// Parse error.
+    #[display(fmt = "Parse error: {}.", _0)]
+    Parse(FormDeError),
+
+    /// Encoding error.
+    #[display(fmt = "Encoding error.")]
+    Encoding,
+
+    /// Serialize error.
+    #[display(fmt = "Serialize error: {}.", _0)]
+    Serialize(FormError),
+
+    /// Payload error.
+    #[display(fmt = "Error that occur during reading payload: {}.", _0)]
+    Payload(PayloadError),
+}
+
+impl ResponseError for UrlencodedError {
+    fn status_code(&self) -> StatusCode {
+        match self {
+            Self::Overflow { .. } => StatusCode::PAYLOAD_TOO_LARGE,
+            Self::UnknownLength => StatusCode::LENGTH_REQUIRED,
+            Self::Payload(err) => err.status_code(),
+            _ => StatusCode::BAD_REQUEST,
+        }
+    }
+}
+
+/// A set of errors that can occur during parsing json payloads
+#[derive(Debug, Display, Error)]
+#[non_exhaustive]
+pub enum JsonPayloadError {
+    /// Payload size is bigger than allowed & content length header set. (default: 2MB)
+    #[display(
+        fmt = "JSON payload ({} bytes) is larger than allowed (limit: {} bytes).",
+        length,
+        limit
+    )]
+    OverflowKnownLength { length: usize, limit: usize },
+
+    /// Payload size is bigger than allowed but no content length header set. (default: 2MB)
+    #[display(fmt = "JSON payload has exceeded limit ({} bytes).", limit)]
+    Overflow { limit: usize },
+
+    /// Content type error
+    #[display(fmt = "Content type error")]
+    ContentType,
+
+    /// Deserialize error
+    #[display(fmt = "Json deserialize error: {}", _0)]
+    Deserialize(JsonError),
+
+    /// Serialize error
+    #[display(fmt = "Json serialize error: {}", _0)]
+    Serialize(JsonError),
+
+    /// Payload error
+    #[display(fmt = "Error that occur during reading payload: {}", _0)]
+    Payload(PayloadError),
+}
+
+impl From<PayloadError> for JsonPayloadError {
+    fn from(err: PayloadError) -> Self {
+        Self::Payload(err)
+    }
+}
+
+impl ResponseError for JsonPayloadError {
+    fn status_code(&self) -> StatusCode {
+        match self {
+            Self::OverflowKnownLength {
+                length: _,
+                limit: _,
+            } => StatusCode::PAYLOAD_TOO_LARGE,
+            Self::Overflow { limit: _ } => StatusCode::PAYLOAD_TOO_LARGE,
+            Self::Serialize(_) => StatusCode::INTERNAL_SERVER_ERROR,
+            Self::Payload(err) => err.status_code(),
+            _ => StatusCode::BAD_REQUEST,
+        }
+    }
+}
+
+/// A set of errors that can occur during parsing request paths
+#[derive(Debug, Display, Error)]
+#[non_exhaustive]
+pub enum PathError {
+    /// Deserialize error
+    #[display(fmt = "Path deserialize error: {}", _0)]
+    Deserialize(serde::de::value::Error),
+}
+
+/// Return `BadRequest` for `PathError`
+impl ResponseError for PathError {
+    fn status_code(&self) -> StatusCode {
+        StatusCode::BAD_REQUEST
+    }
+}
+
+/// A set of errors that can occur during parsing query strings.
+#[derive(Debug, Display, Error, From)]
+#[non_exhaustive]
+pub enum QueryPayloadError {
+    /// Query deserialize error.
+    #[display(fmt = "Query deserialize error: {}", _0)]
+    Deserialize(serde::de::value::Error),
+}
+
+impl ResponseError for QueryPayloadError {
+    fn status_code(&self) -> StatusCode {
+        StatusCode::BAD_REQUEST
+    }
+}
+
+/// Error type returned when reading body as lines.
+#[derive(Debug, Display, Error, From)]
+#[non_exhaustive]
+pub enum ReadlinesError {
+    #[display(fmt = "Encoding error")]
+    /// Payload size is bigger than allowed. (default: 256kB)
+    EncodingError,
+
+    /// Payload error.
+    #[display(fmt = "Error that occur during reading payload: {}", _0)]
+    Payload(PayloadError),
+
+    /// Line limit exceeded.
+    #[display(fmt = "Line limit exceeded")]
+    LimitOverflow,
+
+    /// ContentType error.
+    #[display(fmt = "Content-type error")]
+    ContentTypeError(ContentTypeError),
+}
+
+impl ResponseError for ReadlinesError {
+    fn status_code(&self) -> StatusCode {
+        match *self {
+            ReadlinesError::LimitOverflow => StatusCode::PAYLOAD_TOO_LARGE,
+            _ => StatusCode::BAD_REQUEST,
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_urlencoded_error() {
+        let resp = UrlencodedError::Overflow { size: 0, limit: 0 }.error_response();
+        assert_eq!(resp.status(), StatusCode::PAYLOAD_TOO_LARGE);
+        let resp = UrlencodedError::UnknownLength.error_response();
+        assert_eq!(resp.status(), StatusCode::LENGTH_REQUIRED);
+        let resp = UrlencodedError::ContentType.error_response();
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+    }
+
+    #[test]
+    fn test_json_payload_error() {
+        let resp = JsonPayloadError::OverflowKnownLength {
+            length: 0,
+            limit: 0,
+        }
+        .error_response();
+        assert_eq!(resp.status(), StatusCode::PAYLOAD_TOO_LARGE);
+        let resp = JsonPayloadError::Overflow { limit: 0 }.error_response();
+        assert_eq!(resp.status(), StatusCode::PAYLOAD_TOO_LARGE);
+        let resp = JsonPayloadError::ContentType.error_response();
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+    }
+
+    #[test]
+    fn test_query_payload_error() {
+        let resp = QueryPayloadError::Deserialize(
+            serde_urlencoded::from_str::<i32>("bad query").unwrap_err(),
+        )
+        .error_response();
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+    }
+
+    #[test]
+    fn test_readlines_error() {
+        let resp = ReadlinesError::LimitOverflow.error_response();
+        assert_eq!(resp.status(), StatusCode::PAYLOAD_TOO_LARGE);
+        let resp = ReadlinesError::EncodingError.error_response();
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/error/response_error.rs.html b/src/actix_web/error/response_error.rs.html new file mode 100644 index 000000000..ce2f1ebcf --- /dev/null +++ b/src/actix_web/error/response_error.rs.html @@ -0,0 +1,321 @@ +response_error.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+
//! `ResponseError` trait and foreign impls.
+
+use std::{
+    convert::Infallible,
+    error::Error as StdError,
+    fmt,
+    io::{self, Write as _},
+};
+
+use actix_http::Response;
+use bytes::BytesMut;
+
+use crate::{
+    body::BoxBody,
+    error::{downcast_dyn, downcast_get_type_id},
+    helpers,
+    http::{
+        header::{self, TryIntoHeaderValue},
+        StatusCode,
+    },
+    HttpResponse,
+};
+
+/// Errors that can generate responses.
+// TODO: flesh out documentation
+pub trait ResponseError: fmt::Debug + fmt::Display {
+    /// Returns appropriate status code for error.
+    ///
+    /// A 500 Internal Server Error is used by default. If [error_response](Self::error_response) is
+    /// also implemented and does not call `self.status_code()`, then this will not be used.
+    fn status_code(&self) -> StatusCode {
+        StatusCode::INTERNAL_SERVER_ERROR
+    }
+
+    /// Creates full response for error.
+    ///
+    /// By default, the generated response uses a 500 Internal Server Error status code, a
+    /// `Content-Type` of `text/plain`, and the body is set to `Self`'s `Display` impl.
+    fn error_response(&self) -> HttpResponse<BoxBody> {
+        let mut res = HttpResponse::new(self.status_code());
+
+        let mut buf = BytesMut::new();
+        let _ = write!(helpers::MutWriter(&mut buf), "{}", self);
+
+        let mime = mime::TEXT_PLAIN_UTF_8.try_into_value().unwrap();
+        res.headers_mut().insert(header::CONTENT_TYPE, mime);
+
+        res.set_body(BoxBody::new(buf))
+    }
+
+    downcast_get_type_id!();
+}
+
+downcast_dyn!(ResponseError);
+
+impl ResponseError for Box<dyn StdError + 'static> {}
+
+impl ResponseError for Infallible {
+    fn status_code(&self) -> StatusCode {
+        match *self {}
+    }
+    fn error_response(&self) -> HttpResponse<BoxBody> {
+        match *self {}
+    }
+}
+
+#[cfg(feature = "openssl")]
+impl ResponseError for actix_tls::accept::openssl::reexports::Error {}
+
+impl ResponseError for serde::de::value::Error {
+    fn status_code(&self) -> StatusCode {
+        StatusCode::BAD_REQUEST
+    }
+}
+
+impl ResponseError for serde_json::Error {}
+
+impl ResponseError for serde_urlencoded::ser::Error {}
+
+impl ResponseError for std::str::Utf8Error {
+    fn status_code(&self) -> StatusCode {
+        StatusCode::BAD_REQUEST
+    }
+}
+
+impl ResponseError for std::io::Error {
+    fn status_code(&self) -> StatusCode {
+        match self.kind() {
+            io::ErrorKind::NotFound => StatusCode::NOT_FOUND,
+            io::ErrorKind::PermissionDenied => StatusCode::FORBIDDEN,
+            _ => StatusCode::INTERNAL_SERVER_ERROR,
+        }
+    }
+}
+
+impl ResponseError for actix_http::error::HttpError {}
+
+impl ResponseError for actix_http::Error {
+    fn status_code(&self) -> StatusCode {
+        StatusCode::INTERNAL_SERVER_ERROR
+    }
+
+    fn error_response(&self) -> HttpResponse<BoxBody> {
+        HttpResponse::with_body(self.status_code(), self.to_string()).map_into_boxed_body()
+    }
+}
+
+impl ResponseError for actix_http::header::InvalidHeaderValue {
+    fn status_code(&self) -> StatusCode {
+        StatusCode::BAD_REQUEST
+    }
+}
+
+impl ResponseError for actix_http::error::ParseError {
+    fn status_code(&self) -> StatusCode {
+        StatusCode::BAD_REQUEST
+    }
+}
+
+impl ResponseError for actix_http::error::PayloadError {
+    fn status_code(&self) -> StatusCode {
+        match *self {
+            actix_http::error::PayloadError::Overflow => StatusCode::PAYLOAD_TOO_LARGE,
+            _ => StatusCode::BAD_REQUEST,
+        }
+    }
+}
+
+impl ResponseError for actix_http::ws::ProtocolError {}
+
+impl ResponseError for actix_http::error::ContentTypeError {
+    fn status_code(&self) -> StatusCode {
+        StatusCode::BAD_REQUEST
+    }
+}
+
+impl ResponseError for actix_http::ws::HandshakeError {
+    fn error_response(&self) -> HttpResponse<BoxBody> {
+        Response::from(self).map_into_boxed_body().into()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_error_casting() {
+        use actix_http::error::{ContentTypeError, PayloadError};
+
+        let err = PayloadError::Overflow;
+        let resp_err: &dyn ResponseError = &err;
+
+        let err = resp_err.downcast_ref::<PayloadError>().unwrap();
+        assert_eq!(err.to_string(), "payload reached size limit");
+
+        let not_err = resp_err.downcast_ref::<ContentTypeError>();
+        assert!(not_err.is_none());
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/extract.rs.html b/src/actix_web/extract.rs.html new file mode 100644 index 000000000..d6f75ceff --- /dev/null +++ b/src/actix_web/extract.rs.html @@ -0,0 +1,1111 @@ +extract.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
+
//! Request extractors
+
+use std::{
+    convert::Infallible,
+    future::Future,
+    marker::PhantomData,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use actix_http::{Method, Uri};
+use actix_utils::future::{ok, Ready};
+use futures_core::ready;
+use pin_project_lite::pin_project;
+
+use crate::{dev::Payload, Error, HttpRequest};
+
+/// A type that implements [`FromRequest`] is called an **extractor** and can extract data from
+/// the request. Some types that implement this trait are: [`Json`], [`Header`], and [`Path`].
+///
+/// Check out [`ServiceRequest::extract`](crate::dev::ServiceRequest::extract) if you want to
+/// leverage extractors when implementing middlewares.
+///
+/// # Configuration
+/// An extractor can be customized by injecting the corresponding configuration with one of:
+/// - [`App::app_data()`][crate::App::app_data]
+/// - [`Scope::app_data()`][crate::Scope::app_data]
+/// - [`Resource::app_data()`][crate::Resource::app_data]
+///
+/// Here are some built-in extractors and their corresponding configuration.
+/// Please refer to the respective documentation for details.
+///
+/// | Extractor   | Configuration     |
+/// |-------------|-------------------|
+/// | [`Header`]  | _None_            |
+/// | [`Path`]    | [`PathConfig`]    |
+/// | [`Json`]    | [`JsonConfig`]    |
+/// | [`Form`]    | [`FormConfig`]    |
+/// | [`Query`]   | [`QueryConfig`]   |
+/// | [`Bytes`]   | [`PayloadConfig`] |
+/// | [`String`]  | [`PayloadConfig`] |
+/// | [`Payload`] | [`PayloadConfig`] |
+///
+/// # Implementing An Extractor
+/// To reduce duplicate code in handlers where extracting certain parts of a request has a common
+/// structure, you can implement `FromRequest` for your own types.
+///
+/// Note that the request payload can only be consumed by one extractor.
+///
+/// [`Header`]: crate::web::Header
+/// [`Json`]: crate::web::Json
+/// [`JsonConfig`]: crate::web::JsonConfig
+/// [`Form`]: crate::web::Form
+/// [`FormConfig`]: crate::web::FormConfig
+/// [`Path`]: crate::web::Path
+/// [`PathConfig`]: crate::web::PathConfig
+/// [`Query`]: crate::web::Query
+/// [`QueryConfig`]: crate::web::QueryConfig
+/// [`Payload`]: crate::web::Payload
+/// [`PayloadConfig`]: crate::web::PayloadConfig
+/// [`String`]: FromRequest#impl-FromRequest-for-String
+/// [`Bytes`]: crate::web::Bytes#impl-FromRequest
+/// [`Either`]: crate::web::Either
+#[doc(alias = "extract", alias = "extractor")]
+pub trait FromRequest: Sized {
+    /// The associated error which can be returned.
+    type Error: Into<Error>;
+
+    /// Future that resolves to a `Self`.
+    ///
+    /// To use an async function or block, the futures must be boxed. The following snippet will be
+    /// common when creating async/await extractors (that do not consume the body).
+    ///
+    /// ```ignore
+    /// type Future = Pin<Box<dyn Future<Output = Result<Self, Self::Error>>>>;
+    /// // or
+    /// type Future = futures_util::future::LocalBoxFuture<'static, Result<Self, Self::Error>>;
+    ///
+    /// fn from_request(req: HttpRequest, ...) -> Self::Future {
+    ///     let req = req.clone();
+    ///     Box::pin(async move {
+    ///         ...
+    ///     })
+    /// }
+    /// ```
+    type Future: Future<Output = Result<Self, Self::Error>>;
+
+    /// Create a `Self` from request parts asynchronously.
+    fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future;
+
+    /// Create a `Self` from request head asynchronously.
+    ///
+    /// This method is short for `T::from_request(req, &mut Payload::None)`.
+    fn extract(req: &HttpRequest) -> Self::Future {
+        Self::from_request(req, &mut Payload::None)
+    }
+}
+
+/// Optionally extract from the request.
+///
+/// If the inner `T::from_request` returns an error, handler will receive `None` instead.
+///
+/// # Examples
+/// ```
+/// use actix_web::{web, dev, App, Error, HttpRequest, FromRequest};
+/// use actix_web::error::ErrorBadRequest;
+/// use futures_util::future::{ok, err, Ready};
+/// use serde::Deserialize;
+/// use rand;
+///
+/// #[derive(Debug, Deserialize)]
+/// struct Thing {
+///     name: String
+/// }
+///
+/// impl FromRequest for Thing {
+///     type Error = Error;
+///     type Future = Ready<Result<Self, Self::Error>>;
+///
+///     fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
+///         if rand::random() {
+///             ok(Thing { name: "thingy".into() })
+///         } else {
+///             err(ErrorBadRequest("no luck"))
+///         }
+///
+///     }
+/// }
+///
+/// /// extract `Thing` from request
+/// async fn index(supplied_thing: Option<Thing>) -> String {
+///     match supplied_thing {
+///         // Puns not intended
+///         Some(thing) => format!("Got something: {:?}", thing),
+///         None => format!("No thing!")
+///     }
+/// }
+///
+/// let app = App::new().service(
+///     web::resource("/users/:first").route(
+///         web::post().to(index))
+/// );
+/// ```
+impl<T> FromRequest for Option<T>
+where
+    T: FromRequest,
+{
+    type Error = Infallible;
+    type Future = FromRequestOptFuture<T::Future>;
+
+    #[inline]
+    fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
+        FromRequestOptFuture {
+            fut: T::from_request(req, payload),
+        }
+    }
+}
+
+pin_project! {
+    pub struct FromRequestOptFuture<Fut> {
+        #[pin]
+        fut: Fut,
+    }
+}
+
+impl<Fut, T, E> Future for FromRequestOptFuture<Fut>
+where
+    Fut: Future<Output = Result<T, E>>,
+    E: Into<Error>,
+{
+    type Output = Result<Option<T>, Infallible>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.project();
+        let res = ready!(this.fut.poll(cx));
+        match res {
+            Ok(t) => Poll::Ready(Ok(Some(t))),
+            Err(err) => {
+                log::debug!("Error for Option<T> extractor: {}", err.into());
+                Poll::Ready(Ok(None))
+            }
+        }
+    }
+}
+
+/// Extract from the request, passing error type through to handler.
+///
+/// If the inner `T::from_request` returns an error, allow handler to receive the error rather than
+/// immediately returning an error response.
+///
+/// # Examples
+/// ```
+/// use actix_web::{web, dev, App, Result, Error, HttpRequest, FromRequest};
+/// use actix_web::error::ErrorBadRequest;
+/// use futures_util::future::{ok, err, Ready};
+/// use serde::Deserialize;
+/// use rand;
+///
+/// #[derive(Debug, Deserialize)]
+/// struct Thing {
+///     name: String
+/// }
+///
+/// impl FromRequest for Thing {
+///     type Error = Error;
+///     type Future = Ready<Result<Thing, Error>>;
+///
+///     fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
+///         if rand::random() {
+///             ok(Thing { name: "thingy".into() })
+///         } else {
+///             err(ErrorBadRequest("no luck"))
+///         }
+///     }
+/// }
+///
+/// /// extract `Thing` from request
+/// async fn index(supplied_thing: Result<Thing>) -> String {
+///     match supplied_thing {
+///         Ok(thing) => format!("Got thing: {thing:?}"),
+///         Err(err) => format!("Error extracting thing: {err}"),
+///     }
+/// }
+///
+/// let app = App::new().service(
+///     web::resource("/users/:first").route(web::post().to(index))
+/// );
+/// ```
+impl<T, E> FromRequest for Result<T, E>
+where
+    T: FromRequest,
+    T::Error: Into<E>,
+{
+    type Error = Infallible;
+    type Future = FromRequestResFuture<T::Future, E>;
+
+    #[inline]
+    fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
+        FromRequestResFuture {
+            fut: T::from_request(req, payload),
+            _phantom: PhantomData,
+        }
+    }
+}
+
+pin_project! {
+    pub struct FromRequestResFuture<Fut, E> {
+        #[pin]
+        fut: Fut,
+        _phantom: PhantomData<E>,
+    }
+}
+
+impl<Fut, T, Ei, E> Future for FromRequestResFuture<Fut, E>
+where
+    Fut: Future<Output = Result<T, Ei>>,
+    Ei: Into<E>,
+{
+    type Output = Result<Result<T, E>, Infallible>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.project();
+        let res = ready!(this.fut.poll(cx));
+        Poll::Ready(Ok(res.map_err(Into::into)))
+    }
+}
+
+/// Extract the request's URI.
+///
+/// # Examples
+/// ```
+/// use actix_web::{http::Uri, web, App, Responder};
+///
+/// async fn handler(uri: Uri) -> impl Responder {
+///     format!("Requested path: {}", uri.path())
+/// }
+///
+/// let app = App::new().default_service(web::to(handler));
+/// ```
+impl FromRequest for Uri {
+    type Error = Infallible;
+    type Future = Ready<Result<Self, Self::Error>>;
+
+    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
+        ok(req.uri().clone())
+    }
+}
+
+/// Extract the request's method.
+///
+/// # Examples
+/// ```
+/// use actix_web::{http::Method, web, App, Responder};
+///
+/// async fn handler(method: Method) -> impl Responder {
+///     format!("Request method: {}", method)
+/// }
+///
+/// let app = App::new().default_service(web::to(handler));
+/// ```
+impl FromRequest for Method {
+    type Error = Infallible;
+    type Future = Ready<Result<Self, Self::Error>>;
+
+    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
+        ok(req.method().clone())
+    }
+}
+
+#[doc(hidden)]
+#[allow(non_snake_case)]
+mod tuple_from_req {
+    use super::*;
+
+    macro_rules! tuple_from_req {
+        ($fut: ident; $($T: ident),*) => {
+            /// FromRequest implementation for tuple
+            #[allow(unused_parens)]
+            impl<$($T: FromRequest + 'static),+> FromRequest for ($($T,)+)
+            {
+                type Error = Error;
+                type Future = $fut<$($T),+>;
+
+                fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
+                    $fut {
+                        $(
+                            $T: ExtractFuture::Future {
+                                fut: $T::from_request(req, payload)
+                            },
+                        )+
+                    }
+                }
+            }
+
+            pin_project! {
+                pub struct $fut<$($T: FromRequest),+> {
+                    $(
+                        #[pin]
+                        $T: ExtractFuture<$T::Future, $T>,
+                    )+
+                }
+            }
+
+            impl<$($T: FromRequest),+> Future for $fut<$($T),+>
+            {
+                type Output = Result<($($T,)+), Error>;
+
+                fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+                    let mut this = self.project();
+
+                    let mut ready = true;
+                    $(
+                        match this.$T.as_mut().project() {
+                            ExtractProj::Future { fut } => match fut.poll(cx) {
+                                Poll::Ready(Ok(output)) => {
+                                    let _ = this.$T.as_mut().project_replace(ExtractFuture::Done { output });
+                                },
+                                Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
+                                Poll::Pending => ready = false,
+                            },
+                            ExtractProj::Done { .. } => {},
+                            ExtractProj::Empty => unreachable!("FromRequest polled after finished"),
+                        }
+                    )+
+
+                    if ready {
+                        Poll::Ready(Ok(
+                            ($(
+                                match this.$T.project_replace(ExtractFuture::Empty) {
+                                    ExtractReplaceProj::Done { output } => output,
+                                    _ => unreachable!("FromRequest polled after finished"),
+                                },
+                            )+)
+                        ))
+                    } else {
+                        Poll::Pending
+                    }
+                }
+            }
+        };
+    }
+
+    pin_project! {
+        #[project = ExtractProj]
+        #[project_replace = ExtractReplaceProj]
+        enum ExtractFuture<Fut, Res> {
+            Future {
+                #[pin]
+                fut: Fut
+            },
+            Done {
+                output: Res,
+            },
+            Empty
+        }
+    }
+
+    impl FromRequest for () {
+        type Error = Infallible;
+        type Future = Ready<Result<Self, Self::Error>>;
+
+        fn from_request(_: &HttpRequest, _: &mut Payload) -> Self::Future {
+            ok(())
+        }
+    }
+
+    tuple_from_req! { TupleFromRequest1; A }
+    tuple_from_req! { TupleFromRequest2; A, B }
+    tuple_from_req! { TupleFromRequest3; A, B, C }
+    tuple_from_req! { TupleFromRequest4; A, B, C, D }
+    tuple_from_req! { TupleFromRequest5; A, B, C, D, E }
+    tuple_from_req! { TupleFromRequest6; A, B, C, D, E, F }
+    tuple_from_req! { TupleFromRequest7; A, B, C, D, E, F, G }
+    tuple_from_req! { TupleFromRequest8; A, B, C, D, E, F, G, H }
+    tuple_from_req! { TupleFromRequest9; A, B, C, D, E, F, G, H, I }
+    tuple_from_req! { TupleFromRequest10; A, B, C, D, E, F, G, H, I, J }
+    tuple_from_req! { TupleFromRequest11; A, B, C, D, E, F, G, H, I, J, K }
+    tuple_from_req! { TupleFromRequest12; A, B, C, D, E, F, G, H, I, J, K, L }
+    tuple_from_req! { TupleFromRequest13; A, B, C, D, E, F, G, H, I, J, K, L, M }
+    tuple_from_req! { TupleFromRequest14; A, B, C, D, E, F, G, H, I, J, K, L, M, N }
+    tuple_from_req! { TupleFromRequest15; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O }
+    tuple_from_req! { TupleFromRequest16; A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_http::header;
+    use bytes::Bytes;
+    use serde::Deserialize;
+
+    use super::*;
+    use crate::{
+        test::TestRequest,
+        types::{Form, FormConfig},
+    };
+
+    #[derive(Deserialize, Debug, PartialEq)]
+    struct Info {
+        hello: String,
+    }
+
+    #[actix_rt::test]
+    async fn test_option() {
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((header::CONTENT_TYPE, "application/x-www-form-urlencoded"))
+            .data(FormConfig::default().limit(4096))
+            .to_http_parts();
+
+        let r = Option::<Form<Info>>::from_request(&req, &mut pl)
+            .await
+            .unwrap();
+        assert_eq!(r, None);
+
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((header::CONTENT_TYPE, "application/x-www-form-urlencoded"))
+            .insert_header((header::CONTENT_LENGTH, "9"))
+            .set_payload(Bytes::from_static(b"hello=world"))
+            .to_http_parts();
+
+        let r = Option::<Form<Info>>::from_request(&req, &mut pl)
+            .await
+            .unwrap();
+        assert_eq!(
+            r,
+            Some(Form(Info {
+                hello: "world".into()
+            }))
+        );
+
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((header::CONTENT_TYPE, "application/x-www-form-urlencoded"))
+            .insert_header((header::CONTENT_LENGTH, "9"))
+            .set_payload(Bytes::from_static(b"bye=world"))
+            .to_http_parts();
+
+        let r = Option::<Form<Info>>::from_request(&req, &mut pl)
+            .await
+            .unwrap();
+        assert_eq!(r, None);
+    }
+
+    #[actix_rt::test]
+    async fn test_result() {
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((header::CONTENT_TYPE, "application/x-www-form-urlencoded"))
+            .insert_header((header::CONTENT_LENGTH, "11"))
+            .set_payload(Bytes::from_static(b"hello=world"))
+            .to_http_parts();
+
+        let r = Result::<Form<Info>, Error>::from_request(&req, &mut pl)
+            .await
+            .unwrap()
+            .unwrap();
+        assert_eq!(
+            r,
+            Form(Info {
+                hello: "world".into()
+            })
+        );
+
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((header::CONTENT_TYPE, "application/x-www-form-urlencoded"))
+            .insert_header((header::CONTENT_LENGTH, 9))
+            .set_payload(Bytes::from_static(b"bye=world"))
+            .to_http_parts();
+
+        struct MyError;
+        impl From<Error> for MyError {
+            fn from(_: Error) -> Self {
+                Self
+            }
+        }
+
+        let r = Result::<Form<Info>, MyError>::from_request(&req, &mut pl)
+            .await
+            .unwrap();
+        assert!(r.is_err());
+    }
+
+    #[actix_rt::test]
+    async fn test_uri() {
+        let req = TestRequest::default().uri("/foo/bar").to_http_request();
+        let uri = Uri::extract(&req).await.unwrap();
+        assert_eq!(uri.path(), "/foo/bar");
+    }
+
+    #[actix_rt::test]
+    async fn test_method() {
+        let req = TestRequest::default().method(Method::GET).to_http_request();
+        let method = Method::extract(&req).await.unwrap();
+        assert_eq!(method, Method::GET);
+    }
+
+    #[actix_rt::test]
+    async fn test_concurrent() {
+        let (req, mut pl) = TestRequest::default()
+            .uri("/foo/bar")
+            .method(Method::GET)
+            .insert_header((header::CONTENT_TYPE, "application/x-www-form-urlencoded"))
+            .insert_header((header::CONTENT_LENGTH, "11"))
+            .set_payload(Bytes::from_static(b"hello=world"))
+            .to_http_parts();
+        let (method, uri, form) = <(Method, Uri, Form<Info>)>::from_request(&req, &mut pl)
+            .await
+            .unwrap();
+        assert_eq!(method, Method::GET);
+        assert_eq!(uri.path(), "/foo/bar");
+        assert_eq!(
+            form,
+            Form(Info {
+                hello: "world".into()
+            })
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/guard/acceptable.rs.html b/src/actix_web/guard/acceptable.rs.html new file mode 100644 index 000000000..9d424edd5 --- /dev/null +++ b/src/actix_web/guard/acceptable.rs.html @@ -0,0 +1,199 @@ +acceptable.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
+
use super::{Guard, GuardContext};
+use crate::http::header::Accept;
+
+/// A guard that verifies that an `Accept` header is present and it contains a compatible MIME type.
+///
+/// An exception is that matching `*/*` must be explicitly enabled because most browsers send this
+/// as part of their `Accept` header for almost every request.
+///
+/// # Examples
+/// ```
+/// use actix_web::{guard::Acceptable, web, HttpResponse};
+///
+/// web::resource("/images")
+///     .guard(Acceptable::new(mime::IMAGE_STAR))
+///     .default_service(web::to(|| async {
+///         HttpResponse::Ok().body("only called when images responses are acceptable")
+///     }));
+/// ```
+#[derive(Debug, Clone)]
+pub struct Acceptable {
+    mime: mime::Mime,
+
+    /// Whether to match `*/*` mime type.
+    ///
+    /// Defaults to false because it's not very useful otherwise.
+    match_star_star: bool,
+}
+
+impl Acceptable {
+    /// Constructs new `Acceptable` guard with the given `mime` type/pattern.
+    pub fn new(mime: mime::Mime) -> Self {
+        Self {
+            mime,
+            match_star_star: false,
+        }
+    }
+
+    /// Allows `*/*` in the `Accept` header to pass the guard check.
+    pub fn match_star_star(mut self) -> Self {
+        self.match_star_star = true;
+        self
+    }
+}
+
+impl Guard for Acceptable {
+    fn check(&self, ctx: &GuardContext<'_>) -> bool {
+        let accept = match ctx.header::<Accept>() {
+            Some(hdr) => hdr,
+            None => return false,
+        };
+
+        let target_type = self.mime.type_();
+        let target_subtype = self.mime.subtype();
+
+        for mime in accept.0.into_iter().map(|q| q.item) {
+            return match (mime.type_(), mime.subtype()) {
+                (typ, subtype) if typ == target_type && subtype == target_subtype => true,
+                (typ, mime::STAR) if typ == target_type => true,
+                (mime::STAR, mime::STAR) if self.match_star_star => true,
+                _ => continue,
+            };
+        }
+
+        false
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::{http::header, test::TestRequest};
+
+    #[test]
+    fn test_acceptable() {
+        let req = TestRequest::default().to_srv_request();
+        assert!(!Acceptable::new(mime::APPLICATION_JSON).check(&req.guard_ctx()));
+
+        let req = TestRequest::default()
+            .insert_header((header::ACCEPT, "application/json"))
+            .to_srv_request();
+        assert!(Acceptable::new(mime::APPLICATION_JSON).check(&req.guard_ctx()));
+
+        let req = TestRequest::default()
+            .insert_header((header::ACCEPT, "text/html, application/json"))
+            .to_srv_request();
+        assert!(Acceptable::new(mime::APPLICATION_JSON).check(&req.guard_ctx()));
+    }
+
+    #[test]
+    fn test_acceptable_star() {
+        let req = TestRequest::default()
+            .insert_header((header::ACCEPT, "text/html, */*;q=0.8"))
+            .to_srv_request();
+
+        assert!(Acceptable::new(mime::APPLICATION_JSON)
+            .match_star_star()
+            .check(&req.guard_ctx()));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/guard/host.rs.html b/src/actix_web/guard/host.rs.html new file mode 100644 index 000000000..7989b7da4 --- /dev/null +++ b/src/actix_web/guard/host.rs.html @@ -0,0 +1,419 @@ +host.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
+
use actix_http::{header, uri::Uri, RequestHead};
+
+use super::{Guard, GuardContext};
+
+/// Creates a guard that matches requests targeting a specific host.
+///
+/// # Matching Host
+/// This guard will:
+/// - match against the `Host` header, if present;
+/// - fall-back to matching against the request target's host, if present;
+/// - return false if host cannot be determined;
+///
+/// # Matching Scheme
+/// Optionally, this guard can match against the host's scheme. Set the scheme for matching using
+/// `Host(host).scheme(protocol)`. If the request's scheme cannot be determined, it will not prevent
+/// the guard from matching successfully.
+///
+/// # Examples
+/// The `Host` guard can be used to set up a form of [virtual hosting] within a single app.
+/// Overlapping scope prefixes are usually discouraged, but when combined with non-overlapping guard
+/// definitions they become safe to use in this way. Without these host guards, only routes under
+/// the first-to-be-defined scope would be accessible. You can test this locally using `127.0.0.1`
+/// and `localhost` as the `Host` guards.
+/// ```
+/// use actix_web::{web, http::Method, guard, App, HttpResponse};
+///
+/// App::new()
+///     .service(
+///         web::scope("")
+///             .guard(guard::Host("www.rust-lang.org"))
+///             .default_service(web::to(|| async {
+///                 HttpResponse::Ok().body("marketing site")
+///             })),
+///     )
+///     .service(
+///         web::scope("")
+///             .guard(guard::Host("play.rust-lang.org"))
+///             .default_service(web::to(|| async {
+///                 HttpResponse::Ok().body("playground frontend")
+///             })),
+///     );
+/// ```
+///
+/// The example below additionally guards on the host URI's scheme. This could allow routing to
+/// different handlers for `http:` vs `https:` visitors; to redirect, for example.
+/// ```
+/// use actix_web::{web, guard::Host, HttpResponse};
+///
+/// web::scope("/admin")
+///     .guard(Host("admin.rust-lang.org").scheme("https"))
+///     .default_service(web::to(|| async {
+///         HttpResponse::Ok().body("admin connection is secure")
+///     }));
+/// ```
+///
+/// [virtual hosting]: https://en.wikipedia.org/wiki/Virtual_hosting
+#[allow(non_snake_case)]
+pub fn Host(host: impl AsRef<str>) -> HostGuard {
+    HostGuard {
+        host: host.as_ref().to_string(),
+        scheme: None,
+    }
+}
+
+fn get_host_uri(req: &RequestHead) -> Option<Uri> {
+    req.headers
+        .get(header::HOST)
+        .and_then(|host_value| host_value.to_str().ok())
+        .or_else(|| req.uri.host())
+        .and_then(|host| host.parse().ok())
+}
+
+#[doc(hidden)]
+pub struct HostGuard {
+    host: String,
+    scheme: Option<String>,
+}
+
+impl HostGuard {
+    /// Set request scheme to match
+    pub fn scheme<H: AsRef<str>>(mut self, scheme: H) -> HostGuard {
+        self.scheme = Some(scheme.as_ref().to_string());
+        self
+    }
+}
+
+impl Guard for HostGuard {
+    fn check(&self, ctx: &GuardContext<'_>) -> bool {
+        // parse host URI from header or request target
+        let req_host_uri = match get_host_uri(ctx.head()) {
+            Some(uri) => uri,
+
+            // no match if host cannot be determined
+            None => return false,
+        };
+
+        match req_host_uri.host() {
+            // fall through to scheme checks
+            Some(uri_host) if self.host == uri_host => {}
+
+            // Either:
+            // - request's host does not match guard's host;
+            // - It was possible that the parsed URI from request target did not contain a host.
+            _ => return false,
+        }
+
+        if let Some(ref scheme) = self.scheme {
+            if let Some(ref req_host_uri_scheme) = req_host_uri.scheme_str() {
+                return scheme == req_host_uri_scheme;
+            }
+
+            // TODO: is this the correct behavior?
+            // falls through if scheme cannot be determined
+        }
+
+        // all conditions passed
+        true
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::test::TestRequest;
+
+    #[test]
+    fn host_from_header() {
+        let req = TestRequest::default()
+            .insert_header((
+                header::HOST,
+                header::HeaderValue::from_static("www.rust-lang.org"),
+            ))
+            .to_srv_request();
+
+        let host = Host("www.rust-lang.org");
+        assert!(host.check(&req.guard_ctx()));
+
+        let host = Host("www.rust-lang.org").scheme("https");
+        assert!(host.check(&req.guard_ctx()));
+
+        let host = Host("blog.rust-lang.org");
+        assert!(!host.check(&req.guard_ctx()));
+
+        let host = Host("blog.rust-lang.org").scheme("https");
+        assert!(!host.check(&req.guard_ctx()));
+
+        let host = Host("crates.io");
+        assert!(!host.check(&req.guard_ctx()));
+
+        let host = Host("localhost");
+        assert!(!host.check(&req.guard_ctx()));
+    }
+
+    #[test]
+    fn host_without_header() {
+        let req = TestRequest::default()
+            .uri("www.rust-lang.org")
+            .to_srv_request();
+
+        let host = Host("www.rust-lang.org");
+        assert!(host.check(&req.guard_ctx()));
+
+        let host = Host("www.rust-lang.org").scheme("https");
+        assert!(host.check(&req.guard_ctx()));
+
+        let host = Host("blog.rust-lang.org");
+        assert!(!host.check(&req.guard_ctx()));
+
+        let host = Host("blog.rust-lang.org").scheme("https");
+        assert!(!host.check(&req.guard_ctx()));
+
+        let host = Host("crates.io");
+        assert!(!host.check(&req.guard_ctx()));
+
+        let host = Host("localhost");
+        assert!(!host.check(&req.guard_ctx()));
+    }
+
+    #[test]
+    fn host_scheme() {
+        let req = TestRequest::default()
+            .insert_header((
+                header::HOST,
+                header::HeaderValue::from_static("https://www.rust-lang.org"),
+            ))
+            .to_srv_request();
+
+        let host = Host("www.rust-lang.org").scheme("https");
+        assert!(host.check(&req.guard_ctx()));
+
+        let host = Host("www.rust-lang.org");
+        assert!(host.check(&req.guard_ctx()));
+
+        let host = Host("www.rust-lang.org").scheme("http");
+        assert!(!host.check(&req.guard_ctx()));
+
+        let host = Host("blog.rust-lang.org");
+        assert!(!host.check(&req.guard_ctx()));
+
+        let host = Host("blog.rust-lang.org").scheme("https");
+        assert!(!host.check(&req.guard_ctx()));
+
+        let host = Host("crates.io").scheme("https");
+        assert!(!host.check(&req.guard_ctx()));
+
+        let host = Host("localhost");
+        assert!(!host.check(&req.guard_ctx()));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/guard/mod.rs.html b/src/actix_web/guard/mod.rs.html new file mode 100644 index 000000000..925a00bd0 --- /dev/null +++ b/src/actix_web/guard/mod.rs.html @@ -0,0 +1,1031 @@ +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
+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
+
//! Route guards.
+//!
+//! Guards are used during routing to help select a matching service or handler using some aspect of
+//! the request; though guards should not be used for path matching since it is a built-in function
+//! of the Actix Web router.
+//!
+//! Guards can be used on [`Scope`]s, [`Resource`]s, [`Route`]s, and other custom services.
+//!
+//! Fundamentally, a guard is a predicate function that receives a reference to a request context
+//! object and returns a boolean; true if the request _should_ be handled by the guarded service
+//! or handler. This interface is defined by the [`Guard`] trait.
+//!
+//! Commonly-used guards are provided in this module as well as a way of creating a guard from a
+//! closure ([`fn_guard`]). The [`Not`], [`Any`], and [`All`] guards are noteworthy, as they can be
+//! used to compose other guards in a more flexible and semantic way than calling `.guard(...)` on
+//! services multiple times (which might have different combining behavior than you want).
+//!
+//! There are shortcuts for routes with method guards in the [`web`](crate::web) module:
+//! [`web::get()`](crate::web::get), [`web::post()`](crate::web::post), etc. The routes created by
+//! the following calls are equivalent:
+//!
+//! - `web::get()` (recommended form)
+//! - `web::route().guard(guard::Get())`
+//!
+//! Guards can not modify anything about the request. However, it is possible to store extra
+//! attributes in the request-local data container obtained with [`GuardContext::req_data_mut`].
+//!
+//! Guards can prevent resource definitions from overlapping which, when only considering paths,
+//! would result in inaccessible routes. See the [`Host`] guard for an example of virtual hosting.
+//!
+//! # Examples
+//!
+//! In the following code, the `/guarded` resource has one defined route whose handler will only be
+//! called if the request method is GET or POST and there is a `x-guarded` request header with value
+//! equal to `secret`.
+//!
+//! ```
+//! use actix_web::{web, http::Method, guard, HttpResponse};
+//!
+//! web::resource("/guarded").route(
+//!     web::route()
+//!         .guard(guard::Any(guard::Get()).or(guard::Post()))
+//!         .guard(guard::Header("x-guarded", "secret"))
+//!         .to(|| HttpResponse::Ok())
+//! );
+//! ```
+//!
+//! [`Scope`]: crate::Scope::guard()
+//! [`Resource`]: crate::Resource::guard()
+//! [`Route`]: crate::Route::guard()
+
+use std::{
+    cell::{Ref, RefMut},
+    rc::Rc,
+};
+
+use actix_http::{header, Extensions, Method as HttpMethod, RequestHead};
+
+use crate::{http::header::Header, service::ServiceRequest, HttpMessage as _};
+
+mod acceptable;
+mod host;
+
+pub use self::{
+    acceptable::Acceptable,
+    host::{Host, HostGuard},
+};
+
+/// Provides access to request parts that are useful during routing.
+#[derive(Debug)]
+pub struct GuardContext<'a> {
+    pub(crate) req: &'a ServiceRequest,
+}
+
+impl<'a> GuardContext<'a> {
+    /// Returns reference to the request head.
+    #[inline]
+    pub fn head(&self) -> &RequestHead {
+        self.req.head()
+    }
+
+    /// Returns reference to the request-local data/extensions container.
+    #[inline]
+    pub fn req_data(&self) -> Ref<'a, Extensions> {
+        self.req.extensions()
+    }
+
+    /// Returns mutable reference to the request-local data/extensions container.
+    #[inline]
+    pub fn req_data_mut(&self) -> RefMut<'a, Extensions> {
+        self.req.extensions_mut()
+    }
+
+    /// Extracts a typed header from the request.
+    ///
+    /// Returns `None` if parsing `H` fails.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::{guard::fn_guard, http::header};
+    ///
+    /// let image_accept_guard = fn_guard(|ctx| {
+    ///     match ctx.header::<header::Accept>() {
+    ///         Some(hdr) => hdr.preference() == "image/*",
+    ///         None => false,
+    ///     }
+    /// });
+    /// ```
+    #[inline]
+    pub fn header<H: Header>(&self) -> Option<H> {
+        H::parse(self.req).ok()
+    }
+}
+
+/// Interface for routing guards.
+///
+/// See [module level documentation](self) for more.
+pub trait Guard {
+    /// Returns true if predicate condition is met for a given request.
+    fn check(&self, ctx: &GuardContext<'_>) -> bool;
+}
+
+impl Guard for Rc<dyn Guard> {
+    fn check(&self, ctx: &GuardContext<'_>) -> bool {
+        (**self).check(ctx)
+    }
+}
+
+/// Creates a guard using the given function.
+///
+/// # Examples
+/// ```
+/// use actix_web::{guard, web, HttpResponse};
+///
+/// web::route()
+///     .guard(guard::fn_guard(|ctx| {
+///         ctx.head().headers().contains_key("content-type")
+///     }))
+///     .to(|| HttpResponse::Ok());
+/// ```
+pub fn fn_guard<F>(f: F) -> impl Guard
+where
+    F: Fn(&GuardContext<'_>) -> bool,
+{
+    FnGuard(f)
+}
+
+struct FnGuard<F: Fn(&GuardContext<'_>) -> bool>(F);
+
+impl<F> Guard for FnGuard<F>
+where
+    F: Fn(&GuardContext<'_>) -> bool,
+{
+    fn check(&self, ctx: &GuardContext<'_>) -> bool {
+        (self.0)(ctx)
+    }
+}
+
+impl<F> Guard for F
+where
+    F: Fn(&GuardContext<'_>) -> bool,
+{
+    fn check(&self, ctx: &GuardContext<'_>) -> bool {
+        (self)(ctx)
+    }
+}
+
+/// Creates a guard that matches if any added guards match.
+///
+/// # Examples
+/// The handler below will be called for either request method `GET` or `POST`.
+/// ```
+/// use actix_web::{web, guard, HttpResponse};
+///
+/// web::route()
+///     .guard(
+///         guard::Any(guard::Get())
+///             .or(guard::Post()))
+///     .to(|| HttpResponse::Ok());
+/// ```
+#[allow(non_snake_case)]
+pub fn Any<F: Guard + 'static>(guard: F) -> AnyGuard {
+    AnyGuard {
+        guards: vec![Box::new(guard)],
+    }
+}
+
+/// A collection of guards that match if the disjunction of their `check` outcomes is true.
+///
+/// That is, only one contained guard needs to match in order for the aggregate guard to match.
+///
+/// Construct an `AnyGuard` using [`Any`].
+pub struct AnyGuard {
+    guards: Vec<Box<dyn Guard>>,
+}
+
+impl AnyGuard {
+    /// Adds new guard to the collection of guards to check.
+    pub fn or<F: Guard + 'static>(mut self, guard: F) -> Self {
+        self.guards.push(Box::new(guard));
+        self
+    }
+}
+
+impl Guard for AnyGuard {
+    #[inline]
+    fn check(&self, ctx: &GuardContext<'_>) -> bool {
+        for guard in &self.guards {
+            if guard.check(ctx) {
+                return true;
+            }
+        }
+
+        false
+    }
+}
+
+/// Creates a guard that matches if all added guards match.
+///
+/// # Examples
+/// The handler below will only be called if the request method is `GET` **and** the specified
+/// header name and value match exactly.
+/// ```
+/// use actix_web::{guard, web, HttpResponse};
+///
+/// web::route()
+///     .guard(
+///         guard::All(guard::Get())
+///             .and(guard::Header("accept", "text/plain"))
+///     )
+///     .to(|| HttpResponse::Ok());
+/// ```
+#[allow(non_snake_case)]
+pub fn All<F: Guard + 'static>(guard: F) -> AllGuard {
+    AllGuard {
+        guards: vec![Box::new(guard)],
+    }
+}
+
+/// A collection of guards that match if the conjunction of their `check` outcomes is true.
+///
+/// That is, **all** contained guard needs to match in order for the aggregate guard to match.
+///
+/// Construct an `AllGuard` using [`All`].
+pub struct AllGuard {
+    guards: Vec<Box<dyn Guard>>,
+}
+
+impl AllGuard {
+    /// Adds new guard to the collection of guards to check.
+    pub fn and<F: Guard + 'static>(mut self, guard: F) -> Self {
+        self.guards.push(Box::new(guard));
+        self
+    }
+}
+
+impl Guard for AllGuard {
+    #[inline]
+    fn check(&self, ctx: &GuardContext<'_>) -> bool {
+        for guard in &self.guards {
+            if !guard.check(ctx) {
+                return false;
+            }
+        }
+
+        true
+    }
+}
+
+/// Wraps a guard and inverts the outcome of its `Guard` implementation.
+///
+/// # Examples
+/// The handler below will be called for any request method apart from `GET`.
+/// ```
+/// use actix_web::{guard, web, HttpResponse};
+///
+/// web::route()
+///     .guard(guard::Not(guard::Get()))
+///     .to(|| HttpResponse::Ok());
+/// ```
+pub struct Not<G>(pub G);
+
+impl<G: Guard> Guard for Not<G> {
+    #[inline]
+    fn check(&self, ctx: &GuardContext<'_>) -> bool {
+        !self.0.check(ctx)
+    }
+}
+
+/// Creates a guard that matches a specified HTTP method.
+#[allow(non_snake_case)]
+pub fn Method(method: HttpMethod) -> impl Guard {
+    MethodGuard(method)
+}
+
+#[derive(Debug, Clone)]
+pub(crate) struct RegisteredMethods(pub(crate) Vec<HttpMethod>);
+
+/// HTTP method guard.
+#[derive(Debug)]
+pub(crate) struct MethodGuard(HttpMethod);
+
+impl Guard for MethodGuard {
+    fn check(&self, ctx: &GuardContext<'_>) -> bool {
+        let registered = ctx.req_data_mut().remove::<RegisteredMethods>();
+
+        if let Some(mut methods) = registered {
+            methods.0.push(self.0.clone());
+            ctx.req_data_mut().insert(methods);
+        } else {
+            ctx.req_data_mut()
+                .insert(RegisteredMethods(vec![self.0.clone()]));
+        }
+
+        ctx.head().method == self.0
+    }
+}
+
+macro_rules! method_guard {
+    ($method_fn:ident, $method_const:ident) => {
+        #[doc = concat!("Creates a guard that matches the `", stringify!($method_const), "` request method.")]
+        ///
+        /// # Examples
+        #[doc = concat!("The route in this example will only respond to `", stringify!($method_const), "` requests.")]
+        /// ```
+        /// use actix_web::{guard, web, HttpResponse};
+        ///
+        /// web::route()
+        #[doc = concat!("    .guard(guard::", stringify!($method_fn), "())")]
+        ///     .to(|| HttpResponse::Ok());
+        /// ```
+        #[allow(non_snake_case)]
+        pub fn $method_fn() -> impl Guard {
+            MethodGuard(HttpMethod::$method_const)
+        }
+    };
+}
+
+method_guard!(Get, GET);
+method_guard!(Post, POST);
+method_guard!(Put, PUT);
+method_guard!(Delete, DELETE);
+method_guard!(Head, HEAD);
+method_guard!(Options, OPTIONS);
+method_guard!(Connect, CONNECT);
+method_guard!(Patch, PATCH);
+method_guard!(Trace, TRACE);
+
+/// Creates a guard that matches if request contains given header name and value.
+///
+/// # Examples
+/// The handler below will be called when the request contains an `x-guarded` header with value
+/// equal to `secret`.
+/// ```
+/// use actix_web::{guard, web, HttpResponse};
+///
+/// web::route()
+///     .guard(guard::Header("x-guarded", "secret"))
+///     .to(|| HttpResponse::Ok());
+/// ```
+#[allow(non_snake_case)]
+pub fn Header(name: &'static str, value: &'static str) -> impl Guard {
+    HeaderGuard(
+        header::HeaderName::try_from(name).unwrap(),
+        header::HeaderValue::from_static(value),
+    )
+}
+
+struct HeaderGuard(header::HeaderName, header::HeaderValue);
+
+impl Guard for HeaderGuard {
+    fn check(&self, ctx: &GuardContext<'_>) -> bool {
+        if let Some(val) = ctx.head().headers.get(&self.0) {
+            return val == self.1;
+        }
+
+        false
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_http::Method;
+
+    use super::*;
+    use crate::test::TestRequest;
+
+    #[test]
+    fn header_match() {
+        let req = TestRequest::default()
+            .insert_header((header::TRANSFER_ENCODING, "chunked"))
+            .to_srv_request();
+
+        let hdr = Header("transfer-encoding", "chunked");
+        assert!(hdr.check(&req.guard_ctx()));
+
+        let hdr = Header("transfer-encoding", "other");
+        assert!(!hdr.check(&req.guard_ctx()));
+
+        let hdr = Header("content-type", "chunked");
+        assert!(!hdr.check(&req.guard_ctx()));
+
+        let hdr = Header("content-type", "other");
+        assert!(!hdr.check(&req.guard_ctx()));
+    }
+
+    #[test]
+    fn method_guards() {
+        let get_req = TestRequest::get().to_srv_request();
+        let post_req = TestRequest::post().to_srv_request();
+
+        assert!(Get().check(&get_req.guard_ctx()));
+        assert!(!Get().check(&post_req.guard_ctx()));
+
+        assert!(Post().check(&post_req.guard_ctx()));
+        assert!(!Post().check(&get_req.guard_ctx()));
+
+        let req = TestRequest::put().to_srv_request();
+        assert!(Put().check(&req.guard_ctx()));
+        assert!(!Put().check(&get_req.guard_ctx()));
+
+        let req = TestRequest::patch().to_srv_request();
+        assert!(Patch().check(&req.guard_ctx()));
+        assert!(!Patch().check(&get_req.guard_ctx()));
+
+        let r = TestRequest::delete().to_srv_request();
+        assert!(Delete().check(&r.guard_ctx()));
+        assert!(!Delete().check(&get_req.guard_ctx()));
+
+        let req = TestRequest::default().method(Method::HEAD).to_srv_request();
+        assert!(Head().check(&req.guard_ctx()));
+        assert!(!Head().check(&get_req.guard_ctx()));
+
+        let req = TestRequest::default()
+            .method(Method::OPTIONS)
+            .to_srv_request();
+        assert!(Options().check(&req.guard_ctx()));
+        assert!(!Options().check(&get_req.guard_ctx()));
+
+        let req = TestRequest::default()
+            .method(Method::CONNECT)
+            .to_srv_request();
+        assert!(Connect().check(&req.guard_ctx()));
+        assert!(!Connect().check(&get_req.guard_ctx()));
+
+        let req = TestRequest::default()
+            .method(Method::TRACE)
+            .to_srv_request();
+        assert!(Trace().check(&req.guard_ctx()));
+        assert!(!Trace().check(&get_req.guard_ctx()));
+    }
+
+    #[test]
+    fn aggregate_any() {
+        let req = TestRequest::default()
+            .method(Method::TRACE)
+            .to_srv_request();
+
+        assert!(Any(Trace()).check(&req.guard_ctx()));
+        assert!(Any(Trace()).or(Get()).check(&req.guard_ctx()));
+        assert!(!Any(Get()).or(Get()).check(&req.guard_ctx()));
+    }
+
+    #[test]
+    fn aggregate_all() {
+        let req = TestRequest::default()
+            .method(Method::TRACE)
+            .to_srv_request();
+
+        assert!(All(Trace()).check(&req.guard_ctx()));
+        assert!(All(Trace()).and(Trace()).check(&req.guard_ctx()));
+        assert!(!All(Trace()).and(Get()).check(&req.guard_ctx()));
+    }
+
+    #[test]
+    fn nested_not() {
+        let req = TestRequest::default().to_srv_request();
+
+        let get = Get();
+        assert!(get.check(&req.guard_ctx()));
+
+        let not_get = Not(get);
+        assert!(!not_get.check(&req.guard_ctx()));
+
+        let not_not_get = Not(not_get);
+        assert!(not_not_get.check(&req.guard_ctx()));
+    }
+
+    #[test]
+    fn function_guard() {
+        let domain = "rust-lang.org".to_owned();
+        let guard = fn_guard(|ctx| ctx.head().uri.host().unwrap().ends_with(&domain));
+
+        let req = TestRequest::default()
+            .uri("blog.rust-lang.org")
+            .to_srv_request();
+        assert!(guard.check(&req.guard_ctx()));
+
+        let req = TestRequest::default().uri("crates.io").to_srv_request();
+        assert!(!guard.check(&req.guard_ctx()));
+    }
+
+    #[test]
+    fn mega_nesting() {
+        let guard = fn_guard(|ctx| All(Not(Any(Not(Trace())))).check(ctx));
+
+        let req = TestRequest::default().to_srv_request();
+        assert!(!guard.check(&req.guard_ctx()));
+
+        let req = TestRequest::default()
+            .method(Method::TRACE)
+            .to_srv_request();
+        assert!(guard.check(&req.guard_ctx()));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/handler.rs.html b/src/actix_web/handler.rs.html new file mode 100644 index 000000000..5583c1db9 --- /dev/null +++ b/src/actix_web/handler.rs.html @@ -0,0 +1,375 @@ +handler.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
+
use std::future::Future;
+
+use actix_service::{boxed, fn_service};
+
+use crate::{
+    service::{BoxedHttpServiceFactory, ServiceRequest, ServiceResponse},
+    FromRequest, HttpResponse, Responder,
+};
+
+/// The interface for request handlers.
+///
+/// # What Is A Request Handler
+///
+/// In short, a handler is just an async function that receives request-based arguments, in any
+/// order, and returns something that can be converted to a response.
+///
+/// In particular, a request handler has three requirements:
+///
+/// 1. It is an async function (or a function/closure that returns an appropriate future);
+/// 1. The function parameters (up to 12) implement [`FromRequest`];
+/// 1. The async function (or future) resolves to a type that can be converted into an
+///   [`HttpResponse`] (i.e., it implements the [`Responder`] trait).
+///
+///
+/// # Compiler Errors
+///
+/// If you get the error `the trait Handler<_> is not implemented`, then your handler does not
+/// fulfill the _first_ of the above requirements. (It could also mean that you're attempting to use
+/// a macro-routed handler in a manual routing context like `web::get().to(handler)`, which is not
+/// supported). Breaking the other requirements manifests as errors on implementing [`FromRequest`]
+/// and [`Responder`], respectively.
+///
+/// # How Do Handlers Receive Variable Numbers Of Arguments
+///
+/// Rest assured there is no macro magic here; it's just traits.
+///
+/// The first thing to note is that [`FromRequest`] is implemented for tuples (up to 12 in length).
+///
+/// Secondly, the `Handler` trait is implemented for functions (up to an [arity] of 12) in a way
+/// that aligns their parameter positions with a corresponding tuple of types (becoming the `Args`
+/// type parameter for this trait).
+///
+/// Thanks to Rust's type system, Actix Web can infer the function parameter types. During the
+/// extraction step, the parameter types are described as a tuple type, [`from_request`] is run on
+/// that tuple, and the `Handler::call` implementation for that particular function arity
+/// destructures the tuple into its component types and calls your handler function with them.
+///
+/// In pseudo-code the process looks something like this:
+///
+/// ```ignore
+/// async fn my_handler(body: String, state: web::Data<MyState>) -> impl Responder {
+///     ...
+/// }
+///
+/// // the function params above described as a tuple, names do not matter, only position
+/// type InferredMyHandlerArgs = (String, web::Data<MyState>);
+///
+/// // create tuple of arguments to be passed to handler
+/// let args = InferredMyHandlerArgs::from_request(&request, &payload).await;
+///
+/// // call handler with argument tuple
+/// let response = Handler::call(&my_handler, args).await;
+///
+/// // which is effectively...
+///
+/// let (body, state) = args;
+/// let response = my_handler(body, state).await;
+/// ```
+///
+/// This is the source code for the 2-parameter implementation of `Handler` to help illustrate the
+/// bounds of the handler call after argument extraction:
+/// ```ignore
+/// impl<Func, Arg1, Arg2, Fut> Handler<(Arg1, Arg2)> for Func
+/// where
+///     Func: Fn(Arg1, Arg2) -> Fut + Clone + 'static,
+///     Fut: Future,
+/// {
+///     type Output = Fut::Output;
+///     type Future = Fut;
+///
+///     fn call(&self, (arg1, arg2): (Arg1, Arg2)) -> Self::Future {
+///         (self)(arg1, arg2)
+///     }
+/// }
+/// ```
+///
+/// [arity]: https://en.wikipedia.org/wiki/Arity
+/// [`from_request`]: FromRequest::from_request
+pub trait Handler<Args>: Clone + 'static {
+    type Output;
+    type Future: Future<Output = Self::Output>;
+
+    fn call(&self, args: Args) -> Self::Future;
+}
+
+pub(crate) fn handler_service<F, Args>(handler: F) -> BoxedHttpServiceFactory
+where
+    F: Handler<Args>,
+    Args: FromRequest,
+    F::Output: Responder,
+{
+    boxed::factory(fn_service(move |req: ServiceRequest| {
+        let handler = handler.clone();
+
+        async move {
+            let (req, mut payload) = req.into_parts();
+
+            let res = match Args::from_request(&req, &mut payload).await {
+                Err(err) => HttpResponse::from_error(err),
+
+                Ok(data) => handler
+                    .call(data)
+                    .await
+                    .respond_to(&req)
+                    .map_into_boxed_body(),
+            };
+
+            Ok(ServiceResponse::new(req, res))
+        }
+    }))
+}
+
+/// Generates a [`Handler`] trait impl for N-ary functions where N is specified with a sequence of
+/// space separated type parameters.
+///
+/// # Examples
+/// ```ignore
+/// factory_tuple! {}         // implements Handler for types: fn() -> R
+/// factory_tuple! { A B C }  // implements Handler for types: fn(A, B, C) -> R
+/// ```
+macro_rules! factory_tuple ({ $($param:ident)* } => {
+    impl<Func, Fut, $($param,)*> Handler<($($param,)*)> for Func
+    where
+        Func: Fn($($param),*) -> Fut + Clone + 'static,
+        Fut: Future,
+    {
+        type Output = Fut::Output;
+        type Future = Fut;
+
+        #[inline]
+        #[allow(non_snake_case)]
+        fn call(&self, ($($param,)*): ($($param,)*)) -> Self::Future {
+            (self)($($param,)*)
+        }
+    }
+});
+
+factory_tuple! {}
+factory_tuple! { A }
+factory_tuple! { A B }
+factory_tuple! { A B C }
+factory_tuple! { A B C D }
+factory_tuple! { A B C D E }
+factory_tuple! { A B C D E F }
+factory_tuple! { A B C D E F G }
+factory_tuple! { A B C D E F G H }
+factory_tuple! { A B C D E F G H I }
+factory_tuple! { A B C D E F G H I J }
+factory_tuple! { A B C D E F G H I J K }
+factory_tuple! { A B C D E F G H I J K L }
+factory_tuple! { A B C D E F G H I J K L M }
+factory_tuple! { A B C D E F G H I J K L M N }
+factory_tuple! { A B C D E F G H I J K L M N O }
+factory_tuple! { A B C D E F G H I J K L M N O P }
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    fn assert_impl_handler<T: FromRequest>(_: impl Handler<T>) {}
+
+    #[test]
+    fn arg_number() {
+        async fn handler_min() {}
+
+        #[rustfmt::skip]
+        #[allow(clippy::too_many_arguments, clippy::just_underscores_and_digits, clippy::let_unit_value)]
+        async fn handler_max(
+            _01: (), _02: (), _03: (), _04: (), _05: (), _06: (),
+            _07: (), _08: (), _09: (), _10: (), _11: (), _12: (),
+            _13: (), _14: (), _15: (), _16: (),
+        ) {}
+
+        assert_impl_handler(handler_min);
+        assert_impl_handler(handler_max);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/helpers.rs.html b/src/actix_web/helpers.rs.html new file mode 100644 index 000000000..2c47b1a18 --- /dev/null +++ b/src/actix_web/helpers.rs.html @@ -0,0 +1,51 @@ +helpers.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
+
use std::io;
+
+use bytes::BufMut;
+
+/// An `io::Write`r that only requires mutable reference and assumes that there is space available
+/// in the buffer for every write operation or that it can be extended implicitly (like
+/// `bytes::BytesMut`, for example).
+///
+/// This is slightly faster (~10%) than `bytes::buf::Writer` in such cases because it does not
+/// perform a remaining length check before writing.
+pub(crate) struct MutWriter<'a, B>(pub(crate) &'a mut B);
+
+impl<'a, B> io::Write for MutWriter<'a, B>
+where
+    B: BufMut,
+{
+    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+        self.0.put_slice(buf);
+        Ok(buf.len())
+    }
+
+    fn flush(&mut self) -> io::Result<()> {
+        Ok(())
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/accept.rs.html b/src/actix_web/http/header/accept.rs.html new file mode 100644 index 000000000..9bf1d35fa --- /dev/null +++ b/src/actix_web/http/header/accept.rs.html @@ -0,0 +1,587 @@ +accept.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
+
use std::cmp::Ordering;
+
+use mime::Mime;
+
+use super::{common_header, QualityItem};
+use crate::http::header;
+
+common_header! {
+    /// `Accept` header, defined in [RFC 7231 §5.3.2].
+    ///
+    /// The `Accept` header field can be used by user agents to specify
+    /// response media types that are acceptable. Accept header fields can
+    /// be used to indicate that the request is specifically limited to a
+    /// small set of desired types, as in the case of a request for an
+    /// in-line image
+    ///
+    /// # ABNF
+    /// ```plain
+    /// Accept = #( media-range [ accept-params ] )
+    ///
+    /// media-range    = ( "*/*"
+    ///                  / ( type "/" "*" )
+    ///                  / ( type "/" subtype )
+    ///                  ) *( OWS ";" OWS parameter )
+    /// accept-params  = weight *( accept-ext )
+    /// accept-ext = OWS ";" OWS token [ "=" ( token / quoted-string ) ]
+    /// ```
+    ///
+    /// # Example Values
+    /// * `audio/*; q=0.2, audio/basic`
+    /// * `text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c`
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{Accept, QualityItem};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     Accept(vec![
+    ///         QualityItem::max(mime::TEXT_HTML),
+    ///     ])
+    /// );
+    /// ```
+    ///
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{Accept, QualityItem};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     Accept(vec![
+    ///         QualityItem::max(mime::APPLICATION_JSON),
+    ///     ])
+    /// );
+    /// ```
+    ///
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{Accept, QualityItem, q};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     Accept(vec![
+    ///         QualityItem::max(mime::TEXT_HTML),
+    ///         QualityItem::max("application/xhtml+xml".parse().unwrap()),
+    ///         QualityItem::new(mime::TEXT_XML, q(0.9)),
+    ///         QualityItem::max("image/webp".parse().unwrap()),
+    ///         QualityItem::new(mime::STAR_STAR, q(0.8)),
+    ///     ])
+    /// );
+    /// ```
+    ///
+    /// [RFC 7231 §5.3.2]: https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.2
+    (Accept, header::ACCEPT) => (QualityItem<Mime>)*
+
+    test_parse_and_format {
+        // Tests from the RFC
+         crate::http::header::common_header_test!(
+            test1,
+            [b"audio/*; q=0.2, audio/basic"],
+            Some(Accept(vec![
+                QualityItem::new("audio/*".parse().unwrap(), q(0.2)),
+                QualityItem::max("audio/basic".parse().unwrap()),
+                ])));
+
+        crate::http::header::common_header_test!(
+            test2,
+            [b"text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c"],
+            Some(Accept(vec![
+                QualityItem::new(mime::TEXT_PLAIN, q(0.5)),
+                QualityItem::max(mime::TEXT_HTML),
+                QualityItem::new(
+                    "text/x-dvi".parse().unwrap(),
+                    q(0.8)),
+                QualityItem::max("text/x-c".parse().unwrap()),
+                ])));
+
+        // Custom tests
+        crate::http::header::common_header_test!(
+            test3,
+            [b"text/plain; charset=utf-8"],
+            Some(Accept(vec![
+                QualityItem::max(mime::TEXT_PLAIN_UTF_8),
+            ])));
+        crate::http::header::common_header_test!(
+            test4,
+            [b"text/plain; charset=utf-8; q=0.5"],
+            Some(Accept(vec![
+                QualityItem::new(mime::TEXT_PLAIN_UTF_8, q(0.5)),
+            ])));
+
+        #[test]
+        fn test_fuzzing1() {
+            let req = test::TestRequest::default()
+                .insert_header((header::ACCEPT, "chunk#;e"))
+                .finish();
+            let header = Accept::parse(&req);
+            assert!(header.is_ok());
+        }
+    }
+}
+
+impl Accept {
+    /// Construct `Accept: */*`.
+    pub fn star() -> Accept {
+        Accept(vec![QualityItem::max(mime::STAR_STAR)])
+    }
+
+    /// Construct `Accept: application/json`.
+    pub fn json() -> Accept {
+        Accept(vec![QualityItem::max(mime::APPLICATION_JSON)])
+    }
+
+    /// Construct `Accept: text/*`.
+    pub fn text() -> Accept {
+        Accept(vec![QualityItem::max(mime::TEXT_STAR)])
+    }
+
+    /// Construct `Accept: image/*`.
+    pub fn image() -> Accept {
+        Accept(vec![QualityItem::max(mime::IMAGE_STAR)])
+    }
+
+    /// Construct `Accept: text/html`.
+    pub fn html() -> Accept {
+        Accept(vec![QualityItem::max(mime::TEXT_HTML)])
+    }
+
+    // TODO: method for getting best content encoding based on q-factors, available from server side
+    // and if none are acceptable return None
+
+    /// Extracts the most preferable mime type, accounting for [q-factor weighting].
+    ///
+    /// If no q-factors are provided, the first mime type is chosen. Note that items without
+    /// q-factors are given the maximum preference value.
+    ///
+    /// As per the spec, will return [`mime::STAR_STAR`] (indicating no preference) if the contained
+    /// list is empty.
+    ///
+    /// [q-factor weighting]: https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.2
+    pub fn preference(&self) -> Mime {
+        use actix_http::header::Quality;
+
+        let mut max_item = None;
+        let mut max_pref = Quality::ZERO;
+
+        // uses manual max lookup loop since we want the first occurrence in the case of same
+        // preference but `Iterator::max_by_key` would give us the last occurrence
+
+        for pref in &self.0 {
+            // only change if strictly greater
+            // equal items, even while unsorted, still have higher preference if they appear first
+            if pref.quality > max_pref {
+                max_pref = pref.quality;
+                max_item = Some(pref.item.clone());
+            }
+        }
+
+        max_item.unwrap_or(mime::STAR_STAR)
+    }
+
+    /// Returns a sorted list of mime types from highest to lowest preference, accounting for
+    /// [q-factor weighting] and specificity.
+    ///
+    /// [q-factor weighting]: https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.2
+    pub fn ranked(&self) -> Vec<Mime> {
+        if self.is_empty() {
+            return vec![];
+        }
+
+        let mut types = self.0.clone();
+
+        // use stable sort so items with equal q-factor and specificity retain listed order
+        types.sort_by(|a, b| {
+            // sort by q-factor descending
+            b.quality.cmp(&a.quality).then_with(|| {
+                // use specificity rules on mime types with
+                // same q-factor (eg. text/html > text/* > */*)
+
+                // subtypes are not comparable if main type is star, so return
+                match (a.item.type_(), b.item.type_()) {
+                    (mime::STAR, mime::STAR) => return Ordering::Equal,
+
+                    // a is sorted after b
+                    (mime::STAR, _) => return Ordering::Greater,
+
+                    // a is sorted before b
+                    (_, mime::STAR) => return Ordering::Less,
+
+                    _ => {}
+                }
+
+                // in both these match expressions, the returned ordering appears
+                // inverted because sort is high-to-low ("descending") precedence
+                match (a.item.subtype(), b.item.subtype()) {
+                    (mime::STAR, mime::STAR) => Ordering::Equal,
+
+                    // a is sorted after b
+                    (mime::STAR, _) => Ordering::Greater,
+
+                    // a is sorted before b
+                    (_, mime::STAR) => Ordering::Less,
+
+                    _ => Ordering::Equal,
+                }
+            })
+        });
+
+        types.into_iter().map(|qitem| qitem.item).collect()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::http::header::q;
+
+    #[test]
+    fn ranking_precedence() {
+        let test = Accept(vec![]);
+        assert!(test.ranked().is_empty());
+
+        let test = Accept(vec![QualityItem::max(mime::APPLICATION_JSON)]);
+        assert_eq!(test.ranked(), vec![mime::APPLICATION_JSON]);
+
+        let test = Accept(vec![
+            QualityItem::max(mime::TEXT_HTML),
+            "application/xhtml+xml".parse().unwrap(),
+            QualityItem::new("application/xml".parse().unwrap(), q(0.9)),
+            QualityItem::new(mime::STAR_STAR, q(0.8)),
+        ]);
+        assert_eq!(
+            test.ranked(),
+            vec![
+                mime::TEXT_HTML,
+                "application/xhtml+xml".parse().unwrap(),
+                "application/xml".parse().unwrap(),
+                mime::STAR_STAR,
+            ]
+        );
+
+        let test = Accept(vec![
+            QualityItem::max(mime::STAR_STAR),
+            QualityItem::max(mime::IMAGE_STAR),
+            QualityItem::max(mime::IMAGE_PNG),
+        ]);
+        assert_eq!(
+            test.ranked(),
+            vec![mime::IMAGE_PNG, mime::IMAGE_STAR, mime::STAR_STAR]
+        );
+    }
+
+    #[test]
+    fn preference_selection() {
+        let test = Accept(vec![
+            QualityItem::max(mime::TEXT_HTML),
+            "application/xhtml+xml".parse().unwrap(),
+            QualityItem::new("application/xml".parse().unwrap(), q(0.9)),
+            QualityItem::new(mime::STAR_STAR, q(0.8)),
+        ]);
+        assert_eq!(test.preference(), mime::TEXT_HTML);
+
+        let test = Accept(vec![
+            QualityItem::new("video/*".parse().unwrap(), q(0.8)),
+            QualityItem::max(mime::IMAGE_PNG),
+            QualityItem::new(mime::STAR_STAR, q(0.5)),
+            QualityItem::max(mime::IMAGE_SVG),
+            QualityItem::new(mime::IMAGE_STAR, q(0.8)),
+        ]);
+        assert_eq!(test.preference(), mime::IMAGE_PNG);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/accept_charset.rs.html b/src/actix_web/http/header/accept_charset.rs.html new file mode 100644 index 000000000..12b093162 --- /dev/null +++ b/src/actix_web/http/header/accept_charset.rs.html @@ -0,0 +1,125 @@ +accept_charset.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
+
use super::{common_header, Charset, QualityItem, ACCEPT_CHARSET};
+
+common_header! {
+    /// `Accept-Charset` header, defined in [RFC 7231 §5.3.3].
+    ///
+    /// The `Accept-Charset` header field can be sent by a user agent to
+    /// indicate what charsets are acceptable in textual response content.
+    /// This field allows user agents capable of understanding more
+    /// comprehensive or special-purpose charsets to signal that capability
+    /// to an origin server that is capable of representing information in
+    /// those charsets.
+    ///
+    /// # ABNF
+    /// ```plain
+    /// Accept-Charset = 1#( ( charset / "*" ) [ weight ] )
+    /// ```
+    ///
+    /// # Example Values
+    /// * `iso-8859-5, unicode-1-1;q=0.8`
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{AcceptCharset, Charset, QualityItem};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     AcceptCharset(vec![QualityItem::max(Charset::Us_Ascii)])
+    /// );
+    /// ```
+    ///
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{AcceptCharset, Charset, q, QualityItem};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     AcceptCharset(vec![
+    ///         QualityItem::new(Charset::Us_Ascii, q(0.9)),
+    ///         QualityItem::new(Charset::Iso_8859_10, q(0.2)),
+    ///     ])
+    /// );
+    /// ```
+    ///
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{AcceptCharset, Charset, QualityItem};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     AcceptCharset(vec![QualityItem::max(Charset::Ext("utf-8".to_owned()))])
+    /// );
+    /// ```
+    ///
+    /// [RFC 7231 §5.3.3]: https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.3
+    (AcceptCharset, ACCEPT_CHARSET) => (QualityItem<Charset>)*
+
+    test_parse_and_format {
+        // Test case from RFC
+        common_header_test!(test1, [b"iso-8859-5, unicode-1-1;q=0.8"]);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/accept_encoding.rs.html b/src/actix_web/http/header/accept_encoding.rs.html new file mode 100644 index 000000000..bfad2ef45 --- /dev/null +++ b/src/actix_web/http/header/accept_encoding.rs.html @@ -0,0 +1,921 @@ +accept_encoding.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
+
use std::collections::HashSet;
+
+use super::{common_header, ContentEncoding, Encoding, Preference, Quality, QualityItem};
+use crate::http::header;
+
+common_header! {
+    /// `Accept-Encoding` header, defined
+    /// in [RFC 7231](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.4)
+    ///
+    /// The `Accept-Encoding` header field can be used by user agents to indicate what response
+    /// content-codings are acceptable in the response. An `identity` token is used as a synonym
+    /// for "no encoding" in order to communicate when no encoding is preferred.
+    ///
+    /// # ABNF
+    /// ```plain
+    /// Accept-Encoding  = #( codings [ weight ] )
+    /// codings          = content-coding / "identity" / "*"
+    /// ```
+    ///
+    /// # Example Values
+    /// * `compress, gzip`
+    /// * ``
+    /// * `*`
+    /// * `compress;q=0.5, gzip;q=1`
+    /// * `gzip;q=1.0, identity; q=0.5, *;q=0`
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{AcceptEncoding, Encoding, Preference, QualityItem};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     AcceptEncoding(vec![QualityItem::max(Preference::Specific(Encoding::gzip()))])
+    /// );
+    /// ```
+    ///
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{AcceptEncoding, Encoding, QualityItem};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     AcceptEncoding(vec![
+    ///         "gzip".parse().unwrap(),
+    ///         "br".parse().unwrap(),
+    ///     ])
+    /// );
+    /// ```
+    (AcceptEncoding, header::ACCEPT_ENCODING) => (QualityItem<Preference<Encoding>>)*
+
+    test_parse_and_format {
+        common_header_test!(no_headers, [b""; 0], Some(AcceptEncoding(vec![])));
+        common_header_test!(empty_header, [b""; 1], Some(AcceptEncoding(vec![])));
+
+        common_header_test!(
+            order_of_appearance,
+            [b"br, gzip"],
+            Some(AcceptEncoding(vec![
+                QualityItem::max(Preference::Specific(Encoding::brotli())),
+                QualityItem::max(Preference::Specific(Encoding::gzip())),
+            ]))
+        );
+
+        common_header_test!(any, [b"*"], Some(AcceptEncoding(vec![
+            QualityItem::max(Preference::Any),
+        ])));
+
+        // Note: Removed quality 1 from gzip
+        common_header_test!(implicit_quality, [b"gzip, identity; q=0.5, *;q=0"]);
+
+        // Note: Removed quality 1 from gzip
+        common_header_test!(implicit_quality_out_of_order, [b"compress;q=0.5, gzip"]);
+
+        common_header_test!(
+            only_gzip_no_identity,
+            [b"gzip, *; q=0"],
+            Some(AcceptEncoding(vec![
+                QualityItem::max(Preference::Specific(Encoding::gzip())),
+                QualityItem::zero(Preference::Any),
+            ]))
+        );
+    }
+}
+
+impl AcceptEncoding {
+    /// Selects the most acceptable encoding according to client preference and supported types.
+    ///
+    /// The "identity" encoding is not assumed and should be included in the `supported` iterator
+    /// if a non-encoded representation can be selected.
+    ///
+    /// If `None` is returned, this indicates that none of the supported encodings are acceptable to
+    /// the client. The caller should generate a 406 Not Acceptable response (unencoded) that
+    /// includes the server's supported encodings in the body plus a [`Vary`] header.
+    ///
+    /// [`Vary`]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Vary
+    pub fn negotiate<'a>(&self, supported: impl Iterator<Item = &'a Encoding>) -> Option<Encoding> {
+        // 1. If no Accept-Encoding field is in the request, any content-coding is considered
+        // acceptable by the user agent.
+
+        let supported_set = supported.collect::<HashSet<_>>();
+
+        if supported_set.is_empty() {
+            return None;
+        }
+
+        if self.0.is_empty() {
+            // though it is not recommended to encode in this case, return identity encoding
+            return Some(Encoding::identity());
+        }
+
+        // 2. If the representation has no content-coding, then it is acceptable by default unless
+        // specifically excluded by the Accept-Encoding field stating either "identity;q=0" or
+        // "*;q=0" without a more specific entry for "identity".
+
+        let acceptable_items = self.ranked_items().collect::<Vec<_>>();
+
+        let identity_acceptable = is_identity_acceptable(&acceptable_items);
+        let identity_supported = supported_set.contains(&Encoding::identity());
+
+        if identity_acceptable && identity_supported && supported_set.len() == 1 {
+            return Some(Encoding::identity());
+        }
+
+        // 3. If the representation's content-coding is one of the content-codings listed in the
+        // Accept-Encoding field, then it is acceptable unless it is accompanied by a qvalue of 0.
+
+        // 4. If multiple content-codings are acceptable, then the acceptable content-coding with
+        // the highest non-zero qvalue is preferred.
+
+        let matched = acceptable_items
+            .into_iter()
+            .filter(|q| q.quality > Quality::ZERO)
+            // search relies on item list being in descending order of quality
+            .find(|q| {
+                let enc = &q.item;
+                matches!(enc, Preference::Specific(enc) if supported_set.contains(enc))
+            })
+            .map(|q| q.item);
+
+        match matched {
+            Some(Preference::Specific(enc)) => Some(enc),
+
+            _ if identity_acceptable => Some(Encoding::identity()),
+
+            _ => None,
+        }
+    }
+
+    /// Extracts the most preferable encoding, accounting for [q-factor weighting].
+    ///
+    /// If no q-factors are provided, we prefer brotli > zstd > gzip. Note that items without
+    /// q-factors are given the maximum preference value.
+    ///
+    /// As per the spec, returns [`Preference::Any`] if acceptable list is empty. Though, if this is
+    /// returned, it is recommended to use an un-encoded representation.
+    ///
+    /// If `None` is returned, it means that the client has signalled that no representations
+    /// are acceptable. This should never occur for a well behaved user-agent.
+    ///
+    /// [q-factor weighting]: https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.2
+    pub fn preference(&self) -> Option<Preference<Encoding>> {
+        // empty header indicates no preference
+        if self.0.is_empty() {
+            return Some(Preference::Any);
+        }
+
+        let mut max_item = None;
+        let mut max_pref = Quality::ZERO;
+        let mut max_rank = 0;
+
+        // uses manual max lookup loop since we want the first occurrence in the case of same
+        // preference but `Iterator::max_by_key` would give us the last occurrence
+
+        for pref in &self.0 {
+            // only change if strictly greater
+            // equal items, even while unsorted, still have higher preference if they appear first
+
+            let rank = encoding_rank(pref);
+
+            if (pref.quality, rank) > (max_pref, max_rank) {
+                max_pref = pref.quality;
+                max_item = Some(pref.item.clone());
+                max_rank = rank;
+            }
+        }
+
+        // Return max_item if any items were above 0 quality...
+        max_item.or_else(|| {
+            // ...or else check for "*" or "identity". We can elide quality checks since
+            // entering this block means all items had "q=0".
+            match self.0.iter().find(|pref| {
+                matches!(
+                    pref.item,
+                    Preference::Any
+                        | Preference::Specific(Encoding::Known(ContentEncoding::Identity))
+                )
+            }) {
+                // "identity" or "*" found so no representation is acceptable
+                Some(_) => None,
+
+                // implicit "identity" is acceptable
+                None => Some(Preference::Specific(Encoding::identity())),
+            }
+        })
+    }
+
+    /// Returns a sorted list of encodings from highest to lowest precedence, accounting
+    /// for [q-factor weighting].
+    ///
+    /// If no q-factors are provided, we prefer brotli > zstd > gzip.
+    ///
+    /// [q-factor weighting]: https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.2
+    pub fn ranked(&self) -> Vec<Preference<Encoding>> {
+        self.ranked_items().map(|q| q.item).collect()
+    }
+
+    fn ranked_items(&self) -> impl Iterator<Item = QualityItem<Preference<Encoding>>> {
+        if self.0.is_empty() {
+            return Vec::new().into_iter();
+        }
+
+        let mut types = self.0.clone();
+
+        // use stable sort so items with equal q-factor retain listed order
+        types.sort_by(|a, b| {
+            // sort by q-factor descending then server ranking descending
+
+            b.quality
+                .cmp(&a.quality)
+                .then(encoding_rank(b).cmp(&encoding_rank(a)))
+        });
+
+        types.into_iter()
+    }
+}
+
+/// Returns server-defined encoding ranking.
+fn encoding_rank(qv: &QualityItem<Preference<Encoding>>) -> u8 {
+    // ensure that q=0 items are never sorted above identity encoding
+    // invariant: sorting methods calling this fn use first-on-equal approach
+    if qv.quality == Quality::ZERO {
+        return 0;
+    }
+
+    match qv.item {
+        Preference::Specific(Encoding::Known(ContentEncoding::Brotli)) => 5,
+        Preference::Specific(Encoding::Known(ContentEncoding::Zstd)) => 4,
+        Preference::Specific(Encoding::Known(ContentEncoding::Gzip)) => 3,
+        Preference::Specific(Encoding::Known(ContentEncoding::Deflate)) => 2,
+        Preference::Any => 0,
+        Preference::Specific(Encoding::Known(ContentEncoding::Identity)) => 0,
+        Preference::Specific(Encoding::Known(_)) => 1,
+        Preference::Specific(Encoding::Unknown(_)) => 1,
+    }
+}
+
+/// Returns true if "identity" is an acceptable encoding.
+///
+/// Internal algorithm relies on item list being in descending order of quality.
+fn is_identity_acceptable(items: &'_ [QualityItem<Preference<Encoding>>]) -> bool {
+    if items.is_empty() {
+        return true;
+    }
+
+    // Loop algorithm depends on items being sorted in descending order of quality. As such, it
+    // is sufficient to return (q > 0) when reaching either an "identity" or "*" item.
+    for q in items {
+        match (q.quality, &q.item) {
+            // occurrence of "identity;q=n"; return true if quality is non-zero
+            (q, Preference::Specific(Encoding::Known(ContentEncoding::Identity))) => {
+                return q > Quality::ZERO
+            }
+
+            // occurrence of "*;q=n"; return true if quality is non-zero
+            (q, Preference::Any) => return q > Quality::ZERO,
+
+            _ => {}
+        }
+    }
+
+    // implicit acceptable identity
+    true
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::http::header::*;
+
+    macro_rules! accept_encoding {
+        () => { AcceptEncoding(vec![]) };
+        ($($q:expr),+ $(,)?) => { AcceptEncoding(vec![$($q.parse().unwrap()),+]) };
+    }
+
+    /// Parses an encoding string.
+    fn enc(enc: &str) -> Preference<Encoding> {
+        enc.parse().unwrap()
+    }
+
+    #[test]
+    fn detect_identity_acceptable() {
+        macro_rules! accept_encoding_ranked {
+            () => { accept_encoding!().ranked_items().collect::<Vec<_>>() };
+            ($($q:expr),+ $(,)?) => { accept_encoding!($($q),+).ranked_items().collect::<Vec<_>>() };
+        }
+
+        let test = accept_encoding_ranked!();
+        assert!(is_identity_acceptable(&test));
+        let test = accept_encoding_ranked!("gzip");
+        assert!(is_identity_acceptable(&test));
+        let test = accept_encoding_ranked!("gzip", "br");
+        assert!(is_identity_acceptable(&test));
+        let test = accept_encoding_ranked!("gzip", "*;q=0.1");
+        assert!(is_identity_acceptable(&test));
+        let test = accept_encoding_ranked!("gzip", "identity;q=0.1");
+        assert!(is_identity_acceptable(&test));
+        let test = accept_encoding_ranked!("gzip", "identity;q=0.1", "*;q=0");
+        assert!(is_identity_acceptable(&test));
+        let test = accept_encoding_ranked!("gzip", "*;q=0", "identity;q=0.1");
+        assert!(is_identity_acceptable(&test));
+
+        let test = accept_encoding_ranked!("gzip", "*;q=0");
+        assert!(!is_identity_acceptable(&test));
+        let test = accept_encoding_ranked!("gzip", "identity;q=0");
+        assert!(!is_identity_acceptable(&test));
+        let test = accept_encoding_ranked!("gzip", "identity;q=0", "*;q=0");
+        assert!(!is_identity_acceptable(&test));
+        let test = accept_encoding_ranked!("gzip", "*;q=0", "identity;q=0");
+        assert!(!is_identity_acceptable(&test));
+    }
+
+    #[test]
+    fn encoding_negotiation() {
+        // no preference
+        let test = accept_encoding!();
+        assert_eq!(test.negotiate([].iter()), None);
+
+        let test = accept_encoding!();
+        assert_eq!(
+            test.negotiate([Encoding::identity()].iter()),
+            Some(Encoding::identity()),
+        );
+
+        let test = accept_encoding!("identity;q=0");
+        assert_eq!(test.negotiate([Encoding::identity()].iter()), None);
+
+        let test = accept_encoding!("*;q=0");
+        assert_eq!(test.negotiate([Encoding::identity()].iter()), None);
+
+        let test = accept_encoding!();
+        assert_eq!(
+            test.negotiate([Encoding::gzip(), Encoding::identity()].iter()),
+            Some(Encoding::identity()),
+        );
+
+        let test = accept_encoding!("gzip");
+        assert_eq!(
+            test.negotiate([Encoding::gzip(), Encoding::identity()].iter()),
+            Some(Encoding::gzip()),
+        );
+        assert_eq!(
+            test.negotiate([Encoding::brotli(), Encoding::identity()].iter()),
+            Some(Encoding::identity()),
+        );
+        assert_eq!(
+            test.negotiate([Encoding::brotli(), Encoding::gzip(), Encoding::identity()].iter()),
+            Some(Encoding::gzip()),
+        );
+
+        let test = accept_encoding!("gzip", "identity;q=0");
+        assert_eq!(
+            test.negotiate([Encoding::gzip(), Encoding::identity()].iter()),
+            Some(Encoding::gzip()),
+        );
+        assert_eq!(
+            test.negotiate([Encoding::brotli(), Encoding::identity()].iter()),
+            None
+        );
+
+        let test = accept_encoding!("gzip", "*;q=0");
+        assert_eq!(
+            test.negotiate([Encoding::gzip(), Encoding::identity()].iter()),
+            Some(Encoding::gzip()),
+        );
+        assert_eq!(
+            test.negotiate([Encoding::brotli(), Encoding::identity()].iter()),
+            None
+        );
+
+        let test = accept_encoding!("gzip", "deflate", "br");
+        assert_eq!(
+            test.negotiate([Encoding::gzip(), Encoding::identity()].iter()),
+            Some(Encoding::gzip()),
+        );
+        assert_eq!(
+            test.negotiate([Encoding::brotli(), Encoding::identity()].iter()),
+            Some(Encoding::brotli())
+        );
+        assert_eq!(
+            test.negotiate([Encoding::deflate(), Encoding::identity()].iter()),
+            Some(Encoding::deflate())
+        );
+        assert_eq!(
+            test.negotiate([Encoding::gzip(), Encoding::deflate(), Encoding::identity()].iter()),
+            Some(Encoding::gzip())
+        );
+        assert_eq!(
+            test.negotiate([Encoding::gzip(), Encoding::brotli(), Encoding::identity()].iter()),
+            Some(Encoding::brotli())
+        );
+        assert_eq!(
+            test.negotiate([Encoding::brotli(), Encoding::gzip(), Encoding::identity()].iter()),
+            Some(Encoding::brotli())
+        );
+    }
+
+    #[test]
+    fn ranking_precedence() {
+        let test = accept_encoding!();
+        assert!(test.ranked().is_empty());
+
+        let test = accept_encoding!("gzip");
+        assert_eq!(test.ranked(), vec![enc("gzip")]);
+
+        let test = accept_encoding!("gzip;q=0.900", "*;q=0.700", "br;q=1.0");
+        assert_eq!(test.ranked(), vec![enc("br"), enc("gzip"), enc("*")]);
+
+        let test = accept_encoding!("br", "gzip", "*");
+        assert_eq!(test.ranked(), vec![enc("br"), enc("gzip"), enc("*")]);
+
+        let test = accept_encoding!("gzip", "br", "*");
+        assert_eq!(test.ranked(), vec![enc("br"), enc("gzip"), enc("*")]);
+    }
+
+    #[test]
+    fn preference_selection() {
+        assert_eq!(accept_encoding!().preference(), Some(Preference::Any));
+
+        assert_eq!(accept_encoding!("identity;q=0").preference(), None);
+        assert_eq!(accept_encoding!("*;q=0").preference(), None);
+        assert_eq!(accept_encoding!("compress;q=0", "*;q=0").preference(), None);
+        assert_eq!(accept_encoding!("identity;q=0", "*;q=0").preference(), None);
+
+        let test = accept_encoding!("*;q=0.5");
+        assert_eq!(test.preference().unwrap(), enc("*"));
+
+        let test = accept_encoding!("br;q=0");
+        assert_eq!(test.preference().unwrap(), enc("identity"));
+
+        let test = accept_encoding!("br;q=0.900", "gzip;q=1.0", "*;q=0.500");
+        assert_eq!(test.preference().unwrap(), enc("gzip"));
+
+        let test = accept_encoding!("br", "gzip", "*");
+        assert_eq!(test.preference().unwrap(), enc("br"));
+
+        let test = accept_encoding!("gzip", "br", "*");
+        assert_eq!(test.preference().unwrap(), enc("br"));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/accept_language.rs.html b/src/actix_web/http/header/accept_language.rs.html new file mode 100644 index 000000000..1b8181da7 --- /dev/null +++ b/src/actix_web/http/header/accept_language.rs.html @@ -0,0 +1,447 @@ +accept_language.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
+
use language_tags::LanguageTag;
+
+use super::{common_header, Preference, Quality, QualityItem};
+use crate::http::header;
+
+common_header! {
+    /// `Accept-Language` header, defined
+    /// in [RFC 7231 §5.3.5](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.5)
+    ///
+    /// The `Accept-Language` header field can be used by user agents to indicate the set of natural
+    /// languages that are preferred in the response.
+    ///
+    /// The `Accept-Language` header is defined in
+    /// [RFC 7231 §5.3.5](https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.5) using language
+    /// ranges defined in [RFC 4647 §2.1](https://datatracker.ietf.org/doc/html/rfc4647#section-2.1).
+    ///
+    /// # ABNF
+    /// ```plain
+    /// Accept-Language = 1#( language-range [ weight ] )
+    /// language-range  = (1*8ALPHA *("-" 1*8alphanum)) / "*"
+    /// alphanum        = ALPHA / DIGIT
+    /// weight          = OWS ";" OWS "q=" qvalue
+    /// qvalue          = ( "0" [ "." 0*3DIGIT ] )
+    ///                 / ( "1" [ "." 0*3("0") ] )
+    /// ```
+    ///
+    /// # Example Values
+    /// - `da, en-gb;q=0.8, en;q=0.7`
+    /// - `en-us;q=1.0, en;q=0.5, fr`
+    /// - `fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5`
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{AcceptLanguage, QualityItem};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     AcceptLanguage(vec![
+    ///         "en-US".parse().unwrap(),
+    ///     ])
+    /// );
+    /// ```
+    ///
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{AcceptLanguage, QualityItem, q};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     AcceptLanguage(vec![
+    ///         "da".parse().unwrap(),
+    ///         "en-GB;q=0.8".parse().unwrap(),
+    ///         "en;q=0.7".parse().unwrap(),
+    ///     ])
+    /// );
+    /// ```
+    (AcceptLanguage, header::ACCEPT_LANGUAGE) => (QualityItem<Preference<LanguageTag>>)*
+
+    test_parse_and_format {
+        common_header_test!(no_headers, [b""; 0], Some(AcceptLanguage(vec![])));
+
+        common_header_test!(empty_header, [b""; 1], Some(AcceptLanguage(vec![])));
+
+        common_header_test!(
+            example_from_rfc,
+            [b"da, en-gb;q=0.8, en;q=0.7"]
+        );
+
+
+        common_header_test!(
+            not_ordered_by_weight,
+            [b"en-US, en; q=0.5, fr"],
+            Some(AcceptLanguage(vec![
+                QualityItem::max("en-US".parse().unwrap()),
+                QualityItem::new("en".parse().unwrap(), q(0.5)),
+                QualityItem::max("fr".parse().unwrap()),
+            ]))
+        );
+
+        common_header_test!(
+            has_wildcard,
+            [b"fr-CH, fr; q=0.9, en; q=0.8, de; q=0.7, *; q=0.5"],
+            Some(AcceptLanguage(vec![
+                QualityItem::max("fr-CH".parse().unwrap()),
+                QualityItem::new("fr".parse().unwrap(), q(0.9)),
+                QualityItem::new("en".parse().unwrap(), q(0.8)),
+                QualityItem::new("de".parse().unwrap(), q(0.7)),
+                QualityItem::new("*".parse().unwrap(), q(0.5)),
+            ]))
+        );
+    }
+}
+
+impl AcceptLanguage {
+    /// Extracts the most preferable language, accounting for [q-factor weighting].
+    ///
+    /// If no q-factors are provided, the first language is chosen. Note that items without
+    /// q-factors are given the maximum preference value.
+    ///
+    /// As per the spec, returns [`Preference::Any`] if contained list is empty.
+    ///
+    /// [q-factor weighting]: https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.2
+    pub fn preference(&self) -> Preference<LanguageTag> {
+        let mut max_item = None;
+        let mut max_pref = Quality::ZERO;
+
+        // uses manual max lookup loop since we want the first occurrence in the case of same
+        // preference but `Iterator::max_by_key` would give us the last occurrence
+
+        for pref in &self.0 {
+            // only change if strictly greater
+            // equal items, even while unsorted, still have higher preference if they appear first
+            if pref.quality > max_pref {
+                max_pref = pref.quality;
+                max_item = Some(pref.item.clone());
+            }
+        }
+
+        max_item.unwrap_or(Preference::Any)
+    }
+
+    /// Returns a sorted list of languages from highest to lowest precedence, accounting
+    /// for [q-factor weighting].
+    ///
+    /// [q-factor weighting]: https://datatracker.ietf.org/doc/html/rfc7231#section-5.3.2
+    pub fn ranked(&self) -> Vec<Preference<LanguageTag>> {
+        if self.0.is_empty() {
+            return vec![];
+        }
+
+        let mut types = self.0.clone();
+
+        // use stable sort so items with equal q-factor retain listed order
+        types.sort_by(|a, b| {
+            // sort by q-factor descending
+            b.quality.cmp(&a.quality)
+        });
+
+        types.into_iter().map(|q_item| q_item.item).collect()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::http::header::*;
+
+    #[test]
+    fn ranking_precedence() {
+        let test = AcceptLanguage(vec![]);
+        assert!(test.ranked().is_empty());
+
+        let test = AcceptLanguage(vec![QualityItem::max("fr-CH".parse().unwrap())]);
+        assert_eq!(test.ranked(), vec!["fr-CH".parse().unwrap()]);
+
+        let test = AcceptLanguage(vec![
+            QualityItem::new("fr".parse().unwrap(), q(0.900)),
+            QualityItem::new("fr-CH".parse().unwrap(), q(1.0)),
+            QualityItem::new("en".parse().unwrap(), q(0.800)),
+            QualityItem::new("*".parse().unwrap(), q(0.500)),
+            QualityItem::new("de".parse().unwrap(), q(0.700)),
+        ]);
+        assert_eq!(
+            test.ranked(),
+            vec![
+                "fr-CH".parse().unwrap(),
+                "fr".parse().unwrap(),
+                "en".parse().unwrap(),
+                "de".parse().unwrap(),
+                "*".parse().unwrap(),
+            ]
+        );
+
+        let test = AcceptLanguage(vec![
+            QualityItem::max("fr".parse().unwrap()),
+            QualityItem::max("fr-CH".parse().unwrap()),
+            QualityItem::max("en".parse().unwrap()),
+            QualityItem::max("*".parse().unwrap()),
+            QualityItem::max("de".parse().unwrap()),
+        ]);
+        assert_eq!(
+            test.ranked(),
+            vec![
+                "fr".parse().unwrap(),
+                "fr-CH".parse().unwrap(),
+                "en".parse().unwrap(),
+                "*".parse().unwrap(),
+                "de".parse().unwrap(),
+            ]
+        );
+    }
+
+    #[test]
+    fn preference_selection() {
+        let test = AcceptLanguage(vec![
+            QualityItem::new("fr".parse().unwrap(), q(0.900)),
+            QualityItem::new("fr-CH".parse().unwrap(), q(1.0)),
+            QualityItem::new("en".parse().unwrap(), q(0.800)),
+            QualityItem::new("*".parse().unwrap(), q(0.500)),
+            QualityItem::new("de".parse().unwrap(), q(0.700)),
+        ]);
+        assert_eq!(
+            test.preference(),
+            Preference::Specific("fr-CH".parse().unwrap())
+        );
+
+        let test = AcceptLanguage(vec![
+            QualityItem::max("fr".parse().unwrap()),
+            QualityItem::max("fr-CH".parse().unwrap()),
+            QualityItem::max("en".parse().unwrap()),
+            QualityItem::max("*".parse().unwrap()),
+            QualityItem::max("de".parse().unwrap()),
+        ]);
+        assert_eq!(
+            test.preference(),
+            Preference::Specific("fr".parse().unwrap())
+        );
+
+        let test = AcceptLanguage(vec![]);
+        assert_eq!(test.preference(), Preference::Any);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/allow.rs.html b/src/actix_web/http/header/allow.rs.html new file mode 100644 index 000000000..2162d5e13 --- /dev/null +++ b/src/actix_web/http/header/allow.rs.html @@ -0,0 +1,159 @@ +allow.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
+
use actix_http::Method;
+
+use crate::http::header;
+
+crate::http::header::common_header! {
+    /// `Allow` header, defined
+    /// in [RFC 7231 §7.4.1](https://datatracker.ietf.org/doc/html/rfc7231#section-7.4.1)
+    ///
+    /// The `Allow` header field lists the set of methods advertised as
+    /// supported by the target resource. The purpose of this field is
+    /// strictly to inform the recipient of valid request methods associated
+    /// with the resource.
+    ///
+    /// # ABNF
+    /// ```plain
+    /// Allow = #method
+    /// ```
+    ///
+    /// # Example Values
+    /// * `GET, HEAD, PUT`
+    /// * `OPTIONS, GET, PUT, POST, DELETE, HEAD, TRACE, CONNECT, PATCH, fOObAr`
+    /// * ``
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::{header::Allow, Method};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     Allow(vec![Method::GET])
+    /// );
+    /// ```
+    ///
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::{header::Allow, Method};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     Allow(vec![
+    ///         Method::GET,
+    ///         Method::POST,
+    ///         Method::PATCH,
+    ///     ])
+    /// );
+    /// ```
+    (Allow, header::ALLOW) => (Method)*
+
+    test_parse_and_format {
+        // from the RFC
+
+        crate::http::header::common_header_test!(
+            test1,
+            [b"GET, HEAD, PUT"],
+            Some(HeaderField(vec![Method::GET, Method::HEAD, Method::PUT])));
+
+        // other tests
+
+        crate::http::header::common_header_test!(
+            test2,
+            [b"OPTIONS, GET, PUT, POST, DELETE, HEAD, TRACE, CONNECT, PATCH"],
+            Some(HeaderField(vec![
+                Method::OPTIONS,
+                Method::GET,
+                Method::PUT,
+                Method::POST,
+                Method::DELETE,
+                Method::HEAD,
+                Method::TRACE,
+                Method::CONNECT,
+                Method::PATCH])));
+
+        crate::http::header::common_header_test!(
+            test3,
+            [b""],
+            Some(HeaderField(Vec::<Method>::new())));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/cache_control.rs.html b/src/actix_web/http/header/cache_control.rs.html new file mode 100644 index 000000000..6df04b975 --- /dev/null +++ b/src/actix_web/http/header/cache_control.rs.html @@ -0,0 +1,385 @@ +cache_control.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
+
use std::{fmt, str};
+
+use super::common_header;
+use crate::http::header;
+
+common_header! {
+    /// `Cache-Control` header, defined
+    /// in [RFC 7234 §5.2](https://datatracker.ietf.org/doc/html/rfc7234#section-5.2).
+    ///
+    /// The `Cache-Control` header field is used to specify directives for
+    /// caches along the request/response chain.  Such cache directives are
+    /// unidirectional in that the presence of a directive in a request does
+    /// not imply that the same directive is to be given in the response.
+    ///
+    /// # ABNF
+    /// ```text
+    /// Cache-Control   = 1#cache-directive
+    /// cache-directive = token [ "=" ( token / quoted-string ) ]
+    /// ```
+    ///
+    /// # Example Values
+    /// * `no-cache`
+    /// * `private, community="UCI"`
+    /// * `max-age=30`
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{CacheControl, CacheDirective};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(CacheControl(vec![CacheDirective::MaxAge(86400u32)]));
+    /// ```
+    ///
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{CacheControl, CacheDirective};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(CacheControl(vec![
+    ///     CacheDirective::NoCache,
+    ///     CacheDirective::Private,
+    ///     CacheDirective::MaxAge(360u32),
+    ///     CacheDirective::Extension("foo".to_owned(), Some("bar".to_owned())),
+    /// ]));
+    /// ```
+    (CacheControl, header::CACHE_CONTROL) => (CacheDirective)+
+
+    test_parse_and_format {
+        common_header_test!(no_headers, [b""; 0], None);
+        common_header_test!(empty_header, [b""; 1], None);
+        common_header_test!(bad_syntax, [b"foo="], None);
+
+        common_header_test!(
+            multiple_headers,
+            [&b"no-cache"[..], &b"private"[..]],
+            Some(CacheControl(vec![
+                CacheDirective::NoCache,
+                CacheDirective::Private,
+            ]))
+        );
+
+        common_header_test!(
+            argument,
+            [b"max-age=100, private"],
+            Some(CacheControl(vec![
+                CacheDirective::MaxAge(100),
+                CacheDirective::Private,
+            ]))
+        );
+
+        common_header_test!(
+            extension,
+            [b"foo, bar=baz"],
+            Some(CacheControl(vec![
+                CacheDirective::Extension("foo".to_owned(), None),
+                CacheDirective::Extension("bar".to_owned(), Some("baz".to_owned())),
+            ]))
+        );
+
+        #[test]
+        fn parse_quote_form() {
+            let req = test::TestRequest::default()
+                .insert_header((header::CACHE_CONTROL, "max-age=\"200\""))
+                .finish();
+
+            assert_eq!(
+                Header::parse(&req).ok(),
+                Some(CacheControl(vec![CacheDirective::MaxAge(200)]))
+            )
+        }
+    }
+}
+
+/// `CacheControl` contains a list of these directives.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum CacheDirective {
+    /// "no-cache"
+    NoCache,
+    /// "no-store"
+    NoStore,
+    /// "no-transform"
+    NoTransform,
+    /// "only-if-cached"
+    OnlyIfCached,
+
+    // request directives
+    /// "max-age=delta"
+    MaxAge(u32),
+    /// "max-stale=delta"
+    MaxStale(u32),
+    /// "min-fresh=delta"
+    MinFresh(u32),
+
+    // response directives
+    /// "must-revalidate"
+    MustRevalidate,
+    /// "public"
+    Public,
+    /// "private"
+    Private,
+    /// "proxy-revalidate"
+    ProxyRevalidate,
+    /// "s-maxage=delta"
+    SMaxAge(u32),
+
+    /// Extension directives. Optionally include an argument.
+    Extension(String, Option<String>),
+}
+
+impl fmt::Display for CacheDirective {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        use self::CacheDirective::*;
+
+        let dir_str = match self {
+            NoCache => "no-cache",
+            NoStore => "no-store",
+            NoTransform => "no-transform",
+            OnlyIfCached => "only-if-cached",
+
+            MaxAge(secs) => return write!(f, "max-age={}", secs),
+            MaxStale(secs) => return write!(f, "max-stale={}", secs),
+            MinFresh(secs) => return write!(f, "min-fresh={}", secs),
+
+            MustRevalidate => "must-revalidate",
+            Public => "public",
+            Private => "private",
+            ProxyRevalidate => "proxy-revalidate",
+            SMaxAge(secs) => return write!(f, "s-maxage={}", secs),
+
+            Extension(name, None) => name.as_str(),
+            Extension(name, Some(arg)) => return write!(f, "{}={}", name, arg),
+        };
+
+        f.write_str(dir_str)
+    }
+}
+
+impl str::FromStr for CacheDirective {
+    type Err = Option<<u32 as str::FromStr>::Err>;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        use self::CacheDirective::*;
+
+        match s {
+            "" => Err(None),
+
+            "no-cache" => Ok(NoCache),
+            "no-store" => Ok(NoStore),
+            "no-transform" => Ok(NoTransform),
+            "only-if-cached" => Ok(OnlyIfCached),
+            "must-revalidate" => Ok(MustRevalidate),
+            "public" => Ok(Public),
+            "private" => Ok(Private),
+            "proxy-revalidate" => Ok(ProxyRevalidate),
+
+            _ => match s.find('=') {
+                Some(idx) if idx + 1 < s.len() => {
+                    match (&s[..idx], s[idx + 1..].trim_matches('"')) {
+                        ("max-age", secs) => secs.parse().map(MaxAge).map_err(Some),
+                        ("max-stale", secs) => secs.parse().map(MaxStale).map_err(Some),
+                        ("min-fresh", secs) => secs.parse().map(MinFresh).map_err(Some),
+                        ("s-maxage", secs) => secs.parse().map(SMaxAge).map_err(Some),
+                        (left, right) => Ok(Extension(left.to_owned(), Some(right.to_owned()))),
+                    }
+                }
+                Some(_) => Err(None),
+                None => Ok(Extension(s.to_owned(), None)),
+            },
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/content_disposition.rs.html b/src/actix_web/http/header/content_disposition.rs.html new file mode 100644 index 000000000..cd47e547f --- /dev/null +++ b/src/actix_web/http/header/content_disposition.rs.html @@ -0,0 +1,2015 @@ +content_disposition.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
+
//! The `Content-Disposition` header and associated types.
+//!
+//! # References
+//! - "The Content-Disposition Header Field":
+//!   <https://datatracker.ietf.org/doc/html/rfc2183>
+//! - "The Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)":
+//!   <https://datatracker.ietf.org/doc/html/rfc6266>
+//! - "Returning Values from Forms: multipart/form-data":
+//!   <https://datatracker.ietf.org/doc/html/rfc7578>
+//! - Browser conformance tests at: <http://greenbytes.de/tech/tc2231/>
+//! - IANA assignment: <http://www.iana.org/assignments/cont-disp/cont-disp.xhtml>
+
+use std::fmt::{self, Write};
+
+use once_cell::sync::Lazy;
+#[cfg(feature = "unicode")]
+use regex::Regex;
+#[cfg(not(feature = "unicode"))]
+use regex_lite::Regex;
+
+use super::{ExtendedValue, Header, TryIntoHeaderValue, Writer};
+use crate::http::header;
+
+/// Split at the index of the first `needle` if it exists or at the end.
+fn split_once(haystack: &str, needle: char) -> (&str, &str) {
+    haystack.find(needle).map_or_else(
+        || (haystack, ""),
+        |sc| {
+            let (first, last) = haystack.split_at(sc);
+            (first, last.split_at(1).1)
+        },
+    )
+}
+
+/// Split at the index of the first `needle` if it exists or at the end, trim the right of the
+/// first part and the left of the last part.
+fn split_once_and_trim(haystack: &str, needle: char) -> (&str, &str) {
+    let (first, last) = split_once(haystack, needle);
+    (first.trim_end(), last.trim_start())
+}
+
+/// The implied disposition of the content of the HTTP body.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum DispositionType {
+    /// Inline implies default processing.
+    Inline,
+
+    /// Attachment implies that the recipient should prompt the user to save the response locally,
+    /// rather than process it normally (as per its media type).
+    Attachment,
+
+    /// Used in *multipart/form-data* as defined in
+    /// [RFC 7578](https://datatracker.ietf.org/doc/html/rfc7578) to carry the field name and
+    /// optional filename.
+    FormData,
+
+    /// Extension type. Should be handled by recipients the same way as Attachment.
+    Ext(String),
+}
+
+impl<'a> From<&'a str> for DispositionType {
+    fn from(origin: &'a str) -> DispositionType {
+        if origin.eq_ignore_ascii_case("inline") {
+            DispositionType::Inline
+        } else if origin.eq_ignore_ascii_case("attachment") {
+            DispositionType::Attachment
+        } else if origin.eq_ignore_ascii_case("form-data") {
+            DispositionType::FormData
+        } else {
+            DispositionType::Ext(origin.to_owned())
+        }
+    }
+}
+
+/// Parameter in [`ContentDisposition`].
+///
+/// # Examples
+/// ```
+/// use actix_web::http::header::DispositionParam;
+///
+/// let param = DispositionParam::Filename(String::from("sample.txt"));
+/// assert!(param.is_filename());
+/// assert_eq!(param.as_filename().unwrap(), "sample.txt");
+/// ```
+#[derive(Debug, Clone, PartialEq, Eq)]
+#[allow(clippy::large_enum_variant)]
+pub enum DispositionParam {
+    /// For [`DispositionType::FormData`] (i.e. *multipart/form-data*), the name of an field from
+    /// the form.
+    Name(String),
+
+    /// A plain file name.
+    ///
+    /// It is [not supposed](https://datatracker.ietf.org/doc/html/rfc6266#appendix-D) to contain
+    /// any non-ASCII characters when used in a *Content-Disposition* HTTP response header, where
+    /// [`FilenameExt`](DispositionParam::FilenameExt) with charset UTF-8 may be used instead
+    /// in case there are Unicode characters in file names.
+    Filename(String),
+
+    /// An extended file name. It must not exist for `ContentType::Formdata` according to
+    /// [RFC 7578 §4.2](https://datatracker.ietf.org/doc/html/rfc7578#section-4.2).
+    FilenameExt(ExtendedValue),
+
+    /// An unrecognized regular parameter as defined in
+    /// [RFC 5987 §3.2.1](https://datatracker.ietf.org/doc/html/rfc5987#section-3.2.1) as
+    /// `reg-parameter`, in
+    /// [RFC 6266 §4.1](https://datatracker.ietf.org/doc/html/rfc6266#section-4.1) as
+    /// `token "=" value`. Recipients should ignore unrecognizable parameters.
+    Unknown(String, String),
+
+    /// An unrecognized extended parameter as defined in
+    /// [RFC 5987 §3.2.1](https://datatracker.ietf.org/doc/html/rfc5987#section-3.2.1) as
+    /// `ext-parameter`, in
+    /// [RFC 6266 §4.1](https://datatracker.ietf.org/doc/html/rfc6266#section-4.1) as
+    /// `ext-token "=" ext-value`. The single trailing asterisk is not included. Recipients should
+    /// ignore unrecognizable parameters.
+    UnknownExt(String, ExtendedValue),
+}
+
+impl DispositionParam {
+    /// Returns `true` if the parameter is [`Name`](DispositionParam::Name).
+    #[inline]
+    pub fn is_name(&self) -> bool {
+        self.as_name().is_some()
+    }
+
+    /// Returns `true` if the parameter is [`Filename`](DispositionParam::Filename).
+    #[inline]
+    pub fn is_filename(&self) -> bool {
+        self.as_filename().is_some()
+    }
+
+    /// Returns `true` if the parameter is [`FilenameExt`](DispositionParam::FilenameExt).
+    #[inline]
+    pub fn is_filename_ext(&self) -> bool {
+        self.as_filename_ext().is_some()
+    }
+
+    /// Returns `true` if the parameter is [`Unknown`](DispositionParam::Unknown) and the `name`
+    #[inline]
+    /// matches.
+    pub fn is_unknown<T: AsRef<str>>(&self, name: T) -> bool {
+        self.as_unknown(name).is_some()
+    }
+
+    /// Returns `true` if the parameter is [`UnknownExt`](DispositionParam::UnknownExt) and the
+    /// `name` matches.
+    #[inline]
+    pub fn is_unknown_ext<T: AsRef<str>>(&self, name: T) -> bool {
+        self.as_unknown_ext(name).is_some()
+    }
+
+    /// Returns the name if applicable.
+    #[inline]
+    pub fn as_name(&self) -> Option<&str> {
+        match self {
+            DispositionParam::Name(ref name) => Some(name.as_str()),
+            _ => None,
+        }
+    }
+
+    /// Returns the filename if applicable.
+    #[inline]
+    pub fn as_filename(&self) -> Option<&str> {
+        match self {
+            DispositionParam::Filename(ref filename) => Some(filename.as_str()),
+            _ => None,
+        }
+    }
+
+    /// Returns the filename* if applicable.
+    #[inline]
+    pub fn as_filename_ext(&self) -> Option<&ExtendedValue> {
+        match self {
+            DispositionParam::FilenameExt(ref value) => Some(value),
+            _ => None,
+        }
+    }
+
+    /// Returns the value of the unrecognized regular parameter if it is
+    /// [`Unknown`](DispositionParam::Unknown) and the `name` matches.
+    #[inline]
+    pub fn as_unknown<T: AsRef<str>>(&self, name: T) -> Option<&str> {
+        match self {
+            DispositionParam::Unknown(ref ext_name, ref value)
+                if ext_name.eq_ignore_ascii_case(name.as_ref()) =>
+            {
+                Some(value.as_str())
+            }
+            _ => None,
+        }
+    }
+
+    /// Returns the value of the unrecognized extended parameter if it is
+    /// [`Unknown`](DispositionParam::Unknown) and the `name` matches.
+    #[inline]
+    pub fn as_unknown_ext<T: AsRef<str>>(&self, name: T) -> Option<&ExtendedValue> {
+        match self {
+            DispositionParam::UnknownExt(ref ext_name, ref value)
+                if ext_name.eq_ignore_ascii_case(name.as_ref()) =>
+            {
+                Some(value)
+            }
+            _ => None,
+        }
+    }
+}
+
+/// A *Content-Disposition* header. It is compatible to be used either as
+/// [a response header for the main body](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#as_a_response_header_for_the_main_body)
+/// as (re)defined in [RFC 6266](https://datatracker.ietf.org/doc/html/rfc6266), or as
+/// [a header for a multipart body](https://mdn.io/Content-Disposition#As_a_header_for_a_multipart_body)
+/// as (re)defined in [RFC 7587](https://datatracker.ietf.org/doc/html/rfc7578).
+///
+/// In a regular HTTP response, the *Content-Disposition* response header is a header indicating if
+/// the content is expected to be displayed *inline* in the browser, that is, as a Web page or as
+/// part of a Web page, or as an attachment, that is downloaded and saved locally, and also can be
+/// used to attach additional metadata, such as the filename to use when saving the response payload
+/// locally.
+///
+/// In a *multipart/form-data* body, the HTTP *Content-Disposition* general header is a header that
+/// can be used on the subpart of a multipart body to give information about the field it applies to.
+/// The subpart is delimited by the boundary defined in the *Content-Type* header. Used on the body
+/// itself, *Content-Disposition* has no effect.
+///
+/// # ABNF
+/// ```plain
+/// content-disposition = "Content-Disposition" ":"
+///                       disposition-type *( ";" disposition-parm )
+///
+/// disposition-type    = "inline" | "attachment" | disp-ext-type
+///                       ; case-insensitive
+///
+/// disp-ext-type       = token
+///
+/// disposition-parm    = filename-parm | disp-ext-parm
+///
+/// filename-parm       = "filename" "=" value
+///                     | "filename*" "=" ext-value
+///
+/// disp-ext-parm       = token "=" value
+///                     | ext-token "=" ext-value
+///
+/// ext-token           = <the characters in token, followed by "*">
+/// ```
+///
+/// # Note
+/// *filename* is [not supposed](https://datatracker.ietf.org/doc/html/rfc6266#appendix-D) to
+/// contain any non-ASCII characters when used in a *Content-Disposition* HTTP response header,
+/// where filename* with charset UTF-8 may be used instead in case there are Unicode characters in
+/// file names. Filename is [acceptable](https://datatracker.ietf.org/doc/html/rfc7578#section-4.2)
+/// to be UTF-8 encoded directly in a *Content-Disposition* header for
+/// *multipart/form-data*, though.
+///
+/// *filename* [must not](https://datatracker.ietf.org/doc/html/rfc7578#section-4.2) be used within
+/// *multipart/form-data*.
+///
+/// # Examples
+/// ```
+/// use actix_web::http::header::{
+///     Charset, ContentDisposition, DispositionParam, DispositionType,
+///     ExtendedValue,
+/// };
+///
+/// let cd1 = ContentDisposition {
+///     disposition: DispositionType::Attachment,
+///     parameters: vec![DispositionParam::FilenameExt(ExtendedValue {
+///         charset: Charset::Iso_8859_1, // The character set for the bytes of the filename
+///         language_tag: None, // The optional language tag (see `language-tag` crate)
+///         value: b"\xa9 Copyright 1989.txt".to_vec(), // the actual bytes of the filename
+///     })],
+/// };
+/// assert!(cd1.is_attachment());
+/// assert!(cd1.get_filename_ext().is_some());
+///
+/// let cd2 = ContentDisposition {
+///     disposition: DispositionType::FormData,
+///     parameters: vec![
+///         DispositionParam::Name(String::from("file")),
+///         DispositionParam::Filename(String::from("bill.odt")),
+///     ],
+/// };
+/// assert_eq!(cd2.get_name(), Some("file")); // field name
+/// assert_eq!(cd2.get_filename(), Some("bill.odt"));
+///
+/// // HTTP response header with Unicode characters in file names
+/// let cd3 = ContentDisposition {
+///     disposition: DispositionType::Attachment,
+///     parameters: vec![
+///         DispositionParam::FilenameExt(ExtendedValue {
+///             charset: Charset::Ext(String::from("UTF-8")),
+///             language_tag: None,
+///             value: String::from("\u{1f600}.svg").into_bytes(),
+///         }),
+///         // fallback for better compatibility
+///         DispositionParam::Filename(String::from("Grinning-Face-Emoji.svg"))
+///     ],
+/// };
+/// assert_eq!(cd3.get_filename_ext().map(|ev| ev.value.as_ref()),
+///            Some("\u{1f600}.svg".as_bytes()));
+/// ```
+///
+/// # Security Note
+/// If "filename" parameter is supplied, do not use the file name blindly, check and possibly
+/// change to match local file system conventions if applicable, and do not use directory path
+/// information that may be present.
+/// See [RFC 2183 §2.3](https://datatracker.ietf.org/doc/html/rfc2183#section-2.3).
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct ContentDisposition {
+    /// The disposition type
+    pub disposition: DispositionType,
+
+    /// Disposition parameters
+    pub parameters: Vec<DispositionParam>,
+}
+
+impl ContentDisposition {
+    /// Constructs a Content-Disposition header suitable for downloads.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::http::header::{ContentDisposition, TryIntoHeaderValue as _};
+    ///
+    /// let cd = ContentDisposition::attachment("files.zip");
+    ///
+    /// let cd_val = cd.try_into_value().unwrap();
+    /// assert_eq!(cd_val, "attachment; filename=\"files.zip\"");
+    /// ```
+    pub fn attachment(filename: impl Into<String>) -> Self {
+        Self {
+            disposition: DispositionType::Attachment,
+            parameters: vec![DispositionParam::Filename(filename.into())],
+        }
+    }
+
+    /// Parse a raw Content-Disposition header value.
+    pub fn from_raw(hv: &header::HeaderValue) -> Result<Self, crate::error::ParseError> {
+        // `header::from_one_raw_str` invokes `hv.to_str` which assumes `hv` contains only visible
+        //  ASCII characters. So `hv.as_bytes` is necessary here.
+        let hv = String::from_utf8(hv.as_bytes().to_vec())
+            .map_err(|_| crate::error::ParseError::Header)?;
+
+        let (disp_type, mut left) = split_once_and_trim(hv.as_str().trim(), ';');
+        if disp_type.is_empty() {
+            return Err(crate::error::ParseError::Header);
+        }
+
+        let mut cd = ContentDisposition {
+            disposition: disp_type.into(),
+            parameters: Vec::new(),
+        };
+
+        while !left.is_empty() {
+            let (param_name, new_left) = split_once_and_trim(left, '=');
+            if param_name.is_empty() || param_name == "*" || new_left.is_empty() {
+                return Err(crate::error::ParseError::Header);
+            }
+            left = new_left;
+            if let Some(param_name) = param_name.strip_suffix('*') {
+                // extended parameters
+                let (ext_value, new_left) = split_once_and_trim(left, ';');
+                left = new_left;
+                let ext_value = header::parse_extended_value(ext_value)?;
+
+                let param = if param_name.eq_ignore_ascii_case("filename") {
+                    DispositionParam::FilenameExt(ext_value)
+                } else {
+                    DispositionParam::UnknownExt(param_name.to_owned(), ext_value)
+                };
+                cd.parameters.push(param);
+            } else {
+                // regular parameters
+                let value = if left.starts_with('\"') {
+                    // quoted-string: defined in RFC 6266 -> RFC 2616 Section 3.6
+                    let mut escaping = false;
+                    let mut quoted_string = vec![];
+                    let mut end = None;
+                    // search for closing quote
+                    for (i, &c) in left.as_bytes().iter().skip(1).enumerate() {
+                        if escaping {
+                            escaping = false;
+                            quoted_string.push(c);
+                        } else if c == 0x5c {
+                            // backslash
+                            escaping = true;
+                        } else if c == 0x22 {
+                            // double quote
+                            end = Some(i + 1); // cuz skipped 1 for the leading quote
+                            break;
+                        } else {
+                            quoted_string.push(c);
+                        }
+                    }
+                    left = &left[end.ok_or(crate::error::ParseError::Header)? + 1..];
+                    left = split_once(left, ';').1.trim_start();
+                    // In fact, it should not be Err if the above code is correct.
+                    String::from_utf8(quoted_string)
+                        .map_err(|_| crate::error::ParseError::Header)?
+                } else {
+                    // token: won't contains semicolon according to RFC 2616 Section 2.2
+                    let (token, new_left) = split_once_and_trim(left, ';');
+                    left = new_left;
+                    if token.is_empty() {
+                        // quoted-string can be empty, but token cannot be empty
+                        return Err(crate::error::ParseError::Header);
+                    }
+                    token.to_owned()
+                };
+
+                let param = if param_name.eq_ignore_ascii_case("name") {
+                    DispositionParam::Name(value)
+                } else if param_name.eq_ignore_ascii_case("filename") {
+                    // See also comments in test_from_raw_unnecessary_percent_decode.
+                    DispositionParam::Filename(value)
+                } else {
+                    DispositionParam::Unknown(param_name.to_owned(), value)
+                };
+                cd.parameters.push(param);
+            }
+        }
+
+        Ok(cd)
+    }
+
+    /// Returns `true` if type is [`Inline`](DispositionType::Inline).
+    pub fn is_inline(&self) -> bool {
+        matches!(self.disposition, DispositionType::Inline)
+    }
+
+    /// Returns `true` if type is [`Attachment`](DispositionType::Attachment).
+    pub fn is_attachment(&self) -> bool {
+        matches!(self.disposition, DispositionType::Attachment)
+    }
+
+    /// Returns `true` if type is [`FormData`](DispositionType::FormData).
+    pub fn is_form_data(&self) -> bool {
+        matches!(self.disposition, DispositionType::FormData)
+    }
+
+    /// Returns `true` if type is [`Ext`](DispositionType::Ext) and the `disp_type` matches.
+    pub fn is_ext(&self, disp_type: impl AsRef<str>) -> bool {
+        matches!(
+            self.disposition,
+            DispositionType::Ext(ref t) if t.eq_ignore_ascii_case(disp_type.as_ref())
+        )
+    }
+
+    /// Return the value of *name* if exists.
+    pub fn get_name(&self) -> Option<&str> {
+        self.parameters.iter().find_map(DispositionParam::as_name)
+    }
+
+    /// Return the value of *filename* if exists.
+    pub fn get_filename(&self) -> Option<&str> {
+        self.parameters
+            .iter()
+            .find_map(DispositionParam::as_filename)
+    }
+
+    /// Return the value of *filename\** if exists.
+    pub fn get_filename_ext(&self) -> Option<&ExtendedValue> {
+        self.parameters
+            .iter()
+            .find_map(DispositionParam::as_filename_ext)
+    }
+
+    /// Return the value of the parameter which the `name` matches.
+    pub fn get_unknown(&self, name: impl AsRef<str>) -> Option<&str> {
+        let name = name.as_ref();
+        self.parameters.iter().find_map(|p| p.as_unknown(name))
+    }
+
+    /// Return the value of the extended parameter which the `name` matches.
+    pub fn get_unknown_ext(&self, name: impl AsRef<str>) -> Option<&ExtendedValue> {
+        let name = name.as_ref();
+        self.parameters.iter().find_map(|p| p.as_unknown_ext(name))
+    }
+}
+
+impl TryIntoHeaderValue for ContentDisposition {
+    type Error = header::InvalidHeaderValue;
+
+    fn try_into_value(self) -> Result<header::HeaderValue, Self::Error> {
+        let mut writer = Writer::new();
+        let _ = write!(&mut writer, "{}", self);
+        header::HeaderValue::from_maybe_shared(writer.take())
+    }
+}
+
+impl Header for ContentDisposition {
+    fn name() -> header::HeaderName {
+        header::CONTENT_DISPOSITION
+    }
+
+    fn parse<T: crate::HttpMessage>(msg: &T) -> Result<Self, crate::error::ParseError> {
+        if let Some(h) = msg.headers().get(&Self::name()) {
+            Self::from_raw(h)
+        } else {
+            Err(crate::error::ParseError::Header)
+        }
+    }
+}
+
+impl fmt::Display for DispositionType {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            DispositionType::Inline => write!(f, "inline"),
+            DispositionType::Attachment => write!(f, "attachment"),
+            DispositionType::FormData => write!(f, "form-data"),
+            DispositionType::Ext(ref s) => write!(f, "{}", s),
+        }
+    }
+}
+
+impl fmt::Display for DispositionParam {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        // All ASCII control characters (0-30, 127) including horizontal tab, double quote, and
+        // backslash should be escaped in quoted-string (i.e. "foobar").
+        //
+        // Ref: RFC 6266 §4.1 -> RFC 2616 §3.6
+        //
+        // filename-parm  = "filename" "=" value
+        // value          = token | quoted-string
+        // quoted-string  = ( <"> *(qdtext | quoted-pair ) <"> )
+        // qdtext         = <any TEXT except <">>
+        // quoted-pair    = "\" CHAR
+        // TEXT           = <any OCTET except CTLs,
+        //                  but including LWS>
+        // LWS            = [CRLF] 1*( SP | HT )
+        // OCTET          = <any 8-bit sequence of data>
+        // CHAR           = <any US-ASCII character (octets 0 - 127)>
+        // CTL            = <any US-ASCII control character
+        //                  (octets 0 - 31) and DEL (127)>
+        //
+        // Ref: RFC 7578 S4.2 -> RFC 2183 S2 -> RFC 2045 S5.1
+        // parameter := attribute "=" value
+        // attribute := token
+        //              ; Matching of attributes
+        //              ; is ALWAYS case-insensitive.
+        // value := token / quoted-string
+        // token := 1*<any (US-ASCII) CHAR except SPACE, CTLs,
+        //             or tspecials>
+        // tspecials :=  "(" / ")" / "<" / ">" / "@" /
+        //               "," / ";" / ":" / "\" / <">
+        //               "/" / "[" / "]" / "?" / "="
+        //               ; Must be in quoted-string,
+        //               ; to use within parameter values
+        //
+        //
+        // See also comments in test_from_raw_unnecessary_percent_decode.
+
+        static RE: Lazy<Regex> =
+            Lazy::new(|| Regex::new("[\x00-\x08\x10-\x1F\x7F\"\\\\]").unwrap());
+
+        match self {
+            DispositionParam::Name(ref value) => write!(f, "name={}", value),
+
+            DispositionParam::Filename(ref value) => {
+                write!(f, "filename=\"{}\"", RE.replace_all(value, "\\$0").as_ref())
+            }
+
+            DispositionParam::Unknown(ref name, ref value) => write!(
+                f,
+                "{}=\"{}\"",
+                name,
+                &RE.replace_all(value, "\\$0").as_ref()
+            ),
+
+            DispositionParam::FilenameExt(ref ext_value) => {
+                write!(f, "filename*={}", ext_value)
+            }
+
+            DispositionParam::UnknownExt(ref name, ref ext_value) => {
+                write!(f, "{}*={}", name, ext_value)
+            }
+        }
+    }
+}
+
+impl fmt::Display for ContentDisposition {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}", self.disposition)?;
+        self.parameters
+            .iter()
+            .try_for_each(|param| write!(f, "; {}", param))
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::{ContentDisposition, DispositionParam, DispositionType};
+    use crate::http::header::{Charset, ExtendedValue, HeaderValue};
+
+    #[test]
+    fn test_from_raw_basic() {
+        assert!(ContentDisposition::from_raw(&HeaderValue::from_static("")).is_err());
+
+        let a =
+            HeaderValue::from_static("form-data; dummy=3; name=upload; filename=\"sample.png\"");
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::FormData,
+            parameters: vec![
+                DispositionParam::Unknown("dummy".to_owned(), "3".to_owned()),
+                DispositionParam::Name("upload".to_owned()),
+                DispositionParam::Filename("sample.png".to_owned()),
+            ],
+        };
+        assert_eq!(a, b);
+
+        let a = HeaderValue::from_static("attachment; filename=\"image.jpg\"");
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::Attachment,
+            parameters: vec![DispositionParam::Filename("image.jpg".to_owned())],
+        };
+        assert_eq!(a, b);
+
+        let a = HeaderValue::from_static("inline; filename=image.jpg");
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::Inline,
+            parameters: vec![DispositionParam::Filename("image.jpg".to_owned())],
+        };
+        assert_eq!(a, b);
+
+        let a = HeaderValue::from_static(
+            "attachment; creation-date=\"Wed, 12 Feb 1997 16:29:51 -0500\"",
+        );
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::Attachment,
+            parameters: vec![DispositionParam::Unknown(
+                String::from("creation-date"),
+                "Wed, 12 Feb 1997 16:29:51 -0500".to_owned(),
+            )],
+        };
+        assert_eq!(a, b);
+    }
+
+    #[test]
+    fn test_from_raw_extended() {
+        let a = HeaderValue::from_static(
+            "attachment; filename*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates",
+        );
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::Attachment,
+            parameters: vec![DispositionParam::FilenameExt(ExtendedValue {
+                charset: Charset::Ext(String::from("UTF-8")),
+                language_tag: None,
+                value: vec![
+                    0xc2, 0xa3, 0x20, b'a', b'n', b'd', 0x20, 0xe2, 0x82, 0xac, 0x20, b'r', b'a',
+                    b't', b'e', b's',
+                ],
+            })],
+        };
+        assert_eq!(a, b);
+
+        let a = HeaderValue::from_static(
+            "attachment; filename*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates",
+        );
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::Attachment,
+            parameters: vec![DispositionParam::FilenameExt(ExtendedValue {
+                charset: Charset::Ext(String::from("UTF-8")),
+                language_tag: None,
+                value: vec![
+                    0xc2, 0xa3, 0x20, b'a', b'n', b'd', 0x20, 0xe2, 0x82, 0xac, 0x20, b'r', b'a',
+                    b't', b'e', b's',
+                ],
+            })],
+        };
+        assert_eq!(a, b);
+    }
+
+    #[test]
+    fn test_from_raw_extra_whitespace() {
+        let a = HeaderValue::from_static(
+            "form-data  ; du-mmy= 3  ; name =upload ; filename =  \"sample.png\"  ; ",
+        );
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::FormData,
+            parameters: vec![
+                DispositionParam::Unknown("du-mmy".to_owned(), "3".to_owned()),
+                DispositionParam::Name("upload".to_owned()),
+                DispositionParam::Filename("sample.png".to_owned()),
+            ],
+        };
+        assert_eq!(a, b);
+    }
+
+    #[test]
+    fn test_from_raw_unordered() {
+        let a = HeaderValue::from_static(
+            "form-data; dummy=3; filename=\"sample.png\" ; name=upload;",
+            // Actually, a trailing semicolon is not compliant. But it is fine to accept.
+        );
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::FormData,
+            parameters: vec![
+                DispositionParam::Unknown("dummy".to_owned(), "3".to_owned()),
+                DispositionParam::Filename("sample.png".to_owned()),
+                DispositionParam::Name("upload".to_owned()),
+            ],
+        };
+        assert_eq!(a, b);
+
+        let a = HeaderValue::from_str(
+            "attachment; filename*=iso-8859-1''foo-%E4.html; filename=\"foo-ä.html\"",
+        )
+        .unwrap();
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::Attachment,
+            parameters: vec![
+                DispositionParam::FilenameExt(ExtendedValue {
+                    charset: Charset::Iso_8859_1,
+                    language_tag: None,
+                    value: b"foo-\xe4.html".to_vec(),
+                }),
+                DispositionParam::Filename("foo-ä.html".to_owned()),
+            ],
+        };
+        assert_eq!(a, b);
+    }
+
+    #[test]
+    fn test_from_raw_only_disp() {
+        let a = ContentDisposition::from_raw(&HeaderValue::from_static("attachment")).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::Attachment,
+            parameters: vec![],
+        };
+        assert_eq!(a, b);
+
+        let a = ContentDisposition::from_raw(&HeaderValue::from_static("inline ;")).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::Inline,
+            parameters: vec![],
+        };
+        assert_eq!(a, b);
+
+        let a =
+            ContentDisposition::from_raw(&HeaderValue::from_static("unknown-disp-param")).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::Ext(String::from("unknown-disp-param")),
+            parameters: vec![],
+        };
+        assert_eq!(a, b);
+    }
+
+    #[test]
+    fn from_raw_with_mixed_case() {
+        let a = HeaderValue::from_str(
+            "InLInE; fIlenAME*=iso-8859-1''foo-%E4.html; filEName=\"foo-ä.html\"",
+        )
+        .unwrap();
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::Inline,
+            parameters: vec![
+                DispositionParam::FilenameExt(ExtendedValue {
+                    charset: Charset::Iso_8859_1,
+                    language_tag: None,
+                    value: b"foo-\xe4.html".to_vec(),
+                }),
+                DispositionParam::Filename("foo-ä.html".to_owned()),
+            ],
+        };
+        assert_eq!(a, b);
+    }
+
+    #[test]
+    fn from_raw_with_unicode() {
+        /* RFC 7578 Section 4.2:
+        Some commonly deployed systems use multipart/form-data with file names directly encoded
+        including octets outside the US-ASCII range. The encoding used for the file names is
+        typically UTF-8, although HTML forms will use the charset associated with the form.
+
+        Mainstream browsers like Firefox (gecko) and Chrome use UTF-8 directly as above.
+        (And now, only UTF-8 is handled by this implementation.)
+        */
+        let a = HeaderValue::from_str("form-data; name=upload; filename=\"文件.webp\"").unwrap();
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::FormData,
+            parameters: vec![
+                DispositionParam::Name(String::from("upload")),
+                DispositionParam::Filename(String::from("文件.webp")),
+            ],
+        };
+        assert_eq!(a, b);
+
+        let a = HeaderValue::from_str(
+            "form-data; name=upload; filename=\"余固知謇謇之為患兮,忍而不能舍也.pptx\"",
+        )
+        .unwrap();
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::FormData,
+            parameters: vec![
+                DispositionParam::Name(String::from("upload")),
+                DispositionParam::Filename(String::from("余固知謇謇之為患兮,忍而不能舍也.pptx")),
+            ],
+        };
+        assert_eq!(a, b);
+    }
+
+    #[test]
+    fn test_from_raw_escape() {
+        let a = HeaderValue::from_static(
+            "form-data; dummy=3; name=upload; filename=\"s\\amp\\\"le.png\"",
+        );
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::FormData,
+            parameters: vec![
+                DispositionParam::Unknown("dummy".to_owned(), "3".to_owned()),
+                DispositionParam::Name("upload".to_owned()),
+                DispositionParam::Filename(
+                    ['s', 'a', 'm', 'p', '\"', 'l', 'e', '.', 'p', 'n', 'g']
+                        .iter()
+                        .collect(),
+                ),
+            ],
+        };
+        assert_eq!(a, b);
+    }
+
+    #[test]
+    fn test_from_raw_semicolon() {
+        let a = HeaderValue::from_static("form-data; filename=\"A semicolon here;.pdf\"");
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::FormData,
+            parameters: vec![DispositionParam::Filename(String::from(
+                "A semicolon here;.pdf",
+            ))],
+        };
+        assert_eq!(a, b);
+    }
+
+    #[test]
+    fn test_from_raw_unnecessary_percent_decode() {
+        // In fact, RFC 7578 (multipart/form-data) Section 2 and 4.2 suggests that filename with
+        // non-ASCII characters MAY be percent-encoded.
+        // On the contrary, RFC 6266 or other RFCs related to Content-Disposition response header
+        // do not mention such percent-encoding.
+        // So, it appears to be undecidable whether to percent-decode or not without
+        // knowing the usage scenario (multipart/form-data v.s. HTTP response header) and
+        // inevitable to unnecessarily percent-decode filename with %XX in the former scenario.
+        // Fortunately, it seems that almost all mainstream browsers just send UTF-8 encoded file
+        // names in quoted-string format (tested on Edge, IE11, Chrome and Firefox) without
+        // percent-encoding. So we do not bother to attempt to percent-decode.
+        let a = HeaderValue::from_static(
+            "form-data; name=photo; filename=\"%74%65%73%74%2e%70%6e%67\"",
+        );
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::FormData,
+            parameters: vec![
+                DispositionParam::Name("photo".to_owned()),
+                DispositionParam::Filename(String::from("%74%65%73%74%2e%70%6e%67")),
+            ],
+        };
+        assert_eq!(a, b);
+
+        let a = HeaderValue::from_static("form-data; name=photo; filename=\"%74%65%73%74.png\"");
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let b = ContentDisposition {
+            disposition: DispositionType::FormData,
+            parameters: vec![
+                DispositionParam::Name("photo".to_owned()),
+                DispositionParam::Filename(String::from("%74%65%73%74.png")),
+            ],
+        };
+        assert_eq!(a, b);
+    }
+
+    #[test]
+    fn test_from_raw_param_value_missing() {
+        let a = HeaderValue::from_static("form-data; name=upload ; filename=");
+        assert!(ContentDisposition::from_raw(&a).is_err());
+
+        let a = HeaderValue::from_static("attachment; dummy=; filename=invoice.pdf");
+        assert!(ContentDisposition::from_raw(&a).is_err());
+
+        let a = HeaderValue::from_static("inline; filename=  ");
+        assert!(ContentDisposition::from_raw(&a).is_err());
+
+        let a = HeaderValue::from_static("inline; filename=\"\"");
+        assert!(ContentDisposition::from_raw(&a)
+            .expect("parse cd")
+            .get_filename()
+            .expect("filename")
+            .is_empty());
+    }
+
+    #[test]
+    fn test_from_raw_param_name_missing() {
+        let a = HeaderValue::from_static("inline; =\"test.txt\"");
+        assert!(ContentDisposition::from_raw(&a).is_err());
+
+        let a = HeaderValue::from_static("inline; =diary.odt");
+        assert!(ContentDisposition::from_raw(&a).is_err());
+
+        let a = HeaderValue::from_static("inline; =");
+        assert!(ContentDisposition::from_raw(&a).is_err());
+    }
+
+    #[test]
+    fn test_display_extended() {
+        let as_string = "attachment; filename*=UTF-8'en'%C2%A3%20and%20%E2%82%AC%20rates";
+        let a = HeaderValue::from_static(as_string);
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let display_rendered = format!("{}", a);
+        assert_eq!(as_string, display_rendered);
+
+        let a = HeaderValue::from_static("attachment; filename=colourful.csv");
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let display_rendered = format!("{}", a);
+        assert_eq!(
+            "attachment; filename=\"colourful.csv\"".to_owned(),
+            display_rendered
+        );
+    }
+
+    #[test]
+    fn test_display_quote() {
+        let as_string = "form-data; name=upload; filename=\"Quote\\\"here.png\"";
+        as_string
+            .find(['\\', '\"'].iter().collect::<String>().as_str())
+            .unwrap(); // ensure `\"` is there
+        let a = HeaderValue::from_static(as_string);
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let display_rendered = format!("{}", a);
+        assert_eq!(as_string, display_rendered);
+    }
+
+    #[test]
+    fn test_display_space_tab() {
+        let as_string = "form-data; name=upload; filename=\"Space here.png\"";
+        let a = HeaderValue::from_static(as_string);
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let display_rendered = format!("{}", a);
+        assert_eq!(as_string, display_rendered);
+
+        let a: ContentDisposition = ContentDisposition {
+            disposition: DispositionType::Inline,
+            parameters: vec![DispositionParam::Filename(String::from("Tab\there.png"))],
+        };
+        let display_rendered = format!("{}", a);
+        assert_eq!("inline; filename=\"Tab\x09here.png\"", display_rendered);
+    }
+
+    #[test]
+    fn test_display_control_characters() {
+        /* let a = "attachment; filename=\"carriage\rreturn.png\"";
+        let a = HeaderValue::from_static(a);
+        let a: ContentDisposition = ContentDisposition::from_raw(&a).unwrap();
+        let display_rendered = format!("{}", a);
+        assert_eq!(
+            "attachment; filename=\"carriage\\\rreturn.png\"",
+            display_rendered
+        );*/
+        // No way to create a HeaderValue containing a carriage return.
+
+        let a: ContentDisposition = ContentDisposition {
+            disposition: DispositionType::Inline,
+            parameters: vec![DispositionParam::Filename(String::from("bell\x07.png"))],
+        };
+        let display_rendered = format!("{}", a);
+        assert_eq!("inline; filename=\"bell\\\x07.png\"", display_rendered);
+    }
+
+    #[test]
+    fn test_param_methods() {
+        let param = DispositionParam::Filename(String::from("sample.txt"));
+        assert!(param.is_filename());
+        assert_eq!(param.as_filename().unwrap(), "sample.txt");
+
+        let param = DispositionParam::Unknown(String::from("foo"), String::from("bar"));
+        assert!(param.is_unknown("foo"));
+        assert_eq!(param.as_unknown("fOo"), Some("bar"));
+    }
+
+    #[test]
+    fn test_disposition_methods() {
+        let cd = ContentDisposition {
+            disposition: DispositionType::FormData,
+            parameters: vec![
+                DispositionParam::Unknown("dummy".to_owned(), "3".to_owned()),
+                DispositionParam::Name("upload".to_owned()),
+                DispositionParam::Filename("sample.png".to_owned()),
+            ],
+        };
+        assert_eq!(cd.get_name(), Some("upload"));
+        assert_eq!(cd.get_unknown("dummy"), Some("3"));
+        assert_eq!(cd.get_filename(), Some("sample.png"));
+        assert_eq!(cd.get_unknown_ext("dummy"), None);
+        assert_eq!(cd.get_unknown("duMMy"), Some("3"));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/content_language.rs.html b/src/actix_web/http/header/content_language.rs.html new file mode 100644 index 000000000..9394671b3 --- /dev/null +++ b/src/actix_web/http/header/content_language.rs.html @@ -0,0 +1,109 @@ +content_language.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
+
use language_tags::LanguageTag;
+
+use super::{common_header, QualityItem, CONTENT_LANGUAGE};
+
+common_header! {
+    /// `Content-Language` header, defined
+    /// in [RFC 7231 §3.1.3.2](https://datatracker.ietf.org/doc/html/rfc7231#section-3.1.3.2)
+    ///
+    /// The `Content-Language` header field describes the natural language(s)
+    /// of the intended audience for the representation.  Note that this
+    /// might not be equivalent to all the languages used within the
+    /// representation.
+    ///
+    /// # ABNF
+    /// ```plain
+    /// Content-Language = 1#language-tag
+    /// ```
+    ///
+    /// # Example Values
+    /// * `da`
+    /// * `mi, en`
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{ContentLanguage, LanguageTag, QualityItem};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     ContentLanguage(vec![
+    ///         QualityItem::max(LanguageTag::parse("en").unwrap()),
+    ///     ])
+    /// );
+    /// ```
+    ///
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{ContentLanguage, LanguageTag, QualityItem};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     ContentLanguage(vec![
+    ///         QualityItem::max(LanguageTag::parse("da").unwrap()),
+    ///         QualityItem::max(LanguageTag::parse("en-GB").unwrap()),
+    ///     ])
+    /// );
+    /// ```
+    (ContentLanguage, CONTENT_LANGUAGE) => (QualityItem<LanguageTag>)+
+
+    test_parse_and_format {
+        crate::http::header::common_header_test!(test1, [b"da"]);
+        crate::http::header::common_header_test!(test2, [b"mi, en"]);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/content_length.rs.html b/src/actix_web/http/header/content_length.rs.html new file mode 100644 index 000000000..b1e060b4e --- /dev/null +++ b/src/actix_web/http/header/content_length.rs.html @@ -0,0 +1,477 @@ +content_length.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
+
use std::{convert::Infallible, str};
+
+use derive_more::{Deref, DerefMut};
+
+use crate::{
+    error::ParseError,
+    http::header::{
+        from_one_raw_str, Header, HeaderName, HeaderValue, TryIntoHeaderValue, CONTENT_LENGTH,
+    },
+    HttpMessage,
+};
+
+/// `Content-Length` header, defined in [RFC 9110 §8.6].
+///
+/// The Content-Length
+///
+/// # ABNF
+///
+/// ```plain
+/// Content-Length = 1*DIGIT
+/// ```
+///
+/// # Example Values
+///
+/// - `0`
+/// - `3495`
+///
+/// # Examples
+///
+/// ```
+/// use actix_web::{http::header::ContentLength, HttpResponse};
+///
+/// let res_empty = HttpResponse::Ok()
+///     .insert_header(ContentLength(0));
+///
+/// let res_fake_cl = HttpResponse::Ok()
+///     .insert_header(ContentLength(3_495));
+/// ```
+///
+/// [RFC 9110 §8.6]: https://www.rfc-editor.org/rfc/rfc9110#name-content-length
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Deref, DerefMut)]
+pub struct ContentLength(pub usize);
+
+impl ContentLength {
+    /// Returns Content-Length value.
+    pub fn into_inner(&self) -> usize {
+        self.0
+    }
+}
+
+impl str::FromStr for ContentLength {
+    type Err = <usize as str::FromStr>::Err;
+
+    #[inline]
+    fn from_str(val: &str) -> Result<Self, Self::Err> {
+        let val = val.trim();
+
+        // decoder prevents this case
+        debug_assert!(!val.starts_with('+'));
+
+        val.parse().map(Self)
+    }
+}
+
+impl TryIntoHeaderValue for ContentLength {
+    type Error = Infallible;
+
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        Ok(HeaderValue::from(self.0))
+    }
+}
+
+impl Header for ContentLength {
+    fn name() -> HeaderName {
+        CONTENT_LENGTH
+    }
+
+    fn parse<M: HttpMessage>(msg: &M) -> Result<Self, ParseError> {
+        let val = from_one_raw_str(msg.headers().get(Self::name()))?;
+
+        // decoder prevents multiple CL headers
+        debug_assert_eq!(msg.headers().get_all(Self::name()).count(), 1);
+
+        Ok(val)
+    }
+}
+
+impl From<ContentLength> for usize {
+    fn from(ContentLength(len): ContentLength) -> Self {
+        len
+    }
+}
+
+impl From<usize> for ContentLength {
+    fn from(len: usize) -> Self {
+        ContentLength(len)
+    }
+}
+
+impl PartialEq<usize> for ContentLength {
+    fn eq(&self, other: &usize) -> bool {
+        self.0 == *other
+    }
+}
+
+impl PartialEq<ContentLength> for usize {
+    fn eq(&self, other: &ContentLength) -> bool {
+        *self == other.0
+    }
+}
+
+impl PartialOrd<usize> for ContentLength {
+    fn partial_cmp(&self, other: &usize) -> Option<std::cmp::Ordering> {
+        self.0.partial_cmp(other)
+    }
+}
+
+impl PartialOrd<ContentLength> for usize {
+    fn partial_cmp(&self, other: &ContentLength) -> Option<std::cmp::Ordering> {
+        self.partial_cmp(&other.0)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::fmt;
+
+    use super::*;
+    use crate::{test::TestRequest, HttpRequest};
+
+    fn req_from_raw_headers<H: Header, I: IntoIterator<Item = V>, V: AsRef<[u8]>>(
+        header_lines: I,
+    ) -> HttpRequest {
+        header_lines
+            .into_iter()
+            .fold(TestRequest::default(), |req, item| {
+                req.append_header((H::name(), item.as_ref().to_vec()))
+            })
+            .to_http_request()
+    }
+
+    #[track_caller]
+    pub(crate) fn assert_parse_fail<
+        H: Header + fmt::Debug,
+        I: IntoIterator<Item = V>,
+        V: AsRef<[u8]>,
+    >(
+        headers: I,
+    ) {
+        let req = req_from_raw_headers::<H, _, _>(headers);
+        H::parse(&req).unwrap_err();
+    }
+
+    #[track_caller]
+    pub(crate) fn assert_parse_eq<
+        H: Header + fmt::Debug + PartialEq,
+        I: IntoIterator<Item = V>,
+        V: AsRef<[u8]>,
+    >(
+        headers: I,
+        expect: H,
+    ) {
+        let req = req_from_raw_headers::<H, _, _>(headers);
+        assert_eq!(H::parse(&req).unwrap(), expect);
+    }
+
+    #[test]
+    fn missing_header() {
+        assert_parse_fail::<ContentLength, _, _>([""; 0]);
+        assert_parse_fail::<ContentLength, _, _>([""]);
+    }
+
+    #[test]
+    fn bad_header() {
+        assert_parse_fail::<ContentLength, _, _>(["-123"]);
+        assert_parse_fail::<ContentLength, _, _>(["123_456"]);
+        assert_parse_fail::<ContentLength, _, _>(["123.456"]);
+
+        // too large for u64 (2^64, 2^64 + 1)
+        assert_parse_fail::<ContentLength, _, _>(["18446744073709551616"]);
+        assert_parse_fail::<ContentLength, _, _>(["18446744073709551617"]);
+
+        // hex notation
+        assert_parse_fail::<ContentLength, _, _>(["0x123"]);
+
+        // multi-value
+        assert_parse_fail::<ContentLength, _, _>(["0, 123"]);
+    }
+
+    #[test]
+    #[should_panic]
+    fn bad_header_plus() {
+        // prevented by HTTP decoder anyway
+        assert_parse_fail::<ContentLength, _, _>(["+123"]);
+    }
+
+    #[test]
+    #[should_panic]
+    fn bad_multiple_value() {
+        // prevented by HTTP decoder anyway
+        assert_parse_fail::<ContentLength, _, _>(["0", "123"]);
+    }
+
+    #[test]
+    fn good_header() {
+        assert_parse_eq::<ContentLength, _, _>(["0"], ContentLength(0));
+        assert_parse_eq::<ContentLength, _, _>(["1"], ContentLength(1));
+        assert_parse_eq::<ContentLength, _, _>(["123"], ContentLength(123));
+
+        // value that looks like octal notation is not interpreted as such
+        assert_parse_eq::<ContentLength, _, _>(["0123"], ContentLength(123));
+
+        // whitespace variations
+        assert_parse_eq::<ContentLength, _, _>([" 0"], ContentLength(0));
+        assert_parse_eq::<ContentLength, _, _>(["0 "], ContentLength(0));
+        assert_parse_eq::<ContentLength, _, _>([" 0 "], ContentLength(0));
+
+        // large value (2^64 - 1)
+        assert_parse_eq::<ContentLength, _, _>(
+            ["18446744073709551615"],
+            ContentLength(18_446_744_073_709_551_615),
+        );
+    }
+
+    #[test]
+    fn equality() {
+        assert!(ContentLength(0) == ContentLength(0));
+        assert!(ContentLength(0) == 0);
+        assert!(0 != ContentLength(123));
+    }
+
+    #[test]
+    fn ordering() {
+        assert!(ContentLength(0) < ContentLength(123));
+        assert!(ContentLength(0) < 123);
+        assert!(0 < ContentLength(123));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/content_range.rs.html b/src/actix_web/http/header/content_range.rs.html new file mode 100644 index 000000000..799898f3c --- /dev/null +++ b/src/actix_web/http/header/content_range.rs.html @@ -0,0 +1,395 @@ +content_range.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::{
+    fmt::{self, Display, Write},
+    str::FromStr,
+};
+
+use super::{HeaderValue, InvalidHeaderValue, TryIntoHeaderValue, Writer, CONTENT_RANGE};
+use crate::error::ParseError;
+
+crate::http::header::common_header! {
+    /// `Content-Range` header, defined
+    /// in [RFC 7233 §4.2](https://datatracker.ietf.org/doc/html/rfc7233#section-4.2)
+    (ContentRange, CONTENT_RANGE) => [ContentRangeSpec]
+
+    test_parse_and_format {
+        crate::http::header::common_header_test!(test_bytes,
+            [b"bytes 0-499/500"],
+            Some(ContentRange(ContentRangeSpec::Bytes {
+                range: Some((0, 499)),
+                instance_length: Some(500)
+            })));
+
+        crate::http::header::common_header_test!(test_bytes_unknown_len,
+            [b"bytes 0-499/*"],
+            Some(ContentRange(ContentRangeSpec::Bytes {
+                range: Some((0, 499)),
+                instance_length: None
+            })));
+
+        crate::http::header::common_header_test!(test_bytes_unknown_range,
+            [b"bytes */500"],
+            Some(ContentRange(ContentRangeSpec::Bytes {
+                range: None,
+                instance_length: Some(500)
+            })));
+
+        crate::http::header::common_header_test!(test_unregistered,
+            [b"seconds 1-2"],
+            Some(ContentRange(ContentRangeSpec::Unregistered {
+                unit: "seconds".to_owned(),
+                resp: "1-2".to_owned()
+            })));
+
+        crate::http::header::common_header_test!(test_no_len,
+            [b"bytes 0-499"],
+            None::<ContentRange>);
+
+        crate::http::header::common_header_test!(test_only_unit,
+            [b"bytes"],
+            None::<ContentRange>);
+
+        crate::http::header::common_header_test!(test_end_less_than_start,
+            [b"bytes 499-0/500"],
+            None::<ContentRange>);
+
+        crate::http::header::common_header_test!(test_blank,
+            [b""],
+            None::<ContentRange>);
+
+        crate::http::header::common_header_test!(test_bytes_many_spaces,
+            [b"bytes 1-2/500 3"],
+            None::<ContentRange>);
+
+        crate::http::header::common_header_test!(test_bytes_many_slashes,
+            [b"bytes 1-2/500/600"],
+            None::<ContentRange>);
+
+        crate::http::header::common_header_test!(test_bytes_many_dashes,
+            [b"bytes 1-2-3/500"],
+            None::<ContentRange>);
+    }
+}
+
+/// Content-Range header, defined
+/// in [RFC 7233 §4.2](https://datatracker.ietf.org/doc/html/rfc7233#section-4.2)
+///
+/// # ABNF
+/// ```plain
+/// Content-Range       = byte-content-range
+///                     / other-content-range
+///
+/// byte-content-range  = bytes-unit SP
+///                       ( byte-range-resp / unsatisfied-range )
+///
+/// byte-range-resp     = byte-range "/" ( complete-length / "*" )
+/// byte-range          = first-byte-pos "-" last-byte-pos
+/// unsatisfied-range   = "*/" complete-length
+///
+/// complete-length     = 1*DIGIT
+///
+/// other-content-range = other-range-unit SP other-range-resp
+/// other-range-resp    = *CHAR
+/// ```
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum ContentRangeSpec {
+    /// Byte range
+    Bytes {
+        /// First and last bytes of the range, omitted if request could not be
+        /// satisfied
+        range: Option<(u64, u64)>,
+
+        /// Total length of the instance, can be omitted if unknown
+        instance_length: Option<u64>,
+    },
+
+    /// Custom range, with unit not registered at IANA
+    Unregistered {
+        /// other-range-unit
+        unit: String,
+
+        /// other-range-resp
+        resp: String,
+    },
+}
+
+impl FromStr for ContentRangeSpec {
+    type Err = ParseError;
+
+    fn from_str(s: &str) -> Result<Self, ParseError> {
+        let res = match s.split_once(' ') {
+            Some(("bytes", resp)) => {
+                let (range, instance_length) = resp.split_once('/').ok_or(ParseError::Header)?;
+
+                let instance_length = if instance_length == "*" {
+                    None
+                } else {
+                    Some(instance_length.parse().map_err(|_| ParseError::Header)?)
+                };
+
+                let range = if range == "*" {
+                    None
+                } else {
+                    let (first_byte, last_byte) =
+                        range.split_once('-').ok_or(ParseError::Header)?;
+                    let first_byte = first_byte.parse().map_err(|_| ParseError::Header)?;
+                    let last_byte = last_byte.parse().map_err(|_| ParseError::Header)?;
+                    if last_byte < first_byte {
+                        return Err(ParseError::Header);
+                    }
+                    Some((first_byte, last_byte))
+                };
+
+                ContentRangeSpec::Bytes {
+                    range,
+                    instance_length,
+                }
+            }
+            Some((unit, resp)) => ContentRangeSpec::Unregistered {
+                unit: unit.to_owned(),
+                resp: resp.to_owned(),
+            },
+            _ => return Err(ParseError::Header),
+        };
+        Ok(res)
+    }
+}
+
+impl Display for ContentRangeSpec {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match *self {
+            ContentRangeSpec::Bytes {
+                range,
+                instance_length,
+            } => {
+                f.write_str("bytes ")?;
+                match range {
+                    Some((first_byte, last_byte)) => {
+                        write!(f, "{}-{}", first_byte, last_byte)?;
+                    }
+                    None => {
+                        f.write_str("*")?;
+                    }
+                };
+                f.write_str("/")?;
+                if let Some(v) = instance_length {
+                    write!(f, "{}", v)
+                } else {
+                    f.write_str("*")
+                }
+            }
+            ContentRangeSpec::Unregistered { ref unit, ref resp } => {
+                f.write_str(unit)?;
+                f.write_str(" ")?;
+                f.write_str(resp)
+            }
+        }
+    }
+}
+
+impl TryIntoHeaderValue for ContentRangeSpec {
+    type Error = InvalidHeaderValue;
+
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        let mut writer = Writer::new();
+        let _ = write!(&mut writer, "{}", self);
+        HeaderValue::from_maybe_shared(writer.take())
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/content_type.rs.html b/src/actix_web/http/header/content_type.rs.html new file mode 100644 index 000000000..3b0ac29de --- /dev/null +++ b/src/actix_web/http/header/content_type.rs.html @@ -0,0 +1,213 @@ +content_type.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
+
use mime::Mime;
+
+use super::CONTENT_TYPE;
+
+crate::http::header::common_header! {
+    /// `Content-Type` header, defined in [RFC 9110 §8.3].
+    ///
+    /// The `Content-Type` header field indicates the media type of the associated representation:
+    /// either the representation enclosed in the message payload or the selected representation,
+    /// as determined by the message semantics. The indicated media type defines both the data
+    /// format and how that data is intended to be processed by a recipient, within the scope of the
+    /// received message semantics, after any content codings indicated by Content-Encoding are
+    /// decoded.
+    ///
+    /// Although the `mime` crate allows the mime options to be any slice, this crate forces the use
+    /// of Vec. This is to make sure the same header can't have more than 1 type. If this is an
+    /// issue, it's possible to implement `Header` on a custom struct.
+    ///
+    /// # ABNF
+    ///
+    /// ```plain
+    /// Content-Type = media-type
+    /// ```
+    ///
+    /// # Example Values
+    ///
+    /// - `text/html; charset=utf-8`
+    /// - `application/json`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use actix_web::{http::header::ContentType, HttpResponse};
+    ///
+    /// let res_json = HttpResponse::Ok()
+    ///     .insert_header(ContentType::json());
+    ///
+    /// let res_html = HttpResponse::Ok()
+    ///     .insert_header(ContentType(mime::TEXT_HTML));
+    /// ```
+    ///
+    /// [RFC 9110 §8.3]: https://datatracker.ietf.org/doc/html/rfc9110#section-8.3
+    (ContentType, CONTENT_TYPE) => [Mime]
+
+    test_parse_and_format {
+        crate::http::header::common_header_test!(
+            test_text_html,
+            [b"text/html"],
+            Some(HeaderField(mime::TEXT_HTML)));
+        crate::http::header::common_header_test!(
+            test_image_star,
+            [b"image/*"],
+            Some(HeaderField(mime::IMAGE_STAR)));
+
+    }
+}
+
+impl ContentType {
+    /// Constructs a `Content-Type: application/json` header.
+    #[inline]
+    pub fn json() -> ContentType {
+        ContentType(mime::APPLICATION_JSON)
+    }
+
+    /// Constructs a `Content-Type: text/plain; charset=utf-8` header.
+    #[inline]
+    pub fn plaintext() -> ContentType {
+        ContentType(mime::TEXT_PLAIN_UTF_8)
+    }
+
+    /// Constructs a `Content-Type: text/html; charset=utf-8` header.
+    #[inline]
+    pub fn html() -> ContentType {
+        ContentType(mime::TEXT_HTML_UTF_8)
+    }
+
+    /// Constructs a `Content-Type: text/xml` header.
+    #[inline]
+    pub fn xml() -> ContentType {
+        ContentType(mime::TEXT_XML)
+    }
+
+    /// Constructs a `Content-Type: application/www-form-url-encoded` header.
+    #[inline]
+    pub fn form_url_encoded() -> ContentType {
+        ContentType(mime::APPLICATION_WWW_FORM_URLENCODED)
+    }
+
+    /// Constructs a `Content-Type: image/jpeg` header.
+    #[inline]
+    pub fn jpeg() -> ContentType {
+        ContentType(mime::IMAGE_JPEG)
+    }
+
+    /// Constructs a `Content-Type: image/png` header.
+    #[inline]
+    pub fn png() -> ContentType {
+        ContentType(mime::IMAGE_PNG)
+    }
+
+    /// Constructs a `Content-Type: application/octet-stream` header.
+    #[inline]
+    pub fn octet_stream() -> ContentType {
+        ContentType(mime::APPLICATION_OCTET_STREAM)
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/date.rs.html b/src/actix_web/http/header/date.rs.html new file mode 100644 index 000000000..2f1396f23 --- /dev/null +++ b/src/actix_web/http/header/date.rs.html @@ -0,0 +1,89 @@ +date.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
+
use std::time::SystemTime;
+
+use super::{HttpDate, DATE};
+
+crate::http::header::common_header! {
+    /// `Date` header, defined
+    /// in [RFC 7231 §7.1.1.2](https://datatracker.ietf.org/doc/html/rfc7231#section-7.1.1.2)
+    ///
+    /// The `Date` header field represents the date and time at which the
+    /// message was originated.
+    ///
+    /// # ABNF
+    /// ```plain
+    /// Date = HTTP-date
+    /// ```
+    ///
+    /// # Example Values
+    /// * `Tue, 15 Nov 1994 08:12:31 GMT`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::time::SystemTime;
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::Date;
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     Date(SystemTime::now().into())
+    /// );
+    /// ```
+    (Date, DATE) => [HttpDate]
+
+    test_parse_and_format {
+        crate::http::header::common_header_test!(test1, [b"Tue, 15 Nov 1994 08:12:31 GMT"]);
+    }
+}
+
+impl Date {
+    /// Create a date instance set to the current system time
+    pub fn now() -> Date {
+        Date(SystemTime::now().into())
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/encoding.rs.html b/src/actix_web/http/header/encoding.rs.html new file mode 100644 index 000000000..bb6431aa7 --- /dev/null +++ b/src/actix_web/http/header/encoding.rs.html @@ -0,0 +1,111 @@ +encoding.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
+
use std::{fmt, str};
+
+use actix_http::ContentEncoding;
+
+/// A value to represent an encoding used in the `Accept-Encoding` and `Content-Encoding` header.
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub enum Encoding {
+    /// A supported content encoding. See [`ContentEncoding`] for variants.
+    Known(ContentEncoding),
+
+    /// Some other encoding that is less common, can be any string.
+    Unknown(String),
+}
+
+impl Encoding {
+    pub const fn identity() -> Self {
+        Self::Known(ContentEncoding::Identity)
+    }
+
+    pub const fn brotli() -> Self {
+        Self::Known(ContentEncoding::Brotli)
+    }
+
+    pub const fn deflate() -> Self {
+        Self::Known(ContentEncoding::Deflate)
+    }
+
+    pub const fn gzip() -> Self {
+        Self::Known(ContentEncoding::Gzip)
+    }
+
+    pub const fn zstd() -> Self {
+        Self::Known(ContentEncoding::Zstd)
+    }
+}
+
+impl fmt::Display for Encoding {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str(match self {
+            Encoding::Known(enc) => enc.as_str(),
+            Encoding::Unknown(enc) => enc.as_str(),
+        })
+    }
+}
+
+impl str::FromStr for Encoding {
+    type Err = crate::error::ParseError;
+
+    fn from_str(enc: &str) -> Result<Self, crate::error::ParseError> {
+        match enc.parse::<ContentEncoding>() {
+            Ok(enc) => Ok(Self::Known(enc)),
+            Err(_) => Ok(Self::Unknown(enc.to_owned())),
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/entity.rs.html b/src/actix_web/http/header/entity.rs.html new file mode 100644 index 000000000..cec1dc51d --- /dev/null +++ b/src/actix_web/http/header/entity.rs.html @@ -0,0 +1,565 @@ +entity.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
+
use std::{
+    fmt::{self, Display, Write},
+    str::FromStr,
+};
+
+use super::{HeaderValue, InvalidHeaderValue, TryIntoHeaderValue, Writer};
+
+/// check that each char in the slice is either:
+/// 1. `%x21`, or
+/// 2. in the range `%x23` to `%x7E`, or
+/// 3. above `%x80`
+fn entity_validate_char(c: u8) -> bool {
+    c == 0x21 || (0x23..=0x7e).contains(&c) || (c >= 0x80)
+}
+
+fn check_slice_validity(slice: &str) -> bool {
+    slice.bytes().all(entity_validate_char)
+}
+
+/// An entity tag, defined in [RFC 7232 §2.3].
+///
+/// An entity tag consists of a string enclosed by two literal double quotes.
+/// Preceding the first double quote is an optional weakness indicator,
+/// which always looks like `W/`. Examples for valid tags are `"xyzzy"` and
+/// `W/"xyzzy"`.
+///
+/// # ABNF
+/// ```plain
+/// entity-tag = [ weak ] opaque-tag
+/// weak       = %x57.2F ; "W/", case-sensitive
+/// opaque-tag = DQUOTE *etagc DQUOTE
+/// etagc      = %x21 / %x23-7E / obs-text
+///            ; VCHAR except double quotes, plus obs-text
+/// ```
+///
+/// # Comparison
+/// To check if two entity tags are equivalent in an application always use the
+/// `strong_eq` or `weak_eq` methods based on the context of the Tag. Only use
+/// `==` to check if two tags are identical.
+///
+/// The example below shows the results for a set of entity-tag pairs and
+/// both the weak and strong comparison function results:
+///
+/// | `ETag 1`| `ETag 2`| Strong Comparison | Weak Comparison |
+/// |---------|---------|-------------------|-----------------|
+/// | `W/"1"` | `W/"1"` | no match          | match           |
+/// | `W/"1"` | `W/"2"` | no match          | no match        |
+/// | `W/"1"` | `"1"`   | no match          | match           |
+/// | `"1"`   | `"1"`   | match             | match           |
+///
+/// [RFC 7232 §2.3](https://datatracker.ietf.org/doc/html/rfc7232#section-2.3)
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct EntityTag {
+    /// Weakness indicator for the tag
+    pub weak: bool,
+
+    /// The opaque string in between the DQUOTEs
+    tag: String,
+}
+
+impl EntityTag {
+    /// Constructs a new `EntityTag`.
+    ///
+    /// # Panics
+    /// If the tag contains invalid characters.
+    pub fn new(weak: bool, tag: String) -> EntityTag {
+        assert!(check_slice_validity(&tag), "Invalid tag: {:?}", tag);
+        EntityTag { weak, tag }
+    }
+
+    /// Constructs a new weak EntityTag.
+    ///
+    /// # Panics
+    /// If the tag contains invalid characters.
+    pub fn new_weak(tag: String) -> EntityTag {
+        EntityTag::new(true, tag)
+    }
+
+    #[deprecated(since = "3.0.0", note = "Renamed to `new_weak`.")]
+    pub fn weak(tag: String) -> EntityTag {
+        Self::new_weak(tag)
+    }
+
+    /// Constructs a new strong EntityTag.
+    ///
+    /// # Panics
+    /// If the tag contains invalid characters.
+    pub fn new_strong(tag: String) -> EntityTag {
+        EntityTag::new(false, tag)
+    }
+
+    #[deprecated(since = "3.0.0", note = "Renamed to `new_strong`.")]
+    pub fn strong(tag: String) -> EntityTag {
+        Self::new_strong(tag)
+    }
+
+    /// Returns tag.
+    pub fn tag(&self) -> &str {
+        self.tag.as_ref()
+    }
+
+    /// Sets tag.
+    ///
+    /// # Panics
+    /// If the tag contains invalid characters.
+    pub fn set_tag(&mut self, tag: impl Into<String>) {
+        let tag = tag.into();
+        assert!(check_slice_validity(&tag), "Invalid tag: {:?}", tag);
+        self.tag = tag
+    }
+
+    /// For strong comparison two entity-tags are equivalent if both are not weak and their
+    /// opaque-tags match character-by-character.
+    pub fn strong_eq(&self, other: &EntityTag) -> bool {
+        !self.weak && !other.weak && self.tag == other.tag
+    }
+
+    /// For weak comparison two entity-tags are equivalent if their opaque-tags match
+    /// character-by-character, regardless of either or both being tagged as "weak".
+    pub fn weak_eq(&self, other: &EntityTag) -> bool {
+        self.tag == other.tag
+    }
+
+    /// Returns the inverse of `strong_eq()`.
+    pub fn strong_ne(&self, other: &EntityTag) -> bool {
+        !self.strong_eq(other)
+    }
+
+    /// Returns inverse of `weak_eq()`.
+    pub fn weak_ne(&self, other: &EntityTag) -> bool {
+        !self.weak_eq(other)
+    }
+}
+
+impl Display for EntityTag {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        if self.weak {
+            write!(f, "W/\"{}\"", self.tag)
+        } else {
+            write!(f, "\"{}\"", self.tag)
+        }
+    }
+}
+
+impl FromStr for EntityTag {
+    type Err = crate::error::ParseError;
+
+    fn from_str(slice: &str) -> Result<EntityTag, crate::error::ParseError> {
+        let length = slice.len();
+        // Early exits if it doesn't terminate in a DQUOTE.
+        if !slice.ends_with('"') || slice.len() < 2 {
+            return Err(crate::error::ParseError::Header);
+        }
+        // The etag is weak if its first char is not a DQUOTE.
+        if slice.len() >= 2 && slice.starts_with('"') && check_slice_validity(&slice[1..length - 1])
+        {
+            // No need to check if the last char is a DQUOTE,
+            // we already did that above.
+            return Ok(EntityTag {
+                weak: false,
+                tag: slice[1..length - 1].to_owned(),
+            });
+        } else if slice.len() >= 4
+            && slice.starts_with("W/\"")
+            && check_slice_validity(&slice[3..length - 1])
+        {
+            return Ok(EntityTag {
+                weak: true,
+                tag: slice[3..length - 1].to_owned(),
+            });
+        }
+        Err(crate::error::ParseError::Header)
+    }
+}
+
+impl TryIntoHeaderValue for EntityTag {
+    type Error = InvalidHeaderValue;
+
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        let mut wrt = Writer::new();
+        write!(wrt, "{}", self).unwrap();
+        HeaderValue::from_maybe_shared(wrt.take())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::EntityTag;
+
+    #[test]
+    fn test_etag_parse_success() {
+        // Expected success
+        assert_eq!(
+            "\"foobar\"".parse::<EntityTag>().unwrap(),
+            EntityTag::new_strong("foobar".to_owned())
+        );
+        assert_eq!(
+            "\"\"".parse::<EntityTag>().unwrap(),
+            EntityTag::new_strong("".to_owned())
+        );
+        assert_eq!(
+            "W/\"weaktag\"".parse::<EntityTag>().unwrap(),
+            EntityTag::new_weak("weaktag".to_owned())
+        );
+        assert_eq!(
+            "W/\"\x65\x62\"".parse::<EntityTag>().unwrap(),
+            EntityTag::new_weak("\x65\x62".to_owned())
+        );
+        assert_eq!(
+            "W/\"\"".parse::<EntityTag>().unwrap(),
+            EntityTag::new_weak("".to_owned())
+        );
+    }
+
+    #[test]
+    fn test_etag_parse_failures() {
+        // Expected failures
+        assert!("no-dquotes".parse::<EntityTag>().is_err());
+        assert!("w/\"the-first-w-is-case-sensitive\""
+            .parse::<EntityTag>()
+            .is_err());
+        assert!("".parse::<EntityTag>().is_err());
+        assert!("\"unmatched-dquotes1".parse::<EntityTag>().is_err());
+        assert!("unmatched-dquotes2\"".parse::<EntityTag>().is_err());
+        assert!("matched-\"dquotes\"".parse::<EntityTag>().is_err());
+    }
+
+    #[test]
+    fn test_etag_fmt() {
+        assert_eq!(
+            format!("{}", EntityTag::new_strong("foobar".to_owned())),
+            "\"foobar\""
+        );
+        assert_eq!(format!("{}", EntityTag::new_strong("".to_owned())), "\"\"");
+        assert_eq!(
+            format!("{}", EntityTag::new_weak("weak-etag".to_owned())),
+            "W/\"weak-etag\""
+        );
+        assert_eq!(
+            format!("{}", EntityTag::new_weak("\u{0065}".to_owned())),
+            "W/\"\x65\""
+        );
+        assert_eq!(format!("{}", EntityTag::new_weak("".to_owned())), "W/\"\"");
+    }
+
+    #[test]
+    fn test_cmp() {
+        // | ETag 1  | ETag 2  | Strong Comparison | Weak Comparison |
+        // |---------|---------|-------------------|-----------------|
+        // | `W/"1"` | `W/"1"` | no match          | match           |
+        // | `W/"1"` | `W/"2"` | no match          | no match        |
+        // | `W/"1"` | `"1"`   | no match          | match           |
+        // | `"1"`   | `"1"`   | match             | match           |
+        let mut etag1 = EntityTag::new_weak("1".to_owned());
+        let mut etag2 = EntityTag::new_weak("1".to_owned());
+        assert!(!etag1.strong_eq(&etag2));
+        assert!(etag1.weak_eq(&etag2));
+        assert!(etag1.strong_ne(&etag2));
+        assert!(!etag1.weak_ne(&etag2));
+
+        etag1 = EntityTag::new_weak("1".to_owned());
+        etag2 = EntityTag::new_weak("2".to_owned());
+        assert!(!etag1.strong_eq(&etag2));
+        assert!(!etag1.weak_eq(&etag2));
+        assert!(etag1.strong_ne(&etag2));
+        assert!(etag1.weak_ne(&etag2));
+
+        etag1 = EntityTag::new_weak("1".to_owned());
+        etag2 = EntityTag::new_strong("1".to_owned());
+        assert!(!etag1.strong_eq(&etag2));
+        assert!(etag1.weak_eq(&etag2));
+        assert!(etag1.strong_ne(&etag2));
+        assert!(!etag1.weak_ne(&etag2));
+
+        etag1 = EntityTag::new_strong("1".to_owned());
+        etag2 = EntityTag::new_strong("1".to_owned());
+        assert!(etag1.strong_eq(&etag2));
+        assert!(etag1.weak_eq(&etag2));
+        assert!(!etag1.strong_ne(&etag2));
+        assert!(!etag1.weak_ne(&etag2));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/etag.rs.html b/src/actix_web/http/header/etag.rs.html new file mode 100644 index 000000000..74d95ae3c --- /dev/null +++ b/src/actix_web/http/header/etag.rs.html @@ -0,0 +1,197 @@ +etag.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
+
use super::{EntityTag, ETAG};
+
+crate::http::header::common_header! {
+    /// `ETag` header, defined in
+    /// [RFC 7232 §2.3](https://datatracker.ietf.org/doc/html/rfc7232#section-2.3)
+    ///
+    /// The `ETag` header field in a response provides the current entity-tag
+    /// for the selected representation, as determined at the conclusion of
+    /// handling the request.  An entity-tag is an opaque validator for
+    /// differentiating between multiple representations of the same
+    /// resource, regardless of whether those multiple representations are
+    /// due to resource state changes over time, content negotiation
+    /// resulting in multiple representations being valid at the same time,
+    /// or both.  An entity-tag consists of an opaque quoted string, possibly
+    /// prefixed by a weakness indicator.
+    ///
+    /// # ABNF
+    /// ```plain
+    /// ETag       = entity-tag
+    /// ```
+    ///
+    /// # Example Values
+    /// * `"xyzzy"`
+    /// * `W/"xyzzy"`
+    /// * `""`
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{ETag, EntityTag};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     ETag(EntityTag::new_strong("xyzzy".to_owned()))
+    /// );
+    /// ```
+    ///
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{ETag, EntityTag};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     ETag(EntityTag::new_weak("xyzzy".to_owned()))
+    /// );
+    /// ```
+    (ETag, ETAG) => [EntityTag]
+
+    test_parse_and_format {
+        // From the RFC
+        crate::http::header::common_header_test!(test1,
+            [b"\"xyzzy\""],
+            Some(ETag(EntityTag::new_strong("xyzzy".to_owned()))));
+        crate::http::header::common_header_test!(test2,
+            [b"W/\"xyzzy\""],
+            Some(ETag(EntityTag::new_weak("xyzzy".to_owned()))));
+        crate::http::header::common_header_test!(test3,
+            [b"\"\""],
+            Some(ETag(EntityTag::new_strong("".to_owned()))));
+        // Own tests
+        crate::http::header::common_header_test!(test4,
+            [b"\"foobar\""],
+            Some(ETag(EntityTag::new_strong("foobar".to_owned()))));
+        crate::http::header::common_header_test!(test5,
+            [b"\"\""],
+            Some(ETag(EntityTag::new_strong("".to_owned()))));
+        crate::http::header::common_header_test!(test6,
+            [b"W/\"weak-etag\""],
+            Some(ETag(EntityTag::new_weak("weak-etag".to_owned()))));
+        crate::http::header::common_header_test!(test7,
+            [b"W/\"\x65\x62\""],
+            Some(ETag(EntityTag::new_weak("\u{0065}\u{0062}".to_owned()))));
+        crate::http::header::common_header_test!(test8,
+            [b"W/\"\""],
+            Some(ETag(EntityTag::new_weak("".to_owned()))));
+        crate::http::header::common_header_test!(test9,
+            [b"no-dquotes"],
+            None::<ETag>);
+        crate::http::header::common_header_test!(test10,
+            [b"w/\"the-first-w-is-case-sensitive\""],
+            None::<ETag>);
+        crate::http::header::common_header_test!(test11,
+            [b""],
+            None::<ETag>);
+        crate::http::header::common_header_test!(test12,
+            [b"\"unmatched-dquotes1"],
+            None::<ETag>);
+        crate::http::header::common_header_test!(test13,
+            [b"unmatched-dquotes2\""],
+            None::<ETag>);
+        crate::http::header::common_header_test!(test14,
+            [b"matched-\"dquotes\""],
+            None::<ETag>);
+        crate::http::header::common_header_test!(test15,
+            [b"\""],
+            None::<ETag>);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/expires.rs.html b/src/actix_web/http/header/expires.rs.html new file mode 100644 index 000000000..9d1538aa2 --- /dev/null +++ b/src/actix_web/http/header/expires.rs.html @@ -0,0 +1,83 @@ +expires.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
+
use super::{HttpDate, EXPIRES};
+
+crate::http::header::common_header! {
+    /// `Expires` header, defined
+    /// in [RFC 7234 §5.3](https://datatracker.ietf.org/doc/html/rfc7234#section-5.3)
+    ///
+    /// The `Expires` header field gives the date/time after which the
+    /// response is considered stale.
+    ///
+    /// The presence of an Expires field does not imply that the original
+    /// resource will change or cease to exist at, before, or after that
+    /// time.
+    ///
+    /// # ABNF
+    /// ```plain
+    /// Expires = HTTP-date
+    /// ```
+    ///
+    /// # Example Values
+    /// * `Thu, 01 Dec 1994 16:00:00 GMT`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::time::{SystemTime, Duration};
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::Expires;
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// let expiration = SystemTime::now() + Duration::from_secs(60 * 60 * 24);
+    /// builder.insert_header(
+    ///     Expires(expiration.into())
+    /// );
+    /// ```
+    (Expires, EXPIRES) => [HttpDate]
+
+    test_parse_and_format {
+        // Test case from RFC
+        crate::http::header::common_header_test!(test1, [b"Thu, 01 Dec 1994 16:00:00 GMT"]);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/if_match.rs.html b/src/actix_web/http/header/if_match.rs.html new file mode 100644 index 000000000..a18cc6a1a --- /dev/null +++ b/src/actix_web/http/header/if_match.rs.html @@ -0,0 +1,137 @@ +if_match.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
+
use super::{common_header, EntityTag, IF_MATCH};
+
+common_header! {
+    /// `If-Match` header, defined
+    /// in [RFC 7232 §3.1](https://datatracker.ietf.org/doc/html/rfc7232#section-3.1)
+    ///
+    /// The `If-Match` header field makes the request method conditional on
+    /// the recipient origin server either having at least one current
+    /// representation of the target resource, when the field-value is "*",
+    /// or having a current representation of the target resource that has an
+    /// entity-tag matching a member of the list of entity-tags provided in
+    /// the field-value.
+    ///
+    /// An origin server MUST use the strong comparison function when
+    /// comparing entity-tags for `If-Match`, since the client
+    /// intends this precondition to prevent the method from being applied if
+    /// there have been any changes to the representation data.
+    ///
+    /// # ABNF
+    /// ```plain
+    /// If-Match = "*" / 1#entity-tag
+    /// ```
+    ///
+    /// # Example Values
+    /// * `"xyzzy"`
+    /// * "xyzzy", "r2d2xxxx", "c3piozzzz"
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::IfMatch;
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(IfMatch::Any);
+    /// ```
+    ///
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{IfMatch, EntityTag};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     IfMatch::Items(vec![
+    ///         EntityTag::new(false, "xyzzy".to_owned()),
+    ///         EntityTag::new(false, "foobar".to_owned()),
+    ///         EntityTag::new(false, "bazquux".to_owned()),
+    ///     ])
+    /// );
+    /// ```
+    (IfMatch, IF_MATCH) => {Any / (EntityTag)+}
+
+    test_parse_and_format {
+        crate::http::header::common_header_test!(
+            test1,
+            [b"\"xyzzy\""],
+            Some(HeaderField::Items(
+                vec![EntityTag::new_strong("xyzzy".to_owned())])));
+
+        crate::http::header::common_header_test!(
+            test2,
+            [b"\"xyzzy\", \"r2d2xxxx\", \"c3piozzzz\""],
+            Some(HeaderField::Items(
+                vec![EntityTag::new_strong("xyzzy".to_owned()),
+                     EntityTag::new_strong("r2d2xxxx".to_owned()),
+                     EntityTag::new_strong("c3piozzzz".to_owned())])));
+        crate::http::header::common_header_test!(test3, [b"*"], Some(IfMatch::Any));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/if_modified_since.rs.html b/src/actix_web/http/header/if_modified_since.rs.html new file mode 100644 index 000000000..2b0919442 --- /dev/null +++ b/src/actix_web/http/header/if_modified_since.rs.html @@ -0,0 +1,81 @@ +if_modified_since.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
+
use super::{HttpDate, IF_MODIFIED_SINCE};
+
+crate::http::header::common_header! {
+    /// `If-Modified-Since` header, defined
+    /// in [RFC 7232 §3.3](https://datatracker.ietf.org/doc/html/rfc7232#section-3.3)
+    ///
+    /// The `If-Modified-Since` header field makes a GET or HEAD request
+    /// method conditional on the selected representation's modification date
+    /// being more recent than the date provided in the field-value.
+    /// Transfer of the selected representation's data is avoided if that
+    /// data has not changed.
+    ///
+    /// # ABNF
+    /// ```plain
+    /// If-Unmodified-Since = HTTP-date
+    /// ```
+    ///
+    /// # Example Values
+    /// * `Sat, 29 Oct 1994 19:43:31 GMT`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::time::{SystemTime, Duration};
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::IfModifiedSince;
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// let modified = SystemTime::now() - Duration::from_secs(60 * 60 * 24);
+    /// builder.insert_header(
+    ///     IfModifiedSince(modified.into())
+    /// );
+    /// ```
+    (IfModifiedSince, IF_MODIFIED_SINCE) => [HttpDate]
+
+    test_parse_and_format {
+        // Test case from RFC
+        crate::http::header::common_header_test!(test1, [b"Sat, 29 Oct 1994 19:43:31 GMT"]);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/if_none_match.rs.html b/src/actix_web/http/header/if_none_match.rs.html new file mode 100644 index 000000000..63c90a1f5 --- /dev/null +++ b/src/actix_web/http/header/if_none_match.rs.html @@ -0,0 +1,183 @@ +if_none_match.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
+
use super::{EntityTag, IF_NONE_MATCH};
+
+crate::http::header::common_header! {
+    /// `If-None-Match` header, defined
+    /// in [RFC 7232 §3.2](https://datatracker.ietf.org/doc/html/rfc7232#section-3.2)
+    ///
+    /// The `If-None-Match` header field makes the request method conditional
+    /// on a recipient cache or origin server either not having any current
+    /// representation of the target resource, when the field-value is "*",
+    /// or having a selected representation with an entity-tag that does not
+    /// match any of those listed in the field-value.
+    ///
+    /// A recipient MUST use the weak comparison function when comparing
+    /// entity-tags for If-None-Match (Section 2.3.2), since weak entity-tags
+    /// can be used for cache validation even if there have been changes to
+    /// the representation data.
+    ///
+    /// # ABNF
+    /// ```plain
+    /// If-None-Match = "*" / 1#entity-tag
+    /// ```
+    ///
+    /// # Example Values
+    /// * `"xyzzy"`
+    /// * `W/"xyzzy"`
+    /// * `"xyzzy", "r2d2xxxx", "c3piozzzz"`
+    /// * `W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"`
+    /// * `*`
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::IfNoneMatch;
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(IfNoneMatch::Any);
+    /// ```
+    ///
+    /// ```
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::{IfNoneMatch, EntityTag};
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// builder.insert_header(
+    ///     IfNoneMatch::Items(vec![
+    ///         EntityTag::new(false, "xyzzy".to_owned()),
+    ///         EntityTag::new(false, "foobar".to_owned()),
+    ///         EntityTag::new(false, "bazquux".to_owned()),
+    ///     ])
+    /// );
+    /// ```
+    (IfNoneMatch, IF_NONE_MATCH) => {Any / (EntityTag)+}
+
+    test_parse_and_format {
+        crate::http::header::common_header_test!(test1, [b"\"xyzzy\""]);
+        crate::http::header::common_header_test!(test2, [b"W/\"xyzzy\""]);
+        crate::http::header::common_header_test!(test3, [b"\"xyzzy\", \"r2d2xxxx\", \"c3piozzzz\""]);
+        crate::http::header::common_header_test!(test4, [b"W/\"xyzzy\", W/\"r2d2xxxx\", W/\"c3piozzzz\""]);
+        crate::http::header::common_header_test!(test5, [b"*"]);
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_http::test::TestRequest;
+
+    use super::IfNoneMatch;
+    use crate::http::header::{EntityTag, Header, IF_NONE_MATCH};
+
+    #[test]
+    fn test_if_none_match() {
+        let req = TestRequest::default()
+            .insert_header((IF_NONE_MATCH, "*"))
+            .finish();
+
+        let mut if_none_match = IfNoneMatch::parse(&req);
+        assert_eq!(if_none_match.ok(), Some(IfNoneMatch::Any));
+
+        let req = TestRequest::default()
+            .insert_header((IF_NONE_MATCH, &b"\"foobar\", W/\"weak-etag\""[..]))
+            .finish();
+
+        if_none_match = Header::parse(&req);
+        let mut entities: Vec<EntityTag> = Vec::new();
+        let foobar_etag = EntityTag::new_strong("foobar".to_owned());
+        let weak_etag = EntityTag::new_weak("weak-etag".to_owned());
+        entities.push(foobar_etag);
+        entities.push(weak_etag);
+        assert_eq!(if_none_match.ok(), Some(IfNoneMatch::Items(entities)));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/if_range.rs.html b/src/actix_web/http/header/if_range.rs.html new file mode 100644 index 000000000..4eda94f8e --- /dev/null +++ b/src/actix_web/http/header/if_range.rs.html @@ -0,0 +1,235 @@ +if_range.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
+
use std::fmt::{self, Display, Write};
+
+use super::{
+    from_one_raw_str, EntityTag, Header, HeaderName, HeaderValue, HttpDate, InvalidHeaderValue,
+    TryIntoHeaderValue, Writer,
+};
+use crate::{error::ParseError, http::header, HttpMessage};
+
+/// `If-Range` header, defined
+/// in [RFC 7233 §3.2](https://datatracker.ietf.org/doc/html/rfc7233#section-3.2)
+///
+/// If a client has a partial copy of a representation and wishes to have
+/// an up-to-date copy of the entire representation, it could use the
+/// Range header field with a conditional GET (using either or both of
+/// If-Unmodified-Since and If-Match.)  However, if the precondition
+/// fails because the representation has been modified, the client would
+/// then have to make a second request to obtain the entire current
+/// representation.
+///
+/// The `If-Range` header field allows a client to \"short-circuit\" the
+/// second request.  Informally, its meaning is as follows: if the
+/// representation is unchanged, send me the part(s) that I am requesting
+/// in Range; otherwise, send me the entire representation.
+///
+/// # ABNF
+/// ```plain
+/// If-Range = entity-tag / HTTP-date
+/// ```
+///
+/// # Example Values
+///
+/// * `Sat, 29 Oct 1994 19:43:31 GMT`
+/// * `\"xyzzy\"`
+///
+/// # Examples
+/// ```
+/// use actix_web::HttpResponse;
+/// use actix_web::http::header::{EntityTag, IfRange};
+///
+/// let mut builder = HttpResponse::Ok();
+/// builder.insert_header(
+///     IfRange::EntityTag(
+///         EntityTag::new(false, "abc".to_owned())
+///     )
+/// );
+/// ```
+///
+/// ```
+/// use std::time::{Duration, SystemTime};
+/// use actix_web::{http::header::IfRange, HttpResponse};
+///
+/// let mut builder = HttpResponse::Ok();
+/// let fetched = SystemTime::now() - Duration::from_secs(60 * 60 * 24);
+/// builder.insert_header(
+///     IfRange::Date(fetched.into())
+/// );
+/// ```
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub enum IfRange {
+    /// The entity-tag the client has of the resource.
+    EntityTag(EntityTag),
+
+    /// The date when the client retrieved the resource.
+    Date(HttpDate),
+}
+
+impl Header for IfRange {
+    fn name() -> HeaderName {
+        header::IF_RANGE
+    }
+    #[inline]
+    fn parse<T>(msg: &T) -> Result<Self, ParseError>
+    where
+        T: HttpMessage,
+    {
+        let etag: Result<EntityTag, _> = from_one_raw_str(msg.headers().get(&header::IF_RANGE));
+        if let Ok(etag) = etag {
+            return Ok(IfRange::EntityTag(etag));
+        }
+        let date: Result<HttpDate, _> = from_one_raw_str(msg.headers().get(&header::IF_RANGE));
+        if let Ok(date) = date {
+            return Ok(IfRange::Date(date));
+        }
+        Err(ParseError::Header)
+    }
+}
+
+impl Display for IfRange {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match *self {
+            IfRange::EntityTag(ref x) => Display::fmt(x, f),
+            IfRange::Date(ref x) => Display::fmt(x, f),
+        }
+    }
+}
+
+impl TryIntoHeaderValue for IfRange {
+    type Error = InvalidHeaderValue;
+
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        let mut writer = Writer::new();
+        let _ = write!(&mut writer, "{}", self);
+        HeaderValue::from_maybe_shared(writer.take())
+    }
+}
+
+#[cfg(test)]
+mod test_parse_and_format {
+    use std::str;
+
+    use super::IfRange as HeaderField;
+    use crate::http::header::*;
+
+    crate::http::header::common_header_test!(test1, [b"Sat, 29 Oct 1994 19:43:31 GMT"]);
+    crate::http::header::common_header_test!(test2, [b"\"abc\""]);
+    crate::http::header::common_header_test!(test3, [b"this-is-invalid"], None::<IfRange>);
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/if_unmodified_since.rs.html b/src/actix_web/http/header/if_unmodified_since.rs.html new file mode 100644 index 000000000..e420bcfa8 --- /dev/null +++ b/src/actix_web/http/header/if_unmodified_since.rs.html @@ -0,0 +1,81 @@ +if_unmodified_since.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
+
use super::{HttpDate, IF_UNMODIFIED_SINCE};
+
+crate::http::header::common_header! {
+    /// `If-Unmodified-Since` header, defined
+    /// in [RFC 7232 §3.4](https://datatracker.ietf.org/doc/html/rfc7232#section-3.4)
+    ///
+    /// The `If-Unmodified-Since` header field makes the request method
+    /// conditional on the selected representation's last modification date
+    /// being earlier than or equal to the date provided in the field-value.
+    /// This field accomplishes the same purpose as If-Match for cases where
+    /// the user agent does not have an entity-tag for the representation.
+    ///
+    /// # ABNF
+    /// ```plain
+    /// If-Unmodified-Since = HTTP-date
+    /// ```
+    ///
+    /// # Example Values
+    /// * `Sat, 29 Oct 1994 19:43:31 GMT`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::time::{SystemTime, Duration};
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::IfUnmodifiedSince;
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// let modified = SystemTime::now() - Duration::from_secs(60 * 60 * 24);
+    /// builder.insert_header(
+    ///     IfUnmodifiedSince(modified.into())
+    /// );
+    /// ```
+    (IfUnmodifiedSince, IF_UNMODIFIED_SINCE) => [HttpDate]
+
+    test_parse_and_format {
+        // Test case from RFC
+        crate::http::header::common_header_test!(test1, [b"Sat, 29 Oct 1994 19:43:31 GMT"]);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/last_modified.rs.html b/src/actix_web/http/header/last_modified.rs.html new file mode 100644 index 000000000..24dd32959 --- /dev/null +++ b/src/actix_web/http/header/last_modified.rs.html @@ -0,0 +1,79 @@ +last_modified.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
+
use super::{HttpDate, LAST_MODIFIED};
+
+crate::http::header::common_header! {
+    /// `Last-Modified` header, defined
+    /// in [RFC 7232 §2.2](https://datatracker.ietf.org/doc/html/rfc7232#section-2.2)
+    ///
+    /// The `Last-Modified` header field in a response provides a timestamp
+    /// indicating the date and time at which the origin server believes the
+    /// selected representation was last modified, as determined at the
+    /// conclusion of handling the request.
+    ///
+    /// # ABNF
+    /// ```plain
+    /// Expires = HTTP-date
+    /// ```
+    ///
+    /// # Example Values
+    /// * `Sat, 29 Oct 1994 19:43:31 GMT`
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::time::{SystemTime, Duration};
+    /// use actix_web::HttpResponse;
+    /// use actix_web::http::header::LastModified;
+    ///
+    /// let mut builder = HttpResponse::Ok();
+    /// let modified = SystemTime::now() - Duration::from_secs(60 * 60 * 24);
+    /// builder.insert_header(
+    ///     LastModified(modified.into())
+    /// );
+    /// ```
+    (LastModified, LAST_MODIFIED) => [HttpDate]
+
+    test_parse_and_format {
+        // Test case from RFC
+        crate::http::header::common_header_test!(test1, [b"Sat, 29 Oct 1994 19:43:31 GMT"]);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/macros.rs.html b/src/actix_web/http/header/macros.rs.html new file mode 100644 index 000000000..c1428935e --- /dev/null +++ b/src/actix_web/http/header/macros.rs.html @@ -0,0 +1,641 @@ +macros.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
+
macro_rules! common_header_test_module {
+    ($id:ident, $tm:ident{$($tf:item)*}) => {
+        #[cfg(test)]
+        mod $tm {
+            #![allow(unused_imports)]
+
+            use ::core::str;
+
+            use ::actix_http::{Method, test};
+            use ::mime::*;
+
+            use $crate::http::header::{self, *};
+            use super::{$id as HeaderField, *};
+
+            $($tf)*
+        }
+    }
+}
+
+#[cfg(test)]
+macro_rules! common_header_test {
+    ($id:ident, $raw:expr) => {
+        #[test]
+        fn $id() {
+            use ::actix_http::test;
+
+            let raw = $raw;
+            let headers = raw.iter().map(|x| x.to_vec()).collect::<Vec<_>>();
+
+            let mut req = test::TestRequest::default();
+
+            for item in headers {
+                req = req.append_header((HeaderField::name(), item)).take();
+            }
+
+            let req = req.finish();
+            let value = HeaderField::parse(&req);
+
+            let result = format!("{}", value.unwrap());
+            let expected = ::std::string::String::from_utf8(raw[0].to_vec()).unwrap();
+
+            let result_cmp: Vec<String> = result
+                .to_ascii_lowercase()
+                .split(' ')
+                .map(|x| x.to_owned())
+                .collect();
+            let expected_cmp: Vec<String> = expected
+                .to_ascii_lowercase()
+                .split(' ')
+                .map(|x| x.to_owned())
+                .collect();
+
+            assert_eq!(result_cmp.concat(), expected_cmp.concat());
+        }
+    };
+
+    ($id:ident, $raw:expr, $exp:expr) => {
+        #[test]
+        fn $id() {
+            use actix_http::test;
+
+            let headers = $raw.iter().map(|x| x.to_vec()).collect::<Vec<_>>();
+            let mut req = test::TestRequest::default();
+
+            for item in headers {
+                req.append_header((HeaderField::name(), item));
+            }
+
+            let req = req.finish();
+            let val = HeaderField::parse(&req);
+
+            let exp: ::core::option::Option<HeaderField> = $exp;
+
+            // test parsing
+            assert_eq!(val.ok(), exp);
+
+            // test formatting
+            if let Some(exp) = exp {
+                let raw = &($raw)[..];
+                let mut iter = raw.iter().map(|b| str::from_utf8(&b[..]).unwrap());
+                let mut joined = String::new();
+                if let Some(s) = iter.next() {
+                    joined.push_str(s);
+                    for s in iter {
+                        joined.push_str(", ");
+                        joined.push_str(s);
+                    }
+                }
+                assert_eq!(format!("{}", exp), joined);
+            }
+        }
+    };
+}
+
+macro_rules! common_header {
+    // TODO: these docs are wrong, there's no $n or $nn
+    // $attrs:meta: Attributes associated with the header item (usually docs)
+    // $id:ident: Identifier of the header
+    // $n:expr: Lowercase name of the header
+    // $nn:expr: Nice name of the header
+
+    // List header, zero or more items
+    ($(#[$attrs:meta])*($id:ident, $name:expr) => ($item:ty)*) => {
+        $(#[$attrs])*
+        #[derive(Debug, Clone, PartialEq, Eq, ::derive_more::Deref, ::derive_more::DerefMut)]
+        pub struct $id(pub Vec<$item>);
+
+        impl $crate::http::header::Header for $id {
+            #[inline]
+            fn name() -> $crate::http::header::HeaderName {
+                $name
+            }
+
+            #[inline]
+            fn parse<M: $crate::HttpMessage>(msg: &M) -> Result<Self, $crate::error::ParseError> {
+                let headers = msg.headers().get_all(Self::name());
+                $crate::http::header::from_comma_delimited(headers).map($id)
+            }
+        }
+
+        impl ::core::fmt::Display for $id {
+            #[inline]
+            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
+                $crate::http::header::fmt_comma_delimited(f, &self.0[..])
+            }
+        }
+
+        impl $crate::http::header::TryIntoHeaderValue for $id {
+            type Error = $crate::http::header::InvalidHeaderValue;
+
+            #[inline]
+            fn try_into_value(self) -> Result<$crate::http::header::HeaderValue, Self::Error> {
+                use ::core::fmt::Write;
+                let mut writer = $crate::http::header::Writer::new();
+                let _ = write!(&mut writer, "{}", self);
+                $crate::http::header::HeaderValue::from_maybe_shared(writer.take())
+            }
+        }
+    };
+
+    // List header, one or more items
+    ($(#[$attrs:meta])*($id:ident, $name:expr) => ($item:ty)+) => {
+        $(#[$attrs])*
+        #[derive(Debug, Clone, PartialEq, Eq, ::derive_more::Deref, ::derive_more::DerefMut)]
+        pub struct $id(pub Vec<$item>);
+
+        impl $crate::http::header::Header for $id {
+            #[inline]
+            fn name() -> $crate::http::header::HeaderName {
+                $name
+            }
+
+            #[inline]
+            fn parse<M: $crate::HttpMessage>(msg: &M) -> Result<Self, $crate::error::ParseError>{
+                let headers = msg.headers().get_all(Self::name());
+
+                $crate::http::header::from_comma_delimited(headers)
+                    .and_then(|items| {
+                        if items.is_empty() {
+                            Err($crate::error::ParseError::Header)
+                        } else {
+                            Ok($id(items))
+                        }
+                    })
+            }
+        }
+
+        impl ::core::fmt::Display for $id {
+            #[inline]
+            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
+                $crate::http::header::fmt_comma_delimited(f, &self.0[..])
+            }
+        }
+
+        impl $crate::http::header::TryIntoHeaderValue for $id {
+            type Error = $crate::http::header::InvalidHeaderValue;
+
+            #[inline]
+            fn try_into_value(self) -> Result<$crate::http::header::HeaderValue, Self::Error> {
+                use ::core::fmt::Write;
+                let mut writer = $crate::http::header::Writer::new();
+                let _ = write!(&mut writer, "{}", self);
+                $crate::http::header::HeaderValue::from_maybe_shared(writer.take())
+            }
+        }
+    };
+
+    // Single value header
+    ($(#[$attrs:meta])*($id:ident, $name:expr) => [$value:ty]) => {
+        $(#[$attrs])*
+        #[derive(Debug, Clone, PartialEq, Eq, ::derive_more::Deref, ::derive_more::DerefMut)]
+        pub struct $id(pub $value);
+
+        impl $crate::http::header::Header for $id {
+            #[inline]
+            fn name() -> $crate::http::header::HeaderName {
+                $name
+            }
+
+            #[inline]
+            fn parse<M: $crate::HttpMessage>(msg: &M) -> Result<Self, $crate::error::ParseError> {
+                let header = msg.headers().get(Self::name());
+                $crate::http::header::from_one_raw_str(header).map($id)
+            }
+        }
+
+        impl ::core::fmt::Display for $id {
+            #[inline]
+            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
+                ::core::fmt::Display::fmt(&self.0, f)
+            }
+        }
+
+        impl $crate::http::header::TryIntoHeaderValue for $id {
+            type Error = $crate::http::header::InvalidHeaderValue;
+
+            #[inline]
+            fn try_into_value(self) -> Result<$crate::http::header::HeaderValue, Self::Error> {
+                self.0.try_into_value()
+            }
+        }
+    };
+
+    // List header, one or more items with "*" option
+    ($(#[$attrs:meta])*($id:ident, $name:expr) => {Any / ($item:ty)+}) => {
+        $(#[$attrs])*
+        #[derive(Clone, Debug, PartialEq, Eq)]
+        pub enum $id {
+            /// Any value is a match
+            Any,
+
+            /// Only the listed items are a match
+            Items(Vec<$item>),
+        }
+
+        impl $crate::http::header::Header for $id {
+            #[inline]
+            fn name() -> $crate::http::header::HeaderName {
+                $name
+            }
+
+            #[inline]
+            fn parse<M: $crate::HttpMessage>(msg: &M) -> Result<Self, $crate::error::ParseError> {
+                let is_any = msg
+                    .headers()
+                    .get(Self::name())
+                    .and_then(|hdr| hdr.to_str().ok())
+                    .map(|hdr| hdr.trim() == "*");
+
+                if let Some(true) = is_any {
+                    Ok($id::Any)
+                } else {
+                    let headers = msg.headers().get_all(Self::name());
+                    Ok($id::Items($crate::http::header::from_comma_delimited(headers)?))
+                }
+            }
+        }
+
+        impl ::core::fmt::Display for $id {
+            #[inline]
+            fn fmt(&self, f: &mut ::core::fmt::Formatter<'_>) -> ::core::fmt::Result {
+                match *self {
+                    $id::Any => f.write_str("*"),
+                    $id::Items(ref fields) =>
+                        $crate::http::header::fmt_comma_delimited(f, &fields[..])
+                }
+            }
+        }
+
+        impl $crate::http::header::TryIntoHeaderValue for $id {
+            type Error = $crate::http::header::InvalidHeaderValue;
+
+            #[inline]
+            fn try_into_value(self) -> Result<$crate::http::header::HeaderValue, Self::Error> {
+                use ::core::fmt::Write;
+                let mut writer = $crate::http::header::Writer::new();
+                let _ = write!(&mut writer, "{}", self);
+                $crate::http::header::HeaderValue::from_maybe_shared(writer.take())
+            }
+        }
+    };
+
+    // optional test module
+    ($(#[$attrs:meta])*($id:ident, $name:expr) => ($item:ty)* $tm:ident{$($tf:item)*}) => {
+        crate::http::header::common_header! {
+            $(#[$attrs])*
+            ($id, $name) => ($item)*
+        }
+
+        crate::http::header::common_header_test_module! { $id, $tm { $($tf)* }}
+    };
+    ($(#[$attrs:meta])*($id:ident, $n:expr) => ($item:ty)+ $tm:ident{$($tf:item)*}) => {
+        crate::http::header::common_header! {
+            $(#[$attrs])*
+            ($id, $n) => ($item)+
+        }
+
+        crate::http::header::common_header_test_module! { $id, $tm { $($tf)* }}
+    };
+    ($(#[$attrs:meta])*($id:ident, $name:expr) => [$item:ty] $tm:ident{$($tf:item)*}) => {
+        crate::http::header::common_header! {
+            $(#[$attrs])* ($id, $name) => [$item]
+        }
+
+        crate::http::header::common_header_test_module! { $id, $tm { $($tf)* }}
+    };
+    ($(#[$attrs:meta])*($id:ident, $name:expr) => {Any / ($item:ty)+} $tm:ident{$($tf:item)*}) => {
+        crate::http::header::common_header! {
+            $(#[$attrs])*
+            ($id, $name) => {Any / ($item)+}
+        }
+
+        crate::http::header::common_header_test_module! { $id, $tm { $($tf)* }}
+    };
+}
+
+pub(crate) use common_header;
+#[cfg(test)]
+pub(crate) use common_header_test;
+pub(crate) use common_header_test_module;
+
\ No newline at end of file diff --git a/src/actix_web/http/header/mod.rs.html b/src/actix_web/http/header/mod.rs.html new file mode 100644 index 000000000..006c911a0 --- /dev/null +++ b/src/actix_web/http/header/mod.rs.html @@ -0,0 +1,209 @@ +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
+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
+
//! A Collection of Header implementations for common HTTP Headers.
+//!
+//! ## Mime Types
+//! Several header fields use MIME values for their contents. Keeping with the strongly-typed theme,
+//! the [mime] crate is used in such headers as [`ContentType`] and [`Accept`].
+
+use std::fmt;
+
+// re-export from actix-http
+// - header name / value types
+// - relevant traits for converting to header name / value
+// - all const header names
+// - header map
+// - the few typed headers from actix-http
+// - header parsing utils
+pub use actix_http::header::*;
+use bytes::{Bytes, BytesMut};
+
+mod accept;
+mod accept_charset;
+mod accept_encoding;
+mod accept_language;
+mod allow;
+mod cache_control;
+mod content_disposition;
+mod content_language;
+mod content_length;
+mod content_range;
+mod content_type;
+mod date;
+mod encoding;
+mod entity;
+mod etag;
+mod expires;
+mod if_match;
+mod if_modified_since;
+mod if_none_match;
+mod if_range;
+mod if_unmodified_since;
+mod last_modified;
+mod macros;
+mod preference;
+mod range;
+
+#[cfg(test)]
+pub(crate) use self::macros::common_header_test;
+pub(crate) use self::macros::{common_header, common_header_test_module};
+pub use self::{
+    accept::Accept,
+    accept_charset::AcceptCharset,
+    accept_encoding::AcceptEncoding,
+    accept_language::AcceptLanguage,
+    allow::Allow,
+    cache_control::{CacheControl, CacheDirective},
+    content_disposition::{ContentDisposition, DispositionParam, DispositionType},
+    content_language::ContentLanguage,
+    content_length::ContentLength,
+    content_range::{ContentRange, ContentRangeSpec},
+    content_type::ContentType,
+    date::Date,
+    encoding::Encoding,
+    entity::EntityTag,
+    etag::ETag,
+    expires::Expires,
+    if_match::IfMatch,
+    if_modified_since::IfModifiedSince,
+    if_none_match::IfNoneMatch,
+    if_range::IfRange,
+    if_unmodified_since::IfUnmodifiedSince,
+    last_modified::LastModified,
+    preference::Preference,
+    range::{ByteRangeSpec, Range},
+};
+
+/// Format writer ([`fmt::Write`]) for a [`BytesMut`].
+#[derive(Debug, Default)]
+struct Writer {
+    buf: BytesMut,
+}
+
+impl Writer {
+    /// Constructs new bytes writer.
+    pub fn new() -> Writer {
+        Writer::default()
+    }
+
+    /// Splits bytes out of writer, leaving writer buffer empty.
+    pub fn take(&mut self) -> Bytes {
+        self.buf.split().freeze()
+    }
+}
+
+impl fmt::Write for Writer {
+    #[inline]
+    fn write_str(&mut self, s: &str) -> fmt::Result {
+        self.buf.extend_from_slice(s.as_bytes());
+        Ok(())
+    }
+
+    #[inline]
+    fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result {
+        fmt::write(self, args)
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/preference.rs.html b/src/actix_web/http/header/preference.rs.html new file mode 100644 index 000000000..2fcd2072a --- /dev/null +++ b/src/actix_web/http/header/preference.rs.html @@ -0,0 +1,141 @@ +preference.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
+
use std::{
+    fmt::{self, Write as _},
+    str,
+};
+
+/// A wrapper for types used in header values where wildcard (`*`) items are allowed but the
+/// underlying type does not support them.
+///
+/// For example, we use the `language-tags` crate for the [`AcceptLanguage`](super::AcceptLanguage)
+/// typed header but it does not parse `*` successfully. On the other hand, the `mime` crate, used
+/// for [`Accept`](super::Accept), has first-party support for wildcard items so this wrapper is not
+/// used in those header types.
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Hash)]
+pub enum Preference<T> {
+    /// A wildcard value.
+    Any,
+
+    /// A valid `T`.
+    Specific(T),
+}
+
+impl<T> Preference<T> {
+    /// Returns true if preference is the any/wildcard (`*`) value.
+    pub fn is_any(&self) -> bool {
+        matches!(self, Self::Any)
+    }
+
+    /// Returns true if preference is the specific item (`T`) variant.
+    pub fn is_specific(&self) -> bool {
+        matches!(self, Self::Specific(_))
+    }
+
+    /// Returns reference to value in `Specific` variant, if it is set.
+    pub fn item(&self) -> Option<&T> {
+        match self {
+            Preference::Specific(ref item) => Some(item),
+            Preference::Any => None,
+        }
+    }
+
+    /// Consumes the container, returning the value in the `Specific` variant, if it is set.
+    pub fn into_item(self) -> Option<T> {
+        match self {
+            Preference::Specific(item) => Some(item),
+            Preference::Any => None,
+        }
+    }
+}
+
+impl<T: fmt::Display> fmt::Display for Preference<T> {
+    #[inline]
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Preference::Any => f.write_char('*'),
+            Preference::Specific(item) => fmt::Display::fmt(item, f),
+        }
+    }
+}
+
+impl<T: str::FromStr> str::FromStr for Preference<T> {
+    type Err = T::Err;
+
+    #[inline]
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        match s.trim() {
+            "*" => Ok(Self::Any),
+            other => other.parse().map(Preference::Specific),
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/header/range.rs.html b/src/actix_web/http/header/range.rs.html new file mode 100644 index 000000000..4df7e77a7 --- /dev/null +++ b/src/actix_web/http/header/range.rs.html @@ -0,0 +1,855 @@ +range.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
+
use std::{
+    cmp,
+    fmt::{self, Display, Write},
+    str::FromStr,
+};
+
+use actix_http::{error::ParseError, header, HttpMessage};
+
+use super::{Header, HeaderName, HeaderValue, InvalidHeaderValue, TryIntoHeaderValue, Writer};
+
+/// `Range` header, defined
+/// in [RFC 7233 §3.1](https://datatracker.ietf.org/doc/html/rfc7233#section-3.1)
+///
+/// The "Range" header field on a GET request modifies the method semantics to request transfer of
+/// only one or more sub-ranges of the selected representation data, rather than the entire selected
+/// representation data.
+///
+/// # ABNF
+/// ```plain
+/// Range = byte-ranges-specifier / other-ranges-specifier
+/// other-ranges-specifier = other-range-unit "=" other-range-set
+/// other-range-set = 1*VCHAR
+///
+/// bytes-unit = "bytes"
+///
+/// byte-ranges-specifier = bytes-unit "=" byte-range-set
+/// byte-range-set = 1#(byte-range-spec / suffix-byte-range-spec)
+/// byte-range-spec = first-byte-pos "-" [last-byte-pos]
+/// suffix-byte-range-spec = "-" suffix-length
+/// suffix-length = 1*DIGIT
+/// first-byte-pos = 1*DIGIT
+/// last-byte-pos = 1*DIGIT
+/// ```
+///
+/// # Example Values
+/// * `bytes=1000-`
+/// * `bytes=-50`
+/// * `bytes=0-1,30-40`
+/// * `bytes=0-10,20-90,-100`
+/// * `custom_unit=0-123`
+/// * `custom_unit=xxx-yyy`
+///
+/// # Examples
+/// ```
+/// use actix_web::http::header::{Range, ByteRangeSpec};
+/// use actix_web::HttpResponse;
+///
+/// let mut builder = HttpResponse::Ok();
+/// builder.insert_header(Range::Bytes(
+///     vec![ByteRangeSpec::FromTo(1, 100), ByteRangeSpec::From(200)]
+/// ));
+/// builder.insert_header(Range::Unregistered("letters".to_owned(), "a-f".to_owned()));
+/// builder.insert_header(Range::bytes(1, 100));
+/// builder.insert_header(Range::bytes_multi(vec![(1, 100), (200, 300)]));
+/// ```
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum Range {
+    /// Byte range.
+    Bytes(Vec<ByteRangeSpec>),
+
+    /// Custom range, with unit not registered at IANA.
+    ///
+    /// (`other-range-unit`: String , `other-range-set`: String)
+    Unregistered(String, String),
+}
+
+/// A range of bytes to fetch.
+///
+/// Each [`Range::Bytes`] header can contain one or more `ByteRangeSpec`s.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum ByteRangeSpec {
+    /// All bytes from `x` to `y`, inclusive.
+    ///
+    /// Serialized as `x-y`.
+    ///
+    /// Example: `bytes=500-999` would represent the second 500 bytes.
+    FromTo(u64, u64),
+
+    /// All bytes starting from `x`, inclusive.
+    ///
+    /// Serialized as `x-`.
+    ///
+    /// Example: For a file of 1000 bytes, `bytes=950-` would represent bytes 950-999, inclusive.
+    From(u64),
+
+    /// The last `y` bytes, inclusive.
+    ///
+    /// Using the spec terminology, this is `suffix-byte-range-spec`. Serialized as `-y`.
+    ///
+    /// Example: For a file of 1000 bytes, `bytes=-50` is equivalent to `bytes=950-`.
+    Last(u64),
+}
+
+impl ByteRangeSpec {
+    /// Given the full length of the entity, attempt to normalize the byte range into an satisfiable
+    /// end-inclusive `(from, to)` range.
+    ///
+    /// The resulting range is guaranteed to be a satisfiable range within the bounds
+    /// of `0 <= from <= to < full_length`.
+    ///
+    /// If the byte range is deemed unsatisfiable, `None` is returned. An unsatisfiable range is
+    /// generally cause for a server to either reject the client request with a
+    /// `416 Range Not Satisfiable` status code, or to simply ignore the range header and serve the
+    /// full entity using a `200 OK` status code.
+    ///
+    /// This function closely follows [RFC 7233 §2.1]. As such, it considers ranges to be
+    /// satisfiable if they meet the following conditions:
+    ///
+    /// > If a valid byte-range-set includes at least one byte-range-spec with a first-byte-pos that
+    /// is less than the current length of the representation, or at least one
+    /// suffix-byte-range-spec with a non-zero suffix-length, then the byte-range-set
+    /// is satisfiable. Otherwise, the byte-range-set is unsatisfiable.
+    ///
+    /// The function also computes remainder ranges based on the RFC:
+    ///
+    /// > If the last-byte-pos value is absent, or if the value is greater than or equal to the
+    /// current length of the representation data, the byte range is interpreted as the remainder
+    /// of the representation (i.e., the server replaces the value of last-byte-pos with a value
+    /// that is one less than the current length of the selected representation).
+    ///
+    /// [RFC 7233 §2.1]: https://datatracker.ietf.org/doc/html/rfc7233
+    pub fn to_satisfiable_range(&self, full_length: u64) -> Option<(u64, u64)> {
+        // If the full length is zero, there is no satisfiable end-inclusive range.
+        if full_length == 0 {
+            return None;
+        }
+
+        match *self {
+            ByteRangeSpec::FromTo(from, to) => {
+                if from < full_length && from <= to {
+                    Some((from, cmp::min(to, full_length - 1)))
+                } else {
+                    None
+                }
+            }
+
+            ByteRangeSpec::From(from) => {
+                if from < full_length {
+                    Some((from, full_length - 1))
+                } else {
+                    None
+                }
+            }
+
+            ByteRangeSpec::Last(last) => {
+                if last > 0 {
+                    // From the RFC: If the selected representation is shorter than the specified
+                    // suffix-length, the entire representation is used.
+                    if last > full_length {
+                        Some((0, full_length - 1))
+                    } else {
+                        Some((full_length - last, full_length - 1))
+                    }
+                } else {
+                    None
+                }
+            }
+        }
+    }
+}
+
+impl Range {
+    /// Constructs a common byte range header.
+    ///
+    /// Eg: `bytes=from-to`
+    pub fn bytes(from: u64, to: u64) -> Range {
+        Range::Bytes(vec![ByteRangeSpec::FromTo(from, to)])
+    }
+
+    /// Constructs a byte range header with multiple subranges.
+    ///
+    /// Eg: `bytes=from1-to1,from2-to2,fromX-toX`
+    pub fn bytes_multi(ranges: Vec<(u64, u64)>) -> Range {
+        Range::Bytes(
+            ranges
+                .into_iter()
+                .map(|(from, to)| ByteRangeSpec::FromTo(from, to))
+                .collect(),
+        )
+    }
+}
+
+impl fmt::Display for ByteRangeSpec {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match *self {
+            ByteRangeSpec::FromTo(from, to) => write!(f, "{}-{}", from, to),
+            ByteRangeSpec::Last(pos) => write!(f, "-{}", pos),
+            ByteRangeSpec::From(pos) => write!(f, "{}-", pos),
+        }
+    }
+}
+
+impl fmt::Display for Range {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Range::Bytes(ranges) => {
+                write!(f, "bytes=")?;
+
+                for (i, range) in ranges.iter().enumerate() {
+                    if i != 0 {
+                        f.write_str(",")?;
+                    }
+
+                    Display::fmt(range, f)?;
+                }
+                Ok(())
+            }
+
+            Range::Unregistered(unit, range_str) => {
+                write!(f, "{}={}", unit, range_str)
+            }
+        }
+    }
+}
+
+impl FromStr for Range {
+    type Err = ParseError;
+
+    fn from_str(s: &str) -> Result<Range, ParseError> {
+        let (unit, val) = s.split_once('=').ok_or(ParseError::Header)?;
+
+        match (unit, val) {
+            ("bytes", ranges) => {
+                let ranges = from_comma_delimited(ranges);
+
+                if ranges.is_empty() {
+                    return Err(ParseError::Header);
+                }
+
+                Ok(Range::Bytes(ranges))
+            }
+
+            (_, "") => Err(ParseError::Header),
+            ("", _) => Err(ParseError::Header),
+
+            (unit, range_str) => Ok(Range::Unregistered(unit.to_owned(), range_str.to_owned())),
+        }
+    }
+}
+
+impl FromStr for ByteRangeSpec {
+    type Err = ParseError;
+
+    fn from_str(s: &str) -> Result<ByteRangeSpec, ParseError> {
+        let (start, end) = s.split_once('-').ok_or(ParseError::Header)?;
+
+        match (start, end) {
+            ("", end) => end
+                .parse()
+                .or(Err(ParseError::Header))
+                .map(ByteRangeSpec::Last),
+
+            (start, "") => start
+                .parse()
+                .or(Err(ParseError::Header))
+                .map(ByteRangeSpec::From),
+
+            (start, end) => match (start.parse(), end.parse()) {
+                (Ok(start), Ok(end)) if start <= end => Ok(ByteRangeSpec::FromTo(start, end)),
+                _ => Err(ParseError::Header),
+            },
+        }
+    }
+}
+
+impl Header for Range {
+    fn name() -> HeaderName {
+        header::RANGE
+    }
+
+    #[inline]
+    fn parse<T: HttpMessage>(msg: &T) -> Result<Self, ParseError> {
+        header::from_one_raw_str(msg.headers().get(&Self::name()))
+    }
+}
+
+impl TryIntoHeaderValue for Range {
+    type Error = InvalidHeaderValue;
+
+    fn try_into_value(self) -> Result<HeaderValue, Self::Error> {
+        let mut wrt = Writer::new();
+        let _ = write!(wrt, "{}", self);
+        HeaderValue::from_maybe_shared(wrt.take())
+    }
+}
+
+/// Parses 0 or more items out of a comma delimited string, ignoring invalid items.
+fn from_comma_delimited<T: FromStr>(s: &str) -> Vec<T> {
+    s.split(',')
+        .filter_map(|x| match x.trim() {
+            "" => None,
+            y => Some(y),
+        })
+        .filter_map(|x| x.parse().ok())
+        .collect()
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_http::{test::TestRequest, Request};
+
+    use super::*;
+
+    fn req(s: &str) -> Request {
+        TestRequest::default()
+            .insert_header((header::RANGE, s))
+            .finish()
+    }
+
+    #[test]
+    fn test_parse_bytes_range_valid() {
+        let r: Range = Header::parse(&req("bytes=1-100")).unwrap();
+        let r2: Range = Header::parse(&req("bytes=1-100,-")).unwrap();
+        let r3 = Range::bytes(1, 100);
+        assert_eq!(r, r2);
+        assert_eq!(r2, r3);
+
+        let r: Range = Header::parse(&req("bytes=1-100,200-")).unwrap();
+        let r2: Range = Header::parse(&req("bytes= 1-100 , 101-xxx,  200- ")).unwrap();
+        let r3 = Range::Bytes(vec![
+            ByteRangeSpec::FromTo(1, 100),
+            ByteRangeSpec::From(200),
+        ]);
+        assert_eq!(r, r2);
+        assert_eq!(r2, r3);
+
+        let r: Range = Header::parse(&req("bytes=1-100,-100")).unwrap();
+        let r2: Range = Header::parse(&req("bytes=1-100, ,,-100")).unwrap();
+        let r3 = Range::Bytes(vec![
+            ByteRangeSpec::FromTo(1, 100),
+            ByteRangeSpec::Last(100),
+        ]);
+        assert_eq!(r, r2);
+        assert_eq!(r2, r3);
+
+        let r: Range = Header::parse(&req("custom=1-100,-100")).unwrap();
+        let r2 = Range::Unregistered("custom".to_owned(), "1-100,-100".to_owned());
+        assert_eq!(r, r2);
+    }
+
+    #[test]
+    fn test_parse_unregistered_range_valid() {
+        let r: Range = Header::parse(&req("custom=1-100,-100")).unwrap();
+        let r2 = Range::Unregistered("custom".to_owned(), "1-100,-100".to_owned());
+        assert_eq!(r, r2);
+
+        let r: Range = Header::parse(&req("custom=abcd")).unwrap();
+        let r2 = Range::Unregistered("custom".to_owned(), "abcd".to_owned());
+        assert_eq!(r, r2);
+
+        let r: Range = Header::parse(&req("custom=xxx-yyy")).unwrap();
+        let r2 = Range::Unregistered("custom".to_owned(), "xxx-yyy".to_owned());
+        assert_eq!(r, r2);
+    }
+
+    #[test]
+    fn test_parse_invalid() {
+        let r: Result<Range, ParseError> = Header::parse(&req("bytes=1-a,-"));
+        assert_eq!(r.ok(), None);
+
+        let r: Result<Range, ParseError> = Header::parse(&req("bytes=1-2-3"));
+        assert_eq!(r.ok(), None);
+
+        let r: Result<Range, ParseError> = Header::parse(&req("abc"));
+        assert_eq!(r.ok(), None);
+
+        let r: Result<Range, ParseError> = Header::parse(&req("bytes=1-100="));
+        assert_eq!(r.ok(), None);
+
+        let r: Result<Range, ParseError> = Header::parse(&req("bytes="));
+        assert_eq!(r.ok(), None);
+
+        let r: Result<Range, ParseError> = Header::parse(&req("custom="));
+        assert_eq!(r.ok(), None);
+
+        let r: Result<Range, ParseError> = Header::parse(&req("=1-100"));
+        assert_eq!(r.ok(), None);
+    }
+
+    #[test]
+    fn test_fmt() {
+        let range = Range::Bytes(vec![
+            ByteRangeSpec::FromTo(0, 1000),
+            ByteRangeSpec::From(2000),
+        ]);
+        assert_eq!(&range.to_string(), "bytes=0-1000,2000-");
+
+        let range = Range::Bytes(vec![]);
+
+        assert_eq!(&range.to_string(), "bytes=");
+
+        let range = Range::Unregistered("custom".to_owned(), "1-xxx".to_owned());
+
+        assert_eq!(&range.to_string(), "custom=1-xxx");
+    }
+
+    #[test]
+    fn test_byte_range_spec_to_satisfiable_range() {
+        assert_eq!(
+            Some((0, 0)),
+            ByteRangeSpec::FromTo(0, 0).to_satisfiable_range(3)
+        );
+        assert_eq!(
+            Some((1, 2)),
+            ByteRangeSpec::FromTo(1, 2).to_satisfiable_range(3)
+        );
+        assert_eq!(
+            Some((1, 2)),
+            ByteRangeSpec::FromTo(1, 5).to_satisfiable_range(3)
+        );
+        assert_eq!(None, ByteRangeSpec::FromTo(3, 3).to_satisfiable_range(3));
+        assert_eq!(None, ByteRangeSpec::FromTo(2, 1).to_satisfiable_range(3));
+        assert_eq!(None, ByteRangeSpec::FromTo(0, 0).to_satisfiable_range(0));
+
+        assert_eq!(Some((0, 2)), ByteRangeSpec::From(0).to_satisfiable_range(3));
+        assert_eq!(Some((2, 2)), ByteRangeSpec::From(2).to_satisfiable_range(3));
+        assert_eq!(None, ByteRangeSpec::From(3).to_satisfiable_range(3));
+        assert_eq!(None, ByteRangeSpec::From(5).to_satisfiable_range(3));
+        assert_eq!(None, ByteRangeSpec::From(0).to_satisfiable_range(0));
+
+        assert_eq!(Some((1, 2)), ByteRangeSpec::Last(2).to_satisfiable_range(3));
+        assert_eq!(Some((2, 2)), ByteRangeSpec::Last(1).to_satisfiable_range(3));
+        assert_eq!(Some((0, 2)), ByteRangeSpec::Last(5).to_satisfiable_range(3));
+        assert_eq!(None, ByteRangeSpec::Last(0).to_satisfiable_range(3));
+        assert_eq!(None, ByteRangeSpec::Last(2).to_satisfiable_range(0));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/http/mod.rs.html b/src/actix_web/http/mod.rs.html new file mode 100644 index 000000000..829af9b28 --- /dev/null +++ b/src/actix_web/http/mod.rs.html @@ -0,0 +1,11 @@ +mod.rs - source
1
+2
+3
+4
+5
+
//! Various HTTP related types.
+
+pub mod header;
+
+pub use actix_http::{uri, ConnectionType, Error, KeepAlive, Method, StatusCode, Uri, Version};
+
\ No newline at end of file diff --git a/src/actix_web/info.rs.html b/src/actix_web/info.rs.html new file mode 100644 index 000000000..d09f09179 --- /dev/null +++ b/src/actix_web/info.rs.html @@ -0,0 +1,933 @@ +info.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
+
use std::{convert::Infallible, net::SocketAddr};
+
+use actix_utils::future::{err, ok, Ready};
+use derive_more::{Display, Error};
+
+use crate::{
+    dev::{AppConfig, Payload, RequestHead},
+    http::{
+        header::{self, HeaderName},
+        uri::{Authority, Scheme},
+    },
+    FromRequest, HttpRequest, ResponseError,
+};
+
+static X_FORWARDED_FOR: HeaderName = HeaderName::from_static("x-forwarded-for");
+static X_FORWARDED_HOST: HeaderName = HeaderName::from_static("x-forwarded-host");
+static X_FORWARDED_PROTO: HeaderName = HeaderName::from_static("x-forwarded-proto");
+
+/// Trim whitespace then any quote marks.
+fn unquote(val: &str) -> &str {
+    val.trim().trim_start_matches('"').trim_end_matches('"')
+}
+
+/// Extracts and trims first value for given header name.
+fn first_header_value<'a>(req: &'a RequestHead, name: &'_ HeaderName) -> Option<&'a str> {
+    let hdr = req.headers.get(name)?.to_str().ok()?;
+    let val = hdr.split(',').next()?.trim();
+    Some(val)
+}
+
+/// HTTP connection information.
+///
+/// `ConnectionInfo` implements `FromRequest` and can be extracted in handlers.
+///
+/// # Examples
+/// ```
+/// # use actix_web::{HttpResponse, Responder};
+/// use actix_web::dev::ConnectionInfo;
+///
+/// async fn handler(conn: ConnectionInfo) -> impl Responder {
+///     match conn.host() {
+///         "actix.rs" => HttpResponse::Ok().body("Welcome!"),
+///         "admin.actix.rs" => HttpResponse::Ok().body("Admin portal."),
+///         _ => HttpResponse::NotFound().finish()
+///     }
+/// }
+/// # let _svc = actix_web::web::to(handler);
+/// ```
+///
+/// # Implementation Notes
+/// Parses `Forwarded` header information according to [RFC 7239][rfc7239] but does not try to
+/// interpret the values for each property. As such, the getter methods on `ConnectionInfo` return
+/// strings instead of IP addresses or other types to acknowledge that they may be
+/// [obfuscated][rfc7239-63] or [unknown][rfc7239-62].
+///
+/// If the older, related headers are also present (eg. `X-Forwarded-For`), then `Forwarded`
+/// is preferred.
+///
+/// [rfc7239]: https://datatracker.ietf.org/doc/html/rfc7239
+/// [rfc7239-62]: https://datatracker.ietf.org/doc/html/rfc7239#section-6.2
+/// [rfc7239-63]: https://datatracker.ietf.org/doc/html/rfc7239#section-6.3
+#[derive(Debug, Clone, Default)]
+pub struct ConnectionInfo {
+    host: String,
+    scheme: String,
+    peer_addr: Option<String>,
+    realip_remote_addr: Option<String>,
+}
+
+impl ConnectionInfo {
+    pub(crate) fn new(req: &RequestHead, cfg: &AppConfig) -> ConnectionInfo {
+        let mut host = None;
+        let mut scheme = None;
+        let mut realip_remote_addr = None;
+
+        for (name, val) in req
+            .headers
+            .get_all(&header::FORWARDED)
+            .filter_map(|hdr| hdr.to_str().ok())
+            // "for=1.2.3.4, for=5.6.7.8; scheme=https"
+            .flat_map(|val| val.split(';'))
+            // ["for=1.2.3.4, for=5.6.7.8", " scheme=https"]
+            .flat_map(|vals| vals.split(','))
+            // ["for=1.2.3.4", " for=5.6.7.8", " scheme=https"]
+            .flat_map(|pair| {
+                let mut items = pair.trim().splitn(2, '=');
+                Some((items.next()?, items.next()?))
+            })
+        {
+            // [(name , val      ), ...                                    ]
+            // [("for", "1.2.3.4"), ("for", "5.6.7.8"), ("scheme", "https")]
+
+            // taking the first value for each property is correct because spec states that first
+            // "for" value is client and rest are proxies; multiple values other properties have
+            // no defined semantics
+            //
+            // > In a chain of proxy servers where this is fully utilized, the first
+            // > "for" parameter will disclose the client where the request was first
+            // > made, followed by any subsequent proxy identifiers.
+            // --- https://datatracker.ietf.org/doc/html/rfc7239#section-5.2
+
+            match name.trim().to_lowercase().as_str() {
+                "for" => realip_remote_addr.get_or_insert_with(|| unquote(val)),
+                "proto" => scheme.get_or_insert_with(|| unquote(val)),
+                "host" => host.get_or_insert_with(|| unquote(val)),
+                "by" => {
+                    // TODO: implement https://datatracker.ietf.org/doc/html/rfc7239#section-5.1
+                    continue;
+                }
+                _ => continue,
+            };
+        }
+
+        let scheme = scheme
+            .or_else(|| first_header_value(req, &X_FORWARDED_PROTO))
+            .or_else(|| req.uri.scheme().map(Scheme::as_str))
+            .or_else(|| Some("https").filter(|_| cfg.secure()))
+            .unwrap_or("http")
+            .to_owned();
+
+        let host = host
+            .or_else(|| first_header_value(req, &X_FORWARDED_HOST))
+            .or_else(|| req.headers.get(&header::HOST)?.to_str().ok())
+            .or_else(|| req.uri.authority().map(Authority::as_str))
+            .unwrap_or_else(|| cfg.host())
+            .to_owned();
+
+        let realip_remote_addr = realip_remote_addr
+            .or_else(|| first_header_value(req, &X_FORWARDED_FOR))
+            .map(str::to_owned);
+
+        let peer_addr = req.peer_addr.map(|addr| addr.ip().to_string());
+
+        ConnectionInfo {
+            host,
+            scheme,
+            peer_addr,
+            realip_remote_addr,
+        }
+    }
+
+    /// Real IP (remote address) of client that initiated request.
+    ///
+    /// The address is resolved through the following, in order:
+    /// - `Forwarded` header
+    /// - `X-Forwarded-For` header
+    /// - peer address of opened socket (same as [`remote_addr`](Self::remote_addr))
+    ///
+    /// # Security
+    /// Do not use this function for security purposes unless you can be sure that the `Forwarded`
+    /// and `X-Forwarded-For` headers cannot be spoofed by the client. If you are running without a
+    /// proxy then [obtaining the peer address](Self::peer_addr) would be more appropriate.
+    #[inline]
+    pub fn realip_remote_addr(&self) -> Option<&str> {
+        self.realip_remote_addr
+            .as_deref()
+            .or(self.peer_addr.as_deref())
+    }
+
+    /// Returns serialized IP address of the peer connection.
+    ///
+    /// See [`HttpRequest::peer_addr`] for more details.
+    #[inline]
+    pub fn peer_addr(&self) -> Option<&str> {
+        self.peer_addr.as_deref()
+    }
+
+    /// Hostname of the request.
+    ///
+    /// Hostname is resolved through the following, in order:
+    /// - `Forwarded` header
+    /// - `X-Forwarded-Host` header
+    /// - `Host` header
+    /// - request target / URI
+    /// - configured server hostname
+    #[inline]
+    pub fn host(&self) -> &str {
+        &self.host
+    }
+
+    /// Scheme of the request.
+    ///
+    /// Scheme is resolved through the following, in order:
+    /// - `Forwarded` header
+    /// - `X-Forwarded-Proto` header
+    /// - request target / URI
+    #[inline]
+    pub fn scheme(&self) -> &str {
+        &self.scheme
+    }
+
+    #[doc(hidden)]
+    #[deprecated(since = "4.0.0", note = "Renamed to `peer_addr`.")]
+    pub fn remote_addr(&self) -> Option<&str> {
+        self.peer_addr()
+    }
+}
+
+impl FromRequest for ConnectionInfo {
+    type Error = Infallible;
+    type Future = Ready<Result<Self, Self::Error>>;
+
+    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
+        ok(req.connection_info().clone())
+    }
+}
+
+/// Extractor for peer's socket address.
+///
+/// Also see [`HttpRequest::peer_addr`] and [`ConnectionInfo::peer_addr`].
+///
+/// # Examples
+/// ```
+/// # use actix_web::Responder;
+/// use actix_web::dev::PeerAddr;
+///
+/// async fn handler(peer_addr: PeerAddr) -> impl Responder {
+///     let socket_addr = peer_addr.0;
+///     socket_addr.to_string()
+/// }
+/// # let _svc = actix_web::web::to(handler);
+/// ```
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Display)]
+#[display(fmt = "{}", _0)]
+pub struct PeerAddr(pub SocketAddr);
+
+impl PeerAddr {
+    /// Unwrap into inner `SocketAddr` value.
+    pub fn into_inner(self) -> SocketAddr {
+        self.0
+    }
+}
+
+#[derive(Debug, Display, Error)]
+#[non_exhaustive]
+#[display(fmt = "Missing peer address")]
+pub struct MissingPeerAddr;
+
+impl ResponseError for MissingPeerAddr {}
+
+impl FromRequest for PeerAddr {
+    type Error = MissingPeerAddr;
+    type Future = Ready<Result<Self, Self::Error>>;
+
+    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
+        match req.peer_addr() {
+            Some(addr) => ok(PeerAddr(addr)),
+            None => {
+                log::error!("Missing peer address.");
+                err(MissingPeerAddr)
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::test::TestRequest;
+
+    const X_FORWARDED_FOR: &str = "x-forwarded-for";
+    const X_FORWARDED_HOST: &str = "x-forwarded-host";
+    const X_FORWARDED_PROTO: &str = "x-forwarded-proto";
+
+    #[test]
+    fn info_default() {
+        let req = TestRequest::default().to_http_request();
+        let info = req.connection_info();
+        assert_eq!(info.scheme(), "http");
+        assert_eq!(info.host(), "localhost:8080");
+    }
+
+    #[test]
+    fn host_header() {
+        let req = TestRequest::default()
+            .insert_header((header::HOST, "rust-lang.org"))
+            .to_http_request();
+
+        let info = req.connection_info();
+        assert_eq!(info.scheme(), "http");
+        assert_eq!(info.host(), "rust-lang.org");
+        assert_eq!(info.realip_remote_addr(), None);
+    }
+
+    #[test]
+    fn x_forwarded_for_header() {
+        let req = TestRequest::default()
+            .insert_header((X_FORWARDED_FOR, "192.0.2.60"))
+            .to_http_request();
+        let info = req.connection_info();
+        assert_eq!(info.realip_remote_addr(), Some("192.0.2.60"));
+    }
+
+    #[test]
+    fn x_forwarded_host_header() {
+        let req = TestRequest::default()
+            .insert_header((X_FORWARDED_HOST, "192.0.2.60"))
+            .to_http_request();
+        let info = req.connection_info();
+        assert_eq!(info.host(), "192.0.2.60");
+        assert_eq!(info.realip_remote_addr(), None);
+    }
+
+    #[test]
+    fn x_forwarded_proto_header() {
+        let req = TestRequest::default()
+            .insert_header((X_FORWARDED_PROTO, "https"))
+            .to_http_request();
+        let info = req.connection_info();
+        assert_eq!(info.scheme(), "https");
+    }
+
+    #[test]
+    fn forwarded_header() {
+        let req = TestRequest::default()
+            .insert_header((
+                header::FORWARDED,
+                "for=192.0.2.60; proto=https; by=203.0.113.43; host=rust-lang.org",
+            ))
+            .to_http_request();
+
+        let info = req.connection_info();
+        assert_eq!(info.scheme(), "https");
+        assert_eq!(info.host(), "rust-lang.org");
+        assert_eq!(info.realip_remote_addr(), Some("192.0.2.60"));
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::FORWARDED,
+                "for=192.0.2.60; proto=https; by=203.0.113.43; host=rust-lang.org",
+            ))
+            .to_http_request();
+
+        let info = req.connection_info();
+        assert_eq!(info.scheme(), "https");
+        assert_eq!(info.host(), "rust-lang.org");
+        assert_eq!(info.realip_remote_addr(), Some("192.0.2.60"));
+    }
+
+    #[test]
+    fn forwarded_case_sensitivity() {
+        let req = TestRequest::default()
+            .insert_header((header::FORWARDED, "For=192.0.2.60"))
+            .to_http_request();
+        let info = req.connection_info();
+        assert_eq!(info.realip_remote_addr(), Some("192.0.2.60"));
+    }
+
+    #[test]
+    fn forwarded_weird_whitespace() {
+        let req = TestRequest::default()
+            .insert_header((header::FORWARDED, "for= 1.2.3.4; proto= https"))
+            .to_http_request();
+        let info = req.connection_info();
+        assert_eq!(info.realip_remote_addr(), Some("1.2.3.4"));
+        assert_eq!(info.scheme(), "https");
+
+        let req = TestRequest::default()
+            .insert_header((header::FORWARDED, "  for = 1.2.3.4  "))
+            .to_http_request();
+        let info = req.connection_info();
+        assert_eq!(info.realip_remote_addr(), Some("1.2.3.4"));
+    }
+
+    #[test]
+    fn forwarded_for_quoted() {
+        let req = TestRequest::default()
+            .insert_header((header::FORWARDED, r#"for="192.0.2.60:8080""#))
+            .to_http_request();
+        let info = req.connection_info();
+        assert_eq!(info.realip_remote_addr(), Some("192.0.2.60:8080"));
+    }
+
+    #[test]
+    fn forwarded_for_ipv6() {
+        let req = TestRequest::default()
+            .insert_header((header::FORWARDED, r#"for="[2001:db8:cafe::17]:4711""#))
+            .to_http_request();
+        let info = req.connection_info();
+        assert_eq!(info.realip_remote_addr(), Some("[2001:db8:cafe::17]:4711"));
+    }
+
+    #[test]
+    fn forwarded_for_multiple() {
+        let req = TestRequest::default()
+            .insert_header((header::FORWARDED, "for=192.0.2.60, for=198.51.100.17"))
+            .to_http_request();
+        let info = req.connection_info();
+        // takes the first value
+        assert_eq!(info.realip_remote_addr(), Some("192.0.2.60"));
+    }
+
+    #[test]
+    fn scheme_from_uri() {
+        let req = TestRequest::get()
+            .uri("https://actix.rs/test")
+            .to_http_request();
+        let info = req.connection_info();
+        assert_eq!(info.scheme(), "https");
+    }
+
+    #[test]
+    fn host_from_uri() {
+        let req = TestRequest::get()
+            .uri("https://actix.rs/test")
+            .to_http_request();
+        let info = req.connection_info();
+        assert_eq!(info.host(), "actix.rs");
+    }
+
+    #[test]
+    fn host_from_server_hostname() {
+        let mut req = TestRequest::get();
+        req.set_server_hostname("actix.rs");
+        let req = req.to_http_request();
+
+        let info = req.connection_info();
+        assert_eq!(info.host(), "actix.rs");
+    }
+
+    #[actix_rt::test]
+    async fn conn_info_extract() {
+        let req = TestRequest::default()
+            .uri("https://actix.rs/test")
+            .to_http_request();
+        let conn_info = ConnectionInfo::extract(&req).await.unwrap();
+        assert_eq!(conn_info.scheme(), "https");
+        assert_eq!(conn_info.host(), "actix.rs");
+    }
+
+    #[actix_rt::test]
+    async fn peer_addr_extract() {
+        let req = TestRequest::default().to_http_request();
+        let res = PeerAddr::extract(&req).await;
+        assert!(res.is_err());
+
+        let addr = "127.0.0.1:8080".parse().unwrap();
+        let req = TestRequest::default().peer_addr(addr).to_http_request();
+        let peer_addr = PeerAddr::extract(&req).await.unwrap();
+        assert_eq!(peer_addr, PeerAddr(addr));
+    }
+
+    #[actix_rt::test]
+    async fn remote_address() {
+        let req = TestRequest::default().to_http_request();
+        let res = ConnectionInfo::extract(&req).await.unwrap();
+        assert!(res.peer_addr().is_none());
+
+        let addr = "127.0.0.1:8080".parse().unwrap();
+        let req = TestRequest::default().peer_addr(addr).to_http_request();
+        let conn_info = ConnectionInfo::extract(&req).await.unwrap();
+        assert_eq!(conn_info.peer_addr().unwrap(), "127.0.0.1");
+    }
+
+    #[actix_rt::test]
+    async fn real_ip_from_socket_addr() {
+        let req = TestRequest::default().to_http_request();
+        let res = ConnectionInfo::extract(&req).await.unwrap();
+        assert!(res.realip_remote_addr().is_none());
+
+        let addr = "127.0.0.1:8080".parse().unwrap();
+        let req = TestRequest::default().peer_addr(addr).to_http_request();
+        let conn_info = ConnectionInfo::extract(&req).await.unwrap();
+        assert_eq!(conn_info.realip_remote_addr().unwrap(), "127.0.0.1");
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/lib.rs.html b/src/actix_web/lib.rs.html new file mode 100644 index 000000000..09b3644fc --- /dev/null +++ b/src/actix_web/lib.rs.html @@ -0,0 +1,299 @@ +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
+
//! Actix Web is a powerful, pragmatic, and extremely fast web framework for Rust.
+//!
+//! # Examples
+//! ```no_run
+//! use actix_web::{get, web, App, HttpServer, Responder};
+//!
+//! #[get("/hello/{name}")]
+//! async fn greet(name: web::Path<String>) -> impl Responder {
+//!     format!("Hello {}!", name)
+//! }
+//!
+//! #[actix_web::main] // or #[tokio::main]
+//! async fn main() -> std::io::Result<()> {
+//!     HttpServer::new(|| {
+//!         App::new().service(greet)
+//!     })
+//!     .bind(("127.0.0.1", 8080))?
+//!     .run()
+//!     .await
+//! }
+//! ```
+//!
+//! # Documentation & Community Resources
+//! In addition to this API documentation, several other resources are available:
+//!
+//! * [Website & User Guide](https://actix.rs/)
+//! * [Examples Repository](https://github.com/actix/examples)
+//! * [Community Chat on Discord](https://discord.gg/NWpN5mmg3x)
+//!
+//! To get started navigating the API docs, you may consider looking at the following pages first:
+//!
+//! * [`App`]: This struct represents an Actix Web application and is used to
+//!   configure routes and other common application settings.
+//!
+//! * [`HttpServer`]: This struct represents an HTTP server instance and is
+//!   used to instantiate and configure servers.
+//!
+//! * [`web`]: This module provides essential types for route registration as well as
+//!   common utilities for request handlers.
+//!
+//! * [`HttpRequest`] and [`HttpResponse`]: These
+//!   structs represent HTTP requests and responses and expose methods for creating, inspecting,
+//!   and otherwise utilizing them.
+//!
+//! # Features
+//! - Supports HTTP/1.x and HTTP/2
+//! - Streaming and pipelining
+//! - Powerful [request routing](https://actix.rs/docs/url-dispatch/) with optional macros
+//! - Full [Tokio](https://tokio.rs) compatibility
+//! - Keep-alive and slow requests handling
+//! - Client/server [WebSockets](https://actix.rs/docs/websockets/) support
+//! - Transparent content compression/decompression (br, gzip, deflate, zstd)
+//! - Multipart streams
+//! - Static assets
+//! - SSL support using OpenSSL or Rustls
+//! - Middlewares ([Logger, Session, CORS, etc](middleware))
+//! - Integrates with the [`awc` HTTP client](https://docs.rs/awc/)
+//! - Runs on stable Rust 1.54+
+//!
+//! # Crate Features
+//! - `cookies` - cookies support (enabled by default)
+//! - `macros` - routing and runtime macros (enabled by default)
+//! - `compress-brotli` - brotli content encoding compression support (enabled by default)
+//! - `compress-gzip` - gzip and deflate content encoding compression support (enabled by default)
+//! - `compress-zstd` - zstd content encoding compression support (enabled by default)
+//! - `openssl` - HTTPS support via `openssl` crate, supports `HTTP/2`
+//! - `rustls` - HTTPS support via `rustls` 0.20 crate, supports `HTTP/2`
+//! - `rustls-0_21` - HTTPS support via `rustls` 0.21 crate, supports `HTTP/2`
+//! - `rustls-0_22` - HTTPS support via `rustls` 0.22 crate, supports `HTTP/2`
+//! - `rustls-0_23` - HTTPS support via `rustls` 0.23 crate, supports `HTTP/2`
+//! - `secure-cookies` - secure cookies support
+
+#![deny(rust_2018_idioms, nonstandard_style)]
+#![warn(future_incompatible)]
+#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
+#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+
+pub use actix_http::{body, HttpMessage};
+#[cfg(feature = "cookies")]
+#[doc(inline)]
+pub use cookie;
+
+mod app;
+mod app_service;
+mod config;
+mod data;
+pub mod dev;
+pub mod error;
+mod extract;
+pub mod guard;
+mod handler;
+mod helpers;
+pub mod http;
+mod info;
+pub mod middleware;
+mod redirect;
+mod request;
+mod request_data;
+mod resource;
+mod response;
+mod rmap;
+mod route;
+pub mod rt;
+mod scope;
+mod server;
+mod service;
+pub mod test;
+pub(crate) mod types;
+pub mod web;
+
+#[doc(inline)]
+pub use crate::error::Result;
+pub use crate::{
+    app::App,
+    error::{Error, ResponseError},
+    extract::FromRequest,
+    handler::Handler,
+    request::HttpRequest,
+    resource::Resource,
+    response::{CustomizeResponder, HttpResponse, HttpResponseBuilder, Responder},
+    route::Route,
+    scope::Scope,
+    server::HttpServer,
+    types::Either,
+};
+
+macro_rules! codegen_reexport {
+    ($name:ident) => {
+        #[cfg(feature = "macros")]
+        pub use actix_web_codegen::$name;
+    };
+}
+
+codegen_reexport!(main);
+codegen_reexport!(test);
+codegen_reexport!(route);
+codegen_reexport!(routes);
+codegen_reexport!(head);
+codegen_reexport!(get);
+codegen_reexport!(post);
+codegen_reexport!(patch);
+codegen_reexport!(put);
+codegen_reexport!(delete);
+codegen_reexport!(trace);
+codegen_reexport!(connect);
+codegen_reexport!(options);
+
+pub(crate) type BoxError = Box<dyn std::error::Error>;
+
\ No newline at end of file diff --git a/src/actix_web/middleware/compat.rs.html b/src/actix_web/middleware/compat.rs.html new file mode 100644 index 000000000..e1d92c03f --- /dev/null +++ b/src/actix_web/middleware/compat.rs.html @@ -0,0 +1,473 @@ +compat.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
+
//! For middleware documentation, see [`Compat`].
+
+use std::{
+    future::Future,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use futures_core::{future::LocalBoxFuture, ready};
+use pin_project_lite::pin_project;
+
+use crate::{
+    body::{BoxBody, MessageBody},
+    dev::{Service, Transform},
+    error::Error,
+    service::ServiceResponse,
+};
+
+/// Middleware for enabling any middleware to be used in [`Resource::wrap`](crate::Resource::wrap),
+/// and [`Condition`](super::Condition).
+///
+/// # Examples
+/// ```
+/// use actix_web::middleware::{Logger, Compat};
+/// use actix_web::{App, web};
+///
+/// let logger = Logger::default();
+///
+/// // this would not compile because of incompatible body types
+/// // let app = App::new()
+/// //     .service(web::scope("scoped").wrap(logger));
+///
+/// // by using this middleware we can use the logger on a scope
+/// let app = App::new()
+///     .service(web::scope("scoped").wrap(Compat::new(logger)));
+/// ```
+pub struct Compat<T> {
+    transform: T,
+}
+
+#[cfg(test)]
+impl Compat<super::Noop> {
+    pub(crate) fn noop() -> Self {
+        Self {
+            transform: super::Noop,
+        }
+    }
+}
+
+impl<T> Compat<T> {
+    /// Wrap a middleware to give it broader compatibility.
+    pub fn new(middleware: T) -> Self {
+        Self {
+            transform: middleware,
+        }
+    }
+}
+
+impl<S, T, Req> Transform<S, Req> for Compat<T>
+where
+    S: Service<Req>,
+    T: Transform<S, Req>,
+    T::Future: 'static,
+    T::Response: MapServiceResponseBody,
+    T::Error: Into<Error>,
+{
+    type Response = ServiceResponse<BoxBody>;
+    type Error = Error;
+    type Transform = CompatMiddleware<T::Transform>;
+    type InitError = T::InitError;
+    type Future = LocalBoxFuture<'static, Result<Self::Transform, Self::InitError>>;
+
+    fn new_transform(&self, service: S) -> Self::Future {
+        let fut = self.transform.new_transform(service);
+        Box::pin(async move {
+            let service = fut.await?;
+            Ok(CompatMiddleware { service })
+        })
+    }
+}
+
+pub struct CompatMiddleware<S> {
+    service: S,
+}
+
+impl<S, Req> Service<Req> for CompatMiddleware<S>
+where
+    S: Service<Req>,
+    S::Response: MapServiceResponseBody,
+    S::Error: Into<Error>,
+{
+    type Response = ServiceResponse<BoxBody>;
+    type Error = Error;
+    type Future = CompatMiddlewareFuture<S::Future>;
+
+    actix_service::forward_ready!(service);
+
+    fn call(&self, req: Req) -> Self::Future {
+        let fut = self.service.call(req);
+        CompatMiddlewareFuture { fut }
+    }
+}
+
+pin_project! {
+    pub struct CompatMiddlewareFuture<Fut> {
+        #[pin]
+        fut: Fut,
+    }
+}
+
+impl<Fut, T, E> Future for CompatMiddlewareFuture<Fut>
+where
+    Fut: Future<Output = Result<T, E>>,
+    T: MapServiceResponseBody,
+    E: Into<Error>,
+{
+    type Output = Result<ServiceResponse<BoxBody>, Error>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let res = match ready!(self.project().fut.poll(cx)) {
+            Ok(res) => res,
+            Err(err) => return Poll::Ready(Err(err.into())),
+        };
+
+        Poll::Ready(Ok(res.map_body()))
+    }
+}
+
+/// Convert `ServiceResponse`'s `ResponseBody<B>` generic type to `ResponseBody<Body>`.
+pub trait MapServiceResponseBody {
+    fn map_body(self) -> ServiceResponse<BoxBody>;
+}
+
+impl<B> MapServiceResponseBody for ServiceResponse<B>
+where
+    B: MessageBody + 'static,
+{
+    #[inline]
+    fn map_body(self) -> ServiceResponse<BoxBody> {
+        self.map_into_boxed_body()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    // easier to code when cookies feature is disabled
+    #![allow(unused_imports)]
+
+    use actix_service::IntoService;
+
+    use super::*;
+    use crate::{
+        dev::ServiceRequest,
+        http::StatusCode,
+        middleware::{self, Condition, Logger},
+        test::{self, call_service, init_service, TestRequest},
+        web, App, HttpResponse,
+    };
+
+    #[actix_rt::test]
+    #[cfg(all(feature = "cookies", feature = "__compress"))]
+    async fn test_scope_middleware() {
+        use crate::middleware::Compress;
+
+        let logger = Logger::default();
+        let compress = Compress::default();
+
+        let srv = init_service(
+            App::new().service(
+                web::scope("app")
+                    .wrap(logger)
+                    .wrap(Compat::new(compress))
+                    .service(web::resource("/test").route(web::get().to(HttpResponse::Ok))),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/app/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    #[cfg(all(feature = "cookies", feature = "__compress"))]
+    async fn test_resource_scope_middleware() {
+        use crate::middleware::Compress;
+
+        let logger = Logger::default();
+        let compress = Compress::default();
+
+        let srv = init_service(
+            App::new().service(
+                web::resource("app/test")
+                    .wrap(Compat::new(logger))
+                    .wrap(Compat::new(compress))
+                    .route(web::get().to(HttpResponse::Ok)),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/app/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_condition_scope_middleware() {
+        let srv = |req: ServiceRequest| {
+            Box::pin(
+                async move { Ok(req.into_response(HttpResponse::InternalServerError().finish())) },
+            )
+        };
+
+        let logger = Logger::default();
+
+        let mw = Condition::new(true, Compat::new(logger))
+            .new_transform(srv.into_service())
+            .await
+            .unwrap();
+        let resp = call_service(&mw, TestRequest::default().to_srv_request()).await;
+        assert_eq!(resp.status(), StatusCode::INTERNAL_SERVER_ERROR);
+    }
+
+    #[actix_rt::test]
+    async fn compat_noop_is_noop() {
+        let srv = test::ok_service();
+
+        let mw = Compat::noop()
+            .new_transform(srv.into_service())
+            .await
+            .unwrap();
+
+        let resp = call_service(&mw, TestRequest::default().to_srv_request()).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/middleware/compress.rs.html b/src/actix_web/middleware/compress.rs.html new file mode 100644 index 000000000..c796b58e1 --- /dev/null +++ b/src/actix_web/middleware/compress.rs.html @@ -0,0 +1,951 @@ +compress.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
+
//! For middleware documentation, see [`Compress`].
+
+use std::{
+    future::Future,
+    marker::PhantomData,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use actix_http::encoding::Encoder;
+use actix_service::{Service, Transform};
+use actix_utils::future::{ok, Either, Ready};
+use futures_core::ready;
+use mime::Mime;
+use once_cell::sync::Lazy;
+use pin_project_lite::pin_project;
+
+use crate::{
+    body::{EitherBody, MessageBody},
+    http::{
+        header::{self, AcceptEncoding, ContentEncoding, Encoding, HeaderValue},
+        StatusCode,
+    },
+    service::{ServiceRequest, ServiceResponse},
+    Error, HttpMessage, HttpResponse,
+};
+
+/// Middleware for compressing response payloads.
+///
+/// # Encoding Negotiation
+/// `Compress` will read the `Accept-Encoding` header to negotiate which compression codec to use.
+/// Payloads are not compressed if the header is not sent. The `compress-*` [feature flags] are also
+/// considered in this selection process.
+///
+/// # Pre-compressed Payload
+/// If you are serving some data that is already using a compressed representation (e.g., a gzip
+/// compressed HTML file from disk) you can signal this to `Compress` by setting an appropriate
+/// `Content-Encoding` header. In addition to preventing double compressing the payload, this header
+/// is required by the spec when using compressed representations and will inform the client that
+/// the content should be uncompressed.
+///
+/// However, it is not advised to unconditionally serve encoded representations of content because
+/// the client may not support it. The [`AcceptEncoding`] typed header has some utilities to help
+/// perform manual encoding negotiation, if required. When negotiating content encoding, it is also
+/// required by the spec to send a `Vary: Accept-Encoding` header.
+///
+/// A (naïve) example serving an pre-compressed Gzip file is included below.
+///
+/// # Examples
+/// To enable automatic payload compression just include `Compress` as a top-level middleware:
+/// ```
+/// use actix_web::{middleware, web, App, HttpResponse};
+///
+/// let app = App::new()
+///     .wrap(middleware::Compress::default())
+///     .default_service(web::to(|| async { HttpResponse::Ok().body("hello world") }));
+/// ```
+///
+/// Pre-compressed Gzip file being served from disk with correct headers added to bypass middleware:
+/// ```no_run
+/// use actix_web::{middleware, http::header, web, App, HttpResponse, Responder};
+///
+/// async fn index_handler() -> actix_web::Result<impl Responder> {
+///     Ok(actix_files::NamedFile::open_async("./assets/index.html.gz").await?
+///         .customize()
+///         .insert_header(header::ContentEncoding::Gzip))
+/// }
+///
+/// let app = App::new()
+///     .wrap(middleware::Compress::default())
+///     .default_service(web::to(index_handler));
+/// ```
+///
+/// [feature flags]: ../index.html#crate-features
+#[derive(Debug, Clone, Default)]
+#[non_exhaustive]
+pub struct Compress;
+
+impl<S, B> Transform<S, ServiceRequest> for Compress
+where
+    B: MessageBody,
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+{
+    type Response = ServiceResponse<EitherBody<Encoder<B>>>;
+    type Error = Error;
+    type Transform = CompressMiddleware<S>;
+    type InitError = ();
+    type Future = Ready<Result<Self::Transform, Self::InitError>>;
+
+    fn new_transform(&self, service: S) -> Self::Future {
+        ok(CompressMiddleware { service })
+    }
+}
+
+pub struct CompressMiddleware<S> {
+    service: S,
+}
+
+impl<S, B> Service<ServiceRequest> for CompressMiddleware<S>
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+    B: MessageBody,
+{
+    type Response = ServiceResponse<EitherBody<Encoder<B>>>;
+    type Error = Error;
+    #[allow(clippy::type_complexity)]
+    type Future = Either<CompressResponse<S, B>, Ready<Result<Self::Response, Self::Error>>>;
+
+    actix_service::forward_ready!(service);
+
+    #[allow(clippy::borrow_interior_mutable_const)]
+    fn call(&self, req: ServiceRequest) -> Self::Future {
+        // negotiate content-encoding
+        let accept_encoding = req.get_header::<AcceptEncoding>();
+
+        let accept_encoding = match accept_encoding {
+            // missing header; fallback to identity
+            None => {
+                return Either::left(CompressResponse {
+                    encoding: Encoding::identity(),
+                    fut: self.service.call(req),
+                    _phantom: PhantomData,
+                })
+            }
+
+            // valid accept-encoding header
+            Some(accept_encoding) => accept_encoding,
+        };
+
+        match accept_encoding.negotiate(SUPPORTED_ENCODINGS.iter()) {
+            None => {
+                let mut res = HttpResponse::with_body(
+                    StatusCode::NOT_ACCEPTABLE,
+                    SUPPORTED_ENCODINGS_STRING.as_str(),
+                );
+
+                res.headers_mut()
+                    .insert(header::VARY, HeaderValue::from_static("Accept-Encoding"));
+
+                Either::right(ok(req
+                    .into_response(res)
+                    .map_into_boxed_body()
+                    .map_into_right_body()))
+            }
+
+            Some(encoding) => Either::left(CompressResponse {
+                fut: self.service.call(req),
+                encoding,
+                _phantom: PhantomData,
+            }),
+        }
+    }
+}
+
+pin_project! {
+    pub struct CompressResponse<S, B>
+    where
+        S: Service<ServiceRequest>,
+    {
+        #[pin]
+        fut: S::Future,
+        encoding: Encoding,
+        _phantom: PhantomData<B>,
+    }
+}
+
+impl<S, B> Future for CompressResponse<S, B>
+where
+    B: MessageBody,
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+{
+    type Output = Result<ServiceResponse<EitherBody<Encoder<B>>>, Error>;
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.as_mut().project();
+
+        match ready!(this.fut.poll(cx)) {
+            Ok(resp) => {
+                let enc = match this.encoding {
+                    Encoding::Known(enc) => *enc,
+                    Encoding::Unknown(enc) => {
+                        unimplemented!("encoding '{enc}' should not be here");
+                    }
+                };
+
+                Poll::Ready(Ok(resp.map_body(move |head, body| {
+                    let content_type = head.headers.get(header::CONTENT_TYPE);
+
+                    fn default_compress_predicate(content_type: Option<&HeaderValue>) -> bool {
+                        match content_type {
+                            None => true,
+                            Some(hdr) => {
+                                match hdr.to_str().ok().and_then(|hdr| hdr.parse::<Mime>().ok()) {
+                                    Some(mime) if mime.type_().as_str() == "image" => false,
+                                    Some(mime) if mime.type_().as_str() == "video" => false,
+                                    _ => true,
+                                }
+                            }
+                        }
+                    }
+
+                    let enc = if default_compress_predicate(content_type) {
+                        enc
+                    } else {
+                        ContentEncoding::Identity
+                    };
+
+                    EitherBody::left(Encoder::response(enc, head, body))
+                })))
+            }
+
+            Err(err) => Poll::Ready(Err(err)),
+        }
+    }
+}
+
+static SUPPORTED_ENCODINGS_STRING: Lazy<String> = Lazy::new(|| {
+    #[allow(unused_mut)] // only unused when no compress features enabled
+    let mut encoding: Vec<&str> = vec![];
+
+    #[cfg(feature = "compress-brotli")]
+    {
+        encoding.push("br");
+    }
+
+    #[cfg(feature = "compress-gzip")]
+    {
+        encoding.push("gzip");
+        encoding.push("deflate");
+    }
+
+    #[cfg(feature = "compress-zstd")]
+    {
+        encoding.push("zstd");
+    }
+
+    assert!(
+        !encoding.is_empty(),
+        "encoding can not be empty unless __compress feature has been explicitly enabled by itself"
+    );
+
+    encoding.join(", ")
+});
+
+static SUPPORTED_ENCODINGS: &[Encoding] = &[
+    Encoding::identity(),
+    #[cfg(feature = "compress-brotli")]
+    {
+        Encoding::brotli()
+    },
+    #[cfg(feature = "compress-gzip")]
+    {
+        Encoding::gzip()
+    },
+    #[cfg(feature = "compress-gzip")]
+    {
+        Encoding::deflate()
+    },
+    #[cfg(feature = "compress-zstd")]
+    {
+        Encoding::zstd()
+    },
+];
+
+// move cfg(feature) to prevents_double_compressing if more tests are added
+#[cfg(feature = "compress-gzip")]
+#[cfg(test)]
+mod tests {
+    use std::collections::HashSet;
+
+    use static_assertions::assert_impl_all;
+
+    use super::*;
+    use crate::{http::header::ContentType, middleware::DefaultHeaders, test, web, App};
+
+    const HTML_DATA_PART: &str = "<html><h1>hello world</h1></html";
+    const HTML_DATA: &str = const_str::repeat!(HTML_DATA_PART, 100);
+
+    const TEXT_DATA_PART: &str = "hello world ";
+    const TEXT_DATA: &str = const_str::repeat!(TEXT_DATA_PART, 100);
+
+    assert_impl_all!(Compress: Send, Sync);
+
+    pub fn gzip_decode(bytes: impl AsRef<[u8]>) -> Vec<u8> {
+        use std::io::Read as _;
+        let mut decoder = flate2::read::GzDecoder::new(bytes.as_ref());
+        let mut buf = Vec::new();
+        decoder.read_to_end(&mut buf).unwrap();
+        buf
+    }
+
+    #[track_caller]
+    fn assert_successful_res_with_content_type<B>(res: &ServiceResponse<B>, ct: &str) {
+        assert!(res.status().is_success());
+        assert!(
+            res.headers()
+                .get(header::CONTENT_TYPE)
+                .expect("content-type header should be present")
+                .to_str()
+                .expect("content-type header should be utf-8")
+                .contains(ct),
+            "response's content-type did not match {}",
+            ct
+        );
+    }
+
+    #[track_caller]
+    fn assert_successful_gzip_res_with_content_type<B>(res: &ServiceResponse<B>, ct: &str) {
+        assert_successful_res_with_content_type(res, ct);
+        assert_eq!(
+            res.headers()
+                .get(header::CONTENT_ENCODING)
+                .expect("response should be gzip compressed"),
+            "gzip",
+        );
+    }
+
+    #[track_caller]
+    fn assert_successful_identity_res_with_content_type<B>(res: &ServiceResponse<B>, ct: &str) {
+        assert_successful_res_with_content_type(res, ct);
+        assert!(
+            res.headers().get(header::CONTENT_ENCODING).is_none(),
+            "response should not be compressed",
+        );
+    }
+
+    #[actix_rt::test]
+    async fn prevents_double_compressing() {
+        let app = test::init_service({
+            App::new()
+                .wrap(Compress::default())
+                .route(
+                    "/single",
+                    web::get().to(move || HttpResponse::Ok().body(TEXT_DATA)),
+                )
+                .service(
+                    web::resource("/double")
+                        .wrap(Compress::default())
+                        .wrap(DefaultHeaders::new().add(("x-double", "true")))
+                        .route(web::get().to(move || HttpResponse::Ok().body(TEXT_DATA))),
+                )
+        })
+        .await;
+
+        let req = test::TestRequest::default()
+            .uri("/single")
+            .insert_header((header::ACCEPT_ENCODING, "gzip"))
+            .to_request();
+        let res = test::call_service(&app, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(res.headers().get("x-double"), None);
+        assert_eq!(res.headers().get(header::CONTENT_ENCODING).unwrap(), "gzip");
+        let bytes = test::read_body(res).await;
+        assert_eq!(gzip_decode(bytes), TEXT_DATA.as_bytes());
+
+        let req = test::TestRequest::default()
+            .uri("/double")
+            .insert_header((header::ACCEPT_ENCODING, "gzip"))
+            .to_request();
+        let res = test::call_service(&app, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(res.headers().get("x-double").unwrap(), "true");
+        assert_eq!(res.headers().get(header::CONTENT_ENCODING).unwrap(), "gzip");
+        let bytes = test::read_body(res).await;
+        assert_eq!(gzip_decode(bytes), TEXT_DATA.as_bytes());
+    }
+
+    #[actix_rt::test]
+    async fn retains_previously_set_vary_header() {
+        let app = test::init_service({
+            App::new()
+                .wrap(Compress::default())
+                .default_service(web::to(move || {
+                    HttpResponse::Ok()
+                        .insert_header((header::VARY, "x-test"))
+                        .body(TEXT_DATA)
+                }))
+        })
+        .await;
+
+        let req = test::TestRequest::default()
+            .insert_header((header::ACCEPT_ENCODING, "gzip"))
+            .to_request();
+        let res = test::call_service(&app, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+        #[allow(clippy::mutable_key_type)]
+        let vary_headers = res.headers().get_all(header::VARY).collect::<HashSet<_>>();
+        assert!(vary_headers.contains(&HeaderValue::from_static("x-test")));
+        assert!(vary_headers.contains(&HeaderValue::from_static("accept-encoding")));
+    }
+
+    fn configure_predicate_test(cfg: &mut web::ServiceConfig) {
+        cfg.route(
+            "/html",
+            web::get().to(|| {
+                HttpResponse::Ok()
+                    .content_type(ContentType::html())
+                    .body(HTML_DATA)
+            }),
+        )
+        .route(
+            "/image",
+            web::get().to(|| {
+                HttpResponse::Ok()
+                    .content_type(ContentType::jpeg())
+                    .body(TEXT_DATA)
+            }),
+        );
+    }
+
+    #[actix_rt::test]
+    async fn prevents_compression_jpeg() {
+        let app = test::init_service(
+            App::new()
+                .wrap(Compress::default())
+                .configure(configure_predicate_test),
+        )
+        .await;
+
+        let req =
+            test::TestRequest::with_uri("/html").insert_header((header::ACCEPT_ENCODING, "gzip"));
+        let res = test::call_service(&app, req.to_request()).await;
+        assert_successful_gzip_res_with_content_type(&res, "text/html");
+        assert_ne!(test::read_body(res).await, HTML_DATA.as_bytes());
+
+        let req =
+            test::TestRequest::with_uri("/image").insert_header((header::ACCEPT_ENCODING, "gzip"));
+        let res = test::call_service(&app, req.to_request()).await;
+        assert_successful_identity_res_with_content_type(&res, "image/jpeg");
+        assert_eq!(test::read_body(res).await, TEXT_DATA.as_bytes());
+    }
+
+    #[actix_rt::test]
+    async fn prevents_compression_empty() {
+        let app = test::init_service({
+            App::new()
+                .wrap(Compress::default())
+                .default_service(web::to(move || HttpResponse::Ok().finish()))
+        })
+        .await;
+
+        let req = test::TestRequest::default()
+            .insert_header((header::ACCEPT_ENCODING, "gzip"))
+            .to_request();
+        let res = test::call_service(&app, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+        assert!(!res.headers().contains_key(header::CONTENT_ENCODING));
+        assert!(test::read_body(res).await.is_empty());
+    }
+}
+
+#[cfg(feature = "compress-brotli")]
+#[cfg(test)]
+mod tests_brotli {
+    use super::*;
+    use crate::{test, web, App};
+
+    #[actix_rt::test]
+    async fn prevents_compression_empty() {
+        let app = test::init_service({
+            App::new()
+                .wrap(Compress::default())
+                .default_service(web::to(move || HttpResponse::Ok().finish()))
+        })
+        .await;
+
+        let req = test::TestRequest::default()
+            .insert_header((header::ACCEPT_ENCODING, "br"))
+            .to_request();
+        let res = test::call_service(&app, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+        assert!(!res.headers().contains_key(header::CONTENT_ENCODING));
+        assert!(test::read_body(res).await.is_empty());
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/middleware/condition.rs.html b/src/actix_web/middleware/condition.rs.html new file mode 100644 index 000000000..bd63aeaea --- /dev/null +++ b/src/actix_web/middleware/condition.rs.html @@ -0,0 +1,415 @@ +condition.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
+
//! For middleware documentation, see [`Condition`].
+
+use std::{
+    future::Future,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use futures_core::{future::LocalBoxFuture, ready};
+use futures_util::FutureExt as _;
+use pin_project_lite::pin_project;
+
+use crate::{
+    body::EitherBody,
+    dev::{Service, ServiceResponse, Transform},
+};
+
+/// Middleware for conditionally enabling other middleware.
+///
+/// # Examples
+/// ```
+/// use actix_web::middleware::{Condition, NormalizePath};
+/// use actix_web::App;
+///
+/// let enable_normalize = std::env::var("NORMALIZE_PATH").is_ok();
+/// let app = App::new()
+///     .wrap(Condition::new(enable_normalize, NormalizePath::default()));
+/// ```
+pub struct Condition<T> {
+    transformer: T,
+    enable: bool,
+}
+
+impl<T> Condition<T> {
+    pub fn new(enable: bool, transformer: T) -> Self {
+        Self {
+            transformer,
+            enable,
+        }
+    }
+}
+
+impl<S, T, Req, BE, BD, Err> Transform<S, Req> for Condition<T>
+where
+    S: Service<Req, Response = ServiceResponse<BD>, Error = Err> + 'static,
+    T: Transform<S, Req, Response = ServiceResponse<BE>, Error = Err>,
+    T::Future: 'static,
+    T::InitError: 'static,
+    T::Transform: 'static,
+{
+    type Response = ServiceResponse<EitherBody<BE, BD>>;
+    type Error = Err;
+    type Transform = ConditionMiddleware<T::Transform, S>;
+    type InitError = T::InitError;
+    type Future = LocalBoxFuture<'static, Result<Self::Transform, Self::InitError>>;
+
+    fn new_transform(&self, service: S) -> Self::Future {
+        if self.enable {
+            let fut = self.transformer.new_transform(service);
+            async move {
+                let wrapped_svc = fut.await?;
+                Ok(ConditionMiddleware::Enable(wrapped_svc))
+            }
+            .boxed_local()
+        } else {
+            async move { Ok(ConditionMiddleware::Disable(service)) }.boxed_local()
+        }
+    }
+}
+
+pub enum ConditionMiddleware<E, D> {
+    Enable(E),
+    Disable(D),
+}
+
+impl<E, D, Req, BE, BD, Err> Service<Req> for ConditionMiddleware<E, D>
+where
+    E: Service<Req, Response = ServiceResponse<BE>, Error = Err>,
+    D: Service<Req, Response = ServiceResponse<BD>, Error = Err>,
+{
+    type Response = ServiceResponse<EitherBody<BE, BD>>;
+    type Error = Err;
+    type Future = ConditionMiddlewareFuture<E::Future, D::Future>;
+
+    fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        match self {
+            ConditionMiddleware::Enable(service) => service.poll_ready(cx),
+            ConditionMiddleware::Disable(service) => service.poll_ready(cx),
+        }
+    }
+
+    fn call(&self, req: Req) -> Self::Future {
+        match self {
+            ConditionMiddleware::Enable(service) => ConditionMiddlewareFuture::Enabled {
+                fut: service.call(req),
+            },
+            ConditionMiddleware::Disable(service) => ConditionMiddlewareFuture::Disabled {
+                fut: service.call(req),
+            },
+        }
+    }
+}
+
+pin_project! {
+    #[doc(hidden)]
+    #[project = ConditionProj]
+    pub enum ConditionMiddlewareFuture<E, D> {
+        Enabled { #[pin] fut: E, },
+        Disabled { #[pin] fut: D, },
+    }
+}
+
+impl<E, D, BE, BD, Err> Future for ConditionMiddlewareFuture<E, D>
+where
+    E: Future<Output = Result<ServiceResponse<BE>, Err>>,
+    D: Future<Output = Result<ServiceResponse<BD>, Err>>,
+{
+    type Output = Result<ServiceResponse<EitherBody<BE, BD>>, Err>;
+
+    #[inline]
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let res = match self.project() {
+            ConditionProj::Enabled { fut } => ready!(fut.poll(cx))?.map_into_left_body(),
+            ConditionProj::Disabled { fut } => ready!(fut.poll(cx))?.map_into_right_body(),
+        };
+
+        Poll::Ready(Ok(res))
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_service::IntoService as _;
+
+    use super::*;
+    use crate::{
+        body::BoxBody,
+        dev::ServiceRequest,
+        error::Result,
+        http::{
+            header::{HeaderValue, CONTENT_TYPE},
+            StatusCode,
+        },
+        middleware::{self, ErrorHandlerResponse, ErrorHandlers},
+        test::{self, TestRequest},
+        web::Bytes,
+        HttpResponse,
+    };
+
+    #[allow(clippy::unnecessary_wraps)]
+    fn render_500<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+        res.response_mut()
+            .headers_mut()
+            .insert(CONTENT_TYPE, HeaderValue::from_static("0001"));
+
+        Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
+    }
+
+    #[test]
+    fn compat_with_builtin_middleware() {
+        let _ = Condition::new(true, middleware::Compat::noop());
+        let _ = Condition::new(true, middleware::Logger::default());
+        let _ = Condition::new(true, middleware::Compress::default());
+        let _ = Condition::new(true, middleware::NormalizePath::trim());
+        let _ = Condition::new(true, middleware::DefaultHeaders::new());
+        let _ = Condition::new(true, middleware::ErrorHandlers::<BoxBody>::new());
+        let _ = Condition::new(true, middleware::ErrorHandlers::<Bytes>::new());
+    }
+
+    #[actix_rt::test]
+    async fn test_handler_enabled() {
+        let srv = |req: ServiceRequest| async move {
+            let resp = HttpResponse::InternalServerError().message_body(String::new())?;
+            Ok(req.into_response(resp))
+        };
+
+        let mw = ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, render_500);
+
+        let mw = Condition::new(true, mw)
+            .new_transform(srv.into_service())
+            .await
+            .unwrap();
+
+        let resp: ServiceResponse<EitherBody<EitherBody<_, _>, String>> =
+            test::call_service(&mw, TestRequest::default().to_srv_request()).await;
+        assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
+    }
+
+    #[actix_rt::test]
+    async fn test_handler_disabled() {
+        let srv = |req: ServiceRequest| async move {
+            let resp = HttpResponse::InternalServerError().message_body(String::new())?;
+            Ok(req.into_response(resp))
+        };
+
+        let mw = ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, render_500);
+
+        let mw = Condition::new(false, mw)
+            .new_transform(srv.into_service())
+            .await
+            .unwrap();
+
+        let resp: ServiceResponse<EitherBody<EitherBody<_, _>, String>> =
+            test::call_service(&mw, TestRequest::default().to_srv_request()).await;
+        assert_eq!(resp.headers().get(CONTENT_TYPE), None);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/middleware/default_headers.rs.html b/src/actix_web/middleware/default_headers.rs.html new file mode 100644 index 000000000..888d581a6 --- /dev/null +++ b/src/actix_web/middleware/default_headers.rs.html @@ -0,0 +1,517 @@ +default_headers.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
+
//! For middleware documentation, see [`DefaultHeaders`].
+
+use std::{
+    future::Future,
+    marker::PhantomData,
+    pin::Pin,
+    rc::Rc,
+    task::{Context, Poll},
+};
+
+use actix_http::error::HttpError;
+use actix_utils::future::{ready, Ready};
+use futures_core::ready;
+use pin_project_lite::pin_project;
+
+use crate::{
+    dev::{Service, Transform},
+    http::header::{HeaderMap, HeaderName, HeaderValue, TryIntoHeaderPair, CONTENT_TYPE},
+    service::{ServiceRequest, ServiceResponse},
+    Error,
+};
+
+/// Middleware for setting default response headers.
+///
+/// Headers with the same key that are already set in a response will *not* be overwritten.
+///
+/// # Examples
+/// ```
+/// use actix_web::{web, http, middleware, App, HttpResponse};
+///
+/// let app = App::new()
+///     .wrap(middleware::DefaultHeaders::new().add(("X-Version", "0.2")))
+///     .service(
+///         web::resource("/test")
+///             .route(web::get().to(|| HttpResponse::Ok()))
+///             .route(web::method(http::Method::HEAD).to(|| HttpResponse::MethodNotAllowed()))
+///     );
+/// ```
+#[derive(Debug, Clone, Default)]
+pub struct DefaultHeaders {
+    inner: Rc<Inner>,
+}
+
+#[derive(Debug, Default)]
+struct Inner {
+    headers: HeaderMap,
+}
+
+impl DefaultHeaders {
+    /// Constructs an empty `DefaultHeaders` middleware.
+    #[inline]
+    pub fn new() -> DefaultHeaders {
+        DefaultHeaders::default()
+    }
+
+    /// Adds a header to the default set.
+    ///
+    /// # Panics
+    /// Panics when resolved header name or value is invalid.
+    #[allow(clippy::should_implement_trait)]
+    pub fn add(mut self, header: impl TryIntoHeaderPair) -> Self {
+        // standard header terminology `insert` or `append` for this method would make the behavior
+        // of this middleware less obvious since it only adds the headers if they are not present
+
+        match header.try_into_pair() {
+            Ok((key, value)) => Rc::get_mut(&mut self.inner)
+                .expect("All default headers must be added before cloning.")
+                .headers
+                .append(key, value),
+            Err(err) => panic!("Invalid header: {}", err.into()),
+        }
+
+        self
+    }
+
+    #[doc(hidden)]
+    #[deprecated(
+        since = "4.0.0",
+        note = "Prefer `.add((key, value))`. Will be removed in v5."
+    )]
+    pub fn header<K, V>(self, key: K, value: V) -> Self
+    where
+        HeaderName: TryFrom<K>,
+        <HeaderName as TryFrom<K>>::Error: Into<HttpError>,
+        HeaderValue: TryFrom<V>,
+        <HeaderValue as TryFrom<V>>::Error: Into<HttpError>,
+    {
+        self.add((
+            HeaderName::try_from(key)
+                .map_err(Into::into)
+                .expect("Invalid header name"),
+            HeaderValue::try_from(value)
+                .map_err(Into::into)
+                .expect("Invalid header value"),
+        ))
+    }
+
+    /// Adds a default *Content-Type* header if response does not contain one.
+    ///
+    /// Default is `application/octet-stream`.
+    pub fn add_content_type(self) -> Self {
+        #[allow(clippy::declare_interior_mutable_const)]
+        const HV_MIME: HeaderValue = HeaderValue::from_static("application/octet-stream");
+        self.add((CONTENT_TYPE, HV_MIME))
+    }
+}
+
+impl<S, B> Transform<S, ServiceRequest> for DefaultHeaders
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+    S::Future: 'static,
+{
+    type Response = ServiceResponse<B>;
+    type Error = Error;
+    type Transform = DefaultHeadersMiddleware<S>;
+    type InitError = ();
+    type Future = Ready<Result<Self::Transform, Self::InitError>>;
+
+    fn new_transform(&self, service: S) -> Self::Future {
+        ready(Ok(DefaultHeadersMiddleware {
+            service,
+            inner: Rc::clone(&self.inner),
+        }))
+    }
+}
+
+pub struct DefaultHeadersMiddleware<S> {
+    service: S,
+    inner: Rc<Inner>,
+}
+
+impl<S, B> Service<ServiceRequest> for DefaultHeadersMiddleware<S>
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+    S::Future: 'static,
+{
+    type Response = ServiceResponse<B>;
+    type Error = Error;
+    type Future = DefaultHeaderFuture<S, B>;
+
+    actix_service::forward_ready!(service);
+
+    fn call(&self, req: ServiceRequest) -> Self::Future {
+        let inner = self.inner.clone();
+        let fut = self.service.call(req);
+
+        DefaultHeaderFuture {
+            fut,
+            inner,
+            _body: PhantomData,
+        }
+    }
+}
+
+pin_project! {
+    pub struct DefaultHeaderFuture<S: Service<ServiceRequest>, B> {
+        #[pin]
+        fut: S::Future,
+        inner: Rc<Inner>,
+        _body: PhantomData<B>,
+    }
+}
+
+impl<S, B> Future for DefaultHeaderFuture<S, B>
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+{
+    type Output = <S::Future as Future>::Output;
+
+    #[allow(clippy::borrow_interior_mutable_const)]
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.project();
+        let mut res = ready!(this.fut.poll(cx))?;
+
+        // set response headers
+        for (key, value) in this.inner.headers.iter() {
+            if !res.headers().contains_key(key) {
+                res.headers_mut().insert(key.clone(), value.clone());
+            }
+        }
+
+        Poll::Ready(Ok(res))
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_service::IntoService;
+    use actix_utils::future::ok;
+
+    use super::*;
+    use crate::{
+        test::{self, TestRequest},
+        HttpResponse,
+    };
+
+    #[actix_rt::test]
+    async fn adding_default_headers() {
+        let mw = DefaultHeaders::new()
+            .add(("X-TEST", "0001"))
+            .add(("X-TEST-TWO", HeaderValue::from_static("123")))
+            .new_transform(test::ok_service())
+            .await
+            .unwrap();
+
+        let req = TestRequest::default().to_srv_request();
+        let res = mw.call(req).await.unwrap();
+        assert_eq!(res.headers().get("x-test").unwrap(), "0001");
+        assert_eq!(res.headers().get("x-test-two").unwrap(), "123");
+    }
+
+    #[actix_rt::test]
+    async fn no_override_existing() {
+        let req = TestRequest::default().to_srv_request();
+        let srv = |req: ServiceRequest| {
+            ok(req.into_response(
+                HttpResponse::Ok()
+                    .insert_header((CONTENT_TYPE, "0002"))
+                    .finish(),
+            ))
+        };
+        let mw = DefaultHeaders::new()
+            .add((CONTENT_TYPE, "0001"))
+            .new_transform(srv.into_service())
+            .await
+            .unwrap();
+        let resp = mw.call(req).await.unwrap();
+        assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0002");
+    }
+
+    #[actix_rt::test]
+    async fn adding_content_type() {
+        let mw = DefaultHeaders::new()
+            .add_content_type()
+            .new_transform(test::ok_service())
+            .await
+            .unwrap();
+
+        let req = TestRequest::default().to_srv_request();
+        let resp = mw.call(req).await.unwrap();
+        assert_eq!(
+            resp.headers().get(CONTENT_TYPE).unwrap(),
+            "application/octet-stream"
+        );
+    }
+
+    #[test]
+    #[should_panic]
+    fn invalid_header_name() {
+        DefaultHeaders::new().add((":", "hello"));
+    }
+
+    #[test]
+    #[should_panic]
+    fn invalid_header_value() {
+        DefaultHeaders::new().add(("x-test", "\n"));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/middleware/err_handlers.rs.html b/src/actix_web/middleware/err_handlers.rs.html new file mode 100644 index 000000000..ec49aa342 --- /dev/null +++ b/src/actix_web/middleware/err_handlers.rs.html @@ -0,0 +1,1241 @@ +err_handlers.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
+
//! For middleware documentation, see [`ErrorHandlers`].
+
+use std::{
+    future::Future,
+    pin::Pin,
+    rc::Rc,
+    task::{Context, Poll},
+};
+
+use actix_service::{Service, Transform};
+use ahash::AHashMap;
+use futures_core::{future::LocalBoxFuture, ready};
+use pin_project_lite::pin_project;
+
+use crate::{
+    body::EitherBody,
+    dev::{ServiceRequest, ServiceResponse},
+    http::StatusCode,
+    Error, Result,
+};
+
+/// Return type for [`ErrorHandlers`] custom handlers.
+pub enum ErrorHandlerResponse<B> {
+    /// Immediate HTTP response.
+    Response(ServiceResponse<EitherBody<B>>),
+
+    /// A future that resolves to an HTTP response.
+    Future(LocalBoxFuture<'static, Result<ServiceResponse<EitherBody<B>>, Error>>),
+}
+
+type ErrorHandler<B> = dyn Fn(ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>>;
+
+type DefaultHandler<B> = Option<Rc<ErrorHandler<B>>>;
+
+/// Middleware for registering custom status code based error handlers.
+///
+/// Register handlers with the [`ErrorHandlers::handler()`] method to register a custom error handler
+/// for a given status code. Handlers can modify existing responses or create completely new ones.
+///
+/// To register a default handler, use the [`ErrorHandlers::default_handler()`] method. This
+/// handler will be used only if a response has an error status code (400-599) that isn't covered by
+/// a more specific handler (set with the [`handler()`][ErrorHandlers::handler] method). See examples
+/// below.
+///
+/// To register a default for only client errors (400-499) or only server errors (500-599), use the
+/// [`ErrorHandlers::default_handler_client()`] and [`ErrorHandlers::default_handler_server()`]
+/// methods, respectively.
+///
+/// Any response with a status code that isn't covered by a specific handler or a default handler
+/// will pass by unchanged by this middleware.
+///
+/// # Examples
+///
+/// Adding a header:
+///
+/// ```
+/// use actix_web::{
+///     dev::ServiceResponse,
+///     http::{header, StatusCode},
+///     middleware::{ErrorHandlerResponse, ErrorHandlers},
+///     web, App, HttpResponse, Result,
+/// };
+///
+/// fn add_error_header<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+///     res.response_mut().headers_mut().insert(
+///         header::CONTENT_TYPE,
+///         header::HeaderValue::from_static("Error"),
+///     );
+///
+///     // body is unchanged, map to "left" slot
+///     Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
+/// }
+///
+/// let app = App::new()
+///     .wrap(ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, add_error_header))
+///     .service(web::resource("/").route(web::get().to(HttpResponse::InternalServerError)));
+/// ```
+///
+/// Modifying response body:
+///
+/// ```
+/// use actix_web::{
+///     dev::ServiceResponse,
+///     http::{header, StatusCode},
+///     middleware::{ErrorHandlerResponse, ErrorHandlers},
+///     web, App, HttpResponse, Result,
+/// };
+///
+/// fn add_error_body<B>(res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+///     // split service response into request and response components
+///     let (req, res) = res.into_parts();
+///
+///     // set body of response to modified body
+///     let res = res.set_body("An error occurred.");
+///
+///     // modified bodies need to be boxed and placed in the "right" slot
+///     let res = ServiceResponse::new(req, res)
+///         .map_into_boxed_body()
+///         .map_into_right_body();
+///
+///     Ok(ErrorHandlerResponse::Response(res))
+/// }
+///
+/// let app = App::new()
+///     .wrap(ErrorHandlers::new().handler(StatusCode::INTERNAL_SERVER_ERROR, add_error_body))
+///     .service(web::resource("/").route(web::get().to(HttpResponse::InternalServerError)));
+/// ```
+///
+/// Registering default handler:
+///
+/// ```
+/// # use actix_web::{
+/// #     dev::ServiceResponse,
+/// #     http::{header, StatusCode},
+/// #     middleware::{ErrorHandlerResponse, ErrorHandlers},
+/// #     web, App, HttpResponse, Result,
+/// # };
+/// fn add_error_header<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+///     res.response_mut().headers_mut().insert(
+///         header::CONTENT_TYPE,
+///         header::HeaderValue::from_static("Error"),
+///     );
+///
+///     // body is unchanged, map to "left" slot
+///     Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
+/// }
+///
+/// fn handle_bad_request<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+///     res.response_mut().headers_mut().insert(
+///         header::CONTENT_TYPE,
+///         header::HeaderValue::from_static("Bad Request Error"),
+///     );
+///
+///     // body is unchanged, map to "left" slot
+///     Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
+/// }
+///
+/// // Bad Request errors will hit `handle_bad_request()`, while all other errors will hit
+/// // `add_error_header()`. The order in which the methods are called is not meaningful.
+/// let app = App::new()
+///     .wrap(
+///         ErrorHandlers::new()
+///             .default_handler(add_error_header)
+///             .handler(StatusCode::BAD_REQUEST, handle_bad_request)
+///     )
+///     .service(web::resource("/").route(web::get().to(HttpResponse::InternalServerError)));
+/// ```
+///
+/// You can set default handlers for all client (4xx) or all server (5xx) errors:
+///
+/// ```
+/// # use actix_web::{
+/// #     dev::ServiceResponse,
+/// #     http::{header, StatusCode},
+/// #     middleware::{ErrorHandlerResponse, ErrorHandlers},
+/// #     web, App, HttpResponse, Result,
+/// # };
+/// # fn add_error_header<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+/// #     res.response_mut().headers_mut().insert(
+/// #         header::CONTENT_TYPE,
+/// #         header::HeaderValue::from_static("Error"),
+/// #     );
+/// #     Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
+/// # }
+/// # fn handle_bad_request<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+/// #     res.response_mut().headers_mut().insert(
+/// #         header::CONTENT_TYPE,
+/// #         header::HeaderValue::from_static("Bad Request Error"),
+/// #     );
+/// #     Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
+/// # }
+/// // Bad request errors will hit `handle_bad_request()`, other client errors will hit
+/// // `add_error_header()`, and server errors will pass through unchanged
+/// let app = App::new()
+///     .wrap(
+///         ErrorHandlers::new()
+///             .default_handler_client(add_error_header) // or .default_handler_server
+///             .handler(StatusCode::BAD_REQUEST, handle_bad_request)
+///     )
+///     .service(web::resource("/").route(web::get().to(HttpResponse::InternalServerError)));
+/// ```
+pub struct ErrorHandlers<B> {
+    default_client: DefaultHandler<B>,
+    default_server: DefaultHandler<B>,
+    handlers: Handlers<B>,
+}
+
+type Handlers<B> = Rc<AHashMap<StatusCode, Box<ErrorHandler<B>>>>;
+
+impl<B> Default for ErrorHandlers<B> {
+    fn default() -> Self {
+        ErrorHandlers {
+            default_client: Default::default(),
+            default_server: Default::default(),
+            handlers: Default::default(),
+        }
+    }
+}
+
+impl<B> ErrorHandlers<B> {
+    /// Construct new `ErrorHandlers` instance.
+    pub fn new() -> Self {
+        ErrorHandlers::default()
+    }
+
+    /// Register error handler for specified status code.
+    pub fn handler<F>(mut self, status: StatusCode, handler: F) -> Self
+    where
+        F: Fn(ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> + 'static,
+    {
+        Rc::get_mut(&mut self.handlers)
+            .unwrap()
+            .insert(status, Box::new(handler));
+        self
+    }
+
+    /// Register a default error handler.
+    ///
+    /// Any request with a status code that hasn't been given a specific other handler (by calling
+    /// [`.handler()`][ErrorHandlers::handler]) will fall back on this.
+    ///
+    /// Note that this will overwrite any default handlers previously set by calling
+    /// [`.default_handler_client()`][ErrorHandlers::default_handler_client] or
+    /// [`.default_handler_server()`][ErrorHandlers::default_handler_server], but not any set by
+    /// calling [`.handler()`][ErrorHandlers::handler].
+    pub fn default_handler<F>(self, handler: F) -> Self
+    where
+        F: Fn(ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> + 'static,
+    {
+        let handler = Rc::new(handler);
+        Self {
+            default_server: Some(handler.clone()),
+            default_client: Some(handler),
+            ..self
+        }
+    }
+
+    /// Register a handler on which to fall back for client error status codes (400-499).
+    pub fn default_handler_client<F>(self, handler: F) -> Self
+    where
+        F: Fn(ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> + 'static,
+    {
+        Self {
+            default_client: Some(Rc::new(handler)),
+            ..self
+        }
+    }
+
+    /// Register a handler on which to fall back for server error status codes (500-599).
+    pub fn default_handler_server<F>(self, handler: F) -> Self
+    where
+        F: Fn(ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> + 'static,
+    {
+        Self {
+            default_server: Some(Rc::new(handler)),
+            ..self
+        }
+    }
+
+    /// Selects the most appropriate handler for the given status code.
+    ///
+    /// If the `handlers` map has an entry for that status code, that handler is returned.
+    /// Otherwise, fall back on the appropriate default handler.
+    fn get_handler<'a>(
+        status: &StatusCode,
+        default_client: Option<&'a ErrorHandler<B>>,
+        default_server: Option<&'a ErrorHandler<B>>,
+        handlers: &'a Handlers<B>,
+    ) -> Option<&'a ErrorHandler<B>> {
+        handlers
+            .get(status)
+            .map(|h| h.as_ref())
+            .or_else(|| status.is_client_error().then_some(default_client).flatten())
+            .or_else(|| status.is_server_error().then_some(default_server).flatten())
+    }
+}
+
+impl<S, B> Transform<S, ServiceRequest> for ErrorHandlers<B>
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
+    S::Future: 'static,
+    B: 'static,
+{
+    type Response = ServiceResponse<EitherBody<B>>;
+    type Error = Error;
+    type Transform = ErrorHandlersMiddleware<S, B>;
+    type InitError = ();
+    type Future = LocalBoxFuture<'static, Result<Self::Transform, Self::InitError>>;
+
+    fn new_transform(&self, service: S) -> Self::Future {
+        let handlers = self.handlers.clone();
+        let default_client = self.default_client.clone();
+        let default_server = self.default_server.clone();
+        Box::pin(async move {
+            Ok(ErrorHandlersMiddleware {
+                service,
+                default_client,
+                default_server,
+                handlers,
+            })
+        })
+    }
+}
+
+#[doc(hidden)]
+pub struct ErrorHandlersMiddleware<S, B> {
+    service: S,
+    default_client: DefaultHandler<B>,
+    default_server: DefaultHandler<B>,
+    handlers: Handlers<B>,
+}
+
+impl<S, B> Service<ServiceRequest> for ErrorHandlersMiddleware<S, B>
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+    S::Future: 'static,
+    B: 'static,
+{
+    type Response = ServiceResponse<EitherBody<B>>;
+    type Error = Error;
+    type Future = ErrorHandlersFuture<S::Future, B>;
+
+    actix_service::forward_ready!(service);
+
+    fn call(&self, req: ServiceRequest) -> Self::Future {
+        let handlers = self.handlers.clone();
+        let default_client = self.default_client.clone();
+        let default_server = self.default_server.clone();
+        let fut = self.service.call(req);
+        ErrorHandlersFuture::ServiceFuture {
+            fut,
+            default_client,
+            default_server,
+            handlers,
+        }
+    }
+}
+
+pin_project! {
+    #[project = ErrorHandlersProj]
+    pub enum ErrorHandlersFuture<Fut, B>
+    where
+        Fut: Future,
+    {
+        ServiceFuture {
+            #[pin]
+            fut: Fut,
+            default_client: DefaultHandler<B>,
+            default_server: DefaultHandler<B>,
+            handlers: Handlers<B>,
+        },
+        ErrorHandlerFuture {
+            fut: LocalBoxFuture<'static, Result<ServiceResponse<EitherBody<B>>, Error>>,
+        },
+    }
+}
+
+impl<Fut, B> Future for ErrorHandlersFuture<Fut, B>
+where
+    Fut: Future<Output = Result<ServiceResponse<B>, Error>>,
+{
+    type Output = Result<ServiceResponse<EitherBody<B>>, Error>;
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        match self.as_mut().project() {
+            ErrorHandlersProj::ServiceFuture {
+                fut,
+                default_client,
+                default_server,
+                handlers,
+            } => {
+                let res = ready!(fut.poll(cx))?;
+                let status = res.status();
+
+                let handler = ErrorHandlers::get_handler(
+                    &status,
+                    default_client.as_mut().map(|f| Rc::as_ref(f)),
+                    default_server.as_mut().map(|f| Rc::as_ref(f)),
+                    handlers,
+                );
+                match handler {
+                    Some(handler) => match handler(res)? {
+                        ErrorHandlerResponse::Response(res) => Poll::Ready(Ok(res)),
+                        ErrorHandlerResponse::Future(fut) => {
+                            self.as_mut()
+                                .set(ErrorHandlersFuture::ErrorHandlerFuture { fut });
+
+                            self.poll(cx)
+                        }
+                    },
+                    None => Poll::Ready(Ok(res.map_into_left_body())),
+                }
+            }
+
+            ErrorHandlersProj::ErrorHandlerFuture { fut } => fut.as_mut().poll(cx),
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_service::IntoService;
+    use actix_utils::future::ok;
+    use bytes::Bytes;
+    use futures_util::FutureExt as _;
+
+    use super::*;
+    use crate::{
+        body,
+        http::header::{HeaderValue, CONTENT_TYPE},
+        test::{self, TestRequest},
+    };
+
+    #[actix_rt::test]
+    async fn add_header_error_handler() {
+        #[allow(clippy::unnecessary_wraps)]
+        fn error_handler<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+            res.response_mut()
+                .headers_mut()
+                .insert(CONTENT_TYPE, HeaderValue::from_static("0001"));
+
+            Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
+        }
+
+        let srv = test::status_service(StatusCode::INTERNAL_SERVER_ERROR);
+
+        let mw = ErrorHandlers::new()
+            .handler(StatusCode::INTERNAL_SERVER_ERROR, error_handler)
+            .new_transform(srv.into_service())
+            .await
+            .unwrap();
+
+        let resp = test::call_service(&mw, TestRequest::default().to_srv_request()).await;
+        assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
+    }
+
+    #[actix_rt::test]
+    async fn add_header_error_handler_async() {
+        #[allow(clippy::unnecessary_wraps)]
+        fn error_handler<B: 'static>(
+            mut res: ServiceResponse<B>,
+        ) -> Result<ErrorHandlerResponse<B>> {
+            res.response_mut()
+                .headers_mut()
+                .insert(CONTENT_TYPE, HeaderValue::from_static("0001"));
+
+            Ok(ErrorHandlerResponse::Future(
+                ok(res.map_into_left_body()).boxed_local(),
+            ))
+        }
+
+        let srv = test::status_service(StatusCode::INTERNAL_SERVER_ERROR);
+
+        let mw = ErrorHandlers::new()
+            .handler(StatusCode::INTERNAL_SERVER_ERROR, error_handler)
+            .new_transform(srv.into_service())
+            .await
+            .unwrap();
+
+        let resp = test::call_service(&mw, TestRequest::default().to_srv_request()).await;
+        assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
+    }
+
+    #[actix_rt::test]
+    async fn changes_body_type() {
+        #[allow(clippy::unnecessary_wraps)]
+        fn error_handler<B>(res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+            let (req, res) = res.into_parts();
+            let res = res.set_body(Bytes::from("sorry, that's no bueno"));
+
+            let res = ServiceResponse::new(req, res)
+                .map_into_boxed_body()
+                .map_into_right_body();
+
+            Ok(ErrorHandlerResponse::Response(res))
+        }
+
+        let srv = test::status_service(StatusCode::INTERNAL_SERVER_ERROR);
+
+        let mw = ErrorHandlers::new()
+            .handler(StatusCode::INTERNAL_SERVER_ERROR, error_handler)
+            .new_transform(srv.into_service())
+            .await
+            .unwrap();
+
+        let res = test::call_service(&mw, TestRequest::default().to_srv_request()).await;
+        assert_eq!(test::read_body(res).await, "sorry, that's no bueno");
+    }
+
+    #[actix_rt::test]
+    async fn error_thrown() {
+        #[allow(clippy::unnecessary_wraps)]
+        fn error_handler<B>(_res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+            Err(crate::error::ErrorInternalServerError(
+                "error in error handler",
+            ))
+        }
+
+        let srv = test::status_service(StatusCode::BAD_REQUEST);
+
+        let mw = ErrorHandlers::new()
+            .handler(StatusCode::BAD_REQUEST, error_handler)
+            .new_transform(srv.into_service())
+            .await
+            .unwrap();
+
+        let err = mw
+            .call(TestRequest::default().to_srv_request())
+            .await
+            .unwrap_err();
+        let res = err.error_response();
+
+        assert_eq!(res.status(), StatusCode::INTERNAL_SERVER_ERROR);
+        assert_eq!(
+            body::to_bytes(res.into_body()).await.unwrap(),
+            "error in error handler"
+        );
+    }
+
+    #[actix_rt::test]
+    async fn default_error_handler() {
+        #[allow(clippy::unnecessary_wraps)]
+        fn error_handler<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+            res.response_mut()
+                .headers_mut()
+                .insert(CONTENT_TYPE, HeaderValue::from_static("0001"));
+            Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
+        }
+
+        let make_mw = |status| async move {
+            ErrorHandlers::new()
+                .default_handler(error_handler)
+                .new_transform(test::status_service(status).into_service())
+                .await
+                .unwrap()
+        };
+        let mw_server = make_mw(StatusCode::INTERNAL_SERVER_ERROR).await;
+        let mw_client = make_mw(StatusCode::BAD_REQUEST).await;
+
+        let resp = test::call_service(&mw_client, TestRequest::default().to_srv_request()).await;
+        assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
+
+        let resp = test::call_service(&mw_server, TestRequest::default().to_srv_request()).await;
+        assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
+    }
+
+    #[actix_rt::test]
+    async fn default_handlers_separate_client_server() {
+        #[allow(clippy::unnecessary_wraps)]
+        fn error_handler_client<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+            res.response_mut()
+                .headers_mut()
+                .insert(CONTENT_TYPE, HeaderValue::from_static("0001"));
+            Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
+        }
+
+        #[allow(clippy::unnecessary_wraps)]
+        fn error_handler_server<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+            res.response_mut()
+                .headers_mut()
+                .insert(CONTENT_TYPE, HeaderValue::from_static("0002"));
+            Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
+        }
+
+        let make_mw = |status| async move {
+            ErrorHandlers::new()
+                .default_handler_server(error_handler_server)
+                .default_handler_client(error_handler_client)
+                .new_transform(test::status_service(status).into_service())
+                .await
+                .unwrap()
+        };
+        let mw_server = make_mw(StatusCode::INTERNAL_SERVER_ERROR).await;
+        let mw_client = make_mw(StatusCode::BAD_REQUEST).await;
+
+        let resp = test::call_service(&mw_client, TestRequest::default().to_srv_request()).await;
+        assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
+
+        let resp = test::call_service(&mw_server, TestRequest::default().to_srv_request()).await;
+        assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0002");
+    }
+
+    #[actix_rt::test]
+    async fn default_handlers_specialization() {
+        #[allow(clippy::unnecessary_wraps)]
+        fn error_handler_client<B>(mut res: ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
+            res.response_mut()
+                .headers_mut()
+                .insert(CONTENT_TYPE, HeaderValue::from_static("0001"));
+            Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
+        }
+
+        #[allow(clippy::unnecessary_wraps)]
+        fn error_handler_specific<B>(
+            mut res: ServiceResponse<B>,
+        ) -> Result<ErrorHandlerResponse<B>> {
+            res.response_mut()
+                .headers_mut()
+                .insert(CONTENT_TYPE, HeaderValue::from_static("0003"));
+            Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
+        }
+
+        let make_mw = |status| async move {
+            ErrorHandlers::new()
+                .default_handler_client(error_handler_client)
+                .handler(StatusCode::UNPROCESSABLE_ENTITY, error_handler_specific)
+                .new_transform(test::status_service(status).into_service())
+                .await
+                .unwrap()
+        };
+        let mw_client = make_mw(StatusCode::BAD_REQUEST).await;
+        let mw_specific = make_mw(StatusCode::UNPROCESSABLE_ENTITY).await;
+
+        let resp = test::call_service(&mw_client, TestRequest::default().to_srv_request()).await;
+        assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0001");
+
+        let resp = test::call_service(&mw_specific, TestRequest::default().to_srv_request()).await;
+        assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "0003");
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/middleware/logger.rs.html b/src/actix_web/middleware/logger.rs.html new file mode 100644 index 000000000..7051a9fd7 --- /dev/null +++ b/src/actix_web/middleware/logger.rs.html @@ -0,0 +1,2023 @@ +logger.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
+
//! For middleware documentation, see [`Logger`].
+
+use std::{
+    borrow::Cow,
+    collections::HashSet,
+    env,
+    fmt::{self, Display as _},
+    future::Future,
+    marker::PhantomData,
+    pin::Pin,
+    rc::Rc,
+    task::{Context, Poll},
+};
+
+use actix_service::{Service, Transform};
+use actix_utils::future::{ready, Ready};
+use bytes::Bytes;
+use futures_core::ready;
+use log::{debug, warn};
+use pin_project_lite::pin_project;
+#[cfg(feature = "unicode")]
+use regex::Regex;
+#[cfg(not(feature = "unicode"))]
+use regex_lite::Regex;
+use time::{format_description::well_known::Rfc3339, OffsetDateTime};
+
+use crate::{
+    body::{BodySize, MessageBody},
+    http::header::HeaderName,
+    service::{ServiceRequest, ServiceResponse},
+    Error, Result,
+};
+
+/// Middleware for logging request and response summaries to the terminal.
+///
+/// This middleware uses the `log` crate to output information. Enable `log`'s output for the
+/// "actix_web" scope using [`env_logger`](https://docs.rs/env_logger) or similar crate.
+///
+/// # Default Format
+/// The [`default`](Logger::default) Logger uses the following format:
+///
+/// ```plain
+/// %a "%r" %s %b "%{Referer}i" "%{User-Agent}i" %T
+///
+/// Example Output:
+/// 127.0.0.1:54278 "GET /test HTTP/1.1" 404 20 "-" "HTTPie/2.2.0" 0.001074
+/// ```
+///
+/// # Examples
+/// ```
+/// use actix_web::{middleware::Logger, App};
+///
+/// // access logs are printed with the INFO level so ensure it is enabled by default
+/// env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
+///
+/// let app = App::new()
+///     // .wrap(Logger::default())
+///     .wrap(Logger::new("%a %{User-Agent}i"));
+/// ```
+///
+/// # Format
+/// Variable | Description
+/// -------- | -----------
+/// `%%` | The percent sign
+/// `%a` | Peer IP address (or IP address of reverse proxy if used)
+/// `%t` | Time when the request started processing (in RFC 3339 format)
+/// `%r` | First line of request (Example: `GET /test HTTP/1.1`)
+/// `%s` | Response status code
+/// `%b` | Size of response in bytes, including HTTP headers
+/// `%T` | Time taken to serve the request, in seconds to 6 decimal places
+/// `%D` | Time taken to serve the request, in milliseconds
+/// `%U` | Request URL
+/// `%{r}a` | "Real IP" remote address **\***
+/// `%{FOO}i` | `request.headers["FOO"]`
+/// `%{FOO}o` | `response.headers["FOO"]`
+/// `%{FOO}e` | `env_var["FOO"]`
+/// `%{FOO}xi` | [Custom request replacement](Logger::custom_request_replace) labelled "FOO"
+/// `%{FOO}xo` | [Custom response replacement](Logger::custom_response_replace) labelled "FOO"
+///
+/// # Security
+/// **\*** "Real IP" remote address is calculated using
+/// [`ConnectionInfo::realip_remote_addr()`](crate::dev::ConnectionInfo::realip_remote_addr())
+///
+/// If you use this value, ensure that all requests come from trusted hosts. Otherwise, it is
+/// trivial for the remote client to falsify their source IP address.
+#[derive(Debug)]
+pub struct Logger(Rc<Inner>);
+
+#[derive(Debug, Clone)]
+struct Inner {
+    format: Format,
+    exclude: HashSet<String>,
+    exclude_regex: Vec<Regex>,
+    log_target: Cow<'static, str>,
+}
+
+impl Logger {
+    /// Create `Logger` middleware with the specified `format`.
+    pub fn new(format: &str) -> Logger {
+        Logger(Rc::new(Inner {
+            format: Format::new(format),
+            exclude: HashSet::new(),
+            exclude_regex: Vec::new(),
+            log_target: Cow::Borrowed(module_path!()),
+        }))
+    }
+
+    /// Ignore and do not log access info for specified path.
+    pub fn exclude<T: Into<String>>(mut self, path: T) -> Self {
+        Rc::get_mut(&mut self.0)
+            .unwrap()
+            .exclude
+            .insert(path.into());
+        self
+    }
+
+    /// Ignore and do not log access info for paths that match regex.
+    pub fn exclude_regex<T: Into<String>>(mut self, path: T) -> Self {
+        let inner = Rc::get_mut(&mut self.0).unwrap();
+        inner.exclude_regex.push(Regex::new(&path.into()).unwrap());
+        self
+    }
+
+    /// Sets the logging target to `target`.
+    ///
+    /// By default, the log target is `module_path!()` of the log call location. In our case, that
+    /// would be `actix_web::middleware::logger`.
+    ///
+    /// # Examples
+    /// Using `.log_target("http_log")` would have this effect on request logs:
+    /// ```diff
+    /// - [2015-10-21T07:28:00Z INFO  actix_web::middleware::logger] 127.0.0.1 "GET / HTTP/1.1" 200 88 "-" "dmc/1.0" 0.001985
+    /// + [2015-10-21T07:28:00Z INFO  http_log] 127.0.0.1 "GET / HTTP/1.1" 200 88 "-" "dmc/1.0" 0.001985
+    ///                               ^^^^^^^^
+    /// ```
+    pub fn log_target(mut self, target: impl Into<Cow<'static, str>>) -> Self {
+        let inner = Rc::get_mut(&mut self.0).unwrap();
+        inner.log_target = target.into();
+        self
+    }
+
+    /// Register a function that receives a ServiceRequest and returns a String for use in the
+    /// log line. The label passed as the first argument should match a replacement substring in
+    /// the logger format like `%{label}xi`.
+    ///
+    /// It is convention to print "-" to indicate no output instead of an empty string.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_web::http::{header::HeaderValue};
+    /// # use actix_web::middleware::Logger;
+    /// # fn parse_jwt_id (_req: Option<&HeaderValue>) -> String { "jwt_uid".to_owned() }
+    /// Logger::new("example %{JWT_ID}xi")
+    ///     .custom_request_replace("JWT_ID", |req| parse_jwt_id(req.headers().get("Authorization")));
+    /// ```
+    pub fn custom_request_replace(
+        mut self,
+        label: &str,
+        f: impl Fn(&ServiceRequest) -> String + 'static,
+    ) -> Self {
+        let inner = Rc::get_mut(&mut self.0).unwrap();
+
+        let ft = inner.format.0.iter_mut().find(
+            |ft| matches!(ft, FormatText::CustomRequest(unit_label, _) if label == unit_label),
+        );
+
+        if let Some(FormatText::CustomRequest(_, request_fn)) = ft {
+            // replace into None or previously registered fn using same label
+            request_fn.replace(CustomRequestFn {
+                inner_fn: Rc::new(f),
+            });
+        } else {
+            // non-printed request replacement function diagnostic
+            debug!(
+                "Attempted to register custom request logging function for nonexistent label: {}",
+                label
+            );
+        }
+
+        self
+    }
+
+    /// Register a function that receives a `ServiceResponse` and returns a string for use in the
+    /// log line.
+    ///
+    /// The label passed as the first argument should match a replacement substring in
+    /// the logger format like `%{label}xo`.
+    ///
+    /// It is convention to print "-" to indicate no output instead of an empty string.
+    ///
+    /// The replacement function does not have access to the response body.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_web::{dev::ServiceResponse, middleware::Logger};
+    /// fn log_if_error(res: &ServiceResponse) -> String {
+    ///     if res.status().as_u16() >= 400 {
+    ///         "ERROR".to_string()
+    ///     } else {
+    ///         "-".to_string()
+    ///     }
+    /// }
+    ///
+    /// Logger::new("example %{ERROR_STATUS}xo")
+    ///     .custom_response_replace("ERROR_STATUS", |res| log_if_error(res) );
+    /// ```
+    pub fn custom_response_replace(
+        mut self,
+        label: &str,
+        f: impl Fn(&ServiceResponse) -> String + 'static,
+    ) -> Self {
+        let inner = Rc::get_mut(&mut self.0).unwrap();
+
+        let ft = inner.format.0.iter_mut().find(
+            |ft| matches!(ft, FormatText::CustomResponse(unit_label, _) if label == unit_label),
+        );
+
+        if let Some(FormatText::CustomResponse(_, res_fn)) = ft {
+            *res_fn = Some(CustomResponseFn {
+                inner_fn: Rc::new(f),
+            });
+        } else {
+            debug!(
+                "Attempted to register custom response logging function for non-existent label: {}",
+                label
+            );
+        }
+
+        self
+    }
+}
+
+impl Default for Logger {
+    /// Create `Logger` middleware with format:
+    ///
+    /// ```plain
+    /// %a "%r" %s %b "%{Referer}i" "%{User-Agent}i" %T
+    /// ```
+    fn default() -> Logger {
+        Logger(Rc::new(Inner {
+            format: Format::default(),
+            exclude: HashSet::new(),
+            exclude_regex: Vec::new(),
+            log_target: Cow::Borrowed(module_path!()),
+        }))
+    }
+}
+
+impl<S, B> Transform<S, ServiceRequest> for Logger
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+    B: MessageBody,
+{
+    type Response = ServiceResponse<StreamLog<B>>;
+    type Error = Error;
+    type Transform = LoggerMiddleware<S>;
+    type InitError = ();
+    type Future = Ready<Result<Self::Transform, Self::InitError>>;
+
+    fn new_transform(&self, service: S) -> Self::Future {
+        for unit in &self.0.format.0 {
+            if let FormatText::CustomRequest(label, None) = unit {
+                warn!(
+                    "No custom request replacement function was registered for label: {}",
+                    label
+                );
+            }
+
+            if let FormatText::CustomResponse(label, None) = unit {
+                warn!(
+                    "No custom response replacement function was registered for label: {}",
+                    label
+                );
+            }
+        }
+
+        ready(Ok(LoggerMiddleware {
+            service,
+            inner: self.0.clone(),
+        }))
+    }
+}
+
+/// Logger middleware service.
+pub struct LoggerMiddleware<S> {
+    inner: Rc<Inner>,
+    service: S,
+}
+
+impl<S, B> Service<ServiceRequest> for LoggerMiddleware<S>
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+    B: MessageBody,
+{
+    type Response = ServiceResponse<StreamLog<B>>;
+    type Error = Error;
+    type Future = LoggerResponse<S, B>;
+
+    actix_service::forward_ready!(service);
+
+    fn call(&self, req: ServiceRequest) -> Self::Future {
+        let excluded = self.inner.exclude.contains(req.path())
+            || self
+                .inner
+                .exclude_regex
+                .iter()
+                .any(|r| r.is_match(req.path()));
+
+        if excluded {
+            LoggerResponse {
+                fut: self.service.call(req),
+                format: None,
+                time: OffsetDateTime::now_utc(),
+                log_target: Cow::Borrowed(""),
+                _phantom: PhantomData,
+            }
+        } else {
+            let now = OffsetDateTime::now_utc();
+            let mut format = self.inner.format.clone();
+
+            for unit in &mut format.0 {
+                unit.render_request(now, &req);
+            }
+
+            LoggerResponse {
+                fut: self.service.call(req),
+                format: Some(format),
+                time: now,
+                log_target: self.inner.log_target.clone(),
+                _phantom: PhantomData,
+            }
+        }
+    }
+}
+
+pin_project! {
+    pub struct LoggerResponse<S, B>
+    where
+        B: MessageBody,
+        S: Service<ServiceRequest>,
+    {
+        #[pin]
+        fut: S::Future,
+        time: OffsetDateTime,
+        format: Option<Format>,
+        log_target: Cow<'static, str>,
+        _phantom: PhantomData<B>,
+    }
+}
+
+impl<S, B> Future for LoggerResponse<S, B>
+where
+    B: MessageBody,
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+{
+    type Output = Result<ServiceResponse<StreamLog<B>>, Error>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.project();
+
+        let res = match ready!(this.fut.poll(cx)) {
+            Ok(res) => res,
+            Err(err) => return Poll::Ready(Err(err)),
+        };
+
+        if let Some(error) = res.response().error() {
+            debug!("Error in response: {:?}", error);
+        }
+
+        let res = if let Some(ref mut format) = this.format {
+            // to avoid polluting all the Logger types with the body parameter we swap the body
+            // out temporarily since it's not usable in custom response functions anyway
+
+            let (req, res) = res.into_parts();
+            let (res, body) = res.into_parts();
+
+            let temp_res = ServiceResponse::new(req, res.map_into_boxed_body());
+
+            for unit in &mut format.0 {
+                unit.render_response(&temp_res);
+            }
+
+            // re-construct original service response
+            let (req, res) = temp_res.into_parts();
+            ServiceResponse::new(req, res.set_body(body))
+        } else {
+            res
+        };
+
+        let time = *this.time;
+        let format = this.format.take();
+        let log_target = this.log_target.clone();
+
+        Poll::Ready(Ok(res.map_body(move |_, body| StreamLog {
+            body,
+            time,
+            format,
+            size: 0,
+            log_target,
+        })))
+    }
+}
+
+pin_project! {
+    pub struct StreamLog<B> {
+        #[pin]
+        body: B,
+        format: Option<Format>,
+        size: usize,
+        time: OffsetDateTime,
+        log_target: Cow<'static, str>,
+    }
+
+    impl<B> PinnedDrop for StreamLog<B> {
+        fn drop(this: Pin<&mut Self>) {
+            if let Some(ref format) = this.format {
+                let render = |fmt: &mut fmt::Formatter<'_>| {
+                    for unit in &format.0 {
+                        unit.render(fmt, this.size, this.time)?;
+                    }
+                    Ok(())
+                };
+
+                log::info!(
+                    target: this.log_target.as_ref(),
+                    "{}", FormatDisplay(&render)
+                );
+            }
+        }
+    }
+}
+
+impl<B: MessageBody> MessageBody for StreamLog<B> {
+    type Error = B::Error;
+
+    #[inline]
+    fn size(&self) -> BodySize {
+        self.body.size()
+    }
+
+    fn poll_next(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+    ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+        let this = self.project();
+
+        match ready!(this.body.poll_next(cx)) {
+            Some(Ok(chunk)) => {
+                *this.size += chunk.len();
+                Poll::Ready(Some(Ok(chunk)))
+            }
+            Some(Err(err)) => Poll::Ready(Some(Err(err))),
+            None => Poll::Ready(None),
+        }
+    }
+}
+
+/// A formatting style for the `Logger` consisting of multiple concatenated `FormatText` items.
+#[derive(Debug, Clone)]
+struct Format(Vec<FormatText>);
+
+impl Default for Format {
+    /// Return the default formatting style for the `Logger`:
+    fn default() -> Format {
+        Format::new(r#"%a "%r" %s %b "%{Referer}i" "%{User-Agent}i" %T"#)
+    }
+}
+
+impl Format {
+    /// Create a `Format` from a format string.
+    ///
+    /// Returns `None` if the format string syntax is incorrect.
+    pub fn new(s: &str) -> Format {
+        log::trace!("Access log format: {}", s);
+        let fmt = Regex::new(r"%(\{([A-Za-z0-9\-_]+)\}([aioe]|x[io])|[%atPrUsbTD]?)").unwrap();
+
+        let mut idx = 0;
+        let mut results = Vec::new();
+        for cap in fmt.captures_iter(s) {
+            let m = cap.get(0).unwrap();
+            let pos = m.start();
+            if idx != pos {
+                results.push(FormatText::Str(s[idx..pos].to_owned()));
+            }
+            idx = m.end();
+
+            if let Some(key) = cap.get(2) {
+                results.push(match cap.get(3).unwrap().as_str() {
+                    "a" => {
+                        if key.as_str() == "r" {
+                            FormatText::RealIpRemoteAddr
+                        } else {
+                            unreachable!("regex and code mismatch")
+                        }
+                    }
+                    "i" => FormatText::RequestHeader(HeaderName::try_from(key.as_str()).unwrap()),
+                    "o" => FormatText::ResponseHeader(HeaderName::try_from(key.as_str()).unwrap()),
+                    "e" => FormatText::EnvironHeader(key.as_str().to_owned()),
+                    "xi" => FormatText::CustomRequest(key.as_str().to_owned(), None),
+                    "xo" => FormatText::CustomResponse(key.as_str().to_owned(), None),
+                    _ => unreachable!(),
+                })
+            } else {
+                let m = cap.get(1).unwrap();
+                results.push(match m.as_str() {
+                    "%" => FormatText::Percent,
+                    "a" => FormatText::RemoteAddr,
+                    "t" => FormatText::RequestTime,
+                    "r" => FormatText::RequestLine,
+                    "s" => FormatText::ResponseStatus,
+                    "b" => FormatText::ResponseSize,
+                    "U" => FormatText::UrlPath,
+                    "T" => FormatText::Time,
+                    "D" => FormatText::TimeMillis,
+                    _ => FormatText::Str(m.as_str().to_owned()),
+                });
+            }
+        }
+        if idx != s.len() {
+            results.push(FormatText::Str(s[idx..].to_owned()));
+        }
+
+        Format(results)
+    }
+}
+
+/// A string of text to be logged.
+///
+/// This is either one of the data fields supported by the `Logger`, or a custom `String`.
+#[non_exhaustive]
+#[derive(Debug, Clone)]
+enum FormatText {
+    Str(String),
+    Percent,
+    RequestLine,
+    RequestTime,
+    ResponseStatus,
+    ResponseSize,
+    Time,
+    TimeMillis,
+    RemoteAddr,
+    RealIpRemoteAddr,
+    UrlPath,
+    RequestHeader(HeaderName),
+    ResponseHeader(HeaderName),
+    EnvironHeader(String),
+    CustomRequest(String, Option<CustomRequestFn>),
+    CustomResponse(String, Option<CustomResponseFn>),
+}
+
+#[derive(Clone)]
+struct CustomRequestFn {
+    inner_fn: Rc<dyn Fn(&ServiceRequest) -> String>,
+}
+
+impl CustomRequestFn {
+    fn call(&self, req: &ServiceRequest) -> String {
+        (self.inner_fn)(req)
+    }
+}
+
+impl fmt::Debug for CustomRequestFn {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("custom_request_fn")
+    }
+}
+
+#[derive(Clone)]
+struct CustomResponseFn {
+    inner_fn: Rc<dyn Fn(&ServiceResponse) -> String>,
+}
+
+impl CustomResponseFn {
+    fn call(&self, res: &ServiceResponse) -> String {
+        (self.inner_fn)(res)
+    }
+}
+
+impl fmt::Debug for CustomResponseFn {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str("custom_response_fn")
+    }
+}
+
+impl FormatText {
+    fn render(
+        &self,
+        fmt: &mut fmt::Formatter<'_>,
+        size: usize,
+        entry_time: OffsetDateTime,
+    ) -> Result<(), fmt::Error> {
+        match self {
+            FormatText::Str(ref string) => fmt.write_str(string),
+            FormatText::Percent => "%".fmt(fmt),
+            FormatText::ResponseSize => size.fmt(fmt),
+            FormatText::Time => {
+                let rt = OffsetDateTime::now_utc() - entry_time;
+                let rt = rt.as_seconds_f64();
+                fmt.write_fmt(format_args!("{:.6}", rt))
+            }
+            FormatText::TimeMillis => {
+                let rt = OffsetDateTime::now_utc() - entry_time;
+                let rt = (rt.whole_nanoseconds() as f64) / 1_000_000.0;
+                fmt.write_fmt(format_args!("{:.6}", rt))
+            }
+            FormatText::EnvironHeader(ref name) => {
+                if let Ok(val) = env::var(name) {
+                    fmt.write_fmt(format_args!("{}", val))
+                } else {
+                    "-".fmt(fmt)
+                }
+            }
+            _ => Ok(()),
+        }
+    }
+
+    fn render_response(&mut self, res: &ServiceResponse) {
+        match self {
+            FormatText::ResponseStatus => {
+                *self = FormatText::Str(format!("{}", res.status().as_u16()))
+            }
+
+            FormatText::ResponseHeader(ref name) => {
+                let s = if let Some(val) = res.headers().get(name) {
+                    if let Ok(s) = val.to_str() {
+                        s
+                    } else {
+                        "-"
+                    }
+                } else {
+                    "-"
+                };
+                *self = FormatText::Str(s.to_string())
+            }
+
+            FormatText::CustomResponse(_, res_fn) => {
+                let text = match res_fn {
+                    Some(res_fn) => FormatText::Str(res_fn.call(res)),
+                    None => FormatText::Str("-".to_owned()),
+                };
+
+                *self = text;
+            }
+
+            _ => {}
+        }
+    }
+
+    fn render_request(&mut self, now: OffsetDateTime, req: &ServiceRequest) {
+        match self {
+            FormatText::RequestLine => {
+                *self = if req.query_string().is_empty() {
+                    FormatText::Str(format!(
+                        "{} {} {:?}",
+                        req.method(),
+                        req.path(),
+                        req.version()
+                    ))
+                } else {
+                    FormatText::Str(format!(
+                        "{} {}?{} {:?}",
+                        req.method(),
+                        req.path(),
+                        req.query_string(),
+                        req.version()
+                    ))
+                };
+            }
+            FormatText::UrlPath => *self = FormatText::Str(req.path().to_string()),
+            FormatText::RequestTime => *self = FormatText::Str(now.format(&Rfc3339).unwrap()),
+            FormatText::RequestHeader(ref name) => {
+                let s = if let Some(val) = req.headers().get(name) {
+                    if let Ok(s) = val.to_str() {
+                        s
+                    } else {
+                        "-"
+                    }
+                } else {
+                    "-"
+                };
+                *self = FormatText::Str(s.to_string());
+            }
+            FormatText::RemoteAddr => {
+                let s = if let Some(peer) = req.connection_info().peer_addr() {
+                    FormatText::Str((*peer).to_string())
+                } else {
+                    FormatText::Str("-".to_string())
+                };
+                *self = s;
+            }
+            FormatText::RealIpRemoteAddr => {
+                let s = if let Some(remote) = req.connection_info().realip_remote_addr() {
+                    FormatText::Str(remote.to_string())
+                } else {
+                    FormatText::Str("-".to_string())
+                };
+                *self = s;
+            }
+            FormatText::CustomRequest(_, request_fn) => {
+                let s = match request_fn {
+                    Some(f) => FormatText::Str(f.call(req)),
+                    None => FormatText::Str("-".to_owned()),
+                };
+
+                *self = s;
+            }
+            _ => {}
+        }
+    }
+}
+
+/// Converter to get a String from something that writes to a Formatter.
+pub(crate) struct FormatDisplay<'a>(&'a dyn Fn(&mut fmt::Formatter<'_>) -> Result<(), fmt::Error>);
+
+impl<'a> fmt::Display for FormatDisplay<'a> {
+    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
+        (self.0)(fmt)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_service::IntoService;
+    use actix_utils::future::ok;
+
+    use super::*;
+    use crate::{
+        http::{header, StatusCode},
+        test::{self, TestRequest},
+        HttpResponse,
+    };
+
+    #[actix_rt::test]
+    async fn test_logger() {
+        let srv = |req: ServiceRequest| {
+            ok(req.into_response(
+                HttpResponse::build(StatusCode::OK)
+                    .insert_header(("X-Test", "ttt"))
+                    .finish(),
+            ))
+        };
+        let logger = Logger::new("%% %{User-Agent}i %{X-Test}o %{HOME}e %D test");
+
+        let srv = logger.new_transform(srv.into_service()).await.unwrap();
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::USER_AGENT,
+                header::HeaderValue::from_static("ACTIX-WEB"),
+            ))
+            .to_srv_request();
+        let _res = srv.call(req).await;
+    }
+
+    #[actix_rt::test]
+    async fn test_logger_exclude_regex() {
+        let srv = |req: ServiceRequest| {
+            ok(req.into_response(
+                HttpResponse::build(StatusCode::OK)
+                    .insert_header(("X-Test", "ttt"))
+                    .finish(),
+            ))
+        };
+        let logger =
+            Logger::new("%% %{User-Agent}i %{X-Test}o %{HOME}e %D test").exclude_regex("\\w");
+
+        let srv = logger.new_transform(srv.into_service()).await.unwrap();
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::USER_AGENT,
+                header::HeaderValue::from_static("ACTIX-WEB"),
+            ))
+            .to_srv_request();
+        let _res = srv.call(req).await.unwrap();
+    }
+
+    #[actix_rt::test]
+    async fn test_escape_percent() {
+        let mut format = Format::new("%%{r}a");
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::FORWARDED,
+                header::HeaderValue::from_static("for=192.0.2.60;proto=http;by=203.0.113.43"),
+            ))
+            .to_srv_request();
+
+        let now = OffsetDateTime::now_utc();
+        for unit in &mut format.0 {
+            unit.render_request(now, &req);
+        }
+
+        let req = TestRequest::default().to_http_request();
+        let res = ServiceResponse::new(req, HttpResponse::Ok().finish());
+        for unit in &mut format.0 {
+            unit.render_response(&res);
+        }
+
+        let entry_time = OffsetDateTime::now_utc();
+        let render = |fmt: &mut fmt::Formatter<'_>| {
+            for unit in &format.0 {
+                unit.render(fmt, 1024, entry_time)?;
+            }
+            Ok(())
+        };
+        let s = format!("{}", FormatDisplay(&render));
+        assert_eq!(s, "%{r}a");
+    }
+
+    #[actix_rt::test]
+    async fn test_url_path() {
+        let mut format = Format::new("%T %U");
+        let req = TestRequest::default()
+            .insert_header((
+                header::USER_AGENT,
+                header::HeaderValue::from_static("ACTIX-WEB"),
+            ))
+            .uri("/test/route/yeah")
+            .to_srv_request();
+
+        let now = OffsetDateTime::now_utc();
+        for unit in &mut format.0 {
+            unit.render_request(now, &req);
+        }
+
+        let req = TestRequest::default().to_http_request();
+        let res = ServiceResponse::new(req, HttpResponse::Ok().force_close().finish());
+        for unit in &mut format.0 {
+            unit.render_response(&res);
+        }
+
+        let render = |fmt: &mut fmt::Formatter<'_>| {
+            for unit in &format.0 {
+                unit.render(fmt, 1024, now)?;
+            }
+            Ok(())
+        };
+        let s = format!("{}", FormatDisplay(&render));
+        assert!(s.contains("/test/route/yeah"));
+    }
+
+    #[actix_rt::test]
+    async fn test_default_format() {
+        let mut format = Format::default();
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::USER_AGENT,
+                header::HeaderValue::from_static("ACTIX-WEB"),
+            ))
+            .peer_addr("127.0.0.1:8081".parse().unwrap())
+            .to_srv_request();
+
+        let now = OffsetDateTime::now_utc();
+        for unit in &mut format.0 {
+            unit.render_request(now, &req);
+        }
+
+        let req = TestRequest::default().to_http_request();
+        let res = ServiceResponse::new(req, HttpResponse::Ok().force_close().finish());
+        for unit in &mut format.0 {
+            unit.render_response(&res);
+        }
+
+        let entry_time = OffsetDateTime::now_utc();
+        let render = |fmt: &mut fmt::Formatter<'_>| {
+            for unit in &format.0 {
+                unit.render(fmt, 1024, entry_time)?;
+            }
+            Ok(())
+        };
+        let s = format!("{}", FormatDisplay(&render));
+        assert!(s.contains("GET / HTTP/1.1"));
+        assert!(s.contains("127.0.0.1"));
+        assert!(s.contains("200 1024"));
+        assert!(s.contains("ACTIX-WEB"));
+    }
+
+    #[actix_rt::test]
+    async fn test_request_time_format() {
+        let mut format = Format::new("%t");
+        let req = TestRequest::default().to_srv_request();
+
+        let now = OffsetDateTime::now_utc();
+        for unit in &mut format.0 {
+            unit.render_request(now, &req);
+        }
+
+        let req = TestRequest::default().to_http_request();
+        let res = ServiceResponse::new(req, HttpResponse::Ok().force_close().finish());
+        for unit in &mut format.0 {
+            unit.render_response(&res);
+        }
+
+        let render = |fmt: &mut fmt::Formatter<'_>| {
+            for unit in &format.0 {
+                unit.render(fmt, 1024, now)?;
+            }
+            Ok(())
+        };
+        let s = format!("{}", FormatDisplay(&render));
+        assert!(s.contains(&now.format(&Rfc3339).unwrap()));
+    }
+
+    #[actix_rt::test]
+    async fn test_remote_addr_format() {
+        let mut format = Format::new("%{r}a");
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::FORWARDED,
+                header::HeaderValue::from_static("for=192.0.2.60;proto=http;by=203.0.113.43"),
+            ))
+            .to_srv_request();
+
+        let now = OffsetDateTime::now_utc();
+        for unit in &mut format.0 {
+            unit.render_request(now, &req);
+        }
+
+        let req = TestRequest::default().to_http_request();
+        let res = ServiceResponse::new(req, HttpResponse::Ok().finish());
+        for unit in &mut format.0 {
+            unit.render_response(&res);
+        }
+
+        let entry_time = OffsetDateTime::now_utc();
+        let render = |fmt: &mut fmt::Formatter<'_>| {
+            for unit in &format.0 {
+                unit.render(fmt, 1024, entry_time)?;
+            }
+            Ok(())
+        };
+        let s = format!("{}", FormatDisplay(&render));
+        assert!(s.contains("192.0.2.60"));
+    }
+
+    #[actix_rt::test]
+    async fn test_custom_closure_req_log() {
+        let mut logger = Logger::new("test %{CUSTOM}xi")
+            .custom_request_replace("CUSTOM", |_req: &ServiceRequest| -> String {
+                String::from("custom_log")
+            });
+        let mut unit = Rc::get_mut(&mut logger.0).unwrap().format.0[1].clone();
+
+        let label = match &unit {
+            FormatText::CustomRequest(label, _) => label,
+            ft => panic!("expected CustomRequest, found {:?}", ft),
+        };
+
+        assert_eq!(label, "CUSTOM");
+
+        let req = TestRequest::default().to_srv_request();
+        let now = OffsetDateTime::now_utc();
+
+        unit.render_request(now, &req);
+
+        let render = |fmt: &mut fmt::Formatter<'_>| unit.render(fmt, 1024, now);
+
+        let log_output = FormatDisplay(&render).to_string();
+        assert_eq!(log_output, "custom_log");
+    }
+
+    #[actix_rt::test]
+    async fn test_custom_closure_response_log() {
+        let mut logger = Logger::new("test %{CUSTOM}xo").custom_response_replace(
+            "CUSTOM",
+            |res: &ServiceResponse| -> String {
+                if res.status().as_u16() == 200 {
+                    String::from("custom_log")
+                } else {
+                    String::from("-")
+                }
+            },
+        );
+        let mut unit = Rc::get_mut(&mut logger.0).unwrap().format.0[1].clone();
+
+        let label = match &unit {
+            FormatText::CustomResponse(label, _) => label,
+            ft => panic!("expected CustomResponse, found {:?}", ft),
+        };
+
+        assert_eq!(label, "CUSTOM");
+
+        let req = TestRequest::default().to_http_request();
+        let resp_ok = ServiceResponse::new(req, HttpResponse::Ok().finish());
+        let now = OffsetDateTime::now_utc();
+        unit.render_response(&resp_ok);
+
+        let render = |fmt: &mut fmt::Formatter<'_>| unit.render(fmt, 1024, now);
+
+        let log_output = FormatDisplay(&render).to_string();
+        assert_eq!(log_output, "custom_log");
+    }
+
+    #[actix_rt::test]
+    async fn test_closure_logger_in_middleware() {
+        let captured = "custom log replacement";
+
+        let logger = Logger::new("%{CUSTOM}xi")
+            .custom_request_replace("CUSTOM", move |_req: &ServiceRequest| -> String {
+                captured.to_owned()
+            });
+
+        let srv = logger.new_transform(test::ok_service()).await.unwrap();
+
+        let req = TestRequest::default().to_srv_request();
+        srv.call(req).await.unwrap();
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/middleware/mod.rs.html b/src/actix_web/middleware/mod.rs.html new file mode 100644 index 000000000..4e96f4dba --- /dev/null +++ b/src/actix_web/middleware/mod.rs.html @@ -0,0 +1,567 @@ +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
+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
+
//! A collection of common middleware.
+//!
+//! # What Is Middleware?
+//!
+//! Actix Web's middleware system allows us to add additional behavior to request/response
+//! processing. Middleware can hook into incoming request and outgoing response processes, enabling
+//! us to modify requests and responses as well as halt request processing to return a response
+//! early.
+//!
+//! Typically, middleware is involved in the following actions:
+//!
+//! - Pre-process the request (e.g., [normalizing paths](NormalizePath))
+//! - Post-process a response (e.g., [logging][Logger])
+//! - Modify application state (through [`ServiceRequest`][crate::dev::ServiceRequest])
+//! - Access external services (e.g., [sessions](https://docs.rs/actix-session), etc.)
+//!
+//! Middleware is registered for each [`App`], [`Scope`](crate::Scope), or
+//! [`Resource`](crate::Resource) and executed in opposite order as registration. In general, a
+//! middleware is a pair of types that implements the [`Service`] trait and [`Transform`] trait,
+//! respectively. The [`new_transform`] and [`call`] methods must return a [`Future`], though it
+//! can often be [an immediately-ready one](actix_utils::future::Ready).
+//!
+//! # Ordering
+//!
+//! ```
+//! # use actix_web::{web, middleware, get, App, Responder};
+//! #
+//! # // some basic types to make sure this compiles
+//! # type ExtractorA = web::Json<String>;
+//! # type ExtractorB = ExtractorA;
+//! #[get("/")]
+//! async fn service(a: ExtractorA, b: ExtractorB) -> impl Responder { "Hello, World!" }
+//!
+//! # fn main() {
+//! # // These aren't snake_case, because they are supposed to be unit structs.
+//! # type MiddlewareA = middleware::Compress;
+//! # type MiddlewareB = middleware::Compress;
+//! # type MiddlewareC = middleware::Compress;
+//! let app = App::new()
+//!     .wrap(MiddlewareA::default())
+//!     .wrap(MiddlewareB::default())
+//!     .wrap(MiddlewareC::default())
+//!     .service(service);
+//! # }
+//! ```
+//!
+//! ```plain
+//!                   Request
+//!                      ⭣
+//! ╭────────────────────┼────╮
+//! │ MiddlewareC        │    │
+//! │ ╭──────────────────┼───╮│
+//! │ │ MiddlewareB      │   ││
+//! │ │ ╭────────────────┼──╮││
+//! │ │ │ MiddlewareA    │  │││
+//! │ │ │ ╭──────────────┼─╮│││
+//! │ │ │ │ ExtractorA   │ ││││
+//! │ │ │ ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┼┈┤│││
+//! │ │ │ │ ExtractorB   │ ││││
+//! │ │ │ ├┈┈┈┈┈┈┈┈┈┈┈┈┈┈┼┈┤│││
+//! │ │ │ │ service      │ ││││
+//! │ │ │ ╰──────────────┼─╯│││
+//! │ │ ╰────────────────┼──╯││
+//! │ ╰──────────────────┼───╯│
+//! ╰────────────────────┼────╯
+//!                      ⭣
+//!                   Response
+//! ```
+//! The request _first_ gets processed by the middleware specified _last_ - `MiddlewareC`. It passes
+//! the request (modified a modified one) to the next middleware - `MiddlewareB` - _or_ directly
+//! responds to the request (e.g. when the request was invalid or an error occurred). `MiddlewareB`
+//! processes the request as well and passes it to `MiddlewareA`, which then passes it to the
+//! [`Service`]. In the [`Service`], the extractors will run first. They don't pass the request on,
+//! but only view it (see [`FromRequest`]). After the [`Service`] responds to the request, the
+//! response is passed back through `MiddlewareA`, `MiddlewareB`, and `MiddlewareC`.
+//!
+//! As you register middleware using [`wrap`][crate::App::wrap] and [`wrap_fn`][crate::App::wrap_fn]
+//! in the [`App`] builder, imagine wrapping layers around an inner [`App`]. The first middleware
+//! layer exposed to a Request is the outermost layer (i.e., the _last_ registered in the builder
+//! chain, in the example above: `MiddlewareC`). Consequently, the _first_ middleware registered in
+//! the builder chain is the _last_ to start executing during request processing (`MiddlewareA`).
+//! Ordering is less obvious when wrapped services also have middleware applied. In this case,
+//! middleware are run in reverse order for [`App`] _and then_ in reverse order for the wrapped
+//! service.
+//!
+//! # Middleware Traits
+//!
+//! ## `Transform<S, Req>`
+//!
+//! The [`Transform`] trait is the builder for the actual [`Service`]s that handle the requests. All
+//! the middleware you pass to the `wrap` methods implement this trait. During construction, each
+//! thread assembles a chain of [`Service`]s by calling [`new_transform`] and passing the next
+//! [`Service`] (`S`) in the chain. The created [`Service`] handles requests of type `Req`.
+//!
+//! In the example from the [ordering](#ordering) section, the chain would be:
+//!
+//! ```plain
+//! MiddlewareCService {
+//!     next: MiddlewareBService {
+//!         next: MiddlewareAService { ... }
+//!     }
+//! }
+//! ```
+//!
+//! ## `Service<Req>`
+//!
+//! A [`Service`] `S` represents an asynchronous operation that turns a request of type `Req` into a
+//! response of type [`S::Response`](crate::dev::Service::Response) or an error of type
+//! [`S::Error`](crate::dev::Service::Error). You can think of the service of being roughly:
+//!
+//! ```ignore
+//! async fn(&self, req: Req) -> Result<S::Response, S::Error>
+//! ```
+//!
+//! In most cases the [`Service`] implementation will, at some point, call the wrapped [`Service`]
+//! in its [`call`] implementation.
+//!
+//! Note that the [`Service`]s created by [`new_transform`] don't need to be [`Send`] or [`Sync`].
+//!
+//! # Example
+//!
+//! ```
+//! use std::{future::{ready, Ready, Future}, pin::Pin};
+//!
+//! use actix_web::{
+//!     dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform},
+//!     web, Error,
+//! #   App
+//! };
+//!
+//! pub struct SayHi;
+//!
+//! // `S` - type of the next service
+//! // `B` - type of response's body
+//! impl<S, B> Transform<S, ServiceRequest> for SayHi
+//! 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 = SayHiMiddleware<S>;
+//!     type Future = Ready<Result<Self::Transform, Self::InitError>>;
+//!
+//!     fn new_transform(&self, service: S) -> Self::Future {
+//!         ready(Ok(SayHiMiddleware { service }))
+//!     }
+//! }
+//!
+//! pub struct SayHiMiddleware<S> {
+//!     /// The next service to call
+//!     service: S,
+//! }
+//!
+//! // This future doesn't have the requirement of being `Send`.
+//! // See: futures_util::future::LocalBoxFuture
+//! type LocalBoxFuture<T> = Pin<Box<dyn Future<Output = T> + 'static>>;
+//!
+//! // `S`: type of the wrapped service
+//! // `B`: type of the body - try to be generic over the body where possible
+//! impl<S, B> Service<ServiceRequest> for SayHiMiddleware<S>
+//! where
+//!     S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+//!     S::Future: 'static,
+//!     B: 'static,
+//! {
+//!     type Response = ServiceResponse<B>;
+//!     type Error = Error;
+//!     type Future = LocalBoxFuture<Result<Self::Response, Self::Error>>;
+//!
+//!     // This service is ready when its next service is ready
+//!     forward_ready!(service);
+//!
+//!     fn call(&self, req: ServiceRequest) -> Self::Future {
+//!         println!("Hi from start. You requested: {}", req.path());
+//!
+//!         // A more complex middleware, could return an error or an early response here.
+//!
+//!         let fut = self.service.call(req);
+//!
+//!         Box::pin(async move {
+//!             let res = fut.await?;
+//!
+//!             println!("Hi from response");
+//!             Ok(res)
+//!         })
+//!     }
+//! }
+//!
+//! # fn main() {
+//! let app = App::new()
+//!     .wrap(SayHi)
+//!     .route("/", web::get().to(|| async { "Hello, middleware!" }));
+//! # }
+//! ```
+//!
+//! # Simpler Middleware
+//!
+//! In many cases, you _can_ actually use an async function via a helper that will provide a more
+//! natural flow for your behavior.
+//!
+//! The experimental `actix_web_lab` crate provides a [`from_fn`][lab_from_fn] utility which allows
+//! an async fn to be wrapped and used in the same way as other middleware. See the
+//! [`from_fn`][lab_from_fn] docs for more info and examples of it's use.
+//!
+//! While [`from_fn`][lab_from_fn] is experimental currently, it's likely this helper will graduate
+//! to Actix Web in some form, so feedback is appreciated.
+//!
+//! [`Future`]: std::future::Future
+//! [`App`]: crate::App
+//! [`FromRequest`]: crate::FromRequest
+//! [`Service`]: crate::dev::Service
+//! [`Transform`]: crate::dev::Transform
+//! [`call`]: crate::dev::Service::call()
+//! [`new_transform`]: crate::dev::Transform::new_transform()
+//! [lab_from_fn]: https://docs.rs/actix-web-lab/latest/actix_web_lab/middleware/fn.from_fn.html
+
+mod compat;
+mod condition;
+mod default_headers;
+mod err_handlers;
+mod logger;
+#[cfg(test)]
+mod noop;
+mod normalize;
+
+#[cfg(test)]
+pub(crate) use self::noop::Noop;
+pub use self::{
+    compat::Compat,
+    condition::Condition,
+    default_headers::DefaultHeaders,
+    err_handlers::{ErrorHandlerResponse, ErrorHandlers},
+    logger::Logger,
+    normalize::{NormalizePath, TrailingSlash},
+};
+
+#[cfg(feature = "__compress")]
+mod compress;
+
+#[cfg(feature = "__compress")]
+pub use self::compress::Compress;
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::{http::StatusCode, App};
+
+    #[test]
+    fn common_combinations() {
+        // ensure there's no reason that the built-in middleware cannot compose
+
+        let _ = App::new()
+            .wrap(Compat::new(Logger::default()))
+            .wrap(Condition::new(true, DefaultHeaders::new()))
+            .wrap(DefaultHeaders::new().add(("X-Test2", "X-Value2")))
+            .wrap(ErrorHandlers::new().handler(StatusCode::FORBIDDEN, |res| {
+                Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
+            }))
+            .wrap(Logger::default())
+            .wrap(NormalizePath::new(TrailingSlash::Trim));
+
+        let _ = App::new()
+            .wrap(NormalizePath::new(TrailingSlash::Trim))
+            .wrap(Logger::default())
+            .wrap(ErrorHandlers::new().handler(StatusCode::FORBIDDEN, |res| {
+                Ok(ErrorHandlerResponse::Response(res.map_into_left_body()))
+            }))
+            .wrap(DefaultHeaders::new().add(("X-Test2", "X-Value2")))
+            .wrap(Condition::new(true, DefaultHeaders::new()))
+            .wrap(Compat::new(Logger::default()));
+
+        #[cfg(feature = "__compress")]
+        {
+            let _ = App::new().wrap(Compress::default()).wrap(Logger::default());
+            let _ = App::new().wrap(Logger::default()).wrap(Compress::default());
+            let _ = App::new().wrap(Compat::new(Compress::default()));
+            let _ = App::new().wrap(Condition::new(true, Compat::new(Compress::default())));
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/middleware/normalize.rs.html b/src/actix_web/middleware/normalize.rs.html new file mode 100644 index 000000000..dff9ae6e7 --- /dev/null +++ b/src/actix_web/middleware/normalize.rs.html @@ -0,0 +1,973 @@ +normalize.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
+
//! For middleware documentation, see [`NormalizePath`].
+
+use actix_http::uri::{PathAndQuery, Uri};
+use actix_service::{Service, Transform};
+use actix_utils::future::{ready, Ready};
+use bytes::Bytes;
+#[cfg(feature = "unicode")]
+use regex::Regex;
+#[cfg(not(feature = "unicode"))]
+use regex_lite::Regex;
+
+use crate::{
+    service::{ServiceRequest, ServiceResponse},
+    Error,
+};
+
+/// Determines the behavior of the [`NormalizePath`] middleware.
+///
+/// The default is `TrailingSlash::Trim`.
+#[non_exhaustive]
+#[derive(Debug, Clone, Copy, Default)]
+pub enum TrailingSlash {
+    /// Trim trailing slashes from the end of the path.
+    ///
+    /// Using this will require all routes to omit trailing slashes for them to be accessible.
+    #[default]
+    Trim,
+
+    /// Only merge any present multiple trailing slashes.
+    ///
+    /// This option provides the best compatibility with behavior in actix-web v2.0.
+    MergeOnly,
+
+    /// Always add a trailing slash to the end of the path.
+    ///
+    /// Using this will require all routes have a trailing slash for them to be accessible.
+    Always,
+}
+
+/// Middleware for normalizing a request's path so that routes can be matched more flexibly.
+///
+/// # Normalization Steps
+/// - Merges consecutive slashes into one. (For example, `/path//one` always becomes `/path/one`.)
+/// - Appends a trailing slash if one is not present, removes one if present, or keeps trailing
+///   slashes as-is, depending on which [`TrailingSlash`] variant is supplied
+///   to [`new`](NormalizePath::new()).
+///
+/// # Default Behavior
+/// The default constructor chooses to strip trailing slashes from the end of paths with them
+/// ([`TrailingSlash::Trim`]). The implication is that route definitions should be defined without
+/// trailing slashes or else they will be inaccessible (or vice versa when using the
+/// `TrailingSlash::Always` behavior), as shown in the example tests below.
+///
+/// # Examples
+/// ```
+/// use actix_web::{web, middleware, App};
+///
+/// # actix_web::rt::System::new().block_on(async {
+/// let app = App::new()
+///     .wrap(middleware::NormalizePath::trim())
+///     .route("/test", web::get().to(|| async { "test" }))
+///     .route("/unmatchable/", web::get().to(|| async { "unmatchable" }));
+///
+/// use actix_web::http::StatusCode;
+/// use actix_web::test::{call_service, init_service, TestRequest};
+///
+/// let app = init_service(app).await;
+///
+/// let req = TestRequest::with_uri("/test").to_request();
+/// let res = call_service(&app, req).await;
+/// assert_eq!(res.status(), StatusCode::OK);
+///
+/// let req = TestRequest::with_uri("/test/").to_request();
+/// let res = call_service(&app, req).await;
+/// assert_eq!(res.status(), StatusCode::OK);
+///
+/// let req = TestRequest::with_uri("/unmatchable").to_request();
+/// let res = call_service(&app, req).await;
+/// assert_eq!(res.status(), StatusCode::NOT_FOUND);
+///
+/// let req = TestRequest::with_uri("/unmatchable/").to_request();
+/// let res = call_service(&app, req).await;
+/// assert_eq!(res.status(), StatusCode::NOT_FOUND);
+/// # })
+/// ```
+#[derive(Debug, Clone, Copy)]
+pub struct NormalizePath(TrailingSlash);
+
+impl Default for NormalizePath {
+    fn default() -> Self {
+        log::warn!(
+            "`NormalizePath::default()` is deprecated. The default trailing slash behavior changed \
+            in v4 from `Always` to `Trim`. Update your call to `NormalizePath::new(...)`."
+        );
+
+        Self(TrailingSlash::Trim)
+    }
+}
+
+impl NormalizePath {
+    /// Create new `NormalizePath` middleware with the specified trailing slash style.
+    pub fn new(trailing_slash_style: TrailingSlash) -> Self {
+        Self(trailing_slash_style)
+    }
+
+    /// Constructs a new `NormalizePath` middleware with [trim](TrailingSlash::Trim) semantics.
+    ///
+    /// Use this instead of `NormalizePath::default()` to avoid deprecation warning.
+    pub fn trim() -> Self {
+        Self::new(TrailingSlash::Trim)
+    }
+}
+
+impl<S, B> Transform<S, ServiceRequest> for NormalizePath
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+    S::Future: 'static,
+{
+    type Response = ServiceResponse<B>;
+    type Error = Error;
+    type Transform = NormalizePathNormalization<S>;
+    type InitError = ();
+    type Future = Ready<Result<Self::Transform, Self::InitError>>;
+
+    fn new_transform(&self, service: S) -> Self::Future {
+        ready(Ok(NormalizePathNormalization {
+            service,
+            merge_slash: Regex::new("//+").unwrap(),
+            trailing_slash_behavior: self.0,
+        }))
+    }
+}
+
+pub struct NormalizePathNormalization<S> {
+    service: S,
+    merge_slash: Regex,
+    trailing_slash_behavior: TrailingSlash,
+}
+
+impl<S, B> Service<ServiceRequest> for NormalizePathNormalization<S>
+where
+    S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
+    S::Future: 'static,
+{
+    type Response = ServiceResponse<B>;
+    type Error = Error;
+    type Future = S::Future;
+
+    actix_service::forward_ready!(service);
+
+    fn call(&self, mut req: ServiceRequest) -> Self::Future {
+        let head = req.head_mut();
+
+        let original_path = head.uri.path();
+
+        // An empty path here means that the URI has no valid path. We skip normalization in this
+        // case, because adding a path can make the URI invalid
+        if !original_path.is_empty() {
+            // Either adds a string to the end (duplicates will be removed anyways) or trims all
+            // slashes from the end
+            let path = match self.trailing_slash_behavior {
+                TrailingSlash::Always => format!("{}/", original_path),
+                TrailingSlash::MergeOnly => original_path.to_string(),
+                TrailingSlash::Trim => original_path.trim_end_matches('/').to_string(),
+            };
+
+            // normalize multiple /'s to one /
+            let path = self.merge_slash.replace_all(&path, "/");
+
+            // Ensure root paths are still resolvable. If resulting path is blank after previous
+            // step it means the path was one or more slashes. Reduce to single slash.
+            let path = if path.is_empty() { "/" } else { path.as_ref() };
+
+            // Check whether the path has been changed
+            //
+            // This check was previously implemented as string length comparison
+            //
+            // That approach fails when a trailing slash is added,
+            // and a duplicate slash is removed,
+            // since the length of the strings remains the same
+            //
+            // For example, the path "/v1//s" will be normalized to "/v1/s/"
+            // Both of the paths have the same length,
+            // so the change can not be deduced from the length comparison
+            if path != original_path {
+                let mut parts = head.uri.clone().into_parts();
+                let query = parts.path_and_query.as_ref().and_then(|pq| pq.query());
+
+                let path = match query {
+                    Some(q) => Bytes::from(format!("{}?{}", path, q)),
+                    None => Bytes::copy_from_slice(path.as_bytes()),
+                };
+                parts.path_and_query = Some(PathAndQuery::from_maybe_shared(path).unwrap());
+
+                let uri = Uri::from_parts(parts).unwrap();
+                req.match_info_mut().get_mut().update(&uri);
+                req.head_mut().uri = uri;
+            }
+        }
+        self.service.call(req)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_http::StatusCode;
+    use actix_service::IntoService;
+
+    use super::*;
+    use crate::{
+        guard::fn_guard,
+        test::{call_service, init_service, TestRequest},
+        web, App, HttpResponse,
+    };
+
+    #[actix_rt::test]
+    async fn test_wrap() {
+        let app = init_service(
+            App::new()
+                .wrap(NormalizePath::default())
+                .service(web::resource("/").to(HttpResponse::Ok))
+                .service(web::resource("/v1/something").to(HttpResponse::Ok))
+                .service(
+                    web::resource("/v2/something")
+                        .guard(fn_guard(|ctx| ctx.head().uri.query() == Some("query=test")))
+                        .to(HttpResponse::Ok),
+                ),
+        )
+        .await;
+
+        let test_uris = vec![
+            "/",
+            "/?query=test",
+            "///",
+            "/v1//something",
+            "/v1//something////",
+            "//v1/something",
+            "//v1//////something",
+            "/v2//something?query=test",
+            "/v2//something////?query=test",
+            "//v2/something?query=test",
+            "//v2//////something?query=test",
+        ];
+
+        for uri in test_uris {
+            let req = TestRequest::with_uri(uri).to_request();
+            let res = call_service(&app, req).await;
+            assert!(res.status().is_success(), "Failed uri: {}", uri);
+        }
+    }
+
+    #[actix_rt::test]
+    async fn trim_trailing_slashes() {
+        let app = init_service(
+            App::new()
+                .wrap(NormalizePath(TrailingSlash::Trim))
+                .service(web::resource("/").to(HttpResponse::Ok))
+                .service(web::resource("/v1/something").to(HttpResponse::Ok))
+                .service(
+                    web::resource("/v2/something")
+                        .guard(fn_guard(|ctx| ctx.head().uri.query() == Some("query=test")))
+                        .to(HttpResponse::Ok),
+                ),
+        )
+        .await;
+
+        let test_uris = vec![
+            "/",
+            "///",
+            "/v1/something",
+            "/v1/something/",
+            "/v1/something////",
+            "//v1//something",
+            "//v1//something//",
+            "/v2/something?query=test",
+            "/v2/something/?query=test",
+            "/v2/something////?query=test",
+            "//v2//something?query=test",
+            "//v2//something//?query=test",
+        ];
+
+        for uri in test_uris {
+            let req = TestRequest::with_uri(uri).to_request();
+            let res = call_service(&app, req).await;
+            assert!(res.status().is_success(), "Failed uri: {}", uri);
+        }
+    }
+
+    #[actix_rt::test]
+    async fn trim_root_trailing_slashes_with_query() {
+        let app = init_service(
+            App::new().wrap(NormalizePath(TrailingSlash::Trim)).service(
+                web::resource("/")
+                    .guard(fn_guard(|ctx| ctx.head().uri.query() == Some("query=test")))
+                    .to(HttpResponse::Ok),
+            ),
+        )
+        .await;
+
+        let test_uris = vec!["/?query=test", "//?query=test", "///?query=test"];
+
+        for uri in test_uris {
+            let req = TestRequest::with_uri(uri).to_request();
+            let res = call_service(&app, req).await;
+            assert!(res.status().is_success(), "Failed uri: {}", uri);
+        }
+    }
+
+    #[actix_rt::test]
+    async fn ensure_trailing_slash() {
+        let app = init_service(
+            App::new()
+                .wrap(NormalizePath(TrailingSlash::Always))
+                .service(web::resource("/").to(HttpResponse::Ok))
+                .service(web::resource("/v1/something/").to(HttpResponse::Ok))
+                .service(
+                    web::resource("/v2/something/")
+                        .guard(fn_guard(|ctx| ctx.head().uri.query() == Some("query=test")))
+                        .to(HttpResponse::Ok),
+                ),
+        )
+        .await;
+
+        let test_uris = vec![
+            "/",
+            "///",
+            "/v1/something",
+            "/v1/something/",
+            "/v1/something////",
+            "//v1//something",
+            "//v1//something//",
+            "/v2/something?query=test",
+            "/v2/something/?query=test",
+            "/v2/something////?query=test",
+            "//v2//something?query=test",
+            "//v2//something//?query=test",
+        ];
+
+        for uri in test_uris {
+            let req = TestRequest::with_uri(uri).to_request();
+            let res = call_service(&app, req).await;
+            assert!(res.status().is_success(), "Failed uri: {}", uri);
+        }
+    }
+
+    #[actix_rt::test]
+    async fn ensure_root_trailing_slash_with_query() {
+        let app = init_service(
+            App::new()
+                .wrap(NormalizePath(TrailingSlash::Always))
+                .service(
+                    web::resource("/")
+                        .guard(fn_guard(|ctx| ctx.head().uri.query() == Some("query=test")))
+                        .to(HttpResponse::Ok),
+                ),
+        )
+        .await;
+
+        let test_uris = vec!["/?query=test", "//?query=test", "///?query=test"];
+
+        for uri in test_uris {
+            let req = TestRequest::with_uri(uri).to_request();
+            let res = call_service(&app, req).await;
+            assert!(res.status().is_success(), "Failed uri: {}", uri);
+        }
+    }
+
+    #[actix_rt::test]
+    async fn keep_trailing_slash_unchanged() {
+        let app = init_service(
+            App::new()
+                .wrap(NormalizePath(TrailingSlash::MergeOnly))
+                .service(web::resource("/").to(HttpResponse::Ok))
+                .service(web::resource("/v1/something").to(HttpResponse::Ok))
+                .service(web::resource("/v1/").to(HttpResponse::Ok))
+                .service(
+                    web::resource("/v2/something")
+                        .guard(fn_guard(|ctx| ctx.head().uri.query() == Some("query=test")))
+                        .to(HttpResponse::Ok),
+                ),
+        )
+        .await;
+
+        let tests = vec![
+            ("/", true), // root paths should still work
+            ("/?query=test", true),
+            ("///", true),
+            ("/v1/something////", false),
+            ("/v1/something/", false),
+            ("//v1//something", true),
+            ("/v1/", true),
+            ("/v1", false),
+            ("/v1////", true),
+            ("//v1//", true),
+            ("///v1", false),
+            ("/v2/something?query=test", true),
+            ("/v2/something/?query=test", false),
+            ("/v2/something//?query=test", false),
+            ("//v2//something?query=test", true),
+        ];
+
+        for (uri, success) in tests {
+            let req = TestRequest::with_uri(uri).to_request();
+            let res = call_service(&app, req).await;
+            assert_eq!(res.status().is_success(), success, "Failed uri: {}", uri);
+        }
+    }
+
+    #[actix_rt::test]
+    async fn no_path() {
+        let app = init_service(
+            App::new()
+                .wrap(NormalizePath::default())
+                .service(web::resource("/").to(HttpResponse::Ok)),
+        )
+        .await;
+
+        // This URI will be interpreted as an authority form, i.e. there is no path nor scheme
+        // (https://datatracker.ietf.org/doc/html/rfc7230#section-5.3.3)
+        let req = TestRequest::with_uri("eh").to_request();
+        let res = call_service(&app, req).await;
+        assert_eq!(res.status(), StatusCode::NOT_FOUND);
+    }
+
+    #[actix_rt::test]
+    async fn test_in_place_normalization() {
+        let srv = |req: ServiceRequest| {
+            assert_eq!("/v1/something", req.path());
+            ready(Ok(req.into_response(HttpResponse::Ok().finish())))
+        };
+
+        let normalize = NormalizePath::default()
+            .new_transform(srv.into_service())
+            .await
+            .unwrap();
+
+        let test_uris = vec![
+            "/v1//something////",
+            "///v1/something",
+            "//v1///something",
+            "/v1//something",
+        ];
+
+        for uri in test_uris {
+            let req = TestRequest::with_uri(uri).to_srv_request();
+            let res = normalize.call(req).await.unwrap();
+            assert!(res.status().is_success(), "Failed uri: {}", uri);
+        }
+    }
+
+    #[actix_rt::test]
+    async fn should_normalize_nothing() {
+        const URI: &str = "/v1/something";
+
+        let srv = |req: ServiceRequest| {
+            assert_eq!(URI, req.path());
+            ready(Ok(req.into_response(HttpResponse::Ok().finish())))
+        };
+
+        let normalize = NormalizePath::default()
+            .new_transform(srv.into_service())
+            .await
+            .unwrap();
+
+        let req = TestRequest::with_uri(URI).to_srv_request();
+        let res = normalize.call(req).await.unwrap();
+        assert!(res.status().is_success());
+    }
+
+    #[actix_rt::test]
+    async fn should_normalize_no_trail() {
+        let srv = |req: ServiceRequest| {
+            assert_eq!("/v1/something", req.path());
+            ready(Ok(req.into_response(HttpResponse::Ok().finish())))
+        };
+
+        let normalize = NormalizePath::default()
+            .new_transform(srv.into_service())
+            .await
+            .unwrap();
+
+        let req = TestRequest::with_uri("/v1/something/").to_srv_request();
+        let res = normalize.call(req).await.unwrap();
+        assert!(res.status().is_success());
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/redirect.rs.html b/src/actix_web/redirect.rs.html new file mode 100644 index 000000000..fd74aa4c9 --- /dev/null +++ b/src/actix_web/redirect.rs.html @@ -0,0 +1,475 @@ +redirect.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
+
//! See [`Redirect`] for service/responder documentation.
+
+use std::borrow::Cow;
+
+use actix_utils::future::ready;
+
+use crate::{
+    dev::{fn_service, AppService, HttpServiceFactory, ResourceDef, ServiceRequest},
+    http::{header::LOCATION, StatusCode},
+    HttpRequest, HttpResponse, Responder,
+};
+
+/// An HTTP service for redirecting one path to another path or URL.
+///
+/// By default, the "307 Temporary Redirect" status is used when responding. See [this MDN
+/// article][mdn-redirects] on why 307 is preferred over 302.
+///
+/// # Examples
+/// As service:
+/// ```
+/// use actix_web::{web, App};
+///
+/// App::new()
+///     // redirect "/duck" to DuckDuckGo
+///     .service(web::redirect("/duck", "https://duck.com"))
+///     .service(
+///         // redirect "/api/old" to "/api/new"
+///         web::scope("/api").service(web::redirect("/old", "/new"))
+///     );
+/// ```
+///
+/// As responder:
+/// ```
+/// use actix_web::{web::Redirect, Responder};
+///
+/// async fn handler() -> impl Responder {
+///     // sends a permanent (308) redirect to duck.com
+///     Redirect::to("https://duck.com").permanent()
+/// }
+/// # actix_web::web::to(handler);
+/// ```
+///
+/// [mdn-redirects]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections#temporary_redirections
+#[derive(Debug, Clone)]
+pub struct Redirect {
+    from: Cow<'static, str>,
+    to: Cow<'static, str>,
+    status_code: StatusCode,
+}
+
+impl Redirect {
+    /// Construct a new `Redirect` service that matches a path.
+    ///
+    /// This service will match exact paths equal to `from` within the current scope. I.e., when
+    /// registered on the root `App`, it will match exact, whole paths. But when registered on a
+    /// `Scope`, it will match paths under that scope, ignoring the defined scope prefix, just like
+    /// a normal `Resource` or `Route`.
+    ///
+    /// The `to` argument can be path or URL; whatever is provided shall be used verbatim when
+    /// setting the redirect location. This means that relative paths can be used to navigate
+    /// relatively to matched paths.
+    ///
+    /// Prefer [`Redirect::to()`](Self::to) when using `Redirect` as a responder since `from` has
+    /// no meaning in that context.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_web::{web::Redirect, App};
+    /// App::new()
+    ///     // redirects "/oh/hi/mark" to "/oh/bye/johnny"
+    ///     .service(Redirect::new("/oh/hi/mark", "../../bye/johnny"));
+    /// ```
+    pub fn new(from: impl Into<Cow<'static, str>>, to: impl Into<Cow<'static, str>>) -> Self {
+        Self {
+            from: from.into(),
+            to: to.into(),
+            status_code: StatusCode::TEMPORARY_REDIRECT,
+        }
+    }
+
+    /// Construct a new `Redirect` to use as a responder.
+    ///
+    /// Only receives the `to` argument since responders do not need to do route matching.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::{web::Redirect, Responder};
+    ///
+    /// async fn admin_page() -> impl Responder {
+    ///     // sends a temporary 307 redirect to the login path
+    ///     Redirect::to("/login")
+    /// }
+    /// # actix_web::web::to(admin_page);
+    /// ```
+    pub fn to(to: impl Into<Cow<'static, str>>) -> Self {
+        Self {
+            from: "/".into(),
+            to: to.into(),
+            status_code: StatusCode::TEMPORARY_REDIRECT,
+        }
+    }
+
+    /// Use the "308 Permanent Redirect" status when responding.
+    ///
+    /// See [this MDN article][mdn-redirects] on why 308 is preferred over 301.
+    ///
+    /// [mdn-redirects]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections#permanent_redirections
+    pub fn permanent(self) -> Self {
+        self.using_status_code(StatusCode::PERMANENT_REDIRECT)
+    }
+
+    /// Use the "307 Temporary Redirect" status when responding.
+    ///
+    /// See [this MDN article][mdn-redirects] on why 307 is preferred over 302.
+    ///
+    /// [mdn-redirects]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections#temporary_redirections
+    pub fn temporary(self) -> Self {
+        self.using_status_code(StatusCode::TEMPORARY_REDIRECT)
+    }
+
+    /// Use the "303 See Other" status when responding.
+    ///
+    /// This status code is semantically correct as the response to a successful login, for example.
+    pub fn see_other(self) -> Self {
+        self.using_status_code(StatusCode::SEE_OTHER)
+    }
+
+    /// Allows the use of custom status codes for less common redirect types.
+    ///
+    /// In most cases, the default status ("308 Permanent Redirect") or using the `temporary`
+    /// method, which uses the "307 Temporary Redirect" status have more consistent behavior than
+    /// 301 and 302 codes, respectively.
+    ///
+    /// ```
+    /// # use actix_web::{http::StatusCode, web::Redirect};
+    /// // redirects would use "301 Moved Permanently" status code
+    /// Redirect::new("/old", "/new")
+    ///     .using_status_code(StatusCode::MOVED_PERMANENTLY);
+    ///
+    /// // redirects would use "302 Found" status code
+    /// Redirect::new("/old", "/new")
+    ///     .using_status_code(StatusCode::FOUND);
+    /// ```
+    pub fn using_status_code(mut self, status: StatusCode) -> Self {
+        self.status_code = status;
+        self
+    }
+}
+
+impl HttpServiceFactory for Redirect {
+    fn register(self, config: &mut AppService) {
+        let redirect = self.clone();
+        let rdef = ResourceDef::new(self.from.into_owned());
+        let redirect_factory = fn_service(move |mut req: ServiceRequest| {
+            let res = redirect.clone().respond_to(req.parts_mut().0);
+            ready(Ok(req.into_response(res.map_into_boxed_body())))
+        });
+
+        config.register_service(rdef, None, redirect_factory, None)
+    }
+}
+
+impl Responder for Redirect {
+    type Body = ();
+
+    fn respond_to(self, _req: &HttpRequest) -> HttpResponse<Self::Body> {
+        let mut res = HttpResponse::with_body(self.status_code, ());
+
+        if let Ok(hdr_val) = self.to.parse() {
+            res.headers_mut().insert(LOCATION, hdr_val);
+        } else {
+            log::error!(
+                "redirect target location can not be converted to header value: {:?}",
+                self.to,
+            );
+        }
+
+        res
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::{dev::Service, test, App};
+
+    #[actix_rt::test]
+    async fn absolute_redirects() {
+        let redirector = Redirect::new("/one", "/two").permanent();
+
+        let svc = test::init_service(App::new().service(redirector)).await;
+
+        let req = test::TestRequest::default().uri("/one").to_request();
+        let res = svc.call(req).await.unwrap();
+        assert_eq!(res.status(), StatusCode::from_u16(308).unwrap());
+        let hdr = res.headers().get(&LOCATION).unwrap();
+        assert_eq!(hdr.to_str().unwrap(), "/two");
+    }
+
+    #[actix_rt::test]
+    async fn relative_redirects() {
+        let redirector = Redirect::new("/one", "two").permanent();
+
+        let svc = test::init_service(App::new().service(redirector)).await;
+
+        let req = test::TestRequest::default().uri("/one").to_request();
+        let res = svc.call(req).await.unwrap();
+        assert_eq!(res.status(), StatusCode::from_u16(308).unwrap());
+        let hdr = res.headers().get(&LOCATION).unwrap();
+        assert_eq!(hdr.to_str().unwrap(), "two");
+    }
+
+    #[actix_rt::test]
+    async fn temporary_redirects() {
+        let external_service = Redirect::new("/external", "https://duck.com");
+
+        let svc = test::init_service(App::new().service(external_service)).await;
+
+        let req = test::TestRequest::default().uri("/external").to_request();
+        let res = svc.call(req).await.unwrap();
+        assert_eq!(res.status(), StatusCode::from_u16(307).unwrap());
+        let hdr = res.headers().get(&LOCATION).unwrap();
+        assert_eq!(hdr.to_str().unwrap(), "https://duck.com");
+    }
+
+    #[actix_rt::test]
+    async fn as_responder() {
+        let responder = Redirect::to("https://duck.com");
+
+        let req = test::TestRequest::default().to_http_request();
+        let res = responder.respond_to(&req);
+
+        assert_eq!(res.status(), StatusCode::from_u16(307).unwrap());
+        let hdr = res.headers().get(&LOCATION).unwrap();
+        assert_eq!(hdr.to_str().unwrap(), "https://duck.com");
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/request.rs.html b/src/actix_web/request.rs.html new file mode 100644 index 000000000..36c90ff4a --- /dev/null +++ b/src/actix_web/request.rs.html @@ -0,0 +1,1933 @@ +request.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
+
use std::{
+    cell::{Ref, RefCell, RefMut},
+    fmt, net,
+    rc::Rc,
+    str,
+};
+
+use actix_http::{Message, RequestHead};
+use actix_router::{Path, Url};
+use actix_utils::future::{ok, Ready};
+#[cfg(feature = "cookies")]
+use cookie::{Cookie, ParseError as CookieParseError};
+use smallvec::SmallVec;
+
+use crate::{
+    app_service::AppInitServiceState,
+    config::AppConfig,
+    dev::{Extensions, Payload},
+    error::UrlGenerationError,
+    http::{header::HeaderMap, Method, Uri, Version},
+    info::ConnectionInfo,
+    rmap::ResourceMap,
+    Error, FromRequest, HttpMessage,
+};
+
+#[cfg(feature = "cookies")]
+struct Cookies(Vec<Cookie<'static>>);
+
+/// An incoming request.
+#[derive(Clone)]
+pub struct HttpRequest {
+    /// # Invariant
+    /// `Rc<HttpRequestInner>` is used exclusively and NO `Weak<HttpRequestInner>`
+    /// is allowed anywhere in the code. Weak pointer is purposely ignored when
+    /// doing `Rc`'s ref counter check. Expect panics if this invariant is violated.
+    pub(crate) inner: Rc<HttpRequestInner>,
+}
+
+pub(crate) struct HttpRequestInner {
+    pub(crate) head: Message<RequestHead>,
+    pub(crate) path: Path<Url>,
+    pub(crate) app_data: SmallVec<[Rc<Extensions>; 4]>,
+    pub(crate) conn_data: Option<Rc<Extensions>>,
+    pub(crate) extensions: Rc<RefCell<Extensions>>,
+    app_state: Rc<AppInitServiceState>,
+}
+
+impl HttpRequest {
+    #[inline]
+    pub(crate) fn new(
+        path: Path<Url>,
+        head: Message<RequestHead>,
+        app_state: Rc<AppInitServiceState>,
+        app_data: Rc<Extensions>,
+        conn_data: Option<Rc<Extensions>>,
+        extensions: Rc<RefCell<Extensions>>,
+    ) -> HttpRequest {
+        let mut data = SmallVec::<[Rc<Extensions>; 4]>::new();
+        data.push(app_data);
+
+        HttpRequest {
+            inner: Rc::new(HttpRequestInner {
+                head,
+                path,
+                app_state,
+                app_data: data,
+                conn_data,
+                extensions,
+            }),
+        }
+    }
+}
+
+impl HttpRequest {
+    /// This method returns reference to the request head
+    #[inline]
+    pub fn head(&self) -> &RequestHead {
+        &self.inner.head
+    }
+
+    /// This method returns mutable reference to the request head.
+    /// panics if multiple references of HTTP request exists.
+    #[inline]
+    pub(crate) fn head_mut(&mut self) -> &mut RequestHead {
+        &mut Rc::get_mut(&mut self.inner).unwrap().head
+    }
+
+    /// Request's uri.
+    #[inline]
+    pub fn uri(&self) -> &Uri {
+        &self.head().uri
+    }
+
+    /// Read the Request method.
+    #[inline]
+    pub fn method(&self) -> &Method {
+        &self.head().method
+    }
+
+    /// Read the Request Version.
+    #[inline]
+    pub fn version(&self) -> Version {
+        self.head().version
+    }
+
+    #[inline]
+    /// Returns request's headers.
+    pub fn headers(&self) -> &HeaderMap {
+        &self.head().headers
+    }
+
+    /// The target path of this request.
+    #[inline]
+    pub fn path(&self) -> &str {
+        self.head().uri.path()
+    }
+
+    /// The query string in the URL.
+    ///
+    /// Example: `id=10`
+    #[inline]
+    pub fn query_string(&self) -> &str {
+        self.uri().query().unwrap_or_default()
+    }
+
+    /// Returns a reference to the URL parameters container.
+    ///
+    /// A URL parameter is specified in the form `{identifier}`, where the identifier can be used
+    /// later in a request handler to access the matched value for that parameter.
+    ///
+    /// # Percent Encoding and URL Parameters
+    /// Because each URL parameter is able to capture multiple path segments, none of
+    /// `["%2F", "%25", "%2B"]` found in the request URI are decoded into `["/", "%", "+"]` in order
+    /// to preserve path integrity. If a URL parameter is expected to contain these characters, then
+    /// it is on the user to decode them or use the [`web::Path`](crate::web::Path) extractor which
+    /// _will_ decode these special sequences.
+    #[inline]
+    pub fn match_info(&self) -> &Path<Url> {
+        &self.inner.path
+    }
+
+    /// Returns a mutable reference to the URL parameters container.
+    ///
+    /// # Panics
+    /// Panics if this `HttpRequest` has been cloned.
+    #[inline]
+    pub(crate) fn match_info_mut(&mut self) -> &mut Path<Url> {
+        &mut Rc::get_mut(&mut self.inner).unwrap().path
+    }
+
+    /// The resource definition pattern that matched the path. Useful for logging and metrics.
+    ///
+    /// For example, when a resource with pattern `/user/{id}/profile` is defined and a call is made
+    /// to `/user/123/profile` this function would return `Some("/user/{id}/profile")`.
+    ///
+    /// Returns a None when no resource is fully matched, including default services.
+    #[inline]
+    pub fn match_pattern(&self) -> Option<String> {
+        self.resource_map().match_pattern(self.path())
+    }
+
+    /// The resource name that matched the path. Useful for logging and metrics.
+    ///
+    /// Returns a None when no resource is fully matched, including default services.
+    #[inline]
+    pub fn match_name(&self) -> Option<&str> {
+        self.resource_map().match_name(self.path())
+    }
+
+    /// Returns a reference a piece of connection data set in an [on-connect] callback.
+    ///
+    /// ```ignore
+    /// let opt_t = req.conn_data::<PeerCertificate>();
+    /// ```
+    ///
+    /// [on-connect]: crate::HttpServer::on_connect
+    pub fn conn_data<T: 'static>(&self) -> Option<&T> {
+        self.inner
+            .conn_data
+            .as_deref()
+            .and_then(|container| container.get::<T>())
+    }
+
+    /// Generates URL for a named resource.
+    ///
+    /// This substitutes in sequence all URL parameters that appear in the resource itself and in
+    /// parent [scopes](crate::web::scope), if any.
+    ///
+    /// It is worth noting that the characters `['/', '%']` are not escaped and therefore a single
+    /// URL parameter may expand into multiple path segments and `elements` can be percent-encoded
+    /// beforehand without worrying about double encoding. Any other character that is not valid in
+    /// a URL path context is escaped using percent-encoding.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_web::{web, App, HttpRequest, HttpResponse};
+    /// fn index(req: HttpRequest) -> HttpResponse {
+    ///     let url = req.url_for("foo", &["1", "2", "3"]); // <- generate URL for "foo" resource
+    ///     HttpResponse::Ok().into()
+    /// }
+    ///
+    /// let app = App::new()
+    ///     .service(web::resource("/test/{one}/{two}/{three}")
+    ///          .name("foo")  // <- set resource name so it can be used in `url_for`
+    ///          .route(web::get().to(|| HttpResponse::Ok()))
+    ///     );
+    /// ```
+    pub fn url_for<U, I>(&self, name: &str, elements: U) -> Result<url::Url, UrlGenerationError>
+    where
+        U: IntoIterator<Item = I>,
+        I: AsRef<str>,
+    {
+        self.resource_map().url_for(self, name, elements)
+    }
+
+    /// Generate URL for named resource
+    ///
+    /// This method is similar to `HttpRequest::url_for()` but it can be used
+    /// for urls that do not contain variable parts.
+    pub fn url_for_static(&self, name: &str) -> Result<url::Url, UrlGenerationError> {
+        const NO_PARAMS: [&str; 0] = [];
+        self.url_for(name, NO_PARAMS)
+    }
+
+    /// Get a reference to a `ResourceMap` of current application.
+    #[inline]
+    pub fn resource_map(&self) -> &ResourceMap {
+        self.app_state().rmap()
+    }
+
+    /// Returns peer socket address.
+    ///
+    /// Peer address is the directly connected peer's socket address. If a proxy is used in front of
+    /// the Actix Web server, then it would be address of this proxy.
+    ///
+    /// For expanded client connection information, use [`connection_info`] instead.
+    ///
+    /// Will only return None when called in unit tests unless [`TestRequest::peer_addr`] is used.
+    ///
+    /// [`TestRequest::peer_addr`]: crate::test::TestRequest::peer_addr
+    /// [`connection_info`]: Self::connection_info
+    #[inline]
+    pub fn peer_addr(&self) -> Option<net::SocketAddr> {
+        self.head().peer_addr
+    }
+
+    /// Returns connection info for the current request.
+    ///
+    /// The return type, [`ConnectionInfo`], can also be used as an extractor.
+    ///
+    /// # Panics
+    /// Panics if request's extensions container is already borrowed.
+    #[inline]
+    pub fn connection_info(&self) -> Ref<'_, ConnectionInfo> {
+        if !self.extensions().contains::<ConnectionInfo>() {
+            let info = ConnectionInfo::new(self.head(), self.app_config());
+            self.extensions_mut().insert(info);
+        }
+
+        Ref::map(self.extensions(), |data| data.get().unwrap())
+    }
+
+    /// Returns a reference to the application's connection configuration.
+    #[inline]
+    pub fn app_config(&self) -> &AppConfig {
+        self.app_state().config()
+    }
+
+    /// Retrieves a piece of application state.
+    ///
+    /// Extracts any object stored with [`App::app_data()`](crate::App::app_data) (or the
+    /// counterpart methods on [`Scope`](crate::Scope::app_data) and
+    /// [`Resource`](crate::Resource::app_data)) during application configuration.
+    ///
+    /// Since the Actix Web router layers application data, the returned object will reference the
+    /// "closest" instance of the type. For example, if an `App` stores a `u32`, a nested `Scope`
+    /// also stores a `u32`, and the delegated request handler falls within that `Scope`, then
+    /// calling `.app_data::<u32>()` on an `HttpRequest` within that handler will return the
+    /// `Scope`'s instance. However, using the same router set up and a request that does not get
+    /// captured by the `Scope`, `.app_data::<u32>()` would return the `App`'s instance.
+    ///
+    /// If the state was stored using the [`Data`] wrapper, then it must also be retrieved using
+    /// this same type.
+    ///
+    /// See also the [`Data`] extractor.
+    ///
+    /// # Examples
+    /// ```no_run
+    /// # use actix_web::{test::TestRequest, web::Data};
+    /// # let req = TestRequest::default().to_http_request();
+    /// # type T = u32;
+    /// let opt_t: Option<&Data<T>> = req.app_data::<Data<T>>();
+    /// ```
+    ///
+    /// [`Data`]: crate::web::Data
+    #[doc(alias = "state")]
+    pub fn app_data<T: 'static>(&self) -> Option<&T> {
+        for container in self.inner.app_data.iter().rev() {
+            if let Some(data) = container.get::<T>() {
+                return Some(data);
+            }
+        }
+
+        None
+    }
+
+    #[inline]
+    fn app_state(&self) -> &AppInitServiceState {
+        &self.inner.app_state
+    }
+
+    /// Load request cookies.
+    #[cfg(feature = "cookies")]
+    pub fn cookies(&self) -> Result<Ref<'_, Vec<Cookie<'static>>>, CookieParseError> {
+        use actix_http::header::COOKIE;
+
+        if self.extensions().get::<Cookies>().is_none() {
+            let mut cookies = Vec::new();
+            for hdr in self.headers().get_all(COOKIE) {
+                let s = str::from_utf8(hdr.as_bytes()).map_err(CookieParseError::from)?;
+                for cookie_str in s.split(';').map(|s| s.trim()) {
+                    if !cookie_str.is_empty() {
+                        cookies.push(Cookie::parse_encoded(cookie_str)?.into_owned());
+                    }
+                }
+            }
+            self.extensions_mut().insert(Cookies(cookies));
+        }
+
+        Ok(Ref::map(self.extensions(), |ext| {
+            &ext.get::<Cookies>().unwrap().0
+        }))
+    }
+
+    /// Return request cookie.
+    #[cfg(feature = "cookies")]
+    pub fn cookie(&self, name: &str) -> Option<Cookie<'static>> {
+        if let Ok(cookies) = self.cookies() {
+            for cookie in cookies.iter() {
+                if cookie.name() == name {
+                    return Some(cookie.to_owned());
+                }
+            }
+        }
+        None
+    }
+}
+
+impl HttpMessage for HttpRequest {
+    type Stream = ();
+
+    #[inline]
+    fn headers(&self) -> &HeaderMap {
+        &self.head().headers
+    }
+
+    #[inline]
+    fn extensions(&self) -> Ref<'_, Extensions> {
+        self.inner.extensions.borrow()
+    }
+
+    #[inline]
+    fn extensions_mut(&self) -> RefMut<'_, Extensions> {
+        self.inner.extensions.borrow_mut()
+    }
+
+    #[inline]
+    fn take_payload(&mut self) -> Payload<Self::Stream> {
+        Payload::None
+    }
+}
+
+impl Drop for HttpRequest {
+    fn drop(&mut self) {
+        // if possible, contribute to current worker's HttpRequest allocation pool
+
+        // This relies on no weak references to inner existing anywhere within the codebase.
+        if let Some(inner) = Rc::get_mut(&mut self.inner) {
+            if inner.app_state.pool().is_available() {
+                // clear additional app_data and keep the root one for reuse.
+                inner.app_data.truncate(1);
+
+                // Inner is borrowed mut here and; get req data mutably to reduce borrow check. Also
+                // we know the req_data Rc will not have any clones at this point to unwrap is okay.
+                Rc::get_mut(&mut inner.extensions)
+                    .unwrap()
+                    .get_mut()
+                    .clear();
+
+                // We can't use the same trick as req data because the conn_data is held by the
+                // dispatcher, too.
+                inner.conn_data = None;
+
+                // a re-borrow of pool is necessary here.
+                let req = Rc::clone(&self.inner);
+                self.app_state().pool().push(req);
+            }
+        }
+    }
+}
+
+/// It is possible to get `HttpRequest` as an extractor handler parameter
+///
+/// # Examples
+/// ```
+/// use actix_web::{web, App, HttpRequest};
+/// use serde::Deserialize;
+///
+/// /// extract `Thing` from request
+/// async fn index(req: HttpRequest) -> String {
+///    format!("Got thing: {:?}", req)
+/// }
+///
+/// let app = App::new().service(
+///     web::resource("/users/{first}").route(
+///         web::get().to(index))
+/// );
+/// ```
+impl FromRequest for HttpRequest {
+    type Error = Error;
+    type Future = Ready<Result<Self, Error>>;
+
+    #[inline]
+    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
+        ok(req.clone())
+    }
+}
+
+impl fmt::Debug for HttpRequest {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        writeln!(
+            f,
+            "\nHttpRequest {:?} {}:{}",
+            self.inner.head.version,
+            self.inner.head.method,
+            self.path()
+        )?;
+
+        if !self.query_string().is_empty() {
+            writeln!(f, "  query: ?{:?}", self.query_string())?;
+        }
+
+        if !self.match_info().is_empty() {
+            writeln!(f, "  params: {:?}", self.match_info())?;
+        }
+
+        writeln!(f, "  headers:")?;
+
+        for (key, val) in self.headers().iter() {
+            match key {
+                // redact sensitive header values from debug output
+                &crate::http::header::AUTHORIZATION
+                | &crate::http::header::PROXY_AUTHORIZATION
+                | &crate::http::header::COOKIE => writeln!(f, "    {:?}: {:?}", key, "*redacted*")?,
+
+                _ => writeln!(f, "    {:?}: {:?}", key, val)?,
+            }
+        }
+
+        Ok(())
+    }
+}
+
+/// Slab-allocated `HttpRequest` Pool
+///
+/// Since request processing may yield for asynchronous events to complete, a worker may have many
+/// requests in-flight at any time. Pooling requests like this amortizes the performance and memory
+/// costs of allocating and de-allocating HttpRequest objects as frequently as they otherwise would.
+///
+/// Request objects are added when they are dropped (see `<HttpRequest as Drop>::drop`) and re-used
+/// in `<AppInitService as Service>::call` when there are available objects in the list.
+///
+/// The pool's default capacity is 128 items.
+pub(crate) struct HttpRequestPool {
+    inner: RefCell<Vec<Rc<HttpRequestInner>>>,
+    cap: usize,
+}
+
+impl Default for HttpRequestPool {
+    fn default() -> Self {
+        Self::with_capacity(128)
+    }
+}
+
+impl HttpRequestPool {
+    pub(crate) fn with_capacity(cap: usize) -> Self {
+        HttpRequestPool {
+            inner: RefCell::new(Vec::with_capacity(cap)),
+            cap,
+        }
+    }
+
+    /// Re-use a previously allocated (but now completed/discarded) HttpRequest object.
+    #[inline]
+    pub(crate) fn pop(&self) -> Option<HttpRequest> {
+        self.inner
+            .borrow_mut()
+            .pop()
+            .map(|inner| HttpRequest { inner })
+    }
+
+    /// Check if the pool still has capacity for request storage.
+    #[inline]
+    pub(crate) fn is_available(&self) -> bool {
+        self.inner.borrow_mut().len() < self.cap
+    }
+
+    /// Push a request to pool.
+    #[inline]
+    pub(crate) fn push(&self, req: Rc<HttpRequestInner>) {
+        self.inner.borrow_mut().push(req);
+    }
+
+    /// Clears all allocated HttpRequest objects.
+    pub(crate) fn clear(&self) {
+        self.inner.borrow_mut().clear()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use bytes::Bytes;
+
+    use super::*;
+    use crate::{
+        dev::{ResourceDef, Service},
+        http::{header, StatusCode},
+        test::{self, call_service, init_service, read_body, TestRequest},
+        web, App, HttpResponse,
+    };
+
+    #[test]
+    fn test_debug() {
+        let req = TestRequest::default()
+            .insert_header(("content-type", "text/plain"))
+            .to_http_request();
+        let dbg = format!("{:?}", req);
+        assert!(dbg.contains("HttpRequest"));
+    }
+
+    #[test]
+    #[cfg(feature = "cookies")]
+    fn test_no_request_cookies() {
+        let req = TestRequest::default().to_http_request();
+        assert!(req.cookies().unwrap().is_empty());
+    }
+
+    #[test]
+    #[cfg(feature = "cookies")]
+    fn test_request_cookies() {
+        let req = TestRequest::default()
+            .append_header((header::COOKIE, "cookie1=value1"))
+            .append_header((header::COOKIE, "cookie2=value2"))
+            .to_http_request();
+        {
+            let cookies = req.cookies().unwrap();
+            assert_eq!(cookies.len(), 2);
+            assert_eq!(cookies[0].name(), "cookie1");
+            assert_eq!(cookies[0].value(), "value1");
+            assert_eq!(cookies[1].name(), "cookie2");
+            assert_eq!(cookies[1].value(), "value2");
+        }
+
+        let cookie = req.cookie("cookie1");
+        assert!(cookie.is_some());
+        let cookie = cookie.unwrap();
+        assert_eq!(cookie.name(), "cookie1");
+        assert_eq!(cookie.value(), "value1");
+
+        let cookie = req.cookie("cookie-unknown");
+        assert!(cookie.is_none());
+    }
+
+    #[test]
+    fn test_request_query() {
+        let req = TestRequest::with_uri("/?id=test").to_http_request();
+        assert_eq!(req.query_string(), "id=test");
+    }
+
+    #[test]
+    fn test_url_for() {
+        let mut res = ResourceDef::new("/user/{name}.{ext}");
+        res.set_name("index");
+
+        let mut rmap = ResourceMap::new(ResourceDef::prefix(""));
+        rmap.add(&mut res, None);
+        assert!(rmap.has_resource("/user/test.html"));
+        assert!(!rmap.has_resource("/test/unknown"));
+
+        let req = TestRequest::default()
+            .insert_header((header::HOST, "www.rust-lang.org"))
+            .rmap(rmap)
+            .to_http_request();
+
+        assert_eq!(
+            req.url_for("unknown", ["test"]),
+            Err(UrlGenerationError::ResourceNotFound)
+        );
+        assert_eq!(
+            req.url_for("index", ["test"]),
+            Err(UrlGenerationError::NotEnoughElements)
+        );
+        let url = req.url_for("index", ["test", "html"]);
+        assert_eq!(
+            url.ok().unwrap().as_str(),
+            "http://www.rust-lang.org/user/test.html"
+        );
+    }
+
+    #[test]
+    fn test_url_for_static() {
+        let mut rdef = ResourceDef::new("/index.html");
+        rdef.set_name("index");
+
+        let mut rmap = ResourceMap::new(ResourceDef::prefix(""));
+        rmap.add(&mut rdef, None);
+
+        assert!(rmap.has_resource("/index.html"));
+
+        let req = TestRequest::with_uri("/test")
+            .insert_header((header::HOST, "www.rust-lang.org"))
+            .rmap(rmap)
+            .to_http_request();
+        let url = req.url_for_static("index");
+        assert_eq!(
+            url.ok().unwrap().as_str(),
+            "http://www.rust-lang.org/index.html"
+        );
+    }
+
+    #[test]
+    fn test_match_name() {
+        let mut rdef = ResourceDef::new("/index.html");
+        rdef.set_name("index");
+
+        let mut rmap = ResourceMap::new(ResourceDef::prefix(""));
+        rmap.add(&mut rdef, None);
+
+        assert!(rmap.has_resource("/index.html"));
+
+        let req = TestRequest::default()
+            .uri("/index.html")
+            .rmap(rmap)
+            .to_http_request();
+
+        assert_eq!(req.match_name(), Some("index"));
+    }
+
+    #[test]
+    fn test_url_for_external() {
+        let mut rdef = ResourceDef::new("https://youtube.com/watch/{video_id}");
+
+        rdef.set_name("youtube");
+
+        let mut rmap = ResourceMap::new(ResourceDef::prefix(""));
+        rmap.add(&mut rdef, None);
+
+        let req = TestRequest::default().rmap(rmap).to_http_request();
+        let url = req.url_for("youtube", ["oHg5SJYRHA0"]);
+        assert_eq!(
+            url.ok().unwrap().as_str(),
+            "https://youtube.com/watch/oHg5SJYRHA0"
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_drop_http_request_pool() {
+        let srv = init_service(
+            App::new().service(web::resource("/").to(|req: HttpRequest| {
+                HttpResponse::Ok()
+                    .insert_header(("pool_cap", req.app_state().pool().cap))
+                    .finish()
+            })),
+        )
+        .await;
+
+        let req = TestRequest::default().to_request();
+        let resp = call_service(&srv, req).await;
+
+        drop(srv);
+
+        assert_eq!(resp.headers().get("pool_cap").unwrap(), "128");
+    }
+
+    #[actix_rt::test]
+    async fn test_data() {
+        let srv = init_service(App::new().app_data(10usize).service(web::resource("/").to(
+            |req: HttpRequest| {
+                if req.app_data::<usize>().is_some() {
+                    HttpResponse::Ok()
+                } else {
+                    HttpResponse::BadRequest()
+                }
+            },
+        )))
+        .await;
+
+        let req = TestRequest::default().to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let srv = init_service(App::new().app_data(10u32).service(web::resource("/").to(
+            |req: HttpRequest| {
+                if req.app_data::<usize>().is_some() {
+                    HttpResponse::Ok()
+                } else {
+                    HttpResponse::BadRequest()
+                }
+            },
+        )))
+        .await;
+
+        let req = TestRequest::default().to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+    }
+
+    #[actix_rt::test]
+    async fn test_cascading_data() {
+        #[allow(dead_code)]
+        fn echo_usize(req: HttpRequest) -> HttpResponse {
+            let num = req.app_data::<usize>().unwrap();
+            HttpResponse::Ok().body(num.to_string())
+        }
+
+        let srv = init_service(
+            App::new()
+                .app_data(88usize)
+                .service(web::resource("/").route(web::get().to(echo_usize)))
+                .service(
+                    web::resource("/one")
+                        .app_data(1u32)
+                        .route(web::get().to(echo_usize)),
+                ),
+        )
+        .await;
+
+        let req = TestRequest::get().uri("/").to_request();
+        let resp = srv.call(req).await.unwrap();
+        let body = read_body(resp).await;
+        assert_eq!(body, Bytes::from_static(b"88"));
+
+        let req = TestRequest::get().uri("/one").to_request();
+        let resp = srv.call(req).await.unwrap();
+        let body = read_body(resp).await;
+        assert_eq!(body, Bytes::from_static(b"88"));
+    }
+
+    #[actix_rt::test]
+    async fn test_overwrite_data() {
+        #[allow(dead_code)]
+        fn echo_usize(req: HttpRequest) -> HttpResponse {
+            let num = req.app_data::<usize>().unwrap();
+            HttpResponse::Ok().body(num.to_string())
+        }
+
+        let srv = init_service(
+            App::new()
+                .app_data(88usize)
+                .service(web::resource("/").route(web::get().to(echo_usize)))
+                .service(
+                    web::resource("/one")
+                        .app_data(1usize)
+                        .route(web::get().to(echo_usize)),
+                ),
+        )
+        .await;
+
+        let req = TestRequest::get().uri("/").to_request();
+        let resp = srv.call(req).await.unwrap();
+        let body = read_body(resp).await;
+        assert_eq!(body, Bytes::from_static(b"88"));
+
+        let req = TestRequest::get().uri("/one").to_request();
+        let resp = srv.call(req).await.unwrap();
+        let body = read_body(resp).await;
+        assert_eq!(body, Bytes::from_static(b"1"));
+    }
+
+    #[actix_rt::test]
+    async fn test_app_data_dropped() {
+        struct Tracker {
+            pub dropped: bool,
+        }
+        struct Foo {
+            tracker: Rc<RefCell<Tracker>>,
+        }
+        impl Drop for Foo {
+            fn drop(&mut self) {
+                self.tracker.borrow_mut().dropped = true;
+            }
+        }
+
+        let tracker = Rc::new(RefCell::new(Tracker { dropped: false }));
+        {
+            let tracker2 = Rc::clone(&tracker);
+            let srv = init_service(App::new().service(web::resource("/").to(
+                move |req: HttpRequest| {
+                    req.extensions_mut().insert(Foo {
+                        tracker: Rc::clone(&tracker2),
+                    });
+                    HttpResponse::Ok()
+                },
+            )))
+            .await;
+
+            let req = TestRequest::default().to_request();
+            let resp = call_service(&srv, req).await;
+            assert_eq!(resp.status(), StatusCode::OK);
+        }
+
+        assert!(tracker.borrow().dropped);
+    }
+
+    #[actix_rt::test]
+    async fn extract_path_pattern() {
+        let srv = init_service(
+            App::new().service(
+                web::scope("/user/{id}")
+                    .service(web::resource("/profile").route(web::get().to(
+                        move |req: HttpRequest| {
+                            assert_eq!(req.match_pattern(), Some("/user/{id}/profile".to_owned()));
+
+                            HttpResponse::Ok().finish()
+                        },
+                    )))
+                    .default_service(web::to(move |req: HttpRequest| {
+                        assert!(req.match_pattern().is_none());
+                        HttpResponse::Ok().finish()
+                    })),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::get().uri("/user/22/profile").to_request();
+        let res = call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+
+        let req = TestRequest::get().uri("/user/22/not-exist").to_request();
+        let res = call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn extract_path_pattern_complex() {
+        let srv = init_service(
+            App::new()
+                .service(web::scope("/user").service(web::scope("/{id}").service(
+                    web::resource("").to(move |req: HttpRequest| {
+                        assert_eq!(req.match_pattern(), Some("/user/{id}".to_owned()));
+
+                        HttpResponse::Ok().finish()
+                    }),
+                )))
+                .service(web::resource("/").to(move |req: HttpRequest| {
+                    assert_eq!(req.match_pattern(), Some("/".to_owned()));
+
+                    HttpResponse::Ok().finish()
+                }))
+                .default_service(web::to(move |req: HttpRequest| {
+                    assert!(req.match_pattern().is_none());
+                    HttpResponse::Ok().finish()
+                })),
+        )
+        .await;
+
+        let req = TestRequest::get().uri("/user/test").to_request();
+        let res = call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+
+        let req = TestRequest::get().uri("/").to_request();
+        let res = call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+
+        let req = TestRequest::get().uri("/not-exist").to_request();
+        let res = call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn url_for_closest_named_resource() {
+        // we mount the route named 'nested' on 2 different scopes, 'a' and 'b'
+        let srv = test::init_service(
+            App::new()
+                .service(
+                    web::scope("/foo")
+                        .service(web::resource("/nested").name("nested").route(web::get().to(
+                            |req: HttpRequest| {
+                                HttpResponse::Ok()
+                                    .body(format!("{}", req.url_for_static("nested").unwrap()))
+                            },
+                        )))
+                        .service(web::scope("/baz").service(web::resource("deep")))
+                        .service(web::resource("{foo_param}")),
+                )
+                .service(web::scope("/bar").service(
+                    web::resource("/nested").name("nested").route(web::get().to(
+                        |req: HttpRequest| {
+                            HttpResponse::Ok()
+                                .body(format!("{}", req.url_for_static("nested").unwrap()))
+                        },
+                    )),
+                )),
+        )
+        .await;
+
+        let foo_resp =
+            test::call_service(&srv, TestRequest::with_uri("/foo/nested").to_request()).await;
+        assert_eq!(foo_resp.status(), StatusCode::OK);
+        let body = read_body(foo_resp).await;
+        // `body` equals http://localhost:8080/bar/nested
+        // because nested from /bar overrides /foo's
+        // to do this any other way would require something like a custom tree search
+        // see https://github.com/actix/actix-web/issues/1763
+        assert_eq!(body, "http://localhost:8080/bar/nested");
+
+        let bar_resp =
+            test::call_service(&srv, TestRequest::with_uri("/bar/nested").to_request()).await;
+        assert_eq!(bar_resp.status(), StatusCode::OK);
+        let body = read_body(bar_resp).await;
+        assert_eq!(body, "http://localhost:8080/bar/nested");
+    }
+
+    #[test]
+    fn authorization_header_hidden_in_debug() {
+        let authorization_header = "Basic bXkgdXNlcm5hbWU6bXkgcGFzc3dvcmQK";
+        let req = TestRequest::get()
+            .insert_header((crate::http::header::AUTHORIZATION, authorization_header))
+            .to_http_request();
+
+        assert!(!format!("{:?}", req).contains(authorization_header));
+    }
+
+    #[test]
+    fn proxy_authorization_header_hidden_in_debug() {
+        let proxy_authorization_header = "secret value";
+        let req = TestRequest::get()
+            .insert_header((
+                crate::http::header::PROXY_AUTHORIZATION,
+                proxy_authorization_header,
+            ))
+            .to_http_request();
+
+        assert!(!format!("{:?}", req).contains(proxy_authorization_header));
+    }
+
+    #[test]
+    fn cookie_header_hidden_in_debug() {
+        let cookie_header = "secret";
+        let req = TestRequest::get()
+            .insert_header((crate::http::header::COOKIE, cookie_header))
+            .to_http_request();
+
+        assert!(!format!("{:?}", req).contains(cookie_header));
+    }
+
+    #[test]
+    fn other_header_visible_in_debug() {
+        let location_header = "192.0.0.1";
+        let req = TestRequest::get()
+            .insert_header((crate::http::header::LOCATION, location_header))
+            .to_http_request();
+
+        assert!(format!("{:?}", req).contains(location_header));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/request_data.rs.html b/src/actix_web/request_data.rs.html new file mode 100644 index 000000000..23b784612 --- /dev/null +++ b/src/actix_web/request_data.rs.html @@ -0,0 +1,349 @@ +request_data.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
+
use std::{any::type_name, ops::Deref};
+
+use actix_utils::future::{err, ok, Ready};
+
+use crate::{
+    dev::Payload, error::ErrorInternalServerError, Error, FromRequest, HttpMessage as _,
+    HttpRequest,
+};
+
+/// Request-local data extractor.
+///
+/// Request-local data is arbitrary data attached to an individual request, usually
+/// by middleware. It can be set via `extensions_mut` on [`HttpRequest`][htr_ext_mut]
+/// or [`ServiceRequest`][srv_ext_mut].
+///
+/// Unlike app data, request data is dropped when the request has finished processing. This makes it
+/// useful as a kind of messaging system between middleware and request handlers. It uses the same
+/// types-as-keys storage system as app data.
+///
+/// # Mutating Request Data
+/// Note that since extractors must output owned data, only types that `impl Clone` can use this
+/// extractor. A clone is taken of the required request data and can, therefore, not be directly
+/// mutated in-place. To mutate request data, continue to use [`HttpRequest::extensions_mut`] or
+/// re-insert the cloned data back into the extensions map. A `DerefMut` impl is intentionally not
+/// provided to make this potential foot-gun more obvious.
+///
+/// # Examples
+/// ```no_run
+/// # use actix_web::{web, HttpResponse, HttpRequest, Responder, HttpMessage as _};
+/// #[derive(Debug, Clone, PartialEq)]
+/// struct FlagFromMiddleware(String);
+///
+/// /// Use the `ReqData<T>` extractor to access request data in a handler.
+/// async fn handler(
+///     req: HttpRequest,
+///     opt_flag: Option<web::ReqData<FlagFromMiddleware>>,
+/// ) -> impl Responder {
+///     // use an option extractor if middleware is not guaranteed to add this type of req data
+///     if let Some(flag) = opt_flag {
+///         assert_eq!(&flag.into_inner(), req.extensions().get::<FlagFromMiddleware>().unwrap());
+///     }
+///
+///     HttpResponse::Ok()
+/// }
+/// ```
+///
+/// [htr_ext_mut]: crate::HttpRequest::extensions_mut
+/// [srv_ext_mut]: crate::dev::ServiceRequest::extensions_mut
+#[derive(Debug, Clone)]
+pub struct ReqData<T: Clone + 'static>(T);
+
+impl<T: Clone + 'static> ReqData<T> {
+    /// Consumes the `ReqData`, returning its wrapped data.
+    pub fn into_inner(self) -> T {
+        self.0
+    }
+}
+
+impl<T: Clone + 'static> Deref for ReqData<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &self.0
+    }
+}
+
+impl<T: Clone + 'static> FromRequest for ReqData<T> {
+    type Error = Error;
+    type Future = Ready<Result<Self, Error>>;
+
+    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
+        if let Some(st) = req.extensions().get::<T>() {
+            ok(ReqData(st.clone()))
+        } else {
+            log::debug!(
+                "Failed to construct App-level ReqData extractor. \
+                 Request path: {:?} (type: {})",
+                req.path(),
+                type_name::<T>(),
+            );
+            err(ErrorInternalServerError(
+                "Missing expected request extension data",
+            ))
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::{cell::RefCell, rc::Rc};
+
+    use futures_util::TryFutureExt as _;
+
+    use super::*;
+    use crate::{
+        dev::Service,
+        http::{Method, StatusCode},
+        test::{init_service, TestRequest},
+        web, App, HttpMessage, HttpResponse,
+    };
+
+    #[actix_rt::test]
+    async fn req_data_extractor() {
+        let srv = init_service(
+            App::new()
+                .wrap_fn(|req, srv| {
+                    if req.method() == Method::POST {
+                        req.extensions_mut().insert(42u32);
+                    }
+
+                    srv.call(req)
+                })
+                .service(web::resource("/test").to(
+                    |req: HttpRequest, data: Option<ReqData<u32>>| {
+                        if req.method() != Method::POST {
+                            assert!(data.is_none());
+                        }
+
+                        if let Some(data) = data {
+                            assert_eq!(*data, 42);
+                            assert_eq!(
+                                Some(data.into_inner()),
+                                req.extensions().get::<u32>().copied()
+                            );
+                        }
+
+                        HttpResponse::Ok()
+                    },
+                )),
+        )
+        .await;
+
+        let req = TestRequest::get().uri("/test").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::post().uri("/test").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn req_data_internal_mutability() {
+        let srv = init_service(
+            App::new()
+                .wrap_fn(|req, srv| {
+                    let data_before = Rc::new(RefCell::new(42u32));
+                    req.extensions_mut().insert(data_before);
+
+                    srv.call(req).map_ok(|res| {
+                        {
+                            let ext = res.request().extensions();
+                            let data_after = ext.get::<Rc<RefCell<u32>>>().unwrap();
+                            assert_eq!(*data_after.borrow(), 53u32);
+                        }
+
+                        res
+                    })
+                })
+                .default_service(web::to(|data: ReqData<Rc<RefCell<u32>>>| {
+                    assert_eq!(*data.borrow(), 42);
+                    *data.borrow_mut() += 11;
+                    assert_eq!(*data.borrow(), 53);
+
+                    HttpResponse::Ok()
+                })),
+        )
+        .await;
+
+        let req = TestRequest::get().uri("/test").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/resource.rs.html b/src/actix_web/resource.rs.html new file mode 100644 index 000000000..5db1cb85c --- /dev/null +++ b/src/actix_web/resource.rs.html @@ -0,0 +1,1733 @@ +resource.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
+
use std::{cell::RefCell, fmt, future::Future, rc::Rc};
+
+use actix_http::Extensions;
+use actix_router::{IntoPatterns, Patterns};
+use actix_service::{
+    apply, apply_fn_factory, boxed, fn_service, IntoServiceFactory, Service, ServiceFactory,
+    ServiceFactoryExt, Transform,
+};
+use futures_core::future::LocalBoxFuture;
+use futures_util::future::join_all;
+
+use crate::{
+    body::MessageBody,
+    data::Data,
+    dev::{ensure_leading_slash, AppService, ResourceDef},
+    guard::{self, Guard},
+    handler::Handler,
+    http::header,
+    route::{Route, RouteService},
+    service::{
+        BoxedHttpService, BoxedHttpServiceFactory, HttpServiceFactory, ServiceRequest,
+        ServiceResponse,
+    },
+    web, Error, FromRequest, HttpResponse, Responder,
+};
+
+/// A collection of [`Route`]s that respond to the same path pattern.
+///
+/// Resource in turn has at least one route. Route consists of an handlers objects and list of
+/// guards (objects that implement `Guard` trait). Resources and routes uses builder-like pattern
+/// for configuration. During request handling, resource object iterate through all routes and check
+/// guards for specific route, if request matches all guards, route considered matched and route
+/// handler get called.
+///
+/// # Examples
+/// ```
+/// use actix_web::{web, App, HttpResponse};
+///
+/// let app = App::new().service(
+///     web::resource("/")
+///         .get(|| HttpResponse::Ok())
+///         .post(|| async { "Hello World!" })
+/// );
+/// ```
+///
+/// If no matching route is found, an empty 405 response is returned which includes an
+/// [appropriate Allow header][RFC 9110 §15.5.6]. This default behavior can be overridden using
+/// [`default_service()`](Self::default_service).
+///
+/// [RFC 9110 §15.5.6]: https://www.rfc-editor.org/rfc/rfc9110.html#section-15.5.6
+pub struct Resource<T = ResourceEndpoint> {
+    endpoint: T,
+    rdef: Patterns,
+    name: Option<String>,
+    routes: Vec<Route>,
+    app_data: Option<Extensions>,
+    guards: Vec<Box<dyn Guard>>,
+    default: BoxedHttpServiceFactory,
+    factory_ref: Rc<RefCell<Option<ResourceFactory>>>,
+}
+
+impl Resource {
+    /// Constructs new resource that matches a `path` pattern.
+    pub fn new<T: IntoPatterns>(path: T) -> Resource {
+        let fref = Rc::new(RefCell::new(None));
+
+        Resource {
+            routes: Vec::new(),
+            rdef: path.patterns(),
+            name: None,
+            endpoint: ResourceEndpoint::new(fref.clone()),
+            factory_ref: fref,
+            guards: Vec::new(),
+            app_data: None,
+            default: boxed::factory(fn_service(|req: ServiceRequest| async {
+                use crate::HttpMessage as _;
+
+                let allowed = req.extensions().get::<guard::RegisteredMethods>().cloned();
+
+                if let Some(methods) = allowed {
+                    Ok(req.into_response(
+                        HttpResponse::MethodNotAllowed()
+                            .insert_header(header::Allow(methods.0))
+                            .finish(),
+                    ))
+                } else {
+                    Ok(req.into_response(HttpResponse::MethodNotAllowed()))
+                }
+            })),
+        }
+    }
+}
+
+impl<T> Resource<T>
+where
+    T: ServiceFactory<ServiceRequest, Config = (), Error = Error, InitError = ()>,
+{
+    /// Set resource name.
+    ///
+    /// Name is used for url generation.
+    pub fn name(mut self, name: &str) -> Self {
+        self.name = Some(name.to_string());
+        self
+    }
+
+    /// Add match guard to a resource.
+    ///
+    /// ```
+    /// use actix_web::{web, guard, App, HttpResponse};
+    ///
+    /// async fn index(data: web::Path<(String, String)>) -> &'static str {
+    ///     "Welcome!"
+    /// }
+    ///
+    /// let app = App::new()
+    ///     .service(
+    ///         web::resource("/app")
+    ///             .guard(guard::Header("content-type", "text/plain"))
+    ///             .route(web::get().to(index))
+    ///     )
+    ///     .service(
+    ///         web::resource("/app")
+    ///             .guard(guard::Header("content-type", "text/json"))
+    ///             .route(web::get().to(|| HttpResponse::MethodNotAllowed()))
+    ///     );
+    /// ```
+    pub fn guard<G: Guard + 'static>(mut self, guard: G) -> Self {
+        self.guards.push(Box::new(guard));
+        self
+    }
+
+    pub(crate) fn add_guards(mut self, guards: Vec<Box<dyn Guard>>) -> Self {
+        self.guards.extend(guards);
+        self
+    }
+
+    /// Register a new route.
+    ///
+    /// ```
+    /// use actix_web::{web, guard, App, HttpResponse};
+    ///
+    /// let app = App::new().service(
+    ///     web::resource("/").route(
+    ///         web::route()
+    ///             .guard(guard::Any(guard::Get()).or(guard::Put()))
+    ///             .guard(guard::Header("Content-Type", "text/plain"))
+    ///             .to(|| HttpResponse::Ok()))
+    /// );
+    /// ```
+    ///
+    /// Multiple routes could be added to a resource. Resource object uses
+    /// match guards for route selection.
+    ///
+    /// ```
+    /// use actix_web::{web, guard, App};
+    ///
+    /// let app = App::new().service(
+    ///     web::resource("/container/")
+    ///          .route(web::get().to(get_handler))
+    ///          .route(web::post().to(post_handler))
+    ///          .route(web::delete().to(delete_handler))
+    /// );
+    ///
+    /// # async fn get_handler() -> impl actix_web::Responder { actix_web::HttpResponse::Ok() }
+    /// # async fn post_handler() -> impl actix_web::Responder { actix_web::HttpResponse::Ok() }
+    /// # async fn delete_handler() -> impl actix_web::Responder { actix_web::HttpResponse::Ok() }
+    /// ```
+    pub fn route(mut self, route: Route) -> Self {
+        self.routes.push(route);
+        self
+    }
+
+    /// Add resource data.
+    ///
+    /// Data of different types from parent contexts will still be accessible. Any `Data<T>` types
+    /// set here can be extracted in handlers using the `Data<T>` extractor.
+    ///
+    /// # Examples
+    /// ```
+    /// use std::cell::Cell;
+    /// use actix_web::{web, App, HttpRequest, HttpResponse, Responder};
+    ///
+    /// struct MyData {
+    ///     count: std::cell::Cell<usize>,
+    /// }
+    ///
+    /// async fn handler(req: HttpRequest, counter: web::Data<MyData>) -> impl Responder {
+    ///     // note this cannot use the Data<T> extractor because it was not added with it
+    ///     let incr = *req.app_data::<usize>().unwrap();
+    ///     assert_eq!(incr, 3);
+    ///
+    ///     // update counter using other value from app data
+    ///     counter.count.set(counter.count.get() + incr);
+    ///
+    ///     HttpResponse::Ok().body(counter.count.get().to_string())
+    /// }
+    ///
+    /// let app = App::new().service(
+    ///     web::resource("/")
+    ///         .app_data(3usize)
+    ///         .app_data(web::Data::new(MyData { count: Default::default() }))
+    ///         .route(web::get().to(handler))
+    /// );
+    /// ```
+    #[doc(alias = "manage")]
+    pub fn app_data<U: 'static>(mut self, data: U) -> Self {
+        self.app_data
+            .get_or_insert_with(Extensions::new)
+            .insert(data);
+
+        self
+    }
+
+    /// Add resource data after wrapping in `Data<T>`.
+    ///
+    /// Deprecated in favor of [`app_data`](Self::app_data).
+    #[deprecated(since = "4.0.0", note = "Use `.app_data(Data::new(val))` instead.")]
+    pub fn data<U: 'static>(self, data: U) -> Self {
+        self.app_data(Data::new(data))
+    }
+
+    /// Register a new route and add handler. This route matches all requests.
+    ///
+    /// ```
+    /// use actix_web::{App, HttpRequest, HttpResponse, web};
+    ///
+    /// async fn index(req: HttpRequest) -> HttpResponse {
+    ///     todo!()
+    /// }
+    ///
+    /// App::new().service(web::resource("/").to(index));
+    /// ```
+    ///
+    /// This is shortcut for:
+    ///
+    /// ```
+    /// # use actix_web::*;
+    /// # async fn index(req: HttpRequest) -> HttpResponse { todo!() }
+    /// App::new().service(web::resource("/").route(web::route().to(index)));
+    /// ```
+    pub fn to<F, Args>(mut self, handler: F) -> Self
+    where
+        F: Handler<Args>,
+        Args: FromRequest + 'static,
+        F::Output: Responder + 'static,
+    {
+        self.routes.push(Route::new().to(handler));
+        self
+    }
+
+    /// Registers a resource middleware.
+    ///
+    /// `mw` is a middleware component (type), that can modify the request and response across all
+    /// routes managed by this `Resource`.
+    ///
+    /// See [`App::wrap`](crate::App::wrap) for more details.
+    #[doc(alias = "middleware")]
+    #[doc(alias = "use")] // nodejs terminology
+    pub fn wrap<M, B>(
+        self,
+        mw: M,
+    ) -> Resource<
+        impl ServiceFactory<
+            ServiceRequest,
+            Config = (),
+            Response = ServiceResponse<B>,
+            Error = Error,
+            InitError = (),
+        >,
+    >
+    where
+        M: Transform<
+                T::Service,
+                ServiceRequest,
+                Response = ServiceResponse<B>,
+                Error = Error,
+                InitError = (),
+            > + 'static,
+        B: MessageBody,
+    {
+        Resource {
+            endpoint: apply(mw, self.endpoint),
+            rdef: self.rdef,
+            name: self.name,
+            guards: self.guards,
+            routes: self.routes,
+            default: self.default,
+            app_data: self.app_data,
+            factory_ref: self.factory_ref,
+        }
+    }
+
+    /// Registers a resource function middleware.
+    ///
+    /// `mw` is a closure that runs during inbound and/or outbound processing in the request
+    /// life-cycle (request -> response), modifying request/response as necessary, across all
+    /// requests handled by the `Resource`.
+    ///
+    /// See [`App::wrap_fn`](crate::App::wrap_fn) for examples and more details.
+    #[doc(alias = "middleware")]
+    #[doc(alias = "use")] // nodejs terminology
+    pub fn wrap_fn<F, R, B>(
+        self,
+        mw: F,
+    ) -> Resource<
+        impl ServiceFactory<
+            ServiceRequest,
+            Config = (),
+            Response = ServiceResponse<B>,
+            Error = Error,
+            InitError = (),
+        >,
+    >
+    where
+        F: Fn(ServiceRequest, &T::Service) -> R + Clone + 'static,
+        R: Future<Output = Result<ServiceResponse<B>, Error>>,
+        B: MessageBody,
+    {
+        Resource {
+            endpoint: apply_fn_factory(self.endpoint, mw),
+            rdef: self.rdef,
+            name: self.name,
+            guards: self.guards,
+            routes: self.routes,
+            default: self.default,
+            app_data: self.app_data,
+            factory_ref: self.factory_ref,
+        }
+    }
+
+    /// Sets the default service to be used if no matching route is found.
+    ///
+    /// Unlike [`Scope`]s, a `Resource` does _not_ inherit its parent's default service. You can
+    /// use a [`Route`] as default service.
+    ///
+    /// If a custom default service is not registered, an empty `405 Method Not Allowed` response
+    /// with an appropriate Allow header will be sent instead.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::{App, HttpResponse, web};
+    ///
+    /// let resource = web::resource("/test")
+    ///     .route(web::get().to(HttpResponse::Ok))
+    ///     .default_service(web::to(|| {
+    ///         HttpResponse::BadRequest()
+    ///     }));
+    ///
+    /// App::new().service(resource);
+    /// ```
+    ///
+    /// [`Scope`]: crate::Scope
+    pub fn default_service<F, U>(mut self, f: F) -> Self
+    where
+        F: IntoServiceFactory<U, ServiceRequest>,
+        U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error>
+            + 'static,
+        U::InitError: fmt::Debug,
+    {
+        // create and configure default resource
+        self.default = boxed::factory(
+            f.into_factory()
+                .map_init_err(|e| log::error!("Can not construct default service: {:?}", e)),
+        );
+
+        self
+    }
+}
+
+macro_rules! route_shortcut {
+    ($method_fn:ident, $method_upper:literal) => {
+        #[doc = concat!(" Adds a ", $method_upper, " route.")]
+        ///
+        /// Use [`route`](Self::route) if you need to add additional guards.
+        ///
+        /// # Examples
+        ///
+        /// ```
+        /// # use actix_web::web;
+        /// web::resource("/")
+        #[doc = concat!("    .", stringify!($method_fn), "(|| async { \"Hello World!\" })")]
+        /// # ;
+        /// ```
+        pub fn $method_fn<F, Args>(self, handler: F) -> Self
+        where
+            F: Handler<Args>,
+            Args: FromRequest + 'static,
+            F::Output: Responder + 'static,
+        {
+            self.route(web::$method_fn().to(handler))
+        }
+    };
+}
+
+/// Concise routes for well-known HTTP methods.
+impl<T> Resource<T>
+where
+    T: ServiceFactory<ServiceRequest, Config = (), Error = Error, InitError = ()>,
+{
+    route_shortcut!(get, "GET");
+    route_shortcut!(post, "POST");
+    route_shortcut!(put, "PUT");
+    route_shortcut!(patch, "PATCH");
+    route_shortcut!(delete, "DELETE");
+    route_shortcut!(head, "HEAD");
+    route_shortcut!(trace, "TRACE");
+}
+
+impl<T, B> HttpServiceFactory for Resource<T>
+where
+    T: ServiceFactory<
+            ServiceRequest,
+            Config = (),
+            Response = ServiceResponse<B>,
+            Error = Error,
+            InitError = (),
+        > + 'static,
+    B: MessageBody + 'static,
+{
+    fn register(mut self, config: &mut AppService) {
+        let guards = if self.guards.is_empty() {
+            None
+        } else {
+            Some(std::mem::take(&mut self.guards))
+        };
+
+        let mut rdef = if config.is_root() || !self.rdef.is_empty() {
+            ResourceDef::new(ensure_leading_slash(self.rdef.clone()))
+        } else {
+            ResourceDef::new(self.rdef.clone())
+        };
+
+        if let Some(ref name) = self.name {
+            rdef.set_name(name);
+        }
+
+        *self.factory_ref.borrow_mut() = Some(ResourceFactory {
+            routes: self.routes,
+            default: self.default,
+        });
+
+        let resource_data = self.app_data.map(Rc::new);
+
+        // wraps endpoint service (including middleware) call and injects app data for this scope
+        let endpoint = apply_fn_factory(self.endpoint, move |mut req: ServiceRequest, srv| {
+            if let Some(ref data) = resource_data {
+                req.add_data_container(Rc::clone(data));
+            }
+
+            let fut = srv.call(req);
+
+            async { Ok(fut.await?.map_into_boxed_body()) }
+        });
+
+        config.register_service(rdef, guards, endpoint, None)
+    }
+}
+
+pub struct ResourceFactory {
+    routes: Vec<Route>,
+    default: BoxedHttpServiceFactory,
+}
+
+impl ServiceFactory<ServiceRequest> for ResourceFactory {
+    type Response = ServiceResponse;
+    type Error = Error;
+    type Config = ();
+    type Service = ResourceService;
+    type InitError = ();
+    type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
+
+    fn new_service(&self, _: ()) -> Self::Future {
+        // construct default service factory future.
+        let default_fut = self.default.new_service(());
+
+        // construct route service factory futures
+        let factory_fut = join_all(self.routes.iter().map(|route| route.new_service(())));
+
+        Box::pin(async move {
+            let default = default_fut.await?;
+            let routes = factory_fut
+                .await
+                .into_iter()
+                .collect::<Result<Vec<_>, _>>()?;
+
+            Ok(ResourceService { routes, default })
+        })
+    }
+}
+
+pub struct ResourceService {
+    routes: Vec<RouteService>,
+    default: BoxedHttpService,
+}
+
+impl Service<ServiceRequest> for ResourceService {
+    type Response = ServiceResponse;
+    type Error = Error;
+    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
+
+    actix_service::always_ready!();
+
+    fn call(&self, mut req: ServiceRequest) -> Self::Future {
+        for route in &self.routes {
+            if route.check(&mut req) {
+                return route.call(req);
+            }
+        }
+
+        self.default.call(req)
+    }
+}
+
+#[doc(hidden)]
+pub struct ResourceEndpoint {
+    factory: Rc<RefCell<Option<ResourceFactory>>>,
+}
+
+impl ResourceEndpoint {
+    fn new(factory: Rc<RefCell<Option<ResourceFactory>>>) -> Self {
+        ResourceEndpoint { factory }
+    }
+}
+
+impl ServiceFactory<ServiceRequest> for ResourceEndpoint {
+    type Response = ServiceResponse;
+    type Error = Error;
+    type Config = ();
+    type Service = ResourceService;
+    type InitError = ();
+    type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
+
+    fn new_service(&self, _: ()) -> Self::Future {
+        self.factory.borrow().as_ref().unwrap().new_service(())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::time::Duration;
+
+    use actix_rt::time::sleep;
+    use actix_utils::future::ok;
+
+    use super::*;
+    use crate::{
+        http::{header::HeaderValue, Method, StatusCode},
+        middleware::DefaultHeaders,
+        test::{call_service, init_service, TestRequest},
+        App, HttpMessage,
+    };
+
+    #[test]
+    fn can_be_returned_from_fn() {
+        fn my_resource_1() -> Resource {
+            web::resource("/test1").route(web::get().to(|| async { "hello" }))
+        }
+
+        fn my_resource_2() -> Resource<
+            impl ServiceFactory<
+                ServiceRequest,
+                Config = (),
+                Response = ServiceResponse<impl MessageBody>,
+                Error = Error,
+                InitError = (),
+            >,
+        > {
+            web::resource("/test2")
+                .wrap_fn(|req, srv| {
+                    let fut = srv.call(req);
+                    async { Ok(fut.await?.map_into_right_body::<()>()) }
+                })
+                .route(web::get().to(|| async { "hello" }))
+        }
+
+        fn my_resource_3() -> impl HttpServiceFactory {
+            web::resource("/test3").route(web::get().to(|| async { "hello" }))
+        }
+
+        App::new()
+            .service(my_resource_1())
+            .service(my_resource_2())
+            .service(my_resource_3());
+    }
+
+    #[actix_rt::test]
+    async fn test_middleware() {
+        let srv = init_service(
+            App::new().service(
+                web::resource("/test")
+                    .name("test")
+                    .wrap(
+                        DefaultHeaders::new()
+                            .add((header::CONTENT_TYPE, HeaderValue::from_static("0001"))),
+                    )
+                    .route(web::get().to(HttpResponse::Ok)),
+            ),
+        )
+        .await;
+        let req = TestRequest::with_uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("0001")
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_middleware_fn() {
+        let srv = init_service(
+            App::new().service(
+                web::resource("/test")
+                    .wrap_fn(|req, srv| {
+                        let fut = srv.call(req);
+                        async {
+                            fut.await.map(|mut res| {
+                                res.headers_mut()
+                                    .insert(header::CONTENT_TYPE, HeaderValue::from_static("0001"));
+                                res
+                            })
+                        }
+                    })
+                    .route(web::get().to(HttpResponse::Ok)),
+            ),
+        )
+        .await;
+        let req = TestRequest::with_uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("0001")
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_to() {
+        let srv = init_service(App::new().service(web::resource("/test").to(|| async {
+            sleep(Duration::from_millis(100)).await;
+            Ok::<_, Error>(HttpResponse::Ok())
+        })))
+        .await;
+        let req = TestRequest::with_uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_pattern() {
+        let srv = init_service(App::new().service(
+            web::resource(["/test", "/test2"]).to(|| async { Ok::<_, Error>(HttpResponse::Ok()) }),
+        ))
+        .await;
+        let req = TestRequest::with_uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        let req = TestRequest::with_uri("/test2").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_default_resource() {
+        let srv = init_service(
+            App::new()
+                .service(
+                    web::resource("/test")
+                        .route(web::get().to(HttpResponse::Ok))
+                        .route(web::delete().to(HttpResponse::Ok)),
+                )
+                .default_service(|r: ServiceRequest| {
+                    ok(r.into_response(HttpResponse::BadRequest()))
+                }),
+        )
+        .await;
+        let req = TestRequest::with_uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/test")
+            .method(Method::POST)
+            .to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
+        assert_eq!(
+            resp.headers().get(header::ALLOW).unwrap().as_bytes(),
+            b"GET, DELETE"
+        );
+
+        let srv = init_service(
+            App::new().service(
+                web::resource("/test")
+                    .route(web::get().to(HttpResponse::Ok))
+                    .default_service(|r: ServiceRequest| {
+                        ok(r.into_response(HttpResponse::BadRequest()))
+                    }),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/test")
+            .method(Method::POST)
+            .to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+    }
+
+    #[actix_rt::test]
+    async fn test_resource_guards() {
+        let srv = init_service(
+            App::new()
+                .service(
+                    web::resource("/test/{p}")
+                        .guard(guard::Get())
+                        .to(HttpResponse::Ok),
+                )
+                .service(
+                    web::resource("/test/{p}")
+                        .guard(guard::Put())
+                        .to(HttpResponse::Created),
+                )
+                .service(
+                    web::resource("/test/{p}")
+                        .guard(guard::Delete())
+                        .to(HttpResponse::NoContent),
+                ),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/test/it")
+            .method(Method::GET)
+            .to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/test/it")
+            .method(Method::PUT)
+            .to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::CREATED);
+
+        let req = TestRequest::with_uri("/test/it")
+            .method(Method::DELETE)
+            .to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::NO_CONTENT);
+    }
+
+    // allow deprecated `{App, Resource}::data`
+    #[allow(deprecated)]
+    #[actix_rt::test]
+    async fn test_data() {
+        let srv = init_service(
+            App::new()
+                .data(1.0f64)
+                .data(1usize)
+                .app_data(web::Data::new('-'))
+                .service(
+                    web::resource("/test")
+                        .data(10usize)
+                        .app_data(web::Data::new('*'))
+                        .guard(guard::Get())
+                        .to(
+                            |data1: web::Data<usize>,
+                             data2: web::Data<char>,
+                             data3: web::Data<f64>| {
+                                assert_eq!(**data1, 10);
+                                assert_eq!(**data2, '*');
+                                let error = f64::EPSILON;
+                                assert!((**data3 - 1.0).abs() < error);
+                                HttpResponse::Ok()
+                            },
+                        ),
+                ),
+        )
+        .await;
+
+        let req = TestRequest::get().uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    // allow deprecated `{App, Resource}::data`
+    #[allow(deprecated)]
+    #[actix_rt::test]
+    async fn test_data_default_service() {
+        let srv =
+            init_service(
+                App::new().data(1usize).service(
+                    web::resource("/test")
+                        .data(10usize)
+                        .default_service(web::to(|data: web::Data<usize>| {
+                            assert_eq!(**data, 10);
+                            HttpResponse::Ok()
+                        })),
+                ),
+            )
+            .await;
+
+        let req = TestRequest::get().uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_middleware_app_data() {
+        let srv = init_service(
+            App::new().service(
+                web::resource("test")
+                    .app_data(1usize)
+                    .wrap_fn(|req, srv| {
+                        assert_eq!(req.app_data::<usize>(), Some(&1usize));
+                        req.extensions_mut().insert(1usize);
+                        srv.call(req)
+                    })
+                    .route(web::get().to(HttpResponse::Ok))
+                    .default_service(|req: ServiceRequest| async move {
+                        let (req, _) = req.into_parts();
+
+                        assert_eq!(req.extensions().get::<usize>(), Some(&1));
+
+                        Ok(ServiceResponse::new(
+                            req,
+                            HttpResponse::BadRequest().finish(),
+                        ))
+                    }),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::get().uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::post().uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+    }
+
+    #[actix_rt::test]
+    async fn test_middleware_body_type() {
+        let srv = init_service(
+            App::new().service(
+                web::resource("/test")
+                    .wrap_fn(|req, srv| {
+                        let fut = srv.call(req);
+                        async { Ok(fut.await?.map_into_right_body::<()>()) }
+                    })
+                    .route(web::get().to(|| async { "hello" })),
+            ),
+        )
+        .await;
+
+        // test if `try_into_bytes()` is preserved across scope layer
+        use actix_http::body::MessageBody as _;
+        let req = TestRequest::with_uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        let body = resp.into_body();
+        assert_eq!(body.try_into_bytes().unwrap(), b"hello".as_ref());
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/response/builder.rs.html b/src/actix_web/response/builder.rs.html new file mode 100644 index 000000000..46aab1ccd --- /dev/null +++ b/src/actix_web/response/builder.rs.html @@ -0,0 +1,1065 @@ +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
+
use std::{
+    cell::{Ref, RefMut},
+    future::Future,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use actix_http::{error::HttpError, Response, ResponseHead};
+use bytes::Bytes;
+use futures_core::Stream;
+use serde::Serialize;
+
+use crate::{
+    body::{BodyStream, BoxBody, MessageBody},
+    dev::Extensions,
+    error::{Error, JsonPayloadError},
+    http::{
+        header::{self, HeaderName, TryIntoHeaderPair, TryIntoHeaderValue},
+        ConnectionType, StatusCode,
+    },
+    BoxError, HttpRequest, HttpResponse, Responder,
+};
+
+/// An HTTP response builder.
+///
+/// This type can be used to construct an instance of `Response` through a builder-like pattern.
+pub struct HttpResponseBuilder {
+    res: Option<Response<BoxBody>>,
+    error: Option<HttpError>,
+}
+
+impl HttpResponseBuilder {
+    #[inline]
+    /// Create response builder
+    pub fn new(status: StatusCode) -> Self {
+        Self {
+            res: Some(Response::with_body(status, BoxBody::new(()))),
+            error: None,
+        }
+    }
+
+    /// Set HTTP status code of this response.
+    #[inline]
+    pub fn status(&mut self, status: StatusCode) -> &mut Self {
+        if let Some(parts) = self.inner() {
+            parts.status = status;
+        }
+        self
+    }
+
+    /// Insert a header, replacing any that were set with an equivalent field name.
+    ///
+    /// ```
+    /// use actix_web::{HttpResponse, http::header};
+    ///
+    /// HttpResponse::Ok()
+    ///     .insert_header(header::ContentType(mime::APPLICATION_JSON))
+    ///     .insert_header(("X-TEST", "value"))
+    ///     .finish();
+    /// ```
+    pub fn insert_header(&mut self, header: impl TryIntoHeaderPair) -> &mut Self {
+        if let Some(parts) = self.inner() {
+            match header.try_into_pair() {
+                Ok((key, value)) => {
+                    parts.headers.insert(key, value);
+                }
+                Err(err) => self.error = Some(err.into()),
+            };
+        }
+
+        self
+    }
+
+    /// Append a header, keeping any that were set with an equivalent field name.
+    ///
+    /// ```
+    /// use actix_web::{HttpResponse, http::header};
+    ///
+    /// HttpResponse::Ok()
+    ///     .append_header(header::ContentType(mime::APPLICATION_JSON))
+    ///     .append_header(("X-TEST", "value1"))
+    ///     .append_header(("X-TEST", "value2"))
+    ///     .finish();
+    /// ```
+    pub fn append_header(&mut self, header: impl TryIntoHeaderPair) -> &mut Self {
+        if let Some(parts) = self.inner() {
+            match header.try_into_pair() {
+                Ok((key, value)) => parts.headers.append(key, value),
+                Err(err) => self.error = Some(err.into()),
+            };
+        }
+
+        self
+    }
+
+    /// Replaced with [`Self::insert_header()`].
+    #[doc(hidden)]
+    #[deprecated(
+        since = "4.0.0",
+        note = "Replaced with `insert_header((key, value))`. Will be removed in v5."
+    )]
+    pub fn set_header<K, V>(&mut self, key: K, value: V) -> &mut Self
+    where
+        K: TryInto<HeaderName>,
+        K::Error: Into<HttpError>,
+        V: TryIntoHeaderValue,
+    {
+        if self.error.is_some() {
+            return self;
+        }
+
+        match (key.try_into(), value.try_into_value()) {
+            (Ok(name), Ok(value)) => return self.insert_header((name, value)),
+            (Err(err), _) => self.error = Some(err.into()),
+            (_, Err(err)) => self.error = Some(err.into()),
+        }
+
+        self
+    }
+
+    /// Replaced with [`Self::append_header()`].
+    #[doc(hidden)]
+    #[deprecated(
+        since = "4.0.0",
+        note = "Replaced with `append_header((key, value))`. Will be removed in v5."
+    )]
+    pub fn header<K, V>(&mut self, key: K, value: V) -> &mut Self
+    where
+        K: TryInto<HeaderName>,
+        K::Error: Into<HttpError>,
+        V: TryIntoHeaderValue,
+    {
+        if self.error.is_some() {
+            return self;
+        }
+
+        match (key.try_into(), value.try_into_value()) {
+            (Ok(name), Ok(value)) => return self.append_header((name, value)),
+            (Err(err), _) => self.error = Some(err.into()),
+            (_, Err(err)) => self.error = Some(err.into()),
+        }
+
+        self
+    }
+
+    /// Set the custom reason for the response.
+    #[inline]
+    pub fn reason(&mut self, reason: &'static str) -> &mut Self {
+        if let Some(parts) = self.inner() {
+            parts.reason = Some(reason);
+        }
+        self
+    }
+
+    /// Set connection type to KeepAlive
+    #[inline]
+    pub fn keep_alive(&mut self) -> &mut Self {
+        if let Some(parts) = self.inner() {
+            parts.set_connection_type(ConnectionType::KeepAlive);
+        }
+        self
+    }
+
+    /// Set connection type to Upgrade
+    #[inline]
+    pub fn upgrade<V>(&mut self, value: V) -> &mut Self
+    where
+        V: TryIntoHeaderValue,
+    {
+        if let Some(parts) = self.inner() {
+            parts.set_connection_type(ConnectionType::Upgrade);
+        }
+
+        if let Ok(value) = value.try_into_value() {
+            self.insert_header((header::UPGRADE, value));
+        }
+
+        self
+    }
+
+    /// Force close connection, even if it is marked as keep-alive
+    #[inline]
+    pub fn force_close(&mut self) -> &mut Self {
+        if let Some(parts) = self.inner() {
+            parts.set_connection_type(ConnectionType::Close);
+        }
+        self
+    }
+
+    /// Disable chunked transfer encoding for HTTP/1.1 streaming responses.
+    #[inline]
+    pub fn no_chunking(&mut self, len: u64) -> &mut Self {
+        let mut buf = itoa::Buffer::new();
+        self.insert_header((header::CONTENT_LENGTH, buf.format(len)));
+
+        if let Some(parts) = self.inner() {
+            parts.no_chunking(true);
+        }
+        self
+    }
+
+    /// Set response content type.
+    #[inline]
+    pub fn content_type<V>(&mut self, value: V) -> &mut Self
+    where
+        V: TryIntoHeaderValue,
+    {
+        if let Some(parts) = self.inner() {
+            match value.try_into_value() {
+                Ok(value) => {
+                    parts.headers.insert(header::CONTENT_TYPE, value);
+                }
+                Err(err) => self.error = Some(err.into()),
+            };
+        }
+        self
+    }
+
+    /// Add a cookie to the response.
+    ///
+    /// To send a "removal" cookie, call [`.make_removal()`](cookie::Cookie::make_removal) on the
+    /// given cookie. See [`HttpResponse::add_removal_cookie()`] to learn more.
+    ///
+    /// # Examples
+    /// Send a new cookie:
+    /// ```
+    /// use actix_web::{HttpResponse, cookie::Cookie};
+    ///
+    /// let res = HttpResponse::Ok()
+    ///     .cookie(
+    ///         Cookie::build("name", "value")
+    ///             .domain("www.rust-lang.org")
+    ///             .path("/")
+    ///             .secure(true)
+    ///             .http_only(true)
+    ///             .finish(),
+    ///     )
+    ///     .finish();
+    /// ```
+    ///
+    /// Send a removal cookie:
+    /// ```
+    /// use actix_web::{HttpResponse, cookie::Cookie};
+    ///
+    /// // the name, domain and path match the cookie created in the previous example
+    /// let mut cookie = Cookie::build("name", "value-does-not-matter")
+    ///     .domain("www.rust-lang.org")
+    ///     .path("/")
+    ///     .finish();
+    /// cookie.make_removal();
+    ///
+    /// let res = HttpResponse::Ok()
+    ///     .cookie(cookie)
+    ///     .finish();
+    /// ```
+    #[cfg(feature = "cookies")]
+    pub fn cookie(&mut self, cookie: cookie::Cookie<'_>) -> &mut Self {
+        match cookie.to_string().try_into_value() {
+            Ok(hdr_val) => self.append_header((header::SET_COOKIE, hdr_val)),
+            Err(err) => {
+                self.error = Some(err.into());
+                self
+            }
+        }
+    }
+
+    /// Returns a reference to the response-local data/extensions container.
+    #[inline]
+    pub fn extensions(&self) -> Ref<'_, Extensions> {
+        self.res
+            .as_ref()
+            .expect("cannot reuse response builder")
+            .extensions()
+    }
+
+    /// Returns a mutable reference to the response-local data/extensions container.
+    #[inline]
+    pub fn extensions_mut(&mut self) -> RefMut<'_, Extensions> {
+        self.res
+            .as_mut()
+            .expect("cannot reuse response builder")
+            .extensions_mut()
+    }
+
+    /// Set a body and build the `HttpResponse`.
+    ///
+    /// Unlike [`message_body`](Self::message_body), errors are converted into error
+    /// responses immediately.
+    ///
+    /// `HttpResponseBuilder` can not be used after this call.
+    pub fn body<B>(&mut self, body: B) -> HttpResponse<BoxBody>
+    where
+        B: MessageBody + 'static,
+    {
+        match self.message_body(body) {
+            Ok(res) => res.map_into_boxed_body(),
+            Err(err) => HttpResponse::from_error(err),
+        }
+    }
+
+    /// Set a body and build the `HttpResponse`.
+    ///
+    /// `HttpResponseBuilder` can not be used after this call.
+    pub fn message_body<B>(&mut self, body: B) -> Result<HttpResponse<B>, Error> {
+        if let Some(err) = self.error.take() {
+            return Err(err.into());
+        }
+
+        let res = self
+            .res
+            .take()
+            .expect("cannot reuse response builder")
+            .set_body(body);
+
+        Ok(HttpResponse::from(res))
+    }
+
+    /// Set a streaming body and build the `HttpResponse`.
+    ///
+    /// `HttpResponseBuilder` can not be used after this call.
+    #[inline]
+    pub fn streaming<S, E>(&mut self, stream: S) -> HttpResponse
+    where
+        S: Stream<Item = Result<Bytes, E>> + 'static,
+        E: Into<BoxError> + 'static,
+    {
+        self.body(BodyStream::new(stream))
+    }
+
+    /// Set a JSON body and build the `HttpResponse`.
+    ///
+    /// `HttpResponseBuilder` can not be used after this call.
+    pub fn json(&mut self, value: impl Serialize) -> HttpResponse {
+        match serde_json::to_string(&value) {
+            Ok(body) => {
+                let contains = if let Some(parts) = self.inner() {
+                    parts.headers.contains_key(header::CONTENT_TYPE)
+                } else {
+                    true
+                };
+
+                if !contains {
+                    self.insert_header((header::CONTENT_TYPE, mime::APPLICATION_JSON));
+                }
+
+                self.body(body)
+            }
+            Err(err) => HttpResponse::from_error(JsonPayloadError::Serialize(err)),
+        }
+    }
+
+    /// Set an empty body and build the `HttpResponse`.
+    ///
+    /// `HttpResponseBuilder` can not be used after this call.
+    #[inline]
+    pub fn finish(&mut self) -> HttpResponse {
+        self.body(())
+    }
+
+    /// This method construct new `HttpResponseBuilder`
+    pub fn take(&mut self) -> Self {
+        Self {
+            res: self.res.take(),
+            error: self.error.take(),
+        }
+    }
+
+    fn inner(&mut self) -> Option<&mut ResponseHead> {
+        if self.error.is_some() {
+            return None;
+        }
+
+        self.res.as_mut().map(Response::head_mut)
+    }
+}
+
+impl From<HttpResponseBuilder> for HttpResponse {
+    fn from(mut builder: HttpResponseBuilder) -> Self {
+        builder.finish()
+    }
+}
+
+impl From<HttpResponseBuilder> for Response<BoxBody> {
+    fn from(mut builder: HttpResponseBuilder) -> Self {
+        builder.finish().into()
+    }
+}
+
+impl Future for HttpResponseBuilder {
+    type Output = Result<HttpResponse, Error>;
+
+    fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
+        Poll::Ready(Ok(self.finish()))
+    }
+}
+
+impl Responder for HttpResponseBuilder {
+    type Body = BoxBody;
+
+    #[inline]
+    fn respond_to(mut self, _: &HttpRequest) -> HttpResponse<Self::Body> {
+        self.finish()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::{
+        body,
+        http::header::{HeaderValue, CONTENT_TYPE},
+        test::assert_body_eq,
+    };
+
+    #[test]
+    fn test_basic_builder() {
+        let resp = HttpResponse::Ok()
+            .insert_header(("X-TEST", "value"))
+            .finish();
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[test]
+    fn test_upgrade() {
+        let resp = HttpResponseBuilder::new(StatusCode::OK)
+            .upgrade("websocket")
+            .finish();
+        assert!(resp.upgrade());
+        assert_eq!(
+            resp.headers().get(header::UPGRADE).unwrap(),
+            HeaderValue::from_static("websocket")
+        );
+    }
+
+    #[test]
+    fn test_force_close() {
+        let resp = HttpResponseBuilder::new(StatusCode::OK)
+            .force_close()
+            .finish();
+        assert!(!resp.keep_alive())
+    }
+
+    #[test]
+    fn test_content_type() {
+        let resp = HttpResponseBuilder::new(StatusCode::OK)
+            .content_type("text/plain")
+            .body(Bytes::new());
+        assert_eq!(resp.headers().get(CONTENT_TYPE).unwrap(), "text/plain")
+    }
+
+    #[actix_rt::test]
+    async fn test_json() {
+        let res = HttpResponse::Ok().json(vec!["v1", "v2", "v3"]);
+        let ct = res.headers().get(CONTENT_TYPE).unwrap();
+        assert_eq!(ct, HeaderValue::from_static("application/json"));
+        assert_body_eq!(res, br#"["v1","v2","v3"]"#);
+
+        let res = HttpResponse::Ok().json(["v1", "v2", "v3"]);
+        let ct = res.headers().get(CONTENT_TYPE).unwrap();
+        assert_eq!(ct, HeaderValue::from_static("application/json"));
+        assert_body_eq!(res, br#"["v1","v2","v3"]"#);
+
+        // content type override
+        let res = HttpResponse::Ok()
+            .insert_header((CONTENT_TYPE, "text/json"))
+            .json(&vec!["v1", "v2", "v3"]);
+        let ct = res.headers().get(CONTENT_TYPE).unwrap();
+        assert_eq!(ct, HeaderValue::from_static("text/json"));
+        assert_body_eq!(res, br#"["v1","v2","v3"]"#);
+    }
+
+    #[actix_rt::test]
+    async fn test_serde_json_in_body() {
+        let resp = HttpResponse::Ok()
+            .body(serde_json::to_vec(&serde_json::json!({ "test-key": "test-value" })).unwrap());
+
+        assert_eq!(
+            body::to_bytes(resp.into_body()).await.unwrap().as_ref(),
+            br#"{"test-key":"test-value"}"#
+        );
+    }
+
+    #[test]
+    fn response_builder_header_insert_kv() {
+        let mut res = HttpResponse::Ok();
+        res.insert_header(("Content-Type", "application/octet-stream"));
+        let res = res.finish();
+
+        assert_eq!(
+            res.headers().get("Content-Type"),
+            Some(&HeaderValue::from_static("application/octet-stream"))
+        );
+    }
+
+    #[test]
+    fn response_builder_header_insert_typed() {
+        let mut res = HttpResponse::Ok();
+        res.insert_header((header::CONTENT_TYPE, mime::APPLICATION_OCTET_STREAM));
+        let res = res.finish();
+
+        assert_eq!(
+            res.headers().get("Content-Type"),
+            Some(&HeaderValue::from_static("application/octet-stream"))
+        );
+    }
+
+    #[test]
+    fn response_builder_header_append_kv() {
+        let mut res = HttpResponse::Ok();
+        res.append_header(("Content-Type", "application/octet-stream"));
+        res.append_header(("Content-Type", "application/json"));
+        let res = res.finish();
+
+        let headers: Vec<_> = res.headers().get_all("Content-Type").cloned().collect();
+        assert_eq!(headers.len(), 2);
+        assert!(headers.contains(&HeaderValue::from_static("application/octet-stream")));
+        assert!(headers.contains(&HeaderValue::from_static("application/json")));
+    }
+
+    #[test]
+    fn response_builder_header_append_typed() {
+        let mut res = HttpResponse::Ok();
+        res.append_header((header::CONTENT_TYPE, mime::APPLICATION_OCTET_STREAM));
+        res.append_header((header::CONTENT_TYPE, mime::APPLICATION_JSON));
+        let res = res.finish();
+
+        let headers: Vec<_> = res.headers().get_all("Content-Type").cloned().collect();
+        assert_eq!(headers.len(), 2);
+        assert!(headers.contains(&HeaderValue::from_static("application/octet-stream")));
+        assert!(headers.contains(&HeaderValue::from_static("application/json")));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/response/customize_responder.rs.html b/src/actix_web/response/customize_responder.rs.html new file mode 100644 index 000000000..ce1e1c717 --- /dev/null +++ b/src/actix_web/response/customize_responder.rs.html @@ -0,0 +1,479 @@ +customize_responder.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
+
use actix_http::{
+    body::EitherBody,
+    error::HttpError,
+    header::{HeaderMap, TryIntoHeaderPair},
+    StatusCode,
+};
+
+use crate::{HttpRequest, HttpResponse, Responder};
+
+/// Allows overriding status code and headers for a [`Responder`].
+///
+/// Created by calling the [`customize`](Responder::customize) method on a [`Responder`] type.
+pub struct CustomizeResponder<R> {
+    inner: CustomizeResponderInner<R>,
+    error: Option<HttpError>,
+}
+
+struct CustomizeResponderInner<R> {
+    responder: R,
+    status: Option<StatusCode>,
+    override_headers: HeaderMap,
+    append_headers: HeaderMap,
+}
+
+impl<R: Responder> CustomizeResponder<R> {
+    pub(crate) fn new(responder: R) -> Self {
+        CustomizeResponder {
+            inner: CustomizeResponderInner {
+                responder,
+                status: None,
+                override_headers: HeaderMap::new(),
+                append_headers: HeaderMap::new(),
+            },
+            error: None,
+        }
+    }
+
+    /// Override a status code for the Responder's response.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::{Responder, http::StatusCode, test::TestRequest};
+    ///
+    /// let responder = "Welcome!".customize().with_status(StatusCode::ACCEPTED);
+    ///
+    /// let request = TestRequest::default().to_http_request();
+    /// let response = responder.respond_to(&request);
+    /// assert_eq!(response.status(), StatusCode::ACCEPTED);
+    /// ```
+    pub fn with_status(mut self, status: StatusCode) -> Self {
+        if let Some(inner) = self.inner() {
+            inner.status = Some(status);
+        }
+
+        self
+    }
+
+    /// Insert (override) header in the final response.
+    ///
+    /// Overrides other headers with the same name.
+    /// See [`HeaderMap::insert`](crate::http::header::HeaderMap::insert).
+    ///
+    /// Headers added with this method will be inserted before those added
+    /// with [`append_header`](Self::append_header). As such, header(s) can be overridden with more
+    /// than one new header by first calling `insert_header` followed by `append_header`.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::{Responder, test::TestRequest};
+    ///
+    /// let responder = "Hello world!"
+    ///     .customize()
+    ///     .insert_header(("x-version", "1.2.3"));
+    ///
+    /// let request = TestRequest::default().to_http_request();
+    /// let response = responder.respond_to(&request);
+    /// assert_eq!(response.headers().get("x-version").unwrap(), "1.2.3");
+    /// ```
+    pub fn insert_header(mut self, header: impl TryIntoHeaderPair) -> Self {
+        if let Some(inner) = self.inner() {
+            match header.try_into_pair() {
+                Ok((key, value)) => {
+                    inner.override_headers.insert(key, value);
+                }
+                Err(err) => self.error = Some(err.into()),
+            };
+        }
+
+        self
+    }
+
+    /// Append header to the final response.
+    ///
+    /// Unlike [`insert_header`](Self::insert_header), this will not override existing headers.
+    /// See [`HeaderMap::append`](crate::http::header::HeaderMap::append).
+    ///
+    /// Headers added here are appended _after_ additions/overrides from `insert_header`.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::{Responder, test::TestRequest};
+    ///
+    /// let responder = "Hello world!"
+    ///     .customize()
+    ///     .append_header(("x-version", "1.2.3"));
+    ///
+    /// let request = TestRequest::default().to_http_request();
+    /// let response = responder.respond_to(&request);
+    /// assert_eq!(response.headers().get("x-version").unwrap(), "1.2.3");
+    /// ```
+    pub fn append_header(mut self, header: impl TryIntoHeaderPair) -> Self {
+        if let Some(inner) = self.inner() {
+            match header.try_into_pair() {
+                Ok((key, value)) => {
+                    inner.append_headers.append(key, value);
+                }
+                Err(err) => self.error = Some(err.into()),
+            };
+        }
+
+        self
+    }
+
+    #[doc(hidden)]
+    #[deprecated(since = "4.0.0", note = "Renamed to `insert_header`.")]
+    pub fn with_header(self, header: impl TryIntoHeaderPair) -> Self
+    where
+        Self: Sized,
+    {
+        self.insert_header(header)
+    }
+
+    fn inner(&mut self) -> Option<&mut CustomizeResponderInner<R>> {
+        if self.error.is_some() {
+            None
+        } else {
+            Some(&mut self.inner)
+        }
+    }
+}
+
+impl<T> Responder for CustomizeResponder<T>
+where
+    T: Responder,
+{
+    type Body = EitherBody<T::Body>;
+
+    fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body> {
+        if let Some(err) = self.error {
+            return HttpResponse::from_error(err).map_into_right_body();
+        }
+
+        let mut res = self.inner.responder.respond_to(req);
+
+        if let Some(status) = self.inner.status {
+            *res.status_mut() = status;
+        }
+
+        for (k, v) in self.inner.override_headers {
+            res.headers_mut().insert(k, v);
+        }
+
+        for (k, v) in self.inner.append_headers {
+            res.headers_mut().append(k, v);
+        }
+
+        res.map_into_left_body()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_http::body::to_bytes;
+    use bytes::Bytes;
+
+    use super::*;
+    use crate::{
+        http::header::{HeaderValue, CONTENT_TYPE},
+        test::TestRequest,
+    };
+
+    #[actix_rt::test]
+    async fn customize_responder() {
+        let req = TestRequest::default().to_http_request();
+        let res = "test"
+            .to_string()
+            .customize()
+            .with_status(StatusCode::BAD_REQUEST)
+            .respond_to(&req);
+
+        assert_eq!(res.status(), StatusCode::BAD_REQUEST);
+        assert_eq!(
+            to_bytes(res.into_body()).await.unwrap(),
+            Bytes::from_static(b"test"),
+        );
+
+        let res = "test"
+            .to_string()
+            .customize()
+            .insert_header(("content-type", "json"))
+            .respond_to(&req);
+
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("json")
+        );
+        assert_eq!(
+            to_bytes(res.into_body()).await.unwrap(),
+            Bytes::from_static(b"test"),
+        );
+    }
+
+    #[actix_rt::test]
+    async fn tuple_responder_with_status_code() {
+        let req = TestRequest::default().to_http_request();
+        let res = ("test".to_string(), StatusCode::BAD_REQUEST).respond_to(&req);
+        assert_eq!(res.status(), StatusCode::BAD_REQUEST);
+        assert_eq!(
+            to_bytes(res.into_body()).await.unwrap(),
+            Bytes::from_static(b"test"),
+        );
+
+        let req = TestRequest::default().to_http_request();
+        let res = ("test".to_string(), StatusCode::OK)
+            .customize()
+            .insert_header((CONTENT_TYPE, mime::APPLICATION_JSON))
+            .respond_to(&req);
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("application/json")
+        );
+        assert_eq!(
+            to_bytes(res.into_body()).await.unwrap(),
+            Bytes::from_static(b"test"),
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/response/http_codes.rs.html b/src/actix_web/response/http_codes.rs.html new file mode 100644 index 000000000..1a7bbf5a0 --- /dev/null +++ b/src/actix_web/response/http_codes.rs.html @@ -0,0 +1,215 @@ +http_codes.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
+
//! Status code based HTTP response builders.
+
+use actix_http::StatusCode;
+
+use crate::{HttpResponse, HttpResponseBuilder};
+
+macro_rules! static_resp {
+    ($name:ident, $status:expr) => {
+        #[allow(non_snake_case, missing_docs)]
+        pub fn $name() -> HttpResponseBuilder {
+            HttpResponseBuilder::new($status)
+        }
+    };
+}
+
+impl HttpResponse {
+    static_resp!(Continue, StatusCode::CONTINUE);
+    static_resp!(SwitchingProtocols, StatusCode::SWITCHING_PROTOCOLS);
+    static_resp!(Processing, StatusCode::PROCESSING);
+
+    static_resp!(Ok, StatusCode::OK);
+    static_resp!(Created, StatusCode::CREATED);
+    static_resp!(Accepted, StatusCode::ACCEPTED);
+    static_resp!(
+        NonAuthoritativeInformation,
+        StatusCode::NON_AUTHORITATIVE_INFORMATION
+    );
+    static_resp!(NoContent, StatusCode::NO_CONTENT);
+    static_resp!(ResetContent, StatusCode::RESET_CONTENT);
+    static_resp!(PartialContent, StatusCode::PARTIAL_CONTENT);
+    static_resp!(MultiStatus, StatusCode::MULTI_STATUS);
+    static_resp!(AlreadyReported, StatusCode::ALREADY_REPORTED);
+    static_resp!(ImUsed, StatusCode::IM_USED);
+
+    static_resp!(MultipleChoices, StatusCode::MULTIPLE_CHOICES);
+    static_resp!(MovedPermanently, StatusCode::MOVED_PERMANENTLY);
+    static_resp!(Found, StatusCode::FOUND);
+    static_resp!(SeeOther, StatusCode::SEE_OTHER);
+    static_resp!(NotModified, StatusCode::NOT_MODIFIED);
+    static_resp!(UseProxy, StatusCode::USE_PROXY);
+    static_resp!(TemporaryRedirect, StatusCode::TEMPORARY_REDIRECT);
+    static_resp!(PermanentRedirect, StatusCode::PERMANENT_REDIRECT);
+
+    static_resp!(BadRequest, StatusCode::BAD_REQUEST);
+    static_resp!(Unauthorized, StatusCode::UNAUTHORIZED);
+    static_resp!(PaymentRequired, StatusCode::PAYMENT_REQUIRED);
+    static_resp!(Forbidden, StatusCode::FORBIDDEN);
+    static_resp!(NotFound, StatusCode::NOT_FOUND);
+    static_resp!(MethodNotAllowed, StatusCode::METHOD_NOT_ALLOWED);
+    static_resp!(NotAcceptable, StatusCode::NOT_ACCEPTABLE);
+    static_resp!(
+        ProxyAuthenticationRequired,
+        StatusCode::PROXY_AUTHENTICATION_REQUIRED
+    );
+    static_resp!(RequestTimeout, StatusCode::REQUEST_TIMEOUT);
+    static_resp!(Conflict, StatusCode::CONFLICT);
+    static_resp!(Gone, StatusCode::GONE);
+    static_resp!(LengthRequired, StatusCode::LENGTH_REQUIRED);
+    static_resp!(PreconditionFailed, StatusCode::PRECONDITION_FAILED);
+    static_resp!(PayloadTooLarge, StatusCode::PAYLOAD_TOO_LARGE);
+    static_resp!(UriTooLong, StatusCode::URI_TOO_LONG);
+    static_resp!(UnsupportedMediaType, StatusCode::UNSUPPORTED_MEDIA_TYPE);
+    static_resp!(RangeNotSatisfiable, StatusCode::RANGE_NOT_SATISFIABLE);
+    static_resp!(ExpectationFailed, StatusCode::EXPECTATION_FAILED);
+    static_resp!(ImATeapot, StatusCode::IM_A_TEAPOT);
+    static_resp!(MisdirectedRequest, StatusCode::MISDIRECTED_REQUEST);
+    static_resp!(UnprocessableEntity, StatusCode::UNPROCESSABLE_ENTITY);
+    static_resp!(Locked, StatusCode::LOCKED);
+    static_resp!(FailedDependency, StatusCode::FAILED_DEPENDENCY);
+    static_resp!(UpgradeRequired, StatusCode::UPGRADE_REQUIRED);
+    static_resp!(PreconditionRequired, StatusCode::PRECONDITION_REQUIRED);
+    static_resp!(TooManyRequests, StatusCode::TOO_MANY_REQUESTS);
+    static_resp!(
+        RequestHeaderFieldsTooLarge,
+        StatusCode::REQUEST_HEADER_FIELDS_TOO_LARGE
+    );
+    static_resp!(
+        UnavailableForLegalReasons,
+        StatusCode::UNAVAILABLE_FOR_LEGAL_REASONS
+    );
+
+    static_resp!(InternalServerError, StatusCode::INTERNAL_SERVER_ERROR);
+    static_resp!(NotImplemented, StatusCode::NOT_IMPLEMENTED);
+    static_resp!(BadGateway, StatusCode::BAD_GATEWAY);
+    static_resp!(ServiceUnavailable, StatusCode::SERVICE_UNAVAILABLE);
+    static_resp!(GatewayTimeout, StatusCode::GATEWAY_TIMEOUT);
+    static_resp!(VersionNotSupported, StatusCode::HTTP_VERSION_NOT_SUPPORTED);
+    static_resp!(VariantAlsoNegotiates, StatusCode::VARIANT_ALSO_NEGOTIATES);
+    static_resp!(InsufficientStorage, StatusCode::INSUFFICIENT_STORAGE);
+    static_resp!(LoopDetected, StatusCode::LOOP_DETECTED);
+    static_resp!(NotExtended, StatusCode::NOT_EXTENDED);
+    static_resp!(
+        NetworkAuthenticationRequired,
+        StatusCode::NETWORK_AUTHENTICATION_REQUIRED
+    );
+}
+
+#[cfg(test)]
+mod tests {
+    use crate::{http::StatusCode, HttpResponse};
+
+    #[test]
+    fn test_build() {
+        let resp = HttpResponse::Ok().finish();
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/response/mod.rs.html b/src/actix_web/response/mod.rs.html new file mode 100644 index 000000000..daaeb700a --- /dev/null +++ b/src/actix_web/response/mod.rs.html @@ -0,0 +1,23 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+
mod builder;
+mod customize_responder;
+mod http_codes;
+mod responder;
+#[allow(clippy::module_inception)]
+mod response;
+
+pub use self::{
+    builder::HttpResponseBuilder, customize_responder::CustomizeResponder, responder::Responder,
+    response::HttpResponse,
+};
+
\ No newline at end of file diff --git a/src/actix_web/response/responder.rs.html b/src/actix_web/response/responder.rs.html new file mode 100644 index 000000000..b8f6341de --- /dev/null +++ b/src/actix_web/response/responder.rs.html @@ -0,0 +1,699 @@ +responder.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
+
use std::borrow::Cow;
+
+use actix_http::{
+    body::{BoxBody, EitherBody, MessageBody},
+    header::TryIntoHeaderPair,
+    StatusCode,
+};
+use bytes::{Bytes, BytesMut};
+
+use super::CustomizeResponder;
+use crate::{Error, HttpRequest, HttpResponse};
+
+/// Trait implemented by types that can be converted to an HTTP response.
+///
+/// Any types that implement this trait can be used in the return type of a handler. Since handlers
+/// will only have one return type, it is idiomatic to use opaque return types `-> impl Responder`.
+///
+/// # Implementations
+/// It is often not required to implement `Responder` for your own types due to a broad base of
+/// built-in implementations:
+/// - `HttpResponse` and `HttpResponseBuilder`
+/// - `Option<R>` where `R: Responder`
+/// - `Result<R, E>` where `R: Responder` and [`E: ResponseError`](crate::ResponseError)
+/// - `(R, StatusCode)` where `R: Responder`
+/// - `&'static str`, `String`, `&'_ String`, `Cow<'_, str>`, [`ByteString`](bytestring::ByteString)
+/// - `&'static [u8]`, `Vec<u8>`, `Bytes`, `BytesMut`
+/// - [`Json<T>`](crate::web::Json) and [`Form<T>`](crate::web::Form) where `T: Serialize`
+/// - [`Either<L, R>`](crate::web::Either) where `L: Serialize` and `R: Serialize`
+/// - [`CustomizeResponder<R>`]
+/// - [`actix_files::NamedFile`](https://docs.rs/actix-files/latest/actix_files/struct.NamedFile.html)
+/// - [Experimental responders from `actix-web-lab`](https://docs.rs/actix-web-lab/latest/actix_web_lab/respond/index.html)
+/// - Third party integrations may also have implemented `Responder` where appropriate. For example,
+///   HTML templating engines.
+///
+/// # Customizing Responder Output
+/// Calling [`.customize()`](Responder::customize) on any responder type will wrap it in a
+/// [`CustomizeResponder`] capable of overriding various parts of the response such as the status
+/// code and header map.
+pub trait Responder {
+    type Body: MessageBody + 'static;
+
+    /// Convert self to `HttpResponse`.
+    fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body>;
+
+    /// Wraps responder to allow alteration of its response.
+    ///
+    /// See [`CustomizeResponder`] docs for more details on its capabilities.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::{Responder, http::StatusCode, test::TestRequest};
+    ///
+    /// let responder = "Hello world!"
+    ///     .customize()
+    ///     .with_status(StatusCode::BAD_REQUEST)
+    ///     .insert_header(("x-hello", "world"));
+    ///
+    /// let request = TestRequest::default().to_http_request();
+    /// let response = responder.respond_to(&request);
+    /// assert_eq!(response.status(), StatusCode::BAD_REQUEST);
+    /// assert_eq!(response.headers().get("x-hello").unwrap(), "world");
+    /// ```
+    #[inline]
+    fn customize(self) -> CustomizeResponder<Self>
+    where
+        Self: Sized,
+    {
+        CustomizeResponder::new(self)
+    }
+
+    #[doc(hidden)]
+    #[deprecated(since = "4.0.0", note = "Prefer `.customize().with_status(header)`.")]
+    fn with_status(self, status: StatusCode) -> CustomizeResponder<Self>
+    where
+        Self: Sized,
+    {
+        self.customize().with_status(status)
+    }
+
+    #[doc(hidden)]
+    #[deprecated(since = "4.0.0", note = "Prefer `.customize().insert_header(header)`.")]
+    fn with_header(self, header: impl TryIntoHeaderPair) -> CustomizeResponder<Self>
+    where
+        Self: Sized,
+    {
+        self.customize().insert_header(header)
+    }
+}
+
+impl Responder for actix_http::Response<BoxBody> {
+    type Body = BoxBody;
+
+    #[inline]
+    fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body> {
+        HttpResponse::from(self)
+    }
+}
+
+impl Responder for actix_http::ResponseBuilder {
+    type Body = BoxBody;
+
+    #[inline]
+    fn respond_to(mut self, req: &HttpRequest) -> HttpResponse<Self::Body> {
+        self.finish().map_into_boxed_body().respond_to(req)
+    }
+}
+
+impl<R: Responder> Responder for Option<R> {
+    type Body = EitherBody<R::Body>;
+
+    fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body> {
+        match self {
+            Some(val) => val.respond_to(req).map_into_left_body(),
+            None => HttpResponse::new(StatusCode::NOT_FOUND).map_into_right_body(),
+        }
+    }
+}
+
+impl<R, E> Responder for Result<R, E>
+where
+    R: Responder,
+    E: Into<Error>,
+{
+    type Body = EitherBody<R::Body>;
+
+    fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body> {
+        match self {
+            Ok(val) => val.respond_to(req).map_into_left_body(),
+            Err(err) => HttpResponse::from_error(err.into()).map_into_right_body(),
+        }
+    }
+}
+
+impl<R: Responder> Responder for (R, StatusCode) {
+    type Body = R::Body;
+
+    fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body> {
+        let mut res = self.0.respond_to(req);
+        *res.status_mut() = self.1;
+        res
+    }
+}
+
+macro_rules! impl_responder_by_forward_into_base_response {
+    ($res:ty, $body:ty) => {
+        impl Responder for $res {
+            type Body = $body;
+
+            fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body> {
+                let res: actix_http::Response<_> = self.into();
+                res.into()
+            }
+        }
+    };
+
+    ($res:ty) => {
+        impl_responder_by_forward_into_base_response!($res, $res);
+    };
+}
+
+impl_responder_by_forward_into_base_response!(&'static [u8]);
+impl_responder_by_forward_into_base_response!(Vec<u8>);
+impl_responder_by_forward_into_base_response!(Bytes);
+impl_responder_by_forward_into_base_response!(BytesMut);
+
+impl_responder_by_forward_into_base_response!(&'static str);
+impl_responder_by_forward_into_base_response!(String);
+impl_responder_by_forward_into_base_response!(bytestring::ByteString);
+
+macro_rules! impl_into_string_responder {
+    ($res:ty) => {
+        impl Responder for $res {
+            type Body = String;
+
+            fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body> {
+                let string: String = self.into();
+                let res: actix_http::Response<_> = string.into();
+                res.into()
+            }
+        }
+    };
+}
+
+impl_into_string_responder!(&'_ String);
+impl_into_string_responder!(Cow<'_, str>);
+
+#[cfg(test)]
+pub(crate) mod tests {
+    use actix_http::body::to_bytes;
+    use actix_service::Service;
+
+    use super::*;
+    use crate::{
+        error,
+        http::header::{HeaderValue, CONTENT_TYPE},
+        test::{assert_body_eq, init_service, TestRequest},
+        web, App,
+    };
+
+    #[actix_rt::test]
+    async fn test_option_responder() {
+        let srv = init_service(
+            App::new()
+                .service(web::resource("/none").to(|| async { Option::<&'static str>::None }))
+                .service(web::resource("/some").to(|| async { Some("some") })),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/none").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+
+        let req = TestRequest::with_uri("/some").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+        assert_body_eq!(resp, b"some");
+    }
+
+    #[actix_rt::test]
+    async fn test_responder() {
+        let req = TestRequest::default().to_http_request();
+
+        let res = "test".respond_to(&req);
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("text/plain; charset=utf-8")
+        );
+        assert_eq!(
+            to_bytes(res.into_body()).await.unwrap(),
+            Bytes::from_static(b"test"),
+        );
+
+        let res = b"test".respond_to(&req);
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("application/octet-stream")
+        );
+        assert_eq!(
+            to_bytes(res.into_body()).await.unwrap(),
+            Bytes::from_static(b"test"),
+        );
+
+        let res = "test".to_string().respond_to(&req);
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("text/plain; charset=utf-8")
+        );
+        assert_eq!(
+            to_bytes(res.into_body()).await.unwrap(),
+            Bytes::from_static(b"test"),
+        );
+
+        let res = (&"test".to_string()).respond_to(&req);
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("text/plain; charset=utf-8")
+        );
+        assert_eq!(
+            to_bytes(res.into_body()).await.unwrap(),
+            Bytes::from_static(b"test"),
+        );
+
+        let s = String::from("test");
+        let res = Cow::Borrowed(s.as_str()).respond_to(&req);
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("text/plain; charset=utf-8")
+        );
+        assert_eq!(
+            to_bytes(res.into_body()).await.unwrap(),
+            Bytes::from_static(b"test"),
+        );
+
+        let res = Cow::<'_, str>::Owned(s).respond_to(&req);
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("text/plain; charset=utf-8")
+        );
+        assert_eq!(
+            to_bytes(res.into_body()).await.unwrap(),
+            Bytes::from_static(b"test"),
+        );
+
+        let res = Cow::Borrowed("test").respond_to(&req);
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("text/plain; charset=utf-8")
+        );
+        assert_eq!(
+            to_bytes(res.into_body()).await.unwrap(),
+            Bytes::from_static(b"test"),
+        );
+
+        let res = Bytes::from_static(b"test").respond_to(&req);
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("application/octet-stream")
+        );
+        assert_eq!(
+            to_bytes(res.into_body()).await.unwrap(),
+            Bytes::from_static(b"test"),
+        );
+
+        let res = BytesMut::from(b"test".as_ref()).respond_to(&req);
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("application/octet-stream")
+        );
+        assert_eq!(
+            to_bytes(res.into_body()).await.unwrap(),
+            Bytes::from_static(b"test"),
+        );
+
+        // InternalError
+        let res = error::InternalError::new("err", StatusCode::BAD_REQUEST).respond_to(&req);
+        assert_eq!(res.status(), StatusCode::BAD_REQUEST);
+    }
+
+    #[actix_rt::test]
+    async fn test_result_responder() {
+        let req = TestRequest::default().to_http_request();
+
+        // Result<I, E>
+        let resp = Ok::<_, Error>("test".to_string()).respond_to(&req);
+        assert_eq!(resp.status(), StatusCode::OK);
+        assert_eq!(
+            resp.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("text/plain; charset=utf-8")
+        );
+        assert_eq!(
+            to_bytes(resp.into_body()).await.unwrap(),
+            Bytes::from_static(b"test"),
+        );
+
+        let res = Err::<String, _>(error::InternalError::new("err", StatusCode::BAD_REQUEST))
+            .respond_to(&req);
+
+        assert_eq!(res.status(), StatusCode::BAD_REQUEST);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/response/response.rs.html b/src/actix_web/response/response.rs.html new file mode 100644 index 000000000..ca688f0ea --- /dev/null +++ b/src/actix_web/response/response.rs.html @@ -0,0 +1,877 @@ +response.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
+
use std::{
+    cell::{Ref, RefMut},
+    fmt,
+};
+
+use actix_http::{
+    body::{BoxBody, EitherBody, MessageBody},
+    header::HeaderMap,
+    Extensions, Response, ResponseHead, StatusCode,
+};
+#[cfg(feature = "cookies")]
+use {
+    actix_http::{
+        error::HttpError,
+        header::{self, HeaderValue},
+    },
+    cookie::Cookie,
+};
+
+use crate::{error::Error, HttpRequest, HttpResponseBuilder, Responder};
+
+/// An outgoing response.
+pub struct HttpResponse<B = BoxBody> {
+    res: Response<B>,
+    error: Option<Error>,
+}
+
+impl HttpResponse<BoxBody> {
+    /// Constructs a response.
+    #[inline]
+    pub fn new(status: StatusCode) -> Self {
+        Self {
+            res: Response::new(status),
+            error: None,
+        }
+    }
+
+    /// Constructs a response builder with specific HTTP status.
+    #[inline]
+    pub fn build(status: StatusCode) -> HttpResponseBuilder {
+        HttpResponseBuilder::new(status)
+    }
+
+    /// Create an error response.
+    #[inline]
+    pub fn from_error(error: impl Into<Error>) -> Self {
+        let error = error.into();
+        let mut response = error.as_response_error().error_response();
+        response.error = Some(error);
+        response
+    }
+}
+
+impl<B> HttpResponse<B> {
+    /// Constructs a response with body
+    #[inline]
+    pub fn with_body(status: StatusCode, body: B) -> Self {
+        Self {
+            res: Response::with_body(status, body),
+            error: None,
+        }
+    }
+
+    /// Returns a reference to response head.
+    #[inline]
+    pub fn head(&self) -> &ResponseHead {
+        self.res.head()
+    }
+
+    /// Returns a mutable reference to response head.
+    #[inline]
+    pub fn head_mut(&mut self) -> &mut ResponseHead {
+        self.res.head_mut()
+    }
+
+    /// The source `error` for this response
+    #[inline]
+    pub fn error(&self) -> Option<&Error> {
+        self.error.as_ref()
+    }
+
+    /// Get the response status code
+    #[inline]
+    pub fn status(&self) -> StatusCode {
+        self.res.status()
+    }
+
+    /// Set the `StatusCode` for this response
+    #[inline]
+    pub fn status_mut(&mut self) -> &mut StatusCode {
+        self.res.status_mut()
+    }
+
+    /// Get the headers from the response
+    #[inline]
+    pub fn headers(&self) -> &HeaderMap {
+        self.res.headers()
+    }
+
+    /// Get a mutable reference to the headers
+    #[inline]
+    pub fn headers_mut(&mut self) -> &mut HeaderMap {
+        self.res.headers_mut()
+    }
+
+    /// Get an iterator for the cookies set by this response.
+    #[cfg(feature = "cookies")]
+    pub fn cookies(&self) -> CookieIter<'_> {
+        CookieIter {
+            iter: self.headers().get_all(header::SET_COOKIE),
+        }
+    }
+
+    /// Add a cookie to this response.
+    ///
+    /// # Errors
+    /// Returns an error if the cookie results in a malformed `Set-Cookie` header.
+    #[cfg(feature = "cookies")]
+    pub fn add_cookie(&mut self, cookie: &Cookie<'_>) -> Result<(), HttpError> {
+        HeaderValue::from_str(&cookie.to_string())
+            .map(|cookie| self.headers_mut().append(header::SET_COOKIE, cookie))
+            .map_err(Into::into)
+    }
+
+    /// Add a "removal" cookie to the response that matches attributes of given cookie.
+    ///
+    /// This will cause browsers/clients to remove stored cookies with this name.
+    ///
+    /// The `Set-Cookie` header added to the response will have:
+    /// - name matching given cookie;
+    /// - domain matching given cookie;
+    /// - path matching given cookie;
+    /// - an empty value;
+    /// - a max-age of `0`;
+    /// - an expiration date far in the past.
+    ///
+    /// If the cookie you're trying to remove has an explicit path or domain set, those attributes
+    /// will need to be included in the cookie passed in here.
+    ///
+    /// # Errors
+    /// Returns an error if the given name results in a malformed `Set-Cookie` header.
+    #[cfg(feature = "cookies")]
+    pub fn add_removal_cookie(&mut self, cookie: &Cookie<'_>) -> Result<(), HttpError> {
+        let mut removal_cookie = cookie.to_owned();
+        removal_cookie.make_removal();
+
+        HeaderValue::from_str(&removal_cookie.to_string())
+            .map(|cookie| self.headers_mut().append(header::SET_COOKIE, cookie))
+            .map_err(Into::into)
+    }
+
+    /// Remove all cookies with the given name from this response.
+    ///
+    /// Returns the number of cookies removed.
+    ///
+    /// This method can _not_ cause a browser/client to delete any of its stored cookies. Its only
+    /// purpose is to delete cookies that were added to this response using [`add_cookie`]
+    /// and [`add_removal_cookie`]. Use [`add_removal_cookie`] to send a "removal" cookie.
+    ///
+    /// [`add_cookie`]: Self::add_cookie
+    /// [`add_removal_cookie`]: Self::add_removal_cookie
+    #[cfg(feature = "cookies")]
+    pub fn del_cookie(&mut self, name: &str) -> usize {
+        let headers = self.headers_mut();
+
+        let vals: Vec<HeaderValue> = headers
+            .get_all(header::SET_COOKIE)
+            .map(|v| v.to_owned())
+            .collect();
+
+        headers.remove(header::SET_COOKIE);
+
+        let mut count: usize = 0;
+
+        for v in vals {
+            if let Ok(s) = v.to_str() {
+                if let Ok(c) = Cookie::parse_encoded(s) {
+                    if c.name() == name {
+                        count += 1;
+                        continue;
+                    }
+                }
+            }
+
+            // put set-cookie header head back if it does not validate
+            headers.append(header::SET_COOKIE, v);
+        }
+
+        count
+    }
+
+    /// Connection upgrade status
+    #[inline]
+    pub fn upgrade(&self) -> bool {
+        self.res.upgrade()
+    }
+
+    /// Keep-alive status for this connection
+    pub fn keep_alive(&self) -> bool {
+        self.res.keep_alive()
+    }
+
+    /// Returns reference to the response-local data/extensions container.
+    #[inline]
+    pub fn extensions(&self) -> Ref<'_, Extensions> {
+        self.res.extensions()
+    }
+
+    /// Returns reference to the response-local data/extensions container.
+    #[inline]
+    pub fn extensions_mut(&mut self) -> RefMut<'_, Extensions> {
+        self.res.extensions_mut()
+    }
+
+    /// Returns a reference to this response's body.
+    #[inline]
+    pub fn body(&self) -> &B {
+        self.res.body()
+    }
+
+    /// Sets new body.
+    pub fn set_body<B2>(self, body: B2) -> HttpResponse<B2> {
+        HttpResponse {
+            res: self.res.set_body(body),
+            error: self.error,
+        }
+    }
+
+    /// Returns split head and body.
+    ///
+    /// # Implementation Notes
+    /// Due to internal performance optimizations, the first element of the returned tuple is an
+    /// `HttpResponse` as well but only contains the head of the response this was called on.
+    pub fn into_parts(self) -> (HttpResponse<()>, B) {
+        let (head, body) = self.res.into_parts();
+
+        (
+            HttpResponse {
+                res: head,
+                error: self.error,
+            },
+            body,
+        )
+    }
+
+    /// Drops body and returns new response.
+    pub fn drop_body(self) -> HttpResponse<()> {
+        HttpResponse {
+            res: self.res.drop_body(),
+            error: self.error,
+        }
+    }
+
+    /// Map the current body type to another using a closure, returning a new response.
+    ///
+    /// Closure receives the response head and the current body type.
+    pub fn map_body<F, B2>(self, f: F) -> HttpResponse<B2>
+    where
+        F: FnOnce(&mut ResponseHead, B) -> B2,
+    {
+        HttpResponse {
+            res: self.res.map_body(f),
+            error: self.error,
+        }
+    }
+
+    /// Map the current body type `B` to `EitherBody::Left(B)`.
+    ///
+    /// Useful for middleware which can generate their own responses.
+    #[inline]
+    pub fn map_into_left_body<R>(self) -> HttpResponse<EitherBody<B, R>> {
+        self.map_body(|_, body| EitherBody::left(body))
+    }
+
+    /// Map the current body type `B` to `EitherBody::Right(B)`.
+    ///
+    /// Useful for middleware which can generate their own responses.
+    #[inline]
+    pub fn map_into_right_body<L>(self) -> HttpResponse<EitherBody<L, B>> {
+        self.map_body(|_, body| EitherBody::right(body))
+    }
+
+    /// Map the current body to a type-erased `BoxBody`.
+    #[inline]
+    pub fn map_into_boxed_body(self) -> HttpResponse<BoxBody>
+    where
+        B: MessageBody + 'static,
+    {
+        self.map_body(|_, body| body.boxed())
+    }
+
+    /// Returns the response body, dropping all other parts.
+    pub fn into_body(self) -> B {
+        self.res.into_body()
+    }
+}
+
+impl<B> fmt::Debug for HttpResponse<B>
+where
+    B: MessageBody,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("HttpResponse")
+            .field("error", &self.error)
+            .field("res", &self.res)
+            .finish()
+    }
+}
+
+impl<B> From<Response<B>> for HttpResponse<B> {
+    fn from(res: Response<B>) -> Self {
+        HttpResponse { res, error: None }
+    }
+}
+
+impl From<Error> for HttpResponse {
+    fn from(err: Error) -> Self {
+        HttpResponse::from_error(err)
+    }
+}
+
+impl<B> From<HttpResponse<B>> for Response<B> {
+    fn from(res: HttpResponse<B>) -> Self {
+        // this impl will always be called as part of dispatcher
+        res.res
+    }
+}
+
+// Rationale for cfg(test): this impl causes false positives on a clippy lint (async_yields_async)
+// when returning an HttpResponse from an async function/closure and it's not very useful outside of
+// tests anyway.
+#[cfg(test)]
+mod response_fut_impl {
+    use std::{
+        future::Future,
+        mem,
+        pin::Pin,
+        task::{Context, Poll},
+    };
+
+    use super::*;
+
+    // Future is only implemented for BoxBody payload type because it's the most useful for making
+    // simple handlers without async blocks. Making it generic over all MessageBody types requires a
+    // future impl on Response which would cause its body field to be, undesirably, Option<B>.
+    //
+    // This impl is not particularly efficient due to the Response construction and should probably
+    // not be invoked if performance is important. Prefer an async fn/block in such cases.
+    impl Future for HttpResponse<BoxBody> {
+        type Output = Result<Response<BoxBody>, Error>;
+
+        fn poll(mut self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Self::Output> {
+            if let Some(err) = self.error.take() {
+                return Poll::Ready(Err(err));
+            }
+
+            Poll::Ready(Ok(mem::replace(
+                &mut self.res,
+                Response::new(StatusCode::default()),
+            )))
+        }
+    }
+}
+
+impl<B> Responder for HttpResponse<B>
+where
+    B: MessageBody + 'static,
+{
+    type Body = B;
+
+    #[inline]
+    fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body> {
+        self
+    }
+}
+
+#[cfg(feature = "cookies")]
+pub struct CookieIter<'a> {
+    iter: std::slice::Iter<'a, HeaderValue>,
+}
+
+#[cfg(feature = "cookies")]
+impl<'a> Iterator for CookieIter<'a> {
+    type Item = Cookie<'a>;
+
+    #[inline]
+    fn next(&mut self) -> Option<Cookie<'a>> {
+        for v in self.iter.by_ref() {
+            if let Ok(c) = Cookie::parse_encoded(v.to_str().ok()?) {
+                return Some(c);
+            }
+        }
+        None
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use static_assertions::assert_impl_all;
+
+    use super::*;
+    use crate::http::header::COOKIE;
+
+    assert_impl_all!(HttpResponse: Responder);
+    assert_impl_all!(HttpResponse<String>: Responder);
+    assert_impl_all!(HttpResponse<&'static str>: Responder);
+    assert_impl_all!(HttpResponse<crate::body::None>: Responder);
+
+    #[test]
+    fn test_debug() {
+        let resp = HttpResponse::Ok()
+            .append_header((COOKIE, HeaderValue::from_static("cookie1=value1; ")))
+            .append_header((COOKIE, HeaderValue::from_static("cookie2=value2; ")))
+            .finish();
+        let dbg = format!("{:?}", resp);
+        assert!(dbg.contains("HttpResponse"));
+    }
+}
+
+#[cfg(test)]
+#[cfg(feature = "cookies")]
+mod cookie_tests {
+    use super::*;
+
+    #[test]
+    fn removal_cookies() {
+        let mut res = HttpResponse::Ok().finish();
+        let cookie = Cookie::new("foo", "");
+        res.add_removal_cookie(&cookie).unwrap();
+        let set_cookie_hdr = res.headers().get(header::SET_COOKIE).unwrap();
+        assert_eq!(
+            &set_cookie_hdr.as_bytes()[..25],
+            &b"foo=; Max-Age=0; Expires="[..],
+            "unexpected set-cookie value: {:?}",
+            set_cookie_hdr.to_str()
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/rmap.rs.html b/src/actix_web/rmap.rs.html new file mode 100644 index 000000000..fa09c330d --- /dev/null +++ b/src/actix_web/rmap.rs.html @@ -0,0 +1,1121 @@ +rmap.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
+
use std::{
+    borrow::Cow,
+    cell::RefCell,
+    fmt::Write as _,
+    rc::{Rc, Weak},
+};
+
+use actix_router::ResourceDef;
+use ahash::AHashMap;
+use url::Url;
+
+use crate::{error::UrlGenerationError, request::HttpRequest};
+
+const AVG_PATH_LEN: usize = 24;
+
+#[derive(Clone, Debug)]
+pub struct ResourceMap {
+    pattern: ResourceDef,
+
+    /// Named resources within the tree or, for external resources, it points to isolated nodes
+    /// outside the tree.
+    named: AHashMap<String, Rc<ResourceMap>>,
+
+    parent: RefCell<Weak<ResourceMap>>,
+
+    /// Must be `None` for "edge" nodes.
+    nodes: Option<Vec<Rc<ResourceMap>>>,
+}
+
+impl ResourceMap {
+    /// Creates a _container_ node in the `ResourceMap` tree.
+    pub fn new(root: ResourceDef) -> Self {
+        ResourceMap {
+            pattern: root,
+            named: AHashMap::default(),
+            parent: RefCell::new(Weak::new()),
+            nodes: Some(Vec::new()),
+        }
+    }
+
+    /// Format resource map as tree structure (unfinished).
+    #[allow(dead_code)]
+    pub(crate) fn tree(&self) -> String {
+        let mut buf = String::new();
+        self._tree(&mut buf, 0);
+        buf
+    }
+
+    pub(crate) fn _tree(&self, buf: &mut String, level: usize) {
+        if let Some(children) = &self.nodes {
+            for child in children {
+                writeln!(
+                    buf,
+                    "{}{} {}",
+                    "--".repeat(level),
+                    child.pattern.pattern().unwrap(),
+                    child
+                        .pattern
+                        .name()
+                        .map(|name| format!("({})", name))
+                        .unwrap_or_else(|| "".to_owned())
+                )
+                .unwrap();
+
+                ResourceMap::_tree(child, buf, level + 1);
+            }
+        }
+    }
+
+    /// Adds a (possibly nested) resource.
+    ///
+    /// To add a non-prefix pattern, `nested` must be `None`.
+    /// To add external resource, supply a pattern without a leading `/`.
+    /// The root pattern of `nested`, if present, should match `pattern`.
+    pub fn add(&mut self, pattern: &mut ResourceDef, nested: Option<Rc<ResourceMap>>) {
+        pattern.set_id(self.nodes.as_ref().unwrap().len() as u16);
+
+        if let Some(new_node) = nested {
+            debug_assert_eq!(
+                &new_node.pattern, pattern,
+                "`pattern` and `nested` mismatch"
+            );
+            // parents absorb references to the named resources of children
+            self.named.extend(new_node.named.clone());
+            self.nodes.as_mut().unwrap().push(new_node);
+        } else {
+            let new_node = Rc::new(ResourceMap {
+                pattern: pattern.clone(),
+                named: AHashMap::default(),
+                parent: RefCell::new(Weak::new()),
+                nodes: None,
+            });
+
+            if let Some(name) = pattern.name() {
+                self.named.insert(name.to_owned(), Rc::clone(&new_node));
+            }
+
+            let is_external = match pattern.pattern() {
+                Some(p) => !p.is_empty() && !p.starts_with('/'),
+                None => false,
+            };
+
+            // don't add external resources to the tree
+            if !is_external {
+                self.nodes.as_mut().unwrap().push(new_node);
+            }
+        }
+    }
+
+    pub(crate) fn finish(self: &Rc<Self>) {
+        for node in self.nodes.iter().flatten() {
+            node.parent.replace(Rc::downgrade(self));
+            ResourceMap::finish(node);
+        }
+    }
+
+    /// Generate URL for named resource.
+    ///
+    /// Check [`HttpRequest::url_for`] for detailed information.
+    pub fn url_for<U, I>(
+        &self,
+        req: &HttpRequest,
+        name: &str,
+        elements: U,
+    ) -> Result<Url, UrlGenerationError>
+    where
+        U: IntoIterator<Item = I>,
+        I: AsRef<str>,
+    {
+        let mut elements = elements.into_iter();
+
+        let path = self
+            .named
+            .get(name)
+            .ok_or(UrlGenerationError::ResourceNotFound)?
+            .root_rmap_fn(String::with_capacity(AVG_PATH_LEN), |mut acc, node| {
+                node.pattern
+                    .resource_path_from_iter(&mut acc, &mut elements)
+                    .then_some(acc)
+            })
+            .ok_or(UrlGenerationError::NotEnoughElements)?;
+
+        let (base, path): (Cow<'_, _>, _) = if path.starts_with('/') {
+            // build full URL from connection info parts and resource path
+            let conn = req.connection_info();
+            let base = format!("{}://{}", conn.scheme(), conn.host());
+            (Cow::Owned(base), path.as_str())
+        } else {
+            // external resource; third slash would be the root slash in the path
+            let third_slash_index = path
+                .char_indices()
+                .filter_map(|(i, c)| (c == '/').then_some(i))
+                .nth(2)
+                .unwrap_or(path.len());
+
+            (
+                Cow::Borrowed(&path[..third_slash_index]),
+                &path[third_slash_index..],
+            )
+        };
+
+        let mut url = Url::parse(&base)?;
+        url.set_path(path);
+        Ok(url)
+    }
+
+    /// Returns true if there is a resource that would match `path`.
+    pub fn has_resource(&self, path: &str) -> bool {
+        self.find_matching_node(path).is_some()
+    }
+
+    /// Returns the name of the route that matches the given path or None if no full match
+    /// is possible or the matching resource is not named.
+    pub fn match_name(&self, path: &str) -> Option<&str> {
+        self.find_matching_node(path)?.pattern.name()
+    }
+
+    /// Returns the full resource pattern matched against a path or None if no full match
+    /// is possible.
+    pub fn match_pattern(&self, path: &str) -> Option<String> {
+        self.find_matching_node(path)?.root_rmap_fn(
+            String::with_capacity(AVG_PATH_LEN),
+            |mut acc, node| {
+                let pattern = node.pattern.pattern()?;
+                acc.push_str(pattern);
+                Some(acc)
+            },
+        )
+    }
+
+    fn find_matching_node(&self, path: &str) -> Option<&ResourceMap> {
+        self._find_matching_node(path).flatten()
+    }
+
+    /// Returns `None` if root pattern doesn't match;
+    /// `Some(None)` if root pattern matches but there is no matching child pattern.
+    /// Don't search sideways when `Some(none)` is returned.
+    fn _find_matching_node(&self, path: &str) -> Option<Option<&ResourceMap>> {
+        let matched_len = self.pattern.find_match(path)?;
+        let path = &path[matched_len..];
+
+        Some(match &self.nodes {
+            // find first sub-node to match remaining path
+            Some(nodes) => nodes
+                .iter()
+                .filter_map(|node| node._find_matching_node(path))
+                .next()
+                .flatten(),
+
+            // only terminate at edge nodes
+            None => Some(self),
+        })
+    }
+
+    /// Find `self`'s highest ancestor and then run `F`, providing `B`, in that rmap context.
+    fn root_rmap_fn<F, B>(&self, init: B, mut f: F) -> Option<B>
+    where
+        F: FnMut(B, &ResourceMap) -> Option<B>,
+    {
+        self._root_rmap_fn(init, &mut f)
+    }
+
+    /// Run `F`, providing `B`, if `self` is top-level resource map, else recurse to parent map.
+    fn _root_rmap_fn<F, B>(&self, init: B, f: &mut F) -> Option<B>
+    where
+        F: FnMut(B, &ResourceMap) -> Option<B>,
+    {
+        let data = match self.parent.borrow().upgrade() {
+            Some(ref parent) => parent._root_rmap_fn(init, f)?,
+            None => init,
+        };
+
+        f(data, self)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn extract_matched_pattern() {
+        let mut root = ResourceMap::new(ResourceDef::root_prefix(""));
+
+        let mut user_map = ResourceMap::new(ResourceDef::root_prefix("/user/{id}"));
+        user_map.add(&mut ResourceDef::new("/"), None);
+        user_map.add(&mut ResourceDef::new("/profile"), None);
+        user_map.add(&mut ResourceDef::new("/article/{id}"), None);
+        user_map.add(&mut ResourceDef::new("/post/{post_id}"), None);
+        user_map.add(
+            &mut ResourceDef::new("/post/{post_id}/comment/{comment_id}"),
+            None,
+        );
+
+        root.add(&mut ResourceDef::new("/info"), None);
+        root.add(&mut ResourceDef::new("/v{version:[[:digit:]]{1}}"), None);
+        root.add(
+            &mut ResourceDef::root_prefix("/user/{id}"),
+            Some(Rc::new(user_map)),
+        );
+        root.add(&mut ResourceDef::new("/info"), None);
+
+        let root = Rc::new(root);
+        ResourceMap::finish(&root);
+
+        // sanity check resource map setup
+
+        assert!(root.has_resource("/info"));
+        assert!(!root.has_resource("/bar"));
+
+        assert!(root.has_resource("/v1"));
+        assert!(root.has_resource("/v2"));
+        assert!(!root.has_resource("/v33"));
+
+        assert!(!root.has_resource("/user/22"));
+        assert!(root.has_resource("/user/22/"));
+        assert!(root.has_resource("/user/22/profile"));
+
+        // extract patterns from paths
+
+        assert!(root.match_pattern("/bar").is_none());
+        assert!(root.match_pattern("/v44").is_none());
+
+        assert_eq!(root.match_pattern("/info"), Some("/info".to_owned()));
+        assert_eq!(
+            root.match_pattern("/v1"),
+            Some("/v{version:[[:digit:]]{1}}".to_owned())
+        );
+        assert_eq!(
+            root.match_pattern("/v2"),
+            Some("/v{version:[[:digit:]]{1}}".to_owned())
+        );
+        assert_eq!(
+            root.match_pattern("/user/22/profile"),
+            Some("/user/{id}/profile".to_owned())
+        );
+        assert_eq!(
+            root.match_pattern("/user/602CFB82-7709-4B17-ADCF-4C347B6F2203/profile"),
+            Some("/user/{id}/profile".to_owned())
+        );
+        assert_eq!(
+            root.match_pattern("/user/22/article/44"),
+            Some("/user/{id}/article/{id}".to_owned())
+        );
+        assert_eq!(
+            root.match_pattern("/user/22/post/my-post"),
+            Some("/user/{id}/post/{post_id}".to_owned())
+        );
+        assert_eq!(
+            root.match_pattern("/user/22/post/other-post/comment/42"),
+            Some("/user/{id}/post/{post_id}/comment/{comment_id}".to_owned())
+        );
+    }
+
+    #[test]
+    fn extract_matched_name() {
+        let mut root = ResourceMap::new(ResourceDef::root_prefix(""));
+
+        let mut rdef = ResourceDef::new("/info");
+        rdef.set_name("root_info");
+        root.add(&mut rdef, None);
+
+        let mut user_map = ResourceMap::new(ResourceDef::root_prefix("/user/{id}"));
+        let mut rdef = ResourceDef::new("/");
+        user_map.add(&mut rdef, None);
+
+        let mut rdef = ResourceDef::new("/post/{post_id}");
+        rdef.set_name("user_post");
+        user_map.add(&mut rdef, None);
+
+        root.add(
+            &mut ResourceDef::root_prefix("/user/{id}"),
+            Some(Rc::new(user_map)),
+        );
+
+        let root = Rc::new(root);
+        ResourceMap::finish(&root);
+
+        // sanity check resource map setup
+
+        assert!(root.has_resource("/info"));
+        assert!(!root.has_resource("/bar"));
+
+        assert!(!root.has_resource("/user/22"));
+        assert!(root.has_resource("/user/22/"));
+        assert!(root.has_resource("/user/22/post/55"));
+
+        // extract patterns from paths
+
+        assert!(root.match_name("/bar").is_none());
+        assert!(root.match_name("/v44").is_none());
+
+        assert_eq!(root.match_name("/info"), Some("root_info"));
+        assert_eq!(root.match_name("/user/22"), None);
+        assert_eq!(root.match_name("/user/22/"), None);
+        assert_eq!(root.match_name("/user/22/post/55"), Some("user_post"));
+    }
+
+    #[test]
+    fn bug_fix_issue_1582_debug_print_exits() {
+        // ref: https://github.com/actix/actix-web/issues/1582
+        let mut root = ResourceMap::new(ResourceDef::root_prefix(""));
+
+        let mut user_map = ResourceMap::new(ResourceDef::root_prefix("/user/{id}"));
+        user_map.add(&mut ResourceDef::new("/"), None);
+        user_map.add(&mut ResourceDef::new("/profile"), None);
+        user_map.add(&mut ResourceDef::new("/article/{id}"), None);
+        user_map.add(&mut ResourceDef::new("/post/{post_id}"), None);
+        user_map.add(
+            &mut ResourceDef::new("/post/{post_id}/comment/{comment_id}"),
+            None,
+        );
+
+        root.add(
+            &mut ResourceDef::root_prefix("/user/{id}"),
+            Some(Rc::new(user_map)),
+        );
+
+        let root = Rc::new(root);
+        ResourceMap::finish(&root);
+
+        // check root has no parent
+        assert!(root.parent.borrow().upgrade().is_none());
+        // check child has parent reference
+        assert!(root.nodes.as_ref().unwrap()[0]
+            .parent
+            .borrow()
+            .upgrade()
+            .is_some());
+        // check child's parent root id matches root's root id
+        assert!(Rc::ptr_eq(
+            &root.nodes.as_ref().unwrap()[0]
+                .parent
+                .borrow()
+                .upgrade()
+                .unwrap(),
+            &root
+        ));
+
+        let output = format!("{:?}", root);
+        assert!(output.starts_with("ResourceMap {"));
+        assert!(output.ends_with(" }"));
+    }
+
+    #[test]
+    fn short_circuit() {
+        let mut root = ResourceMap::new(ResourceDef::prefix(""));
+
+        let mut user_root = ResourceDef::prefix("/user");
+        let mut user_map = ResourceMap::new(user_root.clone());
+        user_map.add(&mut ResourceDef::new("/u1"), None);
+        user_map.add(&mut ResourceDef::new("/u2"), None);
+
+        root.add(&mut ResourceDef::new("/user/u3"), None);
+        root.add(&mut user_root, Some(Rc::new(user_map)));
+        root.add(&mut ResourceDef::new("/user/u4"), None);
+
+        let rmap = Rc::new(root);
+        ResourceMap::finish(&rmap);
+
+        assert!(rmap.has_resource("/user/u1"));
+        assert!(rmap.has_resource("/user/u2"));
+        assert!(rmap.has_resource("/user/u3"));
+        assert!(!rmap.has_resource("/user/u4"));
+    }
+
+    #[test]
+    fn url_for() {
+        let mut root = ResourceMap::new(ResourceDef::prefix(""));
+
+        let mut user_scope_rdef = ResourceDef::prefix("/user");
+        let mut user_scope_map = ResourceMap::new(user_scope_rdef.clone());
+
+        let mut user_rdef = ResourceDef::new("/{user_id}");
+        let mut user_map = ResourceMap::new(user_rdef.clone());
+
+        let mut post_rdef = ResourceDef::new("/post/{sub_id}");
+        post_rdef.set_name("post");
+
+        user_map.add(&mut post_rdef, None);
+        user_scope_map.add(&mut user_rdef, Some(Rc::new(user_map)));
+        root.add(&mut user_scope_rdef, Some(Rc::new(user_scope_map)));
+
+        let rmap = Rc::new(root);
+        ResourceMap::finish(&rmap);
+
+        let mut req = crate::test::TestRequest::default();
+        req.set_server_hostname("localhost:8888");
+        let req = req.to_http_request();
+
+        let url = rmap
+            .url_for(&req, "post", ["u123", "foobar"])
+            .unwrap()
+            .to_string();
+        assert_eq!(url, "http://localhost:8888/user/u123/post/foobar");
+
+        assert!(rmap.url_for(&req, "missing", ["u123"]).is_err());
+    }
+
+    #[test]
+    fn url_for_parser() {
+        let mut root = ResourceMap::new(ResourceDef::prefix(""));
+
+        let mut rdef_1 = ResourceDef::new("/{var}");
+        rdef_1.set_name("internal");
+
+        let mut rdef_2 = ResourceDef::new("http://host.dom/{var}");
+        rdef_2.set_name("external.1");
+
+        let mut rdef_3 = ResourceDef::new("{var}");
+        rdef_3.set_name("external.2");
+
+        root.add(&mut rdef_1, None);
+        root.add(&mut rdef_2, None);
+        root.add(&mut rdef_3, None);
+        let rmap = Rc::new(root);
+        ResourceMap::finish(&rmap);
+
+        let mut req = crate::test::TestRequest::default();
+        req.set_server_hostname("localhost:8888");
+        let req = req.to_http_request();
+
+        const INPUT: &[&str] = &["a/../quick brown%20fox/%nan?query#frag"];
+        const OUTPUT: &str = "/quick%20brown%20fox/%nan%3Fquery%23frag";
+
+        let url = rmap.url_for(&req, "internal", INPUT).unwrap();
+        assert_eq!(url.path(), OUTPUT);
+
+        let url = rmap.url_for(&req, "external.1", INPUT).unwrap();
+        assert_eq!(url.path(), OUTPUT);
+
+        assert!(rmap.url_for(&req, "external.2", INPUT).is_err());
+        assert!(rmap.url_for(&req, "external.2", [""]).is_err());
+    }
+
+    #[test]
+    fn external_resource_with_no_name() {
+        let mut root = ResourceMap::new(ResourceDef::prefix(""));
+
+        let mut rdef = ResourceDef::new("https://duck.com/{query}");
+        root.add(&mut rdef, None);
+
+        let rmap = Rc::new(root);
+        ResourceMap::finish(&rmap);
+
+        assert!(!rmap.has_resource("https://duck.com/abc"));
+    }
+
+    #[test]
+    fn external_resource_with_name() {
+        let mut root = ResourceMap::new(ResourceDef::prefix(""));
+
+        let mut rdef = ResourceDef::new("https://duck.com/{query}");
+        rdef.set_name("duck");
+        root.add(&mut rdef, None);
+
+        let rmap = Rc::new(root);
+        ResourceMap::finish(&rmap);
+
+        assert!(!rmap.has_resource("https://duck.com/abc"));
+
+        let mut req = crate::test::TestRequest::default();
+        req.set_server_hostname("localhost:8888");
+        let req = req.to_http_request();
+
+        assert_eq!(
+            rmap.url_for(&req, "duck", ["abcd"]).unwrap().to_string(),
+            "https://duck.com/abcd"
+        );
+    }
+
+    #[test]
+    fn url_for_override_within_map() {
+        let mut root = ResourceMap::new(ResourceDef::prefix(""));
+
+        let mut foo_rdef = ResourceDef::prefix("/foo");
+        let mut foo_map = ResourceMap::new(foo_rdef.clone());
+        let mut nested_rdef = ResourceDef::new("/nested");
+        nested_rdef.set_name("nested");
+        foo_map.add(&mut nested_rdef, None);
+        root.add(&mut foo_rdef, Some(Rc::new(foo_map)));
+
+        let mut foo_rdef = ResourceDef::prefix("/bar");
+        let mut foo_map = ResourceMap::new(foo_rdef.clone());
+        let mut nested_rdef = ResourceDef::new("/nested");
+        nested_rdef.set_name("nested");
+        foo_map.add(&mut nested_rdef, None);
+        root.add(&mut foo_rdef, Some(Rc::new(foo_map)));
+
+        let rmap = Rc::new(root);
+        ResourceMap::finish(&rmap);
+
+        let req = crate::test::TestRequest::default().to_http_request();
+
+        let url = rmap.url_for(&req, "nested", [""; 0]).unwrap().to_string();
+        assert_eq!(url, "http://localhost:8080/bar/nested");
+
+        assert!(rmap.url_for(&req, "missing", ["u123"]).is_err());
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/route.rs.html b/src/actix_web/route.rs.html new file mode 100644 index 000000000..2bdcf9d5b --- /dev/null +++ b/src/actix_web/route.rs.html @@ -0,0 +1,915 @@ +route.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
+
use std::{mem, rc::Rc};
+
+use actix_http::{body::MessageBody, Method};
+use actix_service::{
+    apply,
+    boxed::{self, BoxService},
+    fn_service, Service, ServiceFactory, ServiceFactoryExt, Transform,
+};
+use futures_core::future::LocalBoxFuture;
+
+use crate::{
+    guard::{self, Guard},
+    handler::{handler_service, Handler},
+    middleware::Compat,
+    service::{BoxedHttpServiceFactory, ServiceRequest, ServiceResponse},
+    Error, FromRequest, HttpResponse, Responder,
+};
+
+/// A request handler with [guards](guard).
+///
+/// Route uses a builder-like pattern for configuration. If handler is not set, a `404 Not Found`
+/// handler is used.
+pub struct Route {
+    service: BoxedHttpServiceFactory,
+    guards: Rc<Vec<Box<dyn Guard>>>,
+}
+
+impl Route {
+    /// Create new route which matches any request.
+    #[allow(clippy::new_without_default)]
+    pub fn new() -> Route {
+        Route {
+            service: boxed::factory(fn_service(|req: ServiceRequest| async {
+                Ok(req.into_response(HttpResponse::NotFound()))
+            })),
+            guards: Rc::new(Vec::new()),
+        }
+    }
+
+    /// Registers a route middleware.
+    ///
+    /// `mw` is a middleware component (type), that can modify the requests and responses handled by
+    /// this `Route`.
+    ///
+    /// See [`App::wrap`](crate::App::wrap) for more details.
+    #[doc(alias = "middleware")]
+    #[doc(alias = "use")] // nodejs terminology
+    pub fn wrap<M, B>(self, mw: M) -> Route
+    where
+        M: Transform<
+                BoxService<ServiceRequest, ServiceResponse, Error>,
+                ServiceRequest,
+                Response = ServiceResponse<B>,
+                Error = Error,
+                InitError = (),
+            > + 'static,
+        B: MessageBody + 'static,
+    {
+        Route {
+            service: boxed::factory(apply(Compat::new(mw), self.service)),
+            guards: self.guards,
+        }
+    }
+
+    pub(crate) fn take_guards(&mut self) -> Vec<Box<dyn Guard>> {
+        mem::take(Rc::get_mut(&mut self.guards).unwrap())
+    }
+}
+
+impl ServiceFactory<ServiceRequest> for Route {
+    type Response = ServiceResponse;
+    type Error = Error;
+    type Config = ();
+    type Service = RouteService;
+    type InitError = ();
+    type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
+
+    fn new_service(&self, _: ()) -> Self::Future {
+        let fut = self.service.new_service(());
+        let guards = self.guards.clone();
+
+        Box::pin(async move {
+            let service = fut.await?;
+            Ok(RouteService { service, guards })
+        })
+    }
+}
+
+pub struct RouteService {
+    service: BoxService<ServiceRequest, ServiceResponse, Error>,
+    guards: Rc<Vec<Box<dyn Guard>>>,
+}
+
+impl RouteService {
+    // TODO(breaking): remove pass by ref mut
+    #[allow(clippy::needless_pass_by_ref_mut)]
+    pub fn check(&self, req: &mut ServiceRequest) -> bool {
+        let guard_ctx = req.guard_ctx();
+
+        for guard in self.guards.iter() {
+            if !guard.check(&guard_ctx) {
+                return false;
+            }
+        }
+        true
+    }
+}
+
+impl Service<ServiceRequest> for RouteService {
+    type Response = ServiceResponse;
+    type Error = Error;
+    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
+
+    actix_service::forward_ready!(service);
+
+    fn call(&self, req: ServiceRequest) -> Self::Future {
+        self.service.call(req)
+    }
+}
+
+impl Route {
+    /// Add method guard to the route.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_web::*;
+    /// # fn main() {
+    /// App::new().service(web::resource("/path").route(
+    ///     web::get()
+    ///         .method(http::Method::CONNECT)
+    ///         .guard(guard::Header("content-type", "text/plain"))
+    ///         .to(|req: HttpRequest| HttpResponse::Ok()))
+    /// );
+    /// # }
+    /// ```
+    pub fn method(mut self, method: Method) -> Self {
+        Rc::get_mut(&mut self.guards)
+            .unwrap()
+            .push(Box::new(guard::Method(method)));
+        self
+    }
+
+    /// Add guard to the route.
+    ///
+    /// # Examples
+    /// ```
+    /// # use actix_web::*;
+    /// # fn main() {
+    /// App::new().service(web::resource("/path").route(
+    ///     web::route()
+    ///         .guard(guard::Get())
+    ///         .guard(guard::Header("content-type", "text/plain"))
+    ///         .to(|req: HttpRequest| HttpResponse::Ok()))
+    /// );
+    /// # }
+    /// ```
+    pub fn guard<F: Guard + 'static>(mut self, f: F) -> Self {
+        Rc::get_mut(&mut self.guards).unwrap().push(Box::new(f));
+        self
+    }
+
+    /// Set handler function, use request extractors for parameters.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::{web, http, App};
+    /// use serde::Deserialize;
+    ///
+    /// #[derive(Deserialize)]
+    /// struct Info {
+    ///     username: String,
+    /// }
+    ///
+    /// /// extract path info using serde
+    /// async fn index(info: web::Path<Info>) -> String {
+    ///     format!("Welcome {}!", info.username)
+    /// }
+    ///
+    /// let app = App::new().service(
+    ///     web::resource("/{username}/index.html") // <- define path parameters
+    ///         .route(web::get().to(index))        // <- register handler
+    /// );
+    /// ```
+    ///
+    /// It is possible to use multiple extractors for one handler function.
+    /// ```
+    /// # use std::collections::HashMap;
+    /// # use serde::Deserialize;
+    /// use actix_web::{web, App};
+    ///
+    /// #[derive(Deserialize)]
+    /// struct Info {
+    ///     username: String,
+    /// }
+    ///
+    /// /// extract path info using serde
+    /// async fn index(
+    ///     path: web::Path<Info>,
+    ///     query: web::Query<HashMap<String, String>>,
+    ///     body: web::Json<Info>
+    /// ) -> String {
+    ///     format!("Welcome {}!", path.username)
+    /// }
+    ///
+    /// let app = App::new().service(
+    ///     web::resource("/{username}/index.html") // <- define path parameters
+    ///         .route(web::get().to(index))
+    /// );
+    /// ```
+    pub fn to<F, Args>(mut self, handler: F) -> Self
+    where
+        F: Handler<Args>,
+        Args: FromRequest + 'static,
+        F::Output: Responder + 'static,
+    {
+        self.service = handler_service(handler);
+        self
+    }
+
+    /// Set raw service to be constructed and called as the request handler.
+    ///
+    /// # Examples
+    /// ```
+    /// # use std::convert::Infallible;
+    /// # use futures_util::future::LocalBoxFuture;
+    /// # use actix_web::{*, dev::*, http::header};
+    /// struct HelloWorld;
+    ///
+    /// impl Service<ServiceRequest> for HelloWorld {
+    ///     type Response = ServiceResponse;
+    ///     type Error = Infallible;
+    ///     type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
+    ///
+    ///     dev::always_ready!();
+    ///
+    ///     fn call(&self, req: ServiceRequest) -> Self::Future {
+    ///         let (req, _) = req.into_parts();
+    ///
+    ///         let res = HttpResponse::Ok()
+    ///             .insert_header(header::ContentType::plaintext())
+    ///             .body("Hello world!");
+    ///
+    ///         Box::pin(async move { Ok(ServiceResponse::new(req, res)) })
+    ///     }
+    /// }
+    ///
+    /// App::new().route(
+    ///     "/",
+    ///     web::get().service(fn_factory(|| async { Ok(HelloWorld) })),
+    /// );
+    /// ```
+    pub fn service<S, E>(mut self, service_factory: S) -> Self
+    where
+        S: ServiceFactory<
+                ServiceRequest,
+                Response = ServiceResponse,
+                Error = E,
+                InitError = (),
+                Config = (),
+            > + 'static,
+        E: Into<Error> + 'static,
+    {
+        self.service = boxed::factory(service_factory.map_err(Into::into));
+        self
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::{convert::Infallible, time::Duration};
+
+    use actix_rt::time::sleep;
+    use bytes::Bytes;
+    use futures_core::future::LocalBoxFuture;
+    use serde::Serialize;
+
+    use crate::{
+        dev::{always_ready, fn_factory, fn_service, Service},
+        error,
+        http::{header, Method, StatusCode},
+        middleware::{DefaultHeaders, Logger},
+        service::{ServiceRequest, ServiceResponse},
+        test::{call_service, init_service, read_body, TestRequest},
+        web, App, HttpResponse,
+    };
+
+    #[derive(Serialize, PartialEq, Debug)]
+    struct MyObject {
+        name: String,
+    }
+
+    #[actix_rt::test]
+    async fn test_route() {
+        let srv =
+            init_service(
+                App::new()
+                    .service(
+                        web::resource("/test")
+                            .route(web::get().to(HttpResponse::Ok))
+                            .route(web::put().to(|| async {
+                                Err::<HttpResponse, _>(error::ErrorBadRequest("err"))
+                            }))
+                            .route(web::post().to(|| async {
+                                sleep(Duration::from_millis(100)).await;
+                                Ok::<_, Infallible>(HttpResponse::Created())
+                            }))
+                            .route(web::delete().to(|| async {
+                                sleep(Duration::from_millis(100)).await;
+                                Err::<HttpResponse, _>(error::ErrorBadRequest("err"))
+                            })),
+                    )
+                    .service(web::resource("/json").route(web::get().to(|| async {
+                        sleep(Duration::from_millis(25)).await;
+                        web::Json(MyObject {
+                            name: "test".to_string(),
+                        })
+                    }))),
+            )
+            .await;
+
+        let req = TestRequest::with_uri("/test")
+            .method(Method::GET)
+            .to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/test")
+            .method(Method::POST)
+            .to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::CREATED);
+
+        let req = TestRequest::with_uri("/test")
+            .method(Method::PUT)
+            .to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+
+        let req = TestRequest::with_uri("/test")
+            .method(Method::DELETE)
+            .to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+
+        let req = TestRequest::with_uri("/test")
+            .method(Method::HEAD)
+            .to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
+
+        let req = TestRequest::with_uri("/json").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let body = read_body(resp).await;
+        assert_eq!(body, Bytes::from_static(b"{\"name\":\"test\"}"));
+    }
+
+    #[actix_rt::test]
+    async fn route_middleware() {
+        let srv = init_service(
+            App::new()
+                .route("/", web::get().to(HttpResponse::Ok).wrap(Logger::default()))
+                .service(
+                    web::resource("/test")
+                        .route(web::get().to(HttpResponse::Ok))
+                        .route(
+                            web::post()
+                                .to(HttpResponse::Created)
+                                .wrap(DefaultHeaders::new().add(("x-test", "x-posted"))),
+                        )
+                        .route(
+                            web::delete()
+                                .to(HttpResponse::Accepted)
+                                // logger changes body type, proving Compat is not needed
+                                .wrap(Logger::default()),
+                        ),
+                ),
+        )
+        .await;
+
+        let req = TestRequest::get().uri("/test").to_request();
+        let res = call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+        assert!(!res.headers().contains_key("x-test"));
+
+        let req = TestRequest::post().uri("/test").to_request();
+        let res = call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::CREATED);
+        assert_eq!(res.headers().get("x-test").unwrap(), "x-posted");
+
+        let req = TestRequest::delete().uri("/test").to_request();
+        let res = call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::ACCEPTED);
+    }
+
+    #[actix_rt::test]
+    async fn test_service_handler() {
+        struct HelloWorld;
+
+        impl Service<ServiceRequest> for HelloWorld {
+            type Response = ServiceResponse;
+            type Error = crate::Error;
+            type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
+
+            always_ready!();
+
+            fn call(&self, req: ServiceRequest) -> Self::Future {
+                let (req, _) = req.into_parts();
+
+                let res = HttpResponse::Ok()
+                    .insert_header(header::ContentType::plaintext())
+                    .body("Hello world!");
+
+                Box::pin(async move { Ok(ServiceResponse::new(req, res)) })
+            }
+        }
+
+        let srv = init_service(
+            App::new()
+                .route(
+                    "/hello",
+                    web::get().service(fn_factory(|| async { Ok(HelloWorld) })),
+                )
+                .route(
+                    "/bye",
+                    web::get().service(fn_factory(|| async {
+                        Ok::<_, ()>(fn_service(|req: ServiceRequest| async {
+                            let (req, _) = req.into_parts();
+
+                            let res = HttpResponse::Ok()
+                                .insert_header(header::ContentType::plaintext())
+                                .body("Goodbye, and thanks for all the fish!");
+
+                            Ok::<_, Infallible>(ServiceResponse::new(req, res))
+                        }))
+                    })),
+                ),
+        )
+        .await;
+
+        let req = TestRequest::get().uri("/hello").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        let body = read_body(resp).await;
+        assert_eq!(body, Bytes::from_static(b"Hello world!"));
+
+        let req = TestRequest::get().uri("/bye").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        let body = read_body(resp).await;
+        assert_eq!(
+            body,
+            Bytes::from_static(b"Goodbye, and thanks for all the fish!")
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/rt.rs.html b/src/actix_web/rt.rs.html new file mode 100644 index 000000000..32d448807 --- /dev/null +++ b/src/actix_web/rt.rs.html @@ -0,0 +1,157 @@ +rt.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
+
//! A selection of re-exports from [`tokio`] and [`actix-rt`].
+//!
+//! Actix Web runs on [Tokio], providing full[^compat] compatibility with its huge ecosystem of
+//! crates. Each of the server's workers uses a single-threaded runtime. Read more about the
+//! architecture in [`actix-rt`]'s docs.
+//!
+//! # Running Actix Web Without Macros
+//!
+//! ```no_run
+//! use actix_web::{middleware, rt, web, App, HttpRequest, HttpServer};
+//!
+//! async fn index(req: HttpRequest) -> &'static str {
+//!     println!("REQ: {:?}", req);
+//!     "Hello world!\r\n"
+//! }
+//!
+//! fn main() -> std::io::Result<()> {
+//!     rt::System::new().block_on(
+//!         HttpServer::new(|| {
+//!             App::new().service(web::resource("/").route(web::get().to(index)))
+//!         })
+//!         .bind(("127.0.0.1", 8080))?
+//!         .run()
+//!     )
+//! }
+//! ```
+//!
+//! # Running Actix Web Using `#[tokio::main]`
+//!
+//! If you need to run something that uses Tokio's work stealing functionality alongside Actix Web,
+//! you can run Actix Web under `#[tokio::main]`. The [`Server`](crate::dev::Server) object returned
+//! from [`HttpServer::run`](crate::HttpServer::run) can also be [`spawn`]ed, if preferred.
+//!
+//! Note that `actix` actor support (and therefore WebSocket support through `actix-web-actors`)
+//! still require `#[actix_web::main]` since they require a [`System`] to be set up.
+//!
+//! Also note that calls to this module's [`spawn()`] re-export require an `#[actix_web::main]`
+//! runtime (or a manually configured `LocalSet`) since it makes calls into to the current thread's
+//! `LocalSet`, which `#[tokio::main]` does not set up.
+//!
+//! ```no_run
+//! use actix_web::{get, middleware, rt, web, App, HttpRequest, HttpServer};
+//!
+//! #[get("/")]
+//! async fn index(req: HttpRequest) -> &'static str {
+//!     println!("REQ: {:?}", req);
+//!     "Hello world!\r\n"
+//! }
+//!
+//! #[tokio::main]
+//! async fn main() -> std::io::Result<()> {
+//!     HttpServer::new(|| {
+//!         App::new().service(index)
+//!     })
+//!     .bind(("127.0.0.1", 8080))?
+//!     .run()
+//!     .await
+//! }
+//! ```
+//!
+//! [^compat]: Crates that use Tokio's [`block_in_place`] will not work with Actix Web. Fortunately,
+//!   the vast majority of Tokio-based crates do not use it.
+//!
+//! [`actix-rt`]: https://docs.rs/actix-rt
+//! [`tokio`]: https://docs.rs/tokio
+//! [Tokio]: https://docs.rs/tokio
+//! [`spawn`]: https://docs.rs/tokio/1/tokio/fn.spawn.html
+//! [`block_in_place`]: https://docs.rs/tokio/1/tokio/task/fn.block_in_place.html
+
+// In particular:
+// - Omit the `Arbiter` types because they have limited value here.
+// - Re-export but hide the runtime macros because they won't work directly but are required for
+//   `#[actix_web::main]` and `#[actix_web::test]` to work.
+
+#[cfg(feature = "macros")]
+#[doc(hidden)]
+pub use actix_macros::{main, test};
+pub use actix_rt::{net, pin, signal, spawn, task, time, Runtime, System, SystemRunner};
+
\ No newline at end of file diff --git a/src/actix_web/scope.rs.html b/src/actix_web/scope.rs.html new file mode 100644 index 000000000..0bd53cea0 --- /dev/null +++ b/src/actix_web/scope.rs.html @@ -0,0 +1,2459 @@ +scope.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
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+
use std::{cell::RefCell, fmt, future::Future, mem, rc::Rc};
+
+use actix_http::{body::MessageBody, Extensions};
+use actix_router::{ResourceDef, Router};
+use actix_service::{
+    apply, apply_fn_factory, boxed, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt,
+    Transform,
+};
+use futures_core::future::LocalBoxFuture;
+use futures_util::future::join_all;
+
+use crate::{
+    config::ServiceConfig,
+    data::Data,
+    dev::AppService,
+    guard::Guard,
+    rmap::ResourceMap,
+    service::{
+        AppServiceFactory, BoxedHttpService, BoxedHttpServiceFactory, HttpServiceFactory,
+        ServiceFactoryWrapper, ServiceRequest, ServiceResponse,
+    },
+    Error, Resource, Route,
+};
+
+type Guards = Vec<Box<dyn Guard>>;
+
+/// A collection of [`Route`]s, [`Resource`]s, or other services that share a common path prefix.
+///
+/// The `Scope`'s path can contain [dynamic segments]. The dynamic segments can be extracted from
+/// requests using the [`Path`](crate::web::Path) extractor or
+/// with [`HttpRequest::match_info()`](crate::HttpRequest::match_info).
+///
+/// # Avoid Trailing Slashes
+/// Avoid using trailing slashes in the scope prefix (e.g., `web::scope("/scope/")`). It will almost
+/// certainly not have the expected behavior. See the [documentation on resource definitions][pat]
+/// to understand why this is the case and how to correctly construct scope/prefix definitions.
+///
+/// # Examples
+/// ```
+/// use actix_web::{web, App, HttpResponse};
+///
+/// let app = App::new().service(
+///     web::scope("/{project_id}")
+///         .service(web::resource("/path1").to(|| async { "OK" }))
+///         .service(web::resource("/path2").route(web::get().to(|| HttpResponse::Ok())))
+///         .service(web::resource("/path3").route(web::head().to(HttpResponse::MethodNotAllowed)))
+/// );
+/// ```
+///
+/// In the above example three routes get registered:
+/// - /{project_id}/path1 - responds to all HTTP methods
+/// - /{project_id}/path2 - responds to `GET` requests
+/// - /{project_id}/path3 - responds to `HEAD` requests
+///
+/// [pat]: crate::dev::ResourceDef#prefix-resources
+/// [dynamic segments]: crate::dev::ResourceDef#dynamic-segments
+pub struct Scope<T = ScopeEndpoint> {
+    endpoint: T,
+    rdef: String,
+    app_data: Option<Extensions>,
+    services: Vec<Box<dyn AppServiceFactory>>,
+    guards: Vec<Box<dyn Guard>>,
+    default: Option<Rc<BoxedHttpServiceFactory>>,
+    external: Vec<ResourceDef>,
+    factory_ref: Rc<RefCell<Option<ScopeFactory>>>,
+}
+
+impl Scope {
+    /// Create a new scope
+    pub fn new(path: &str) -> Scope {
+        let factory_ref = Rc::new(RefCell::new(None));
+
+        Scope {
+            endpoint: ScopeEndpoint::new(Rc::clone(&factory_ref)),
+            rdef: path.to_string(),
+            app_data: None,
+            guards: Vec::new(),
+            services: Vec::new(),
+            default: None,
+            external: Vec::new(),
+            factory_ref,
+        }
+    }
+}
+
+impl<T> Scope<T>
+where
+    T: ServiceFactory<ServiceRequest, Config = (), Error = Error, InitError = ()>,
+{
+    /// Add match guard to a scope.
+    ///
+    /// ```
+    /// use actix_web::{web, guard, App, HttpRequest, HttpResponse};
+    ///
+    /// async fn index(data: web::Path<(String, String)>) -> &'static str {
+    ///     "Welcome!"
+    /// }
+    ///
+    /// let app = App::new().service(
+    ///     web::scope("/app")
+    ///         .guard(guard::Header("content-type", "text/plain"))
+    ///         .route("/test1", web::get().to(index))
+    ///         .route("/test2", web::post().to(|r: HttpRequest| {
+    ///             HttpResponse::MethodNotAllowed()
+    ///         }))
+    /// );
+    /// ```
+    pub fn guard<G: Guard + 'static>(mut self, guard: G) -> Self {
+        self.guards.push(Box::new(guard));
+        self
+    }
+
+    /// Add scope data.
+    ///
+    /// Data of different types from parent contexts will still be accessible. Any `Data<T>` types
+    /// set here can be extracted in handlers using the `Data<T>` extractor.
+    ///
+    /// # Examples
+    /// ```
+    /// use std::cell::Cell;
+    /// use actix_web::{web, App, HttpRequest, HttpResponse, Responder};
+    ///
+    /// struct MyData {
+    ///     count: std::cell::Cell<usize>,
+    /// }
+    ///
+    /// async fn handler(req: HttpRequest, counter: web::Data<MyData>) -> impl Responder {
+    ///     // note this cannot use the Data<T> extractor because it was not added with it
+    ///     let incr = *req.app_data::<usize>().unwrap();
+    ///     assert_eq!(incr, 3);
+    ///
+    ///     // update counter using other value from app data
+    ///     counter.count.set(counter.count.get() + incr);
+    ///
+    ///     HttpResponse::Ok().body(counter.count.get().to_string())
+    /// }
+    ///
+    /// let app = App::new().service(
+    ///     web::scope("/app")
+    ///         .app_data(3usize)
+    ///         .app_data(web::Data::new(MyData { count: Default::default() }))
+    ///         .route("/", web::get().to(handler))
+    /// );
+    /// ```
+    #[doc(alias = "manage")]
+    pub fn app_data<U: 'static>(mut self, data: U) -> Self {
+        self.app_data
+            .get_or_insert_with(Extensions::new)
+            .insert(data);
+
+        self
+    }
+
+    /// Add scope data after wrapping in `Data<T>`.
+    ///
+    /// Deprecated in favor of [`app_data`](Self::app_data).
+    #[deprecated(since = "4.0.0", note = "Use `.app_data(Data::new(val))` instead.")]
+    pub fn data<U: 'static>(self, data: U) -> Self {
+        self.app_data(Data::new(data))
+    }
+
+    /// Run external configuration as part of the scope building process.
+    ///
+    /// This function is useful for moving parts of configuration to a different module or library.
+    /// For example, some of the resource's configuration could be moved to different module.
+    ///
+    /// ```
+    /// use actix_web::{web, middleware, App, HttpResponse};
+    ///
+    /// // this function could be located in different module
+    /// fn config(cfg: &mut web::ServiceConfig) {
+    ///     cfg.service(web::resource("/test")
+    ///         .route(web::get().to(|| HttpResponse::Ok()))
+    ///         .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
+    ///     );
+    /// }
+    ///
+    /// let app = App::new()
+    ///     .wrap(middleware::Logger::default())
+    ///     .service(
+    ///         web::scope("/api")
+    ///             .configure(config)
+    ///     )
+    ///     .route("/index.html", web::get().to(|| HttpResponse::Ok()));
+    /// ```
+    pub fn configure<F>(mut self, cfg_fn: F) -> Self
+    where
+        F: FnOnce(&mut ServiceConfig),
+    {
+        let mut cfg = ServiceConfig::new();
+        cfg_fn(&mut cfg);
+
+        self.services.extend(cfg.services);
+        self.external.extend(cfg.external);
+
+        // TODO: add Extensions::is_empty check and conditionally insert data
+        self.app_data
+            .get_or_insert_with(Extensions::new)
+            .extend(cfg.app_data);
+
+        if let Some(default) = cfg.default {
+            self.default = Some(default);
+        }
+
+        self
+    }
+
+    /// Register HTTP service.
+    ///
+    /// This is similar to `App's` service registration.
+    ///
+    /// Actix Web provides several services implementations:
+    ///
+    /// * *Resource* is an entry in resource table which corresponds to requested URL.
+    /// * *Scope* is a set of resources with common root path.
+    /// * "StaticFiles" is a service for static files support
+    ///
+    /// ```
+    /// use actix_web::{web, App, HttpRequest};
+    ///
+    /// struct AppState;
+    ///
+    /// async fn index(req: HttpRequest) -> &'static str {
+    ///     "Welcome!"
+    /// }
+    ///
+    /// let app = App::new().service(
+    ///     web::scope("/app").service(
+    ///         web::scope("/v1")
+    ///             .service(web::resource("/test1").to(index)))
+    /// );
+    /// ```
+    pub fn service<F>(mut self, factory: F) -> Self
+    where
+        F: HttpServiceFactory + 'static,
+    {
+        self.services
+            .push(Box::new(ServiceFactoryWrapper::new(factory)));
+        self
+    }
+
+    /// Configure route for a specific path.
+    ///
+    /// This is a simplified version of the `Scope::service()` method.
+    /// This method can be called multiple times, in that case
+    /// multiple resources with one route would be registered for same resource path.
+    ///
+    /// ```
+    /// use actix_web::{web, App, HttpResponse};
+    ///
+    /// async fn index(data: web::Path<(String, String)>) -> &'static str {
+    ///     "Welcome!"
+    /// }
+    ///
+    /// let app = App::new().service(
+    ///     web::scope("/app")
+    ///         .route("/test1", web::get().to(index))
+    ///         .route("/test2", web::post().to(|| HttpResponse::MethodNotAllowed()))
+    /// );
+    /// ```
+    pub fn route(self, path: &str, mut route: Route) -> Self {
+        self.service(
+            Resource::new(path)
+                .add_guards(route.take_guards())
+                .route(route),
+        )
+    }
+
+    /// Default service to be used if no matching resource could be found.
+    ///
+    /// If a default service is not registered, it will fall back to the default service of
+    /// the parent [`App`](crate::App) (see [`App::default_service`](crate::App::default_service)).
+    pub fn default_service<F, U>(mut self, f: F) -> Self
+    where
+        F: IntoServiceFactory<U, ServiceRequest>,
+        U: ServiceFactory<ServiceRequest, Config = (), Response = ServiceResponse, Error = Error>
+            + 'static,
+        U::InitError: fmt::Debug,
+    {
+        // create and configure default resource
+        self.default = Some(Rc::new(boxed::factory(f.into_factory().map_init_err(
+            |e| log::error!("Can not construct default service: {:?}", e),
+        ))));
+
+        self
+    }
+
+    /// Registers a scope-wide middleware.
+    ///
+    /// `mw` is a middleware component (type), that can modify the request and response across all
+    /// sub-resources managed by this `Scope`.
+    ///
+    /// See [`App::wrap`](crate::App::wrap) for more details.
+    #[doc(alias = "middleware")]
+    #[doc(alias = "use")] // nodejs terminology
+    pub fn wrap<M, B>(
+        self,
+        mw: M,
+    ) -> Scope<
+        impl ServiceFactory<
+            ServiceRequest,
+            Config = (),
+            Response = ServiceResponse<B>,
+            Error = Error,
+            InitError = (),
+        >,
+    >
+    where
+        M: Transform<
+                T::Service,
+                ServiceRequest,
+                Response = ServiceResponse<B>,
+                Error = Error,
+                InitError = (),
+            > + 'static,
+        B: MessageBody,
+    {
+        Scope {
+            endpoint: apply(mw, self.endpoint),
+            rdef: self.rdef,
+            app_data: self.app_data,
+            guards: self.guards,
+            services: self.services,
+            default: self.default,
+            external: self.external,
+            factory_ref: self.factory_ref,
+        }
+    }
+
+    /// Registers a scope-wide function middleware.
+    ///
+    /// `mw` is a closure that runs during inbound and/or outbound processing in the request
+    /// life-cycle (request -> response), modifying request/response as necessary, across all
+    /// requests handled by the `Scope`.
+    ///
+    /// See [`App::wrap_fn`](crate::App::wrap_fn) for examples and more details.
+    #[doc(alias = "middleware")]
+    #[doc(alias = "use")] // nodejs terminology
+    pub fn wrap_fn<F, R, B>(
+        self,
+        mw: F,
+    ) -> Scope<
+        impl ServiceFactory<
+            ServiceRequest,
+            Config = (),
+            Response = ServiceResponse<B>,
+            Error = Error,
+            InitError = (),
+        >,
+    >
+    where
+        F: Fn(ServiceRequest, &T::Service) -> R + Clone + 'static,
+        R: Future<Output = Result<ServiceResponse<B>, Error>>,
+        B: MessageBody,
+    {
+        Scope {
+            endpoint: apply_fn_factory(self.endpoint, mw),
+            rdef: self.rdef,
+            app_data: self.app_data,
+            guards: self.guards,
+            services: self.services,
+            default: self.default,
+            external: self.external,
+            factory_ref: self.factory_ref,
+        }
+    }
+}
+
+impl<T, B> HttpServiceFactory for Scope<T>
+where
+    T: ServiceFactory<
+            ServiceRequest,
+            Config = (),
+            Response = ServiceResponse<B>,
+            Error = Error,
+            InitError = (),
+        > + 'static,
+    B: MessageBody + 'static,
+{
+    fn register(mut self, config: &mut AppService) {
+        // update default resource if needed
+        let default = self.default.unwrap_or_else(|| config.default_service());
+
+        // register nested services
+        let mut cfg = config.clone_config();
+        self.services
+            .into_iter()
+            .for_each(|mut srv| srv.register(&mut cfg));
+
+        let mut rmap = ResourceMap::new(ResourceDef::root_prefix(&self.rdef));
+
+        // external resources
+        for mut rdef in mem::take(&mut self.external) {
+            rmap.add(&mut rdef, None);
+        }
+
+        // complete scope pipeline creation
+        *self.factory_ref.borrow_mut() = Some(ScopeFactory {
+            default,
+            services: cfg
+                .into_services()
+                .1
+                .into_iter()
+                .map(|(mut rdef, srv, guards, nested)| {
+                    rmap.add(&mut rdef, nested);
+                    (rdef, srv, RefCell::new(guards))
+                })
+                .collect::<Vec<_>>()
+                .into_boxed_slice()
+                .into(),
+        });
+
+        // get guards
+        let guards = if self.guards.is_empty() {
+            None
+        } else {
+            Some(self.guards)
+        };
+
+        let scope_data = self.app_data.map(Rc::new);
+
+        // wraps endpoint service (including middleware) call and injects app data for this scope
+        let endpoint = apply_fn_factory(self.endpoint, move |mut req: ServiceRequest, srv| {
+            if let Some(ref data) = scope_data {
+                req.add_data_container(Rc::clone(data));
+            }
+
+            let fut = srv.call(req);
+
+            async { Ok(fut.await?.map_into_boxed_body()) }
+        });
+
+        // register final service
+        config.register_service(
+            ResourceDef::root_prefix(&self.rdef),
+            guards,
+            endpoint,
+            Some(Rc::new(rmap)),
+        )
+    }
+}
+
+pub struct ScopeFactory {
+    #[allow(clippy::type_complexity)]
+    services: Rc<
+        [(
+            ResourceDef,
+            BoxedHttpServiceFactory,
+            RefCell<Option<Guards>>,
+        )],
+    >,
+    default: Rc<BoxedHttpServiceFactory>,
+}
+
+impl ServiceFactory<ServiceRequest> for ScopeFactory {
+    type Response = ServiceResponse;
+    type Error = Error;
+    type Config = ();
+    type Service = ScopeService;
+    type InitError = ();
+    type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
+
+    fn new_service(&self, _: ()) -> Self::Future {
+        // construct default service factory future
+        let default_fut = self.default.new_service(());
+
+        // construct all services factory future with it's resource def and guards.
+        let factory_fut = join_all(self.services.iter().map(|(path, factory, guards)| {
+            let path = path.clone();
+            let guards = guards.borrow_mut().take().unwrap_or_default();
+            let factory_fut = factory.new_service(());
+            async move {
+                factory_fut
+                    .await
+                    .map(move |service| (path, guards, service))
+            }
+        }));
+
+        Box::pin(async move {
+            let default = default_fut.await?;
+
+            // build router from the factory future result.
+            let router = factory_fut
+                .await
+                .into_iter()
+                .collect::<Result<Vec<_>, _>>()?
+                .drain(..)
+                .fold(Router::build(), |mut router, (path, guards, service)| {
+                    router.push(path, service, guards);
+                    router
+                })
+                .finish();
+
+            Ok(ScopeService { router, default })
+        })
+    }
+}
+
+pub struct ScopeService {
+    router: Router<BoxedHttpService, Vec<Box<dyn Guard>>>,
+    default: BoxedHttpService,
+}
+
+impl Service<ServiceRequest> for ScopeService {
+    type Response = ServiceResponse;
+    type Error = Error;
+    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
+
+    actix_service::always_ready!();
+
+    fn call(&self, mut req: ServiceRequest) -> Self::Future {
+        let res = self.router.recognize_fn(&mut req, |req, guards| {
+            let guard_ctx = req.guard_ctx();
+            guards.iter().all(|guard| guard.check(&guard_ctx))
+        });
+
+        if let Some((srv, _info)) = res {
+            srv.call(req)
+        } else {
+            self.default.call(req)
+        }
+    }
+}
+
+#[doc(hidden)]
+pub struct ScopeEndpoint {
+    factory: Rc<RefCell<Option<ScopeFactory>>>,
+}
+
+impl ScopeEndpoint {
+    fn new(factory: Rc<RefCell<Option<ScopeFactory>>>) -> Self {
+        ScopeEndpoint { factory }
+    }
+}
+
+impl ServiceFactory<ServiceRequest> for ScopeEndpoint {
+    type Response = ServiceResponse;
+    type Error = Error;
+    type Config = ();
+    type Service = ScopeService;
+    type InitError = ();
+    type Future = LocalBoxFuture<'static, Result<Self::Service, Self::InitError>>;
+
+    fn new_service(&self, _: ()) -> Self::Future {
+        self.factory.borrow_mut().as_mut().unwrap().new_service(())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_utils::future::ok;
+    use bytes::Bytes;
+
+    use super::*;
+    use crate::{
+        guard,
+        http::{
+            header::{self, HeaderValue},
+            Method, StatusCode,
+        },
+        middleware::DefaultHeaders,
+        test::{assert_body_eq, call_service, init_service, read_body, TestRequest},
+        web, App, HttpMessage, HttpRequest, HttpResponse,
+    };
+
+    #[test]
+    fn can_be_returned_from_fn() {
+        fn my_scope_1() -> Scope {
+            web::scope("/test")
+                .service(web::resource("").route(web::get().to(|| async { "hello" })))
+        }
+
+        fn my_scope_2() -> Scope<
+            impl ServiceFactory<
+                ServiceRequest,
+                Config = (),
+                Response = ServiceResponse<impl MessageBody>,
+                Error = Error,
+                InitError = (),
+            >,
+        > {
+            web::scope("/test-compat")
+                .wrap_fn(|req, srv| {
+                    let fut = srv.call(req);
+                    async { Ok(fut.await?.map_into_right_body::<()>()) }
+                })
+                .service(web::resource("").route(web::get().to(|| async { "hello" })))
+        }
+
+        fn my_scope_3() -> impl HttpServiceFactory {
+            my_scope_2()
+        }
+
+        App::new()
+            .service(my_scope_1())
+            .service(my_scope_2())
+            .service(my_scope_3());
+    }
+
+    #[actix_rt::test]
+    async fn test_scope() {
+        let srv = init_service(
+            App::new()
+                .service(web::scope("/app").service(web::resource("/path1").to(HttpResponse::Ok))),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/app/path1").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_scope_root() {
+        let srv = init_service(
+            App::new().service(
+                web::scope("/app")
+                    .service(web::resource("").to(HttpResponse::Ok))
+                    .service(web::resource("/").to(HttpResponse::Created)),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/app").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/app/").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::CREATED);
+    }
+
+    #[actix_rt::test]
+    async fn test_scope_root2() {
+        let srv = init_service(
+            App::new().service(web::scope("/app/").service(web::resource("").to(HttpResponse::Ok))),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/app").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+
+        let req = TestRequest::with_uri("/app/").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_scope_root3() {
+        let srv = init_service(
+            App::new()
+                .service(web::scope("/app/").service(web::resource("/").to(HttpResponse::Ok))),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/app").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+
+        let req = TestRequest::with_uri("/app/").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+    }
+
+    #[actix_rt::test]
+    async fn test_scope_route() {
+        let srv = init_service(
+            App::new().service(
+                web::scope("app")
+                    .route("/path1", web::get().to(HttpResponse::Ok))
+                    .route("/path1", web::delete().to(HttpResponse::Ok)),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/app/path1").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/app/path1")
+            .method(Method::DELETE)
+            .to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/app/path1")
+            .method(Method::POST)
+            .to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+    }
+
+    #[actix_rt::test]
+    async fn test_scope_route_without_leading_slash() {
+        let srv = init_service(
+            App::new().service(
+                web::scope("app").service(
+                    web::resource("path1")
+                        .route(web::get().to(HttpResponse::Ok))
+                        .route(web::delete().to(HttpResponse::Ok)),
+                ),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/app/path1").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/app/path1")
+            .method(Method::DELETE)
+            .to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/app/path1")
+            .method(Method::POST)
+            .to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
+    }
+
+    #[actix_rt::test]
+    async fn test_scope_guard() {
+        let srv = init_service(
+            App::new().service(
+                web::scope("/app")
+                    .guard(guard::Get())
+                    .service(web::resource("/path1").to(HttpResponse::Ok)),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/app/path1")
+            .method(Method::POST)
+            .to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+
+        let req = TestRequest::with_uri("/app/path1")
+            .method(Method::GET)
+            .to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_scope_variable_segment() {
+        let srv = init_service(App::new().service(web::scope("/ab-{project}").service(
+            web::resource("/path1").to(|r: HttpRequest| {
+                HttpResponse::Ok().body(format!("project: {}", &r.match_info()["project"]))
+            }),
+        )))
+        .await;
+
+        let req = TestRequest::with_uri("/ab-project1/path1").to_request();
+        let res = srv.call(req).await.unwrap();
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_body_eq!(res, b"project: project1");
+
+        let req = TestRequest::with_uri("/aa-project1/path1").to_request();
+        let res = srv.call(req).await.unwrap();
+        assert_eq!(res.status(), StatusCode::NOT_FOUND);
+    }
+
+    #[actix_rt::test]
+    async fn test_nested_scope() {
+        let srv = init_service(App::new().service(web::scope("/app").service(
+            web::scope("/t1").service(web::resource("/path1").to(HttpResponse::Created)),
+        )))
+        .await;
+
+        let req = TestRequest::with_uri("/app/t1/path1").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::CREATED);
+    }
+
+    #[actix_rt::test]
+    async fn test_nested_scope_no_slash() {
+        let srv =
+            init_service(App::new().service(web::scope("/app").service(
+                web::scope("t1").service(web::resource("/path1").to(HttpResponse::Created)),
+            )))
+            .await;
+
+        let req = TestRequest::with_uri("/app/t1/path1").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::CREATED);
+    }
+
+    #[actix_rt::test]
+    async fn test_nested_scope_root() {
+        let srv = init_service(
+            App::new().service(
+                web::scope("/app").service(
+                    web::scope("/t1")
+                        .service(web::resource("").to(HttpResponse::Ok))
+                        .service(web::resource("/").to(HttpResponse::Created)),
+                ),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/app/t1").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/app/t1/").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::CREATED);
+    }
+
+    #[actix_rt::test]
+    async fn test_nested_scope_filter() {
+        let srv = init_service(
+            App::new().service(
+                web::scope("/app").service(
+                    web::scope("/t1")
+                        .guard(guard::Get())
+                        .service(web::resource("/path1").to(HttpResponse::Ok)),
+                ),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/app/t1/path1")
+            .method(Method::POST)
+            .to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+
+        let req = TestRequest::with_uri("/app/t1/path1")
+            .method(Method::GET)
+            .to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_nested_scope_with_variable_segment() {
+        let srv = init_service(App::new().service(web::scope("/app").service(
+            web::scope("/{project_id}").service(web::resource("/path1").to(|r: HttpRequest| {
+                HttpResponse::Created().body(format!("project: {}", &r.match_info()["project_id"]))
+            })),
+        )))
+        .await;
+
+        let req = TestRequest::with_uri("/app/project_1/path1").to_request();
+        let res = srv.call(req).await.unwrap();
+        assert_eq!(res.status(), StatusCode::CREATED);
+        assert_body_eq!(res, b"project: project_1");
+    }
+
+    #[actix_rt::test]
+    async fn test_nested2_scope_with_variable_segment() {
+        let srv = init_service(App::new().service(web::scope("/app").service(
+            web::scope("/{project}").service(web::scope("/{id}").service(
+                web::resource("/path1").to(|r: HttpRequest| {
+                    HttpResponse::Created().body(format!(
+                        "project: {} - {}",
+                        &r.match_info()["project"],
+                        &r.match_info()["id"],
+                    ))
+                }),
+            )),
+        )))
+        .await;
+
+        let req = TestRequest::with_uri("/app/test/1/path1").to_request();
+        let res = srv.call(req).await.unwrap();
+        assert_eq!(res.status(), StatusCode::CREATED);
+        assert_body_eq!(res, b"project: test - 1");
+
+        let req = TestRequest::with_uri("/app/test/1/path2").to_request();
+        let res = srv.call(req).await.unwrap();
+        assert_eq!(res.status(), StatusCode::NOT_FOUND);
+    }
+
+    #[actix_rt::test]
+    async fn test_default_resource() {
+        let srv = init_service(
+            App::new().service(
+                web::scope("/app")
+                    .service(web::resource("/path1").to(HttpResponse::Ok))
+                    .default_service(|r: ServiceRequest| {
+                        ok(r.into_response(HttpResponse::BadRequest()))
+                    }),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/app/path2").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+
+        let req = TestRequest::with_uri("/path2").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+    }
+
+    #[actix_rt::test]
+    async fn test_default_resource_propagation() {
+        let srv = init_service(
+            App::new()
+                .service(web::scope("/app1").default_service(web::to(HttpResponse::BadRequest)))
+                .service(web::scope("/app2"))
+                .default_service(|r: ServiceRequest| {
+                    ok(r.into_response(HttpResponse::MethodNotAllowed()))
+                }),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/non-exist").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
+
+        let req = TestRequest::with_uri("/app1/non-exist").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+
+        let req = TestRequest::with_uri("/app2/non-exist").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::METHOD_NOT_ALLOWED);
+    }
+
+    #[actix_rt::test]
+    async fn test_middleware() {
+        let srv = init_service(
+            App::new().service(
+                web::scope("app")
+                    .wrap(
+                        DefaultHeaders::new()
+                            .add((header::CONTENT_TYPE, HeaderValue::from_static("0001"))),
+                    )
+                    .service(web::resource("/test").route(web::get().to(HttpResponse::Ok))),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/app/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("0001")
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_middleware_body_type() {
+        // Compile test that Scope accepts any body type; test for `EitherBody`
+        let srv = init_service(
+            App::new().service(
+                web::scope("app")
+                    .wrap_fn(|req, srv| {
+                        let fut = srv.call(req);
+                        async { Ok(fut.await?.map_into_right_body::<()>()) }
+                    })
+                    .service(web::resource("/test").route(web::get().to(|| async { "hello" }))),
+            ),
+        )
+        .await;
+
+        // test if `MessageBody::try_into_bytes()` is preserved across scope layer
+        use actix_http::body::MessageBody as _;
+        let req = TestRequest::with_uri("/app/test").to_request();
+        let resp = call_service(&srv, req).await;
+        let body = resp.into_body();
+        assert_eq!(body.try_into_bytes().unwrap(), b"hello".as_ref());
+    }
+
+    #[actix_rt::test]
+    async fn test_middleware_fn() {
+        let srv = init_service(
+            App::new().service(
+                web::scope("app")
+                    .wrap_fn(|req, srv| {
+                        let fut = srv.call(req);
+                        async move {
+                            let mut res = fut.await?;
+                            res.headers_mut()
+                                .insert(header::CONTENT_TYPE, HeaderValue::from_static("0001"));
+                            Ok(res)
+                        }
+                    })
+                    .route("/test", web::get().to(HttpResponse::Ok)),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/app/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        assert_eq!(
+            resp.headers().get(header::CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("0001")
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_middleware_app_data() {
+        let srv = init_service(
+            App::new().service(
+                web::scope("app")
+                    .app_data(1usize)
+                    .wrap_fn(|req, srv| {
+                        assert_eq!(req.app_data::<usize>(), Some(&1usize));
+                        req.extensions_mut().insert(1usize);
+                        srv.call(req)
+                    })
+                    .route("/test", web::get().to(HttpResponse::Ok))
+                    .default_service(|req: ServiceRequest| async move {
+                        let (req, _) = req.into_parts();
+
+                        assert_eq!(req.extensions().get::<usize>(), Some(&1));
+
+                        Ok(ServiceResponse::new(
+                            req,
+                            HttpResponse::BadRequest().finish(),
+                        ))
+                    }),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/app/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/app/default").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+    }
+
+    // allow deprecated {App, Scope}::data
+    #[allow(deprecated)]
+    #[actix_rt::test]
+    async fn test_override_data() {
+        let srv = init_service(App::new().data(1usize).service(
+            web::scope("app").data(10usize).route(
+                "/t",
+                web::get().to(|data: web::Data<usize>| {
+                    assert_eq!(**data, 10);
+                    HttpResponse::Ok()
+                }),
+            ),
+        ))
+        .await;
+
+        let req = TestRequest::with_uri("/app/t").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    // allow deprecated `{App, Scope}::data`
+    #[allow(deprecated)]
+    #[actix_rt::test]
+    async fn test_override_data_default_service() {
+        let srv =
+            init_service(App::new().data(1usize).service(
+                web::scope("app").data(10usize).default_service(web::to(
+                    |data: web::Data<usize>| {
+                        assert_eq!(**data, 10);
+                        HttpResponse::Ok()
+                    },
+                )),
+            ))
+            .await;
+
+        let req = TestRequest::with_uri("/app/t").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_override_app_data() {
+        let srv = init_service(App::new().app_data(web::Data::new(1usize)).service(
+            web::scope("app").app_data(web::Data::new(10usize)).route(
+                "/t",
+                web::get().to(|data: web::Data<usize>| {
+                    assert_eq!(**data, 10);
+                    HttpResponse::Ok()
+                }),
+            ),
+        ))
+        .await;
+
+        let req = TestRequest::with_uri("/app/t").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_scope_config() {
+        let srv = init_service(App::new().service(web::scope("/app").configure(|s| {
+            s.route("/path1", web::get().to(HttpResponse::Ok));
+        })))
+        .await;
+
+        let req = TestRequest::with_uri("/app/path1").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_scope_config_2() {
+        let srv = init_service(App::new().service(web::scope("/app").configure(|s| {
+            s.service(web::scope("/v1").configure(|s| {
+                s.route("/", web::get().to(HttpResponse::Ok));
+            }));
+        })))
+        .await;
+
+        let req = TestRequest::with_uri("/app/v1/").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_url_for_external() {
+        let srv = init_service(App::new().service(web::scope("/app").configure(|s| {
+            s.service(web::scope("/v1").configure(|s| {
+                s.external_resource("youtube", "https://youtube.com/watch/{video_id}");
+                s.route(
+                    "/",
+                    web::get().to(|req: HttpRequest| {
+                        HttpResponse::Ok()
+                            .body(req.url_for("youtube", ["xxxxxx"]).unwrap().to_string())
+                    }),
+                );
+            }));
+        })))
+        .await;
+
+        let req = TestRequest::with_uri("/app/v1/").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), StatusCode::OK);
+        let body = read_body(resp).await;
+        assert_eq!(body, &b"https://youtube.com/watch/xxxxxx"[..]);
+    }
+
+    #[actix_rt::test]
+    async fn test_url_for_nested() {
+        let srv = init_service(App::new().service(web::scope("/a").service(
+            web::scope("/b").service(web::resource("/c/{stuff}").name("c").route(web::get().to(
+                |req: HttpRequest| {
+                    HttpResponse::Ok().body(format!("{}", req.url_for("c", ["12345"]).unwrap()))
+                },
+            ))),
+        )))
+        .await;
+
+        let req = TestRequest::with_uri("/a/b/c/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+        let body = read_body(resp).await;
+        assert_eq!(
+            body,
+            Bytes::from_static(b"http://localhost:8080/a/b/c/12345")
+        );
+    }
+
+    #[actix_rt::test]
+    async fn dynamic_scopes() {
+        let srv = init_service(
+            App::new().service(
+                web::scope("/{a}/").service(
+                    web::scope("/{b}/")
+                        .route("", web::get().to(|_: HttpRequest| HttpResponse::Created()))
+                        .route(
+                            "/",
+                            web::get().to(|_: HttpRequest| HttpResponse::Accepted()),
+                        )
+                        .route("/{c}", web::get().to(|_: HttpRequest| HttpResponse::Ok())),
+                ),
+            ),
+        )
+        .await;
+
+        // note the unintuitive behavior with trailing slashes on scopes with dynamic segments
+        let req = TestRequest::with_uri("/a//b//c").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/a//b/").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::CREATED);
+
+        let req = TestRequest::with_uri("/a//b//").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::ACCEPTED);
+
+        let req = TestRequest::with_uri("/a//b//c/d").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+
+        let srv = init_service(
+            App::new().service(
+                web::scope("/{a}").service(
+                    web::scope("/{b}")
+                        .route("", web::get().to(|_: HttpRequest| HttpResponse::Created()))
+                        .route(
+                            "/",
+                            web::get().to(|_: HttpRequest| HttpResponse::Accepted()),
+                        )
+                        .route("/{c}", web::get().to(|_: HttpRequest| HttpResponse::Ok())),
+                ),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/a/b/c").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/a/b").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::CREATED);
+
+        let req = TestRequest::with_uri("/a/b/").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::ACCEPTED);
+
+        let req = TestRequest::with_uri("/a/b/c/d").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::NOT_FOUND);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/server.rs.html b/src/actix_web/server.rs.html new file mode 100644 index 000000000..b3184955c --- /dev/null +++ b/src/actix_web/server.rs.html @@ -0,0 +1,2255 @@ +server.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
+
use std::{
+    any::Any,
+    cmp, fmt, io,
+    marker::PhantomData,
+    net,
+    sync::{Arc, Mutex},
+    time::Duration,
+};
+
+#[cfg(any(
+    feature = "openssl",
+    feature = "rustls-0_20",
+    feature = "rustls-0_21",
+    feature = "rustls-0_22",
+    feature = "rustls-0_23",
+))]
+use actix_http::TlsAcceptorConfig;
+use actix_http::{body::MessageBody, Extensions, HttpService, KeepAlive, Request, Response};
+use actix_server::{Server, ServerBuilder};
+use actix_service::{
+    map_config, IntoServiceFactory, Service, ServiceFactory, ServiceFactoryExt as _,
+};
+#[cfg(feature = "openssl")]
+use actix_tls::accept::openssl::reexports::{AlpnError, SslAcceptor, SslAcceptorBuilder};
+
+use crate::{config::AppConfig, Error};
+
+struct Socket {
+    scheme: &'static str,
+    addr: net::SocketAddr,
+}
+
+struct Config {
+    host: Option<String>,
+    keep_alive: KeepAlive,
+    client_request_timeout: Duration,
+    client_disconnect_timeout: Duration,
+    #[allow(dead_code)] // only dead when no TLS features are enabled
+    tls_handshake_timeout: Option<Duration>,
+}
+
+/// An HTTP Server.
+///
+/// Create new HTTP server with application factory.
+///
+/// # Automatic HTTP Version Selection
+///
+/// There are two ways to select the HTTP version of an incoming connection:
+///
+/// - One is to rely on the ALPN information that is provided when using a TLS (HTTPS); both
+///   versions are supported automatically when using either of the `.bind_rustls()` or
+///   `.bind_openssl()` methods.
+/// - The other is to read the first few bytes of the TCP stream. This is the only viable approach
+///   for supporting H2C, which allows the HTTP/2 protocol to work over plaintext connections. Use
+///   the `.bind_auto_h2c()` method to enable this behavior.
+///
+/// # Examples
+///
+/// ```no_run
+/// use actix_web::{web, App, HttpResponse, HttpServer};
+///
+/// #[actix_web::main]
+/// async fn main() -> std::io::Result<()> {
+///     HttpServer::new(|| {
+///         App::new()
+///             .service(web::resource("/").to(|| async { "hello world" }))
+///     })
+///     .bind(("127.0.0.1", 8080))?
+///     .run()
+///     .await
+/// }
+/// ```
+pub struct HttpServer<F, I, S, B>
+where
+    F: Fn() -> I + Send + Clone + 'static,
+    I: IntoServiceFactory<S, Request>,
+    S: ServiceFactory<Request, Config = AppConfig>,
+    S::Error: Into<Error>,
+    S::InitError: fmt::Debug,
+    S::Response: Into<Response<B>>,
+    B: MessageBody,
+{
+    pub(super) factory: F,
+    config: Arc<Mutex<Config>>,
+    backlog: u32,
+    sockets: Vec<Socket>,
+    builder: ServerBuilder,
+    #[allow(clippy::type_complexity)]
+    on_connect_fn: Option<Arc<dyn Fn(&dyn Any, &mut Extensions) + Send + Sync>>,
+    _phantom: PhantomData<(S, B)>,
+}
+
+impl<F, I, S, B> HttpServer<F, I, S, B>
+where
+    F: Fn() -> I + Send + Clone + 'static,
+    I: IntoServiceFactory<S, Request>,
+
+    S: ServiceFactory<Request, Config = AppConfig> + 'static,
+    S::Error: Into<Error> + 'static,
+    S::InitError: fmt::Debug,
+    S::Response: Into<Response<B>> + 'static,
+    <S::Service as Service<Request>>::Future: 'static,
+    S::Service: 'static,
+
+    B: MessageBody + 'static,
+{
+    /// Create new HTTP server with application factory
+    ///
+    /// # Worker Count
+    ///
+    /// The `factory` will be instantiated multiple times in most configurations. See
+    /// [`bind()`](Self::bind()) docs for more on how worker count and bind address resolution
+    /// causes multiple server factory instantiations.
+    pub fn new(factory: F) -> Self {
+        HttpServer {
+            factory,
+            config: Arc::new(Mutex::new(Config {
+                host: None,
+                keep_alive: KeepAlive::default(),
+                client_request_timeout: Duration::from_secs(5),
+                client_disconnect_timeout: Duration::from_secs(1),
+                tls_handshake_timeout: None,
+            })),
+            backlog: 1024,
+            sockets: Vec::new(),
+            builder: ServerBuilder::default(),
+            on_connect_fn: None,
+            _phantom: PhantomData,
+        }
+    }
+
+    /// Sets number of workers to start (per bind address).
+    ///
+    /// The default worker count is the determined by [`std::thread::available_parallelism()`]. See
+    /// its documentation to determine what behavior you should expect when server is run.
+    ///
+    /// Note that the server factory passed to [`new`](Self::new()) will be instantiated **at least
+    /// once per worker**. See [`bind()`](Self::bind()) docs for more on how worker count and bind
+    /// address resolution causes multiple server factory instantiations.
+    ///
+    /// `num` must be greater than 0.
+    ///
+    /// # Panics
+    ///
+    /// Panics if `num` is 0.
+    pub fn workers(mut self, num: usize) -> Self {
+        self.builder = self.builder.workers(num);
+        self
+    }
+
+    /// Sets server keep-alive preference.
+    ///
+    /// By default keep-alive is set to 5 seconds.
+    pub fn keep_alive<T: Into<KeepAlive>>(self, val: T) -> Self {
+        self.config.lock().unwrap().keep_alive = val.into();
+        self
+    }
+
+    /// Sets the maximum number of pending connections.
+    ///
+    /// This refers to the number of clients that can be waiting to be served. Exceeding this number
+    /// results in the client getting an error when attempting to connect. It should only affect
+    /// servers under significant load.
+    ///
+    /// Generally set in the 64–2048 range. Default value is 2048.
+    ///
+    /// This method will have no effect if called after a `bind()`.
+    pub fn backlog(mut self, backlog: u32) -> Self {
+        self.backlog = backlog;
+        self.builder = self.builder.backlog(backlog);
+        self
+    }
+
+    /// Sets the per-worker maximum number of concurrent connections.
+    ///
+    /// All socket listeners will stop accepting connections when this limit is reached for
+    /// each worker.
+    ///
+    /// By default max connections is set to a 25k.
+    pub fn max_connections(mut self, num: usize) -> Self {
+        self.builder = self.builder.max_concurrent_connections(num);
+        self
+    }
+
+    /// Sets the per-worker maximum concurrent TLS connection limit.
+    ///
+    /// All listeners will stop accepting connections when this limit is reached. It can be used to
+    /// limit the global TLS CPU usage.
+    ///
+    /// By default max connections is set to a 256.
+    #[allow(unused_variables)]
+    pub fn max_connection_rate(self, num: usize) -> Self {
+        #[cfg(any(feature = "rustls-0_20", feature = "rustls-0_21", feature = "openssl"))]
+        actix_tls::accept::max_concurrent_tls_connect(num);
+        self
+    }
+
+    /// Sets max number of threads for each worker's blocking task thread pool.
+    ///
+    /// One thread pool is set up **per worker**; not shared across workers.
+    ///
+    /// By default set to 512 divided by the number of workers.
+    pub fn worker_max_blocking_threads(mut self, num: usize) -> Self {
+        self.builder = self.builder.worker_max_blocking_threads(num);
+        self
+    }
+
+    /// Sets server client timeout for first request.
+    ///
+    /// Defines a timeout for reading client request head. If a client does not transmit the entire
+    /// set headers within this time, the request is terminated with a 408 (Request Timeout) error.
+    ///
+    /// To disable timeout set value to 0.
+    ///
+    /// By default client timeout is set to 5000 milliseconds.
+    pub fn client_request_timeout(self, dur: Duration) -> Self {
+        self.config.lock().unwrap().client_request_timeout = dur;
+        self
+    }
+
+    #[doc(hidden)]
+    #[deprecated(since = "4.0.0", note = "Renamed to `client_request_timeout`.")]
+    pub fn client_timeout(self, dur: Duration) -> Self {
+        self.client_request_timeout(dur)
+    }
+
+    /// Sets server connection shutdown timeout.
+    ///
+    /// Defines a timeout for connection shutdown. If a shutdown procedure does not complete within
+    /// this time, the request is dropped.
+    ///
+    /// To disable timeout set value to 0.
+    ///
+    /// By default client timeout is set to 5000 milliseconds.
+    pub fn client_disconnect_timeout(self, dur: Duration) -> Self {
+        self.config.lock().unwrap().client_disconnect_timeout = dur;
+        self
+    }
+
+    /// Sets TLS handshake timeout.
+    ///
+    /// Defines a timeout for TLS handshake. If the TLS handshake does not complete within this
+    /// time, the connection is closed.
+    ///
+    /// By default, the handshake timeout is 3 seconds.
+    #[cfg(any(
+        feature = "openssl",
+        feature = "rustls-0_20",
+        feature = "rustls-0_21",
+        feature = "rustls-0_22",
+        feature = "rustls-0_23",
+    ))]
+    pub fn tls_handshake_timeout(self, dur: Duration) -> Self {
+        self.config
+            .lock()
+            .unwrap()
+            .tls_handshake_timeout
+            .replace(dur);
+
+        self
+    }
+
+    #[doc(hidden)]
+    #[deprecated(since = "4.0.0", note = "Renamed to `client_disconnect_timeout`.")]
+    pub fn client_shutdown(self, dur: u64) -> Self {
+        self.client_disconnect_timeout(Duration::from_millis(dur))
+    }
+
+    /// Sets function that will be called once before each connection is handled.
+    ///
+    /// It will receive a `&std::any::Any`, which contains underlying connection type and an
+    /// [Extensions] container so that connection data can be accessed in middleware and handlers.
+    ///
+    /// # Connection Types
+    /// - `actix_tls::accept::openssl::TlsStream<actix_web::rt::net::TcpStream>` when using OpenSSL.
+    /// - `actix_tls::accept::rustls_0_20::TlsStream<actix_web::rt::net::TcpStream>` when using
+    ///   Rustls v0.20.
+    /// - `actix_tls::accept::rustls_0_21::TlsStream<actix_web::rt::net::TcpStream>` when using
+    ///   Rustls v0.21.
+    /// - `actix_tls::accept::rustls_0_22::TlsStream<actix_web::rt::net::TcpStream>` when using
+    ///   Rustls v0.22.
+    /// - `actix_tls::accept::rustls_0_23::TlsStream<actix_web::rt::net::TcpStream>` when using
+    ///   Rustls v0.23.
+    /// - `actix_web::rt::net::TcpStream` when no encryption is used.
+    ///
+    /// See the `on_connect` example for additional details.
+    pub fn on_connect<CB>(self, f: CB) -> HttpServer<F, I, S, B>
+    where
+        CB: Fn(&dyn Any, &mut Extensions) + Send + Sync + 'static,
+    {
+        HttpServer {
+            factory: self.factory,
+            config: self.config,
+            backlog: self.backlog,
+            sockets: self.sockets,
+            builder: self.builder,
+            on_connect_fn: Some(Arc::new(f)),
+            _phantom: PhantomData,
+        }
+    }
+
+    /// Sets server host name.
+    ///
+    /// Host name is used by application router as a hostname for url generation. Check
+    /// [`ConnectionInfo`](crate::dev::ConnectionInfo::host()) docs for more info.
+    ///
+    /// By default, hostname is set to "localhost".
+    pub fn server_hostname<T: AsRef<str>>(self, val: T) -> Self {
+        self.config.lock().unwrap().host = Some(val.as_ref().to_owned());
+        self
+    }
+
+    /// Flags the `System` to exit after server shutdown.
+    ///
+    /// Does nothing when running under `#[tokio::main]` runtime.
+    pub fn system_exit(mut self) -> Self {
+        self.builder = self.builder.system_exit();
+        self
+    }
+
+    /// Disables signal handling.
+    pub fn disable_signals(mut self) -> Self {
+        self.builder = self.builder.disable_signals();
+        self
+    }
+
+    /// Sets timeout for graceful worker shutdown of workers.
+    ///
+    /// After receiving a stop signal, workers have this much time to finish serving requests.
+    /// Workers still alive after the timeout are force dropped.
+    ///
+    /// By default shutdown timeout sets to 30 seconds.
+    pub fn shutdown_timeout(mut self, sec: u64) -> Self {
+        self.builder = self.builder.shutdown_timeout(sec);
+        self
+    }
+
+    /// Returns addresses of bound sockets.
+    pub fn addrs(&self) -> Vec<net::SocketAddr> {
+        self.sockets.iter().map(|s| s.addr).collect()
+    }
+
+    /// Returns addresses of bound sockets and the scheme for it.
+    ///
+    /// This is useful when the server is bound from different sources with some sockets listening
+    /// on HTTP and some listening on HTTPS and the user should be presented with an enumeration of
+    /// which socket requires which protocol.
+    pub fn addrs_with_scheme(&self) -> Vec<(net::SocketAddr, &str)> {
+        self.sockets.iter().map(|s| (s.addr, s.scheme)).collect()
+    }
+
+    /// Resolves socket address(es) and binds server to created listener(s).
+    ///
+    /// # Hostname Resolution
+    ///
+    /// When `addrs` includes a hostname, it is possible for this method to bind to both the IPv4
+    /// and IPv6 addresses that result from a DNS lookup. You can test this by passing
+    /// `localhost:8080` and noting that the server binds to `127.0.0.1:8080` _and_ `[::1]:8080`. To
+    /// bind additional addresses, call this method multiple times.
+    ///
+    /// Note that, if a DNS lookup is required, resolving hostnames is a blocking operation.
+    ///
+    /// # Worker Count
+    ///
+    /// The `factory` will be instantiated multiple times in most scenarios. The number of
+    /// instantiations is number of [`workers`](Self::workers()) × number of sockets resolved by
+    /// `addrs`.
+    ///
+    /// For example, if you've manually set [`workers`](Self::workers()) to 2, and use `127.0.0.1`
+    /// as the bind `addrs`, then `factory` will be instantiated twice. However, using `localhost`
+    /// as the bind `addrs` can often resolve to both `127.0.0.1` (IPv4) _and_ `::1` (IPv6), causing
+    /// the `factory` to be instantiated 4 times (2 workers × 2 bind addresses).
+    ///
+    /// Using a bind address of `0.0.0.0`, which signals to use all interfaces, may also multiple
+    /// the number of instantiations in a similar way.
+    ///
+    /// # Typical Usage
+    ///
+    /// In general, use `127.0.0.1:<port>` when testing locally and `0.0.0.0:<port>` when deploying
+    /// (with or without a reverse proxy or load balancer) so that the server is accessible.
+    ///
+    /// # Errors
+    ///
+    /// Returns an `io::Error` if:
+    /// - `addrs` cannot be resolved into one or more socket addresses;
+    /// - all the resolved socket addresses are already bound.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # use actix_web::{App, HttpServer};
+    /// # fn inner() -> std::io::Result<()> {
+    /// HttpServer::new(|| App::new())
+    ///     .bind(("127.0.0.1", 8080))?
+    ///     .bind("[::1]:9000")?
+    /// # ; Ok(()) }
+    /// ```
+    pub fn bind<A: net::ToSocketAddrs>(mut self, addrs: A) -> io::Result<Self> {
+        let sockets = bind_addrs(addrs, self.backlog)?;
+
+        for lst in sockets {
+            self = self.listen(lst)?;
+        }
+
+        Ok(self)
+    }
+
+    /// Resolves socket address(es) and binds server to created listener(s) for plaintext HTTP/1.x
+    /// or HTTP/2 connections.
+    ///
+    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
+    #[cfg(feature = "http2")]
+    pub fn bind_auto_h2c<A: net::ToSocketAddrs>(mut self, addrs: A) -> io::Result<Self> {
+        let sockets = bind_addrs(addrs, self.backlog)?;
+
+        for lst in sockets {
+            self = self.listen_auto_h2c(lst)?;
+        }
+
+        Ok(self)
+    }
+
+    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
+    /// using Rustls v0.20.
+    ///
+    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
+    ///
+    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
+    #[cfg(feature = "rustls-0_20")]
+    pub fn bind_rustls<A: net::ToSocketAddrs>(
+        mut self,
+        addrs: A,
+        config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
+    ) -> io::Result<Self> {
+        let sockets = bind_addrs(addrs, self.backlog)?;
+        for lst in sockets {
+            self = self.listen_rustls_0_20_inner(lst, config.clone())?;
+        }
+        Ok(self)
+    }
+
+    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
+    /// using Rustls v0.21.
+    ///
+    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
+    ///
+    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
+    #[cfg(feature = "rustls-0_21")]
+    pub fn bind_rustls_021<A: net::ToSocketAddrs>(
+        mut self,
+        addrs: A,
+        config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
+    ) -> io::Result<Self> {
+        let sockets = bind_addrs(addrs, self.backlog)?;
+        for lst in sockets {
+            self = self.listen_rustls_0_21_inner(lst, config.clone())?;
+        }
+        Ok(self)
+    }
+
+    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
+    /// using Rustls v0.22.
+    ///
+    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
+    ///
+    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
+    #[cfg(feature = "rustls-0_22")]
+    pub fn bind_rustls_0_22<A: net::ToSocketAddrs>(
+        mut self,
+        addrs: A,
+        config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
+    ) -> io::Result<Self> {
+        let sockets = bind_addrs(addrs, self.backlog)?;
+        for lst in sockets {
+            self = self.listen_rustls_0_22_inner(lst, config.clone())?;
+        }
+        Ok(self)
+    }
+
+    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
+    /// using Rustls v0.23.
+    ///
+    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
+    ///
+    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
+    #[cfg(feature = "rustls-0_23")]
+    pub fn bind_rustls_0_23<A: net::ToSocketAddrs>(
+        mut self,
+        addrs: A,
+        config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
+    ) -> io::Result<Self> {
+        let sockets = bind_addrs(addrs, self.backlog)?;
+        for lst in sockets {
+            self = self.listen_rustls_0_23_inner(lst, config.clone())?;
+        }
+        Ok(self)
+    }
+
+    /// Resolves socket address(es) and binds server to created listener(s) for TLS connections
+    /// using OpenSSL.
+    ///
+    /// See [`bind()`](Self::bind()) for more details on `addrs` argument.
+    ///
+    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
+    #[cfg(feature = "openssl")]
+    pub fn bind_openssl<A>(mut self, addrs: A, builder: SslAcceptorBuilder) -> io::Result<Self>
+    where
+        A: net::ToSocketAddrs,
+    {
+        let sockets = bind_addrs(addrs, self.backlog)?;
+        let acceptor = openssl_acceptor(builder)?;
+
+        for lst in sockets {
+            self = self.listen_openssl_inner(lst, acceptor.clone())?;
+        }
+
+        Ok(self)
+    }
+
+    /// Binds to existing listener for accepting incoming connection requests.
+    ///
+    /// No changes are made to `lst`'s configuration. Ensure it is configured properly before
+    /// passing ownership to `listen()`.
+    pub fn listen(mut self, lst: net::TcpListener) -> io::Result<Self> {
+        let cfg = self.config.clone();
+        let factory = self.factory.clone();
+        let addr = lst.local_addr().unwrap();
+
+        self.sockets.push(Socket {
+            addr,
+            scheme: "http",
+        });
+
+        let on_connect_fn = self.on_connect_fn.clone();
+
+        self.builder =
+            self.builder
+                .listen(format!("actix-web-service-{}", addr), lst, move || {
+                    let cfg = cfg.lock().unwrap();
+                    let host = cfg.host.clone().unwrap_or_else(|| format!("{}", addr));
+
+                    let mut svc = HttpService::build()
+                        .keep_alive(cfg.keep_alive)
+                        .client_request_timeout(cfg.client_request_timeout)
+                        .client_disconnect_timeout(cfg.client_disconnect_timeout)
+                        .local_addr(addr);
+
+                    if let Some(handler) = on_connect_fn.clone() {
+                        svc =
+                            svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
+                    };
+
+                    let fac = factory()
+                        .into_factory()
+                        .map_err(|err| err.into().error_response());
+
+                    svc.finish(map_config(fac, move |_| {
+                        AppConfig::new(false, host.clone(), addr)
+                    }))
+                    .tcp()
+                })?;
+
+        Ok(self)
+    }
+
+    /// Binds to existing listener for accepting incoming plaintext HTTP/1.x or HTTP/2 connections.
+    #[cfg(feature = "http2")]
+    pub fn listen_auto_h2c(mut self, lst: net::TcpListener) -> io::Result<Self> {
+        let cfg = self.config.clone();
+        let factory = self.factory.clone();
+        let addr = lst.local_addr().unwrap();
+
+        self.sockets.push(Socket {
+            addr,
+            scheme: "http",
+        });
+
+        let on_connect_fn = self.on_connect_fn.clone();
+
+        self.builder =
+            self.builder
+                .listen(format!("actix-web-service-{}", addr), lst, move || {
+                    let cfg = cfg.lock().unwrap();
+                    let host = cfg.host.clone().unwrap_or_else(|| format!("{}", addr));
+
+                    let mut svc = HttpService::build()
+                        .keep_alive(cfg.keep_alive)
+                        .client_request_timeout(cfg.client_request_timeout)
+                        .client_disconnect_timeout(cfg.client_disconnect_timeout)
+                        .local_addr(addr);
+
+                    if let Some(handler) = on_connect_fn.clone() {
+                        svc =
+                            svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
+                    };
+
+                    let fac = factory()
+                        .into_factory()
+                        .map_err(|err| err.into().error_response());
+
+                    svc.finish(map_config(fac, move |_| {
+                        AppConfig::new(false, host.clone(), addr)
+                    }))
+                    .tcp_auto_h2c()
+                })?;
+
+        Ok(self)
+    }
+
+    /// Binds to existing listener for accepting incoming TLS connection requests using Rustls
+    /// v0.20.
+    ///
+    /// See [`listen()`](Self::listen) for more details on the `lst` argument.
+    ///
+    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
+    #[cfg(feature = "rustls-0_20")]
+    pub fn listen_rustls(
+        self,
+        lst: net::TcpListener,
+        config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
+    ) -> io::Result<Self> {
+        self.listen_rustls_0_20_inner(lst, config)
+    }
+
+    /// Binds to existing listener for accepting incoming TLS connection requests using Rustls
+    /// v0.21.
+    ///
+    /// See [`listen()`](Self::listen()) for more details on the `lst` argument.
+    ///
+    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
+    #[cfg(feature = "rustls-0_21")]
+    pub fn listen_rustls_0_21(
+        self,
+        lst: net::TcpListener,
+        config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
+    ) -> io::Result<Self> {
+        self.listen_rustls_0_21_inner(lst, config)
+    }
+
+    #[cfg(feature = "rustls-0_20")]
+    fn listen_rustls_0_20_inner(
+        mut self,
+        lst: net::TcpListener,
+        config: actix_tls::accept::rustls_0_20::reexports::ServerConfig,
+    ) -> io::Result<Self> {
+        let factory = self.factory.clone();
+        let cfg = self.config.clone();
+        let addr = lst.local_addr().unwrap();
+        self.sockets.push(Socket {
+            addr,
+            scheme: "https",
+        });
+
+        let on_connect_fn = self.on_connect_fn.clone();
+
+        self.builder =
+            self.builder
+                .listen(format!("actix-web-service-{}", addr), lst, move || {
+                    let c = cfg.lock().unwrap();
+                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
+
+                    let svc = HttpService::build()
+                        .keep_alive(c.keep_alive)
+                        .client_request_timeout(c.client_request_timeout)
+                        .client_disconnect_timeout(c.client_disconnect_timeout);
+
+                    let svc = if let Some(handler) = on_connect_fn.clone() {
+                        svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
+                    } else {
+                        svc
+                    };
+
+                    let fac = factory()
+                        .into_factory()
+                        .map_err(|err| err.into().error_response());
+
+                    let acceptor_config = match c.tls_handshake_timeout {
+                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
+                        None => TlsAcceptorConfig::default(),
+                    };
+
+                    svc.finish(map_config(fac, move |_| {
+                        AppConfig::new(true, host.clone(), addr)
+                    }))
+                    .rustls_with_config(config.clone(), acceptor_config)
+                })?;
+
+        Ok(self)
+    }
+
+    #[cfg(feature = "rustls-0_21")]
+    fn listen_rustls_0_21_inner(
+        mut self,
+        lst: net::TcpListener,
+        config: actix_tls::accept::rustls_0_21::reexports::ServerConfig,
+    ) -> io::Result<Self> {
+        let factory = self.factory.clone();
+        let cfg = self.config.clone();
+        let addr = lst.local_addr().unwrap();
+        self.sockets.push(Socket {
+            addr,
+            scheme: "https",
+        });
+
+        let on_connect_fn = self.on_connect_fn.clone();
+
+        self.builder =
+            self.builder
+                .listen(format!("actix-web-service-{}", addr), lst, move || {
+                    let c = cfg.lock().unwrap();
+                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
+
+                    let svc = HttpService::build()
+                        .keep_alive(c.keep_alive)
+                        .client_request_timeout(c.client_request_timeout)
+                        .client_disconnect_timeout(c.client_disconnect_timeout);
+
+                    let svc = if let Some(handler) = on_connect_fn.clone() {
+                        svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
+                    } else {
+                        svc
+                    };
+
+                    let fac = factory()
+                        .into_factory()
+                        .map_err(|err| err.into().error_response());
+
+                    let acceptor_config = match c.tls_handshake_timeout {
+                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
+                        None => TlsAcceptorConfig::default(),
+                    };
+
+                    svc.finish(map_config(fac, move |_| {
+                        AppConfig::new(true, host.clone(), addr)
+                    }))
+                    .rustls_021_with_config(config.clone(), acceptor_config)
+                })?;
+
+        Ok(self)
+    }
+
+    /// Binds to existing listener for accepting incoming TLS connection requests using Rustls
+    /// v0.22.
+    ///
+    /// See [`listen()`](Self::listen()) for more details on the `lst` argument.
+    ///
+    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
+    #[cfg(feature = "rustls-0_22")]
+    pub fn listen_rustls_0_22(
+        self,
+        lst: net::TcpListener,
+        config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
+    ) -> io::Result<Self> {
+        self.listen_rustls_0_22_inner(lst, config)
+    }
+
+    #[cfg(feature = "rustls-0_22")]
+    fn listen_rustls_0_22_inner(
+        mut self,
+        lst: net::TcpListener,
+        config: actix_tls::accept::rustls_0_22::reexports::ServerConfig,
+    ) -> io::Result<Self> {
+        let factory = self.factory.clone();
+        let cfg = self.config.clone();
+        let addr = lst.local_addr().unwrap();
+        self.sockets.push(Socket {
+            addr,
+            scheme: "https",
+        });
+
+        let on_connect_fn = self.on_connect_fn.clone();
+
+        self.builder =
+            self.builder
+                .listen(format!("actix-web-service-{}", addr), lst, move || {
+                    let c = cfg.lock().unwrap();
+                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
+
+                    let svc = HttpService::build()
+                        .keep_alive(c.keep_alive)
+                        .client_request_timeout(c.client_request_timeout)
+                        .client_disconnect_timeout(c.client_disconnect_timeout);
+
+                    let svc = if let Some(handler) = on_connect_fn.clone() {
+                        svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
+                    } else {
+                        svc
+                    };
+
+                    let fac = factory()
+                        .into_factory()
+                        .map_err(|err| err.into().error_response());
+
+                    let acceptor_config = match c.tls_handshake_timeout {
+                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
+                        None => TlsAcceptorConfig::default(),
+                    };
+
+                    svc.finish(map_config(fac, move |_| {
+                        AppConfig::new(true, host.clone(), addr)
+                    }))
+                    .rustls_0_22_with_config(config.clone(), acceptor_config)
+                })?;
+
+        Ok(self)
+    }
+
+    /// Binds to existing listener for accepting incoming TLS connection requests using Rustls
+    /// v0.23.
+    ///
+    /// See [`listen()`](Self::listen()) for more details on the `lst` argument.
+    ///
+    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
+    #[cfg(feature = "rustls-0_23")]
+    pub fn listen_rustls_0_23(
+        self,
+        lst: net::TcpListener,
+        config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
+    ) -> io::Result<Self> {
+        self.listen_rustls_0_23_inner(lst, config)
+    }
+
+    #[cfg(feature = "rustls-0_23")]
+    fn listen_rustls_0_23_inner(
+        mut self,
+        lst: net::TcpListener,
+        config: actix_tls::accept::rustls_0_23::reexports::ServerConfig,
+    ) -> io::Result<Self> {
+        let factory = self.factory.clone();
+        let cfg = self.config.clone();
+        let addr = lst.local_addr().unwrap();
+        self.sockets.push(Socket {
+            addr,
+            scheme: "https",
+        });
+
+        let on_connect_fn = self.on_connect_fn.clone();
+
+        self.builder =
+            self.builder
+                .listen(format!("actix-web-service-{}", addr), lst, move || {
+                    let c = cfg.lock().unwrap();
+                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
+
+                    let svc = HttpService::build()
+                        .keep_alive(c.keep_alive)
+                        .client_request_timeout(c.client_request_timeout)
+                        .client_disconnect_timeout(c.client_disconnect_timeout);
+
+                    let svc = if let Some(handler) = on_connect_fn.clone() {
+                        svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
+                    } else {
+                        svc
+                    };
+
+                    let fac = factory()
+                        .into_factory()
+                        .map_err(|err| err.into().error_response());
+
+                    let acceptor_config = match c.tls_handshake_timeout {
+                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
+                        None => TlsAcceptorConfig::default(),
+                    };
+
+                    svc.finish(map_config(fac, move |_| {
+                        AppConfig::new(true, host.clone(), addr)
+                    }))
+                    .rustls_0_23_with_config(config.clone(), acceptor_config)
+                })?;
+
+        Ok(self)
+    }
+
+    /// Binds to existing listener for accepting incoming TLS connection requests using OpenSSL.
+    ///
+    /// See [`listen()`](Self::listen) for more details on the `lst` argument.
+    ///
+    /// ALPN protocols "h2" and "http/1.1" are added to any configured ones.
+    #[cfg(feature = "openssl")]
+    pub fn listen_openssl(
+        self,
+        lst: net::TcpListener,
+        builder: SslAcceptorBuilder,
+    ) -> io::Result<Self> {
+        self.listen_openssl_inner(lst, openssl_acceptor(builder)?)
+    }
+
+    #[cfg(feature = "openssl")]
+    fn listen_openssl_inner(
+        mut self,
+        lst: net::TcpListener,
+        acceptor: SslAcceptor,
+    ) -> io::Result<Self> {
+        let factory = self.factory.clone();
+        let cfg = self.config.clone();
+        let addr = lst.local_addr().unwrap();
+        self.sockets.push(Socket {
+            addr,
+            scheme: "https",
+        });
+
+        let on_connect_fn = self.on_connect_fn.clone();
+
+        self.builder =
+            self.builder
+                .listen(format!("actix-web-service-{}", addr), lst, move || {
+                    let c = cfg.lock().unwrap();
+                    let host = c.host.clone().unwrap_or_else(|| format!("{}", addr));
+
+                    let svc = HttpService::build()
+                        .keep_alive(c.keep_alive)
+                        .client_request_timeout(c.client_request_timeout)
+                        .client_disconnect_timeout(c.client_disconnect_timeout)
+                        .local_addr(addr);
+
+                    let svc = if let Some(handler) = on_connect_fn.clone() {
+                        svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext))
+                    } else {
+                        svc
+                    };
+
+                    let fac = factory()
+                        .into_factory()
+                        .map_err(|err| err.into().error_response());
+
+                    // false positive lint (?)
+                    #[allow(clippy::significant_drop_in_scrutinee)]
+                    let acceptor_config = match c.tls_handshake_timeout {
+                        Some(dur) => TlsAcceptorConfig::default().handshake_timeout(dur),
+                        None => TlsAcceptorConfig::default(),
+                    };
+
+                    svc.finish(map_config(fac, move |_| {
+                        AppConfig::new(true, host.clone(), addr)
+                    }))
+                    .openssl_with_config(acceptor.clone(), acceptor_config)
+                })?;
+
+        Ok(self)
+    }
+
+    /// Opens Unix Domain Socket (UDS) from `uds` path and binds server to created listener.
+    #[cfg(unix)]
+    pub fn bind_uds<A>(mut self, uds_path: A) -> io::Result<Self>
+    where
+        A: AsRef<std::path::Path>,
+    {
+        use actix_http::Protocol;
+        use actix_rt::net::UnixStream;
+        use actix_service::{fn_service, ServiceFactoryExt as _};
+
+        let cfg = self.config.clone();
+        let factory = self.factory.clone();
+        let socket_addr =
+            net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080);
+
+        self.sockets.push(Socket {
+            scheme: "http",
+            addr: socket_addr,
+        });
+
+        self.builder = self.builder.bind_uds(
+            format!("actix-web-service-{:?}", uds_path.as_ref()),
+            uds_path,
+            move || {
+                let c = cfg.lock().unwrap();
+                let config = AppConfig::new(
+                    false,
+                    c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)),
+                    socket_addr,
+                );
+
+                let fac = factory()
+                    .into_factory()
+                    .map_err(|err| err.into().error_response());
+
+                fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then(
+                    HttpService::build()
+                        .keep_alive(c.keep_alive)
+                        .client_request_timeout(c.client_request_timeout)
+                        .client_disconnect_timeout(c.client_disconnect_timeout)
+                        .finish(map_config(fac, move |_| config.clone())),
+                )
+            },
+        )?;
+
+        Ok(self)
+    }
+
+    /// Binds to existing Unix Domain Socket (UDS) listener.
+    #[cfg(unix)]
+    pub fn listen_uds(mut self, lst: std::os::unix::net::UnixListener) -> io::Result<Self> {
+        use actix_http::Protocol;
+        use actix_rt::net::UnixStream;
+        use actix_service::{fn_service, ServiceFactoryExt as _};
+
+        let cfg = self.config.clone();
+        let factory = self.factory.clone();
+        let socket_addr =
+            net::SocketAddr::new(net::IpAddr::V4(net::Ipv4Addr::new(127, 0, 0, 1)), 8080);
+        self.sockets.push(Socket {
+            scheme: "http",
+            addr: socket_addr,
+        });
+
+        let addr = lst.local_addr()?;
+        let name = format!("actix-web-service-{:?}", addr);
+        let on_connect_fn = self.on_connect_fn.clone();
+
+        self.builder = self.builder.listen_uds(name, lst, move || {
+            let c = cfg.lock().unwrap();
+            let config = AppConfig::new(
+                false,
+                c.host.clone().unwrap_or_else(|| format!("{}", socket_addr)),
+                socket_addr,
+            );
+
+            fn_service(|io: UnixStream| async { Ok((io, Protocol::Http1, None)) }).and_then({
+                let mut svc = HttpService::build()
+                    .keep_alive(c.keep_alive)
+                    .client_request_timeout(c.client_request_timeout)
+                    .client_disconnect_timeout(c.client_disconnect_timeout);
+
+                if let Some(handler) = on_connect_fn.clone() {
+                    svc = svc.on_connect_ext(move |io: &_, ext: _| (handler)(io as &dyn Any, ext));
+                }
+
+                let fac = factory()
+                    .into_factory()
+                    .map_err(|err| err.into().error_response());
+
+                svc.finish(map_config(fac, move |_| config.clone()))
+            })
+        })?;
+        Ok(self)
+    }
+}
+
+impl<F, I, S, B> HttpServer<F, I, S, B>
+where
+    F: Fn() -> I + Send + Clone + 'static,
+    I: IntoServiceFactory<S, Request>,
+    S: ServiceFactory<Request, Config = AppConfig>,
+    S::Error: Into<Error>,
+    S::InitError: fmt::Debug,
+    S::Response: Into<Response<B>>,
+    S::Service: 'static,
+    B: MessageBody,
+{
+    /// Start listening for incoming connections.
+    ///
+    /// # Workers
+    /// This method starts a number of HTTP workers in separate threads. The number of workers in a
+    /// set is defined by [`workers()`](Self::workers) or, by default, the number of the machine's
+    /// physical cores. One worker set is created for each socket address to be bound. For example,
+    /// if workers is set to 4, and there are 2 addresses to bind, then 8 worker threads will be
+    /// spawned.
+    ///
+    /// # Panics
+    /// This methods panics if no socket addresses were successfully bound or if no Tokio runtime
+    /// is set up.
+    pub fn run(self) -> Server {
+        self.builder.run()
+    }
+}
+
+/// Bind TCP listeners to socket addresses resolved from `addrs` with options.
+fn bind_addrs(addrs: impl net::ToSocketAddrs, backlog: u32) -> io::Result<Vec<net::TcpListener>> {
+    let mut err = None;
+    let mut success = false;
+    let mut sockets = Vec::new();
+
+    for addr in addrs.to_socket_addrs()? {
+        match create_tcp_listener(addr, backlog) {
+            Ok(lst) => {
+                success = true;
+                sockets.push(lst);
+            }
+            Err(error) => err = Some(error),
+        }
+    }
+
+    if success {
+        Ok(sockets)
+    } else if let Some(err) = err.take() {
+        Err(err)
+    } else {
+        Err(io::Error::new(
+            io::ErrorKind::Other,
+            "Can not bind to address.",
+        ))
+    }
+}
+
+/// Creates a TCP listener from socket address and options.
+fn create_tcp_listener(addr: net::SocketAddr, backlog: u32) -> io::Result<net::TcpListener> {
+    use socket2::{Domain, Protocol, Socket, Type};
+    let domain = Domain::for_address(addr);
+    let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))?;
+    socket.set_reuse_address(true)?;
+    socket.bind(&addr.into())?;
+    // clamp backlog to max u32 that fits in i32 range
+    let backlog = cmp::min(backlog, i32::MAX as u32) as i32;
+    socket.listen(backlog)?;
+    Ok(net::TcpListener::from(socket))
+}
+
+/// Configures OpenSSL acceptor `builder` with ALPN protocols.
+#[cfg(feature = "openssl")]
+fn openssl_acceptor(mut builder: SslAcceptorBuilder) -> io::Result<SslAcceptor> {
+    builder.set_alpn_select_callback(|_, protocols| {
+        const H2: &[u8] = b"\x02h2";
+        const H11: &[u8] = b"\x08http/1.1";
+
+        if protocols.windows(3).any(|window| window == H2) {
+            Ok(b"h2")
+        } else if protocols.windows(9).any(|window| window == H11) {
+            Ok(b"http/1.1")
+        } else {
+            Err(AlpnError::NOACK)
+        }
+    });
+
+    builder.set_alpn_protos(b"\x08http/1.1\x02h2")?;
+
+    Ok(builder.build())
+}
+
\ No newline at end of file diff --git a/src/actix_web/service.rs.html b/src/actix_web/service.rs.html new file mode 100644 index 000000000..8b0784076 --- /dev/null +++ b/src/actix_web/service.rs.html @@ -0,0 +1,1747 @@ +service.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
+
use std::{
+    cell::{Ref, RefMut},
+    fmt, net,
+    rc::Rc,
+};
+
+use actix_http::{
+    body::{BoxBody, EitherBody, MessageBody},
+    header::HeaderMap,
+    BoxedPayloadStream, Extensions, HttpMessage, Method, Payload, RequestHead, Response,
+    ResponseHead, StatusCode, Uri, Version,
+};
+use actix_router::{IntoPatterns, Path, Patterns, Resource, ResourceDef, Url};
+use actix_service::{
+    boxed::{BoxService, BoxServiceFactory},
+    IntoServiceFactory, ServiceFactory,
+};
+#[cfg(feature = "cookies")]
+use cookie::{Cookie, ParseError as CookieParseError};
+
+use crate::{
+    config::{AppConfig, AppService},
+    dev::ensure_leading_slash,
+    guard::{Guard, GuardContext},
+    info::ConnectionInfo,
+    rmap::ResourceMap,
+    Error, FromRequest, HttpRequest, HttpResponse,
+};
+
+pub(crate) type BoxedHttpService = BoxService<ServiceRequest, ServiceResponse<BoxBody>, Error>;
+pub(crate) type BoxedHttpServiceFactory =
+    BoxServiceFactory<(), ServiceRequest, ServiceResponse<BoxBody>, Error, ()>;
+
+pub trait HttpServiceFactory {
+    fn register(self, config: &mut AppService);
+}
+
+impl<T: HttpServiceFactory> HttpServiceFactory for Vec<T> {
+    fn register(self, config: &mut AppService) {
+        self.into_iter()
+            .for_each(|factory| factory.register(config));
+    }
+}
+
+pub(crate) trait AppServiceFactory {
+    fn register(&mut self, config: &mut AppService);
+}
+
+pub(crate) struct ServiceFactoryWrapper<T> {
+    factory: Option<T>,
+}
+
+impl<T> ServiceFactoryWrapper<T> {
+    pub fn new(factory: T) -> Self {
+        Self {
+            factory: Some(factory),
+        }
+    }
+}
+
+impl<T> AppServiceFactory for ServiceFactoryWrapper<T>
+where
+    T: HttpServiceFactory,
+{
+    fn register(&mut self, config: &mut AppService) {
+        if let Some(item) = self.factory.take() {
+            item.register(config)
+        }
+    }
+}
+
+/// A service level request wrapper.
+///
+/// Allows mutable access to request's internal structures.
+pub struct ServiceRequest {
+    req: HttpRequest,
+    payload: Payload,
+}
+
+impl ServiceRequest {
+    /// Construct `ServiceRequest` from parts.
+    pub(crate) fn new(req: HttpRequest, payload: Payload) -> Self {
+        Self { req, payload }
+    }
+
+    /// Deconstruct `ServiceRequest` into inner parts.
+    #[inline]
+    pub fn into_parts(self) -> (HttpRequest, Payload) {
+        (self.req, self.payload)
+    }
+
+    /// Returns mutable accessors to inner parts.
+    #[inline]
+    pub fn parts_mut(&mut self) -> (&mut HttpRequest, &mut Payload) {
+        (&mut self.req, &mut self.payload)
+    }
+
+    /// Returns immutable accessors to inner parts.
+    #[inline]
+    pub fn parts(&self) -> (&HttpRequest, &Payload) {
+        (&self.req, &self.payload)
+    }
+
+    /// Returns immutable accessor to inner [`HttpRequest`].
+    #[inline]
+    pub fn request(&self) -> &HttpRequest {
+        &self.req
+    }
+
+    /// Derives a type from this request using an [extractor](crate::FromRequest).
+    ///
+    /// Returns the `T` extractor's `Future` type which can be `await`ed. This is particularly handy
+    /// when you want to use an extractor in a middleware implementation.
+    ///
+    /// # Examples
+    /// ```
+    /// use actix_web::{
+    ///     dev::{ServiceRequest, ServiceResponse},
+    ///     web::Path, Error
+    /// };
+    ///
+    /// async fn my_helper(mut srv_req: ServiceRequest) -> Result<ServiceResponse, Error> {
+    ///     let path = srv_req.extract::<Path<(String, u32)>>().await?;
+    ///     // [...]
+    /// #   todo!()
+    /// }
+    /// ```
+    pub fn extract<T>(&mut self) -> <T as FromRequest>::Future
+    where
+        T: FromRequest,
+    {
+        T::from_request(&self.req, &mut self.payload)
+    }
+
+    /// Construct request from parts.
+    pub fn from_parts(req: HttpRequest, payload: Payload) -> Self {
+        #[cfg(debug_assertions)]
+        if Rc::strong_count(&req.inner) > 1 {
+            log::warn!("Cloning an `HttpRequest` might cause panics.");
+        }
+
+        Self { req, payload }
+    }
+
+    /// Construct `ServiceRequest` with no payload from given `HttpRequest`.
+    #[inline]
+    pub fn from_request(req: HttpRequest) -> Self {
+        ServiceRequest {
+            req,
+            payload: Payload::None,
+        }
+    }
+
+    /// Create `ServiceResponse` from this request and given response.
+    #[inline]
+    pub fn into_response<B, R: Into<Response<B>>>(self, res: R) -> ServiceResponse<B> {
+        let res = HttpResponse::from(res.into());
+        ServiceResponse::new(self.req, res)
+    }
+
+    /// Create `ServiceResponse` from this request and given error.
+    #[inline]
+    pub fn error_response<E: Into<Error>>(self, err: E) -> ServiceResponse {
+        let res = HttpResponse::from_error(err.into());
+        ServiceResponse::new(self.req, res)
+    }
+
+    /// Returns a reference to the request head.
+    #[inline]
+    pub fn head(&self) -> &RequestHead {
+        self.req.head()
+    }
+
+    /// Returns a mutable reference to the request head.
+    #[inline]
+    pub fn head_mut(&mut self) -> &mut RequestHead {
+        self.req.head_mut()
+    }
+
+    /// Returns the request URI.
+    #[inline]
+    pub fn uri(&self) -> &Uri {
+        &self.head().uri
+    }
+
+    /// Returns the request method.
+    #[inline]
+    pub fn method(&self) -> &Method {
+        &self.head().method
+    }
+
+    /// Returns the request version.
+    #[inline]
+    pub fn version(&self) -> Version {
+        self.head().version
+    }
+
+    /// Returns a reference to request headers.
+    #[inline]
+    pub fn headers(&self) -> &HeaderMap {
+        &self.head().headers
+    }
+
+    /// Returns a mutable reference to request headers.
+    #[inline]
+    pub fn headers_mut(&mut self) -> &mut HeaderMap {
+        &mut self.head_mut().headers
+    }
+
+    /// Returns request path.
+    #[inline]
+    pub fn path(&self) -> &str {
+        self.head().uri.path()
+    }
+
+    /// Counterpart to [`HttpRequest::query_string`].
+    #[inline]
+    pub fn query_string(&self) -> &str {
+        self.req.query_string()
+    }
+
+    /// Returns peer's socket address.
+    ///
+    /// See [`HttpRequest::peer_addr`] for more details.
+    ///
+    /// [`HttpRequest::peer_addr`]: crate::HttpRequest::peer_addr
+    #[inline]
+    pub fn peer_addr(&self) -> Option<net::SocketAddr> {
+        self.head().peer_addr
+    }
+
+    /// Returns a reference to connection info.
+    #[inline]
+    pub fn connection_info(&self) -> Ref<'_, ConnectionInfo> {
+        self.req.connection_info()
+    }
+
+    /// Counterpart to [`HttpRequest::match_info`].
+    #[inline]
+    pub fn match_info(&self) -> &Path<Url> {
+        self.req.match_info()
+    }
+
+    /// Returns a mutable reference to the path match information.
+    #[inline]
+    pub fn match_info_mut(&mut self) -> &mut Path<Url> {
+        self.req.match_info_mut()
+    }
+
+    /// Counterpart to [`HttpRequest::match_name`].
+    #[inline]
+    pub fn match_name(&self) -> Option<&str> {
+        self.req.match_name()
+    }
+
+    /// Counterpart to [`HttpRequest::match_pattern`].
+    #[inline]
+    pub fn match_pattern(&self) -> Option<String> {
+        self.req.match_pattern()
+    }
+
+    /// Returns a reference to the application's resource map.
+    /// Counterpart to [`HttpRequest::resource_map`].
+    #[inline]
+    pub fn resource_map(&self) -> &ResourceMap {
+        self.req.resource_map()
+    }
+
+    /// Counterpart to [`HttpRequest::app_config`].
+    #[inline]
+    pub fn app_config(&self) -> &AppConfig {
+        self.req.app_config()
+    }
+
+    /// Counterpart to [`HttpRequest::app_data`].
+    #[inline]
+    pub fn app_data<T: 'static>(&self) -> Option<&T> {
+        for container in self.req.inner.app_data.iter().rev() {
+            if let Some(data) = container.get::<T>() {
+                return Some(data);
+            }
+        }
+
+        None
+    }
+
+    /// Counterpart to [`HttpRequest::conn_data`].
+    #[inline]
+    pub fn conn_data<T: 'static>(&self) -> Option<&T> {
+        self.req.conn_data()
+    }
+
+    /// Return request cookies.
+    #[cfg(feature = "cookies")]
+    #[inline]
+    pub fn cookies(&self) -> Result<Ref<'_, Vec<Cookie<'static>>>, CookieParseError> {
+        self.req.cookies()
+    }
+
+    /// Return request cookie.
+    #[cfg(feature = "cookies")]
+    #[inline]
+    pub fn cookie(&self, name: &str) -> Option<Cookie<'static>> {
+        self.req.cookie(name)
+    }
+
+    /// Set request payload.
+    #[inline]
+    pub fn set_payload(&mut self, payload: Payload) {
+        self.payload = payload;
+    }
+
+    /// Add data container to request's resolution set.
+    ///
+    /// In middleware, prefer [`extensions_mut`](ServiceRequest::extensions_mut) for request-local
+    /// data since it is assumed that the same app data is presented for every request.
+    pub fn add_data_container(&mut self, extensions: Rc<Extensions>) {
+        Rc::get_mut(&mut (self.req).inner)
+            .unwrap()
+            .app_data
+            .push(extensions);
+    }
+
+    /// Creates a context object for use with a routing [guard](crate::guard).
+    #[inline]
+    pub fn guard_ctx(&self) -> GuardContext<'_> {
+        GuardContext { req: self }
+    }
+}
+
+impl Resource for ServiceRequest {
+    type Path = Url;
+
+    #[inline]
+    fn resource_path(&mut self) -> &mut Path<Self::Path> {
+        self.match_info_mut()
+    }
+}
+
+impl HttpMessage for ServiceRequest {
+    type Stream = BoxedPayloadStream;
+
+    #[inline]
+    fn headers(&self) -> &HeaderMap {
+        &self.head().headers
+    }
+
+    #[inline]
+    fn extensions(&self) -> Ref<'_, Extensions> {
+        self.req.extensions()
+    }
+
+    #[inline]
+    fn extensions_mut(&self) -> RefMut<'_, Extensions> {
+        self.req.extensions_mut()
+    }
+
+    #[inline]
+    fn take_payload(&mut self) -> Payload<Self::Stream> {
+        self.payload.take()
+    }
+}
+
+impl fmt::Debug for ServiceRequest {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        writeln!(
+            f,
+            "\nServiceRequest {:?} {}:{}",
+            self.head().version,
+            self.head().method,
+            self.path()
+        )?;
+        if !self.query_string().is_empty() {
+            writeln!(f, "  query: ?{:?}", self.query_string())?;
+        }
+        if !self.match_info().is_empty() {
+            writeln!(f, "  params: {:?}", self.match_info())?;
+        }
+        writeln!(f, "  headers:")?;
+        for (key, val) in self.headers().iter() {
+            writeln!(f, "    {:?}: {:?}", key, val)?;
+        }
+        Ok(())
+    }
+}
+
+/// A service level response wrapper.
+pub struct ServiceResponse<B = BoxBody> {
+    request: HttpRequest,
+    response: HttpResponse<B>,
+}
+
+impl ServiceResponse<BoxBody> {
+    /// Create service response from the error
+    pub fn from_err<E: Into<Error>>(err: E, request: HttpRequest) -> Self {
+        let response = HttpResponse::from_error(err);
+        ServiceResponse { request, response }
+    }
+}
+
+impl<B> ServiceResponse<B> {
+    /// Create service response instance
+    pub fn new(request: HttpRequest, response: HttpResponse<B>) -> Self {
+        ServiceResponse { request, response }
+    }
+
+    /// Create service response for error
+    #[inline]
+    pub fn error_response<E: Into<Error>>(self, err: E) -> ServiceResponse {
+        ServiceResponse::from_err(err, self.request)
+    }
+
+    /// Create service response
+    #[inline]
+    pub fn into_response<B1>(self, response: HttpResponse<B1>) -> ServiceResponse<B1> {
+        ServiceResponse::new(self.request, response)
+    }
+
+    /// Returns reference to original request.
+    #[inline]
+    pub fn request(&self) -> &HttpRequest {
+        &self.request
+    }
+
+    /// Returns reference to response.
+    #[inline]
+    pub fn response(&self) -> &HttpResponse<B> {
+        &self.response
+    }
+
+    /// Returns mutable reference to response.
+    #[inline]
+    pub fn response_mut(&mut self) -> &mut HttpResponse<B> {
+        &mut self.response
+    }
+
+    /// Returns response status code.
+    #[inline]
+    pub fn status(&self) -> StatusCode {
+        self.response.status()
+    }
+
+    /// Returns response's headers.
+    #[inline]
+    pub fn headers(&self) -> &HeaderMap {
+        self.response.headers()
+    }
+
+    /// Returns mutable response's headers.
+    #[inline]
+    pub fn headers_mut(&mut self) -> &mut HeaderMap {
+        self.response.headers_mut()
+    }
+
+    /// Destructures `ServiceResponse` into request and response components.
+    #[inline]
+    pub fn into_parts(self) -> (HttpRequest, HttpResponse<B>) {
+        (self.request, self.response)
+    }
+
+    /// Map the current body type to another using a closure. Returns a new response.
+    ///
+    /// Closure receives the response head and the current body type.
+    #[inline]
+    pub fn map_body<F, B2>(self, f: F) -> ServiceResponse<B2>
+    where
+        F: FnOnce(&mut ResponseHead, B) -> B2,
+    {
+        let response = self.response.map_body(f);
+
+        ServiceResponse {
+            response,
+            request: self.request,
+        }
+    }
+
+    #[inline]
+    pub fn map_into_left_body<R>(self) -> ServiceResponse<EitherBody<B, R>> {
+        self.map_body(|_, body| EitherBody::left(body))
+    }
+
+    #[inline]
+    pub fn map_into_right_body<L>(self) -> ServiceResponse<EitherBody<L, B>> {
+        self.map_body(|_, body| EitherBody::right(body))
+    }
+
+    #[inline]
+    pub fn map_into_boxed_body(self) -> ServiceResponse<BoxBody>
+    where
+        B: MessageBody + 'static,
+    {
+        self.map_body(|_, body| body.boxed())
+    }
+
+    /// Consumes the response and returns its body.
+    #[inline]
+    pub fn into_body(self) -> B {
+        self.response.into_body()
+    }
+}
+
+impl<B> From<ServiceResponse<B>> for HttpResponse<B> {
+    fn from(res: ServiceResponse<B>) -> HttpResponse<B> {
+        res.response
+    }
+}
+
+impl<B> From<ServiceResponse<B>> for Response<B> {
+    fn from(res: ServiceResponse<B>) -> Response<B> {
+        res.response.into()
+    }
+}
+
+impl<B> fmt::Debug for ServiceResponse<B>
+where
+    B: MessageBody,
+    B::Error: Into<Error>,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let res = writeln!(
+            f,
+            "\nServiceResponse {:?} {}{}",
+            self.response.head().version,
+            self.response.head().status,
+            self.response.head().reason.unwrap_or(""),
+        );
+        let _ = writeln!(f, "  headers:");
+        for (key, val) in self.response.head().headers.iter() {
+            let _ = writeln!(f, "    {:?}: {:?}", key, val);
+        }
+        let _ = writeln!(f, "  body: {:?}", self.response.body().size());
+        res
+    }
+}
+
+pub struct WebService {
+    rdef: Patterns,
+    name: Option<String>,
+    guards: Vec<Box<dyn Guard>>,
+}
+
+impl WebService {
+    /// Create new `WebService` instance.
+    pub fn new<T: IntoPatterns>(path: T) -> Self {
+        WebService {
+            rdef: path.patterns(),
+            name: None,
+            guards: Vec::new(),
+        }
+    }
+
+    /// Set service name.
+    ///
+    /// Name is used for URL generation.
+    pub fn name(mut self, name: &str) -> Self {
+        self.name = Some(name.to_string());
+        self
+    }
+
+    /// Add match guard to a web service.
+    ///
+    /// ```
+    /// use actix_web::{web, guard, dev, App, Error, HttpResponse};
+    ///
+    /// async fn index(req: dev::ServiceRequest) -> Result<dev::ServiceResponse, Error> {
+    ///     Ok(req.into_response(HttpResponse::Ok().finish()))
+    /// }
+    ///
+    /// let app = App::new()
+    ///     .service(
+    ///         web::service("/app")
+    ///             .guard(guard::Header("content-type", "text/plain"))
+    ///             .finish(index)
+    ///     );
+    /// ```
+    pub fn guard<G: Guard + 'static>(mut self, guard: G) -> Self {
+        self.guards.push(Box::new(guard));
+        self
+    }
+
+    /// Set a service factory implementation and generate web service.
+    pub fn finish<T, F>(self, service: F) -> impl HttpServiceFactory
+    where
+        F: IntoServiceFactory<T, ServiceRequest>,
+        T: ServiceFactory<
+                ServiceRequest,
+                Config = (),
+                Response = ServiceResponse,
+                Error = Error,
+                InitError = (),
+            > + 'static,
+    {
+        WebServiceImpl {
+            srv: service.into_factory(),
+            rdef: self.rdef,
+            name: self.name,
+            guards: self.guards,
+        }
+    }
+}
+
+struct WebServiceImpl<T> {
+    srv: T,
+    rdef: Patterns,
+    name: Option<String>,
+    guards: Vec<Box<dyn Guard>>,
+}
+
+impl<T> HttpServiceFactory for WebServiceImpl<T>
+where
+    T: ServiceFactory<
+            ServiceRequest,
+            Config = (),
+            Response = ServiceResponse,
+            Error = Error,
+            InitError = (),
+        > + 'static,
+{
+    fn register(mut self, config: &mut AppService) {
+        let guards = if self.guards.is_empty() {
+            None
+        } else {
+            Some(std::mem::take(&mut self.guards))
+        };
+
+        let mut rdef = if config.is_root() || !self.rdef.is_empty() {
+            ResourceDef::new(ensure_leading_slash(self.rdef))
+        } else {
+            ResourceDef::new(self.rdef)
+        };
+
+        if let Some(ref name) = self.name {
+            rdef.set_name(name);
+        }
+
+        config.register_service(rdef, guards, self.srv, None)
+    }
+}
+
+/// Macro to help register different types of services at the same time.
+///
+/// The max number of services that can be grouped together is 12 and all must implement the
+/// [`HttpServiceFactory`] trait.
+///
+/// # Examples
+/// ```
+/// use actix_web::{services, web, App};
+///
+/// let services = services![
+///     web::resource("/test2").to(|| async { "test2" }),
+///     web::scope("/test3").route("/", web::get().to(|| async { "test3" }))
+/// ];
+///
+/// let app = App::new().service(services);
+///
+/// // services macro just convert multiple services to a tuple.
+/// // below would also work without importing the macro.
+/// let app = App::new().service((
+///     web::resource("/test2").to(|| async { "test2" }),
+///     web::scope("/test3").route("/", web::get().to(|| async { "test3" }))
+/// ));
+/// ```
+#[macro_export]
+macro_rules! services {
+    ($($x:expr),+ $(,)?) => {
+        ($($x,)+)
+    }
+}
+
+/// HttpServiceFactory trait impl for tuples
+macro_rules! service_tuple ({ $($T:ident)+ } => {
+    impl<$($T: HttpServiceFactory),+> HttpServiceFactory for ($($T,)+) {
+        #[allow(non_snake_case)]
+        fn register(self, config: &mut AppService) {
+            let ($($T,)*) = self;
+            $($T.register(config);)+
+        }
+    }
+});
+
+service_tuple! { A }
+service_tuple! { A B }
+service_tuple! { A B C }
+service_tuple! { A B C D }
+service_tuple! { A B C D E }
+service_tuple! { A B C D E F }
+service_tuple! { A B C D E F G }
+service_tuple! { A B C D E F G H }
+service_tuple! { A B C D E F G H I }
+service_tuple! { A B C D E F G H I J }
+service_tuple! { A B C D E F G H I J K }
+service_tuple! { A B C D E F G H I J K L }
+
+#[cfg(test)]
+mod tests {
+    use actix_service::Service;
+    use actix_utils::future::ok;
+
+    use super::*;
+    use crate::{
+        guard, http,
+        test::{self, init_service, TestRequest},
+        web, App,
+    };
+
+    #[actix_rt::test]
+    async fn test_service() {
+        let srv =
+            init_service(
+                App::new().service(web::service("/test").name("test").finish(
+                    |req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())),
+                )),
+            )
+            .await;
+        let req = TestRequest::with_uri("/test").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), http::StatusCode::OK);
+
+        let srv =
+            init_service(
+                App::new().service(web::service("/test").guard(guard::Get()).finish(
+                    |req: ServiceRequest| ok(req.into_response(HttpResponse::Ok().finish())),
+                )),
+            )
+            .await;
+        let req = TestRequest::with_uri("/test")
+            .method(http::Method::PUT)
+            .to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), http::StatusCode::NOT_FOUND);
+    }
+
+    // allow deprecated App::data
+    #[allow(deprecated)]
+    #[actix_rt::test]
+    async fn test_service_data() {
+        let srv = init_service(
+            App::new()
+                .data(42u32)
+                .service(
+                    web::service("/test")
+                        .name("test")
+                        .finish(|req: ServiceRequest| {
+                            assert_eq!(req.app_data::<web::Data<u32>>().unwrap().as_ref(), &42);
+                            ok(req.into_response(HttpResponse::Ok().finish()))
+                        }),
+                ),
+        )
+        .await;
+        let req = TestRequest::with_uri("/test").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), http::StatusCode::OK);
+    }
+
+    #[test]
+    fn test_fmt_debug() {
+        let req = TestRequest::get()
+            .uri("/index.html?test=1")
+            .insert_header(("x-test", "111"))
+            .to_srv_request();
+        let s = format!("{:?}", req);
+        assert!(s.contains("ServiceRequest"));
+        assert!(s.contains("test=1"));
+        assert!(s.contains("x-test"));
+
+        let res = HttpResponse::Ok().insert_header(("x-test", "111")).finish();
+        let res = TestRequest::post()
+            .uri("/index.html?test=1")
+            .to_srv_response(res);
+
+        let s = format!("{:?}", res);
+        assert!(s.contains("ServiceResponse"));
+        assert!(s.contains("x-test"));
+    }
+
+    #[actix_rt::test]
+    async fn test_services_macro() {
+        let scoped = services![
+            web::service("/scoped_test1").name("scoped_test1").finish(
+                |req: ServiceRequest| async { Ok(req.into_response(HttpResponse::Ok().finish())) }
+            ),
+            web::resource("/scoped_test2").to(|| async { "test2" }),
+        ];
+
+        let services = services![
+            web::service("/test1")
+                .name("test")
+                .finish(|req: ServiceRequest| async {
+                    Ok(req.into_response(HttpResponse::Ok().finish()))
+                }),
+            web::resource("/test2").to(|| async { "test2" }),
+            web::scope("/test3").service(scoped)
+        ];
+
+        let srv = init_service(App::new().service(services)).await;
+
+        let req = TestRequest::with_uri("/test1").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), http::StatusCode::OK);
+
+        let req = TestRequest::with_uri("/test2").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), http::StatusCode::OK);
+
+        let req = TestRequest::with_uri("/test3/scoped_test1").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), http::StatusCode::OK);
+
+        let req = TestRequest::with_uri("/test3/scoped_test2").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), http::StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_services_vec() {
+        let services = vec![
+            web::resource("/test1").to(|| async { "test1" }),
+            web::resource("/test2").to(|| async { "test2" }),
+        ];
+
+        let scoped = vec![
+            web::resource("/scoped_test1").to(|| async { "test1" }),
+            web::resource("/scoped_test2").to(|| async { "test2" }),
+        ];
+
+        let srv = init_service(
+            App::new()
+                .service(services)
+                .service(web::scope("/test3").service(scoped)),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/test1").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), http::StatusCode::OK);
+
+        let req = TestRequest::with_uri("/test2").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), http::StatusCode::OK);
+
+        let req = TestRequest::with_uri("/test3/scoped_test1").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), http::StatusCode::OK);
+
+        let req = TestRequest::with_uri("/test3/scoped_test2").to_request();
+        let resp = srv.call(req).await.unwrap();
+        assert_eq!(resp.status(), http::StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    #[should_panic(expected = "called `Option::unwrap()` on a `None` value")]
+    async fn cloning_request_panics() {
+        async fn index(_name: web::Path<(String,)>) -> &'static str {
+            ""
+        }
+
+        let app = test::init_service(
+            App::new()
+                .wrap_fn(|req, svc| {
+                    let (req, pl) = req.into_parts();
+                    let _req2 = req.clone();
+                    let req = ServiceRequest::from_parts(req, pl);
+                    svc.call(req)
+                })
+                .route("/", web::get().to(|| async { "" }))
+                .service(web::resource("/resource1/{name}/index.html").route(web::get().to(index))),
+        )
+        .await;
+
+        let req = test::TestRequest::default().to_request();
+        let _res = test::call_service(&app, req).await;
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/test/mod.rs.html b/src/actix_web/test/mod.rs.html new file mode 100644 index 000000000..fe6930096 --- /dev/null +++ b/src/actix_web/test/mod.rs.html @@ -0,0 +1,177 @@ +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
+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
+
//! Various helpers for Actix applications to use during testing.
+//!
+//! # Creating A Test Service
+//! - [`init_service`]
+//!
+//! # Off-The-Shelf Test Services
+//! - [`ok_service`]
+//! - [`status_service`]
+//!
+//! # Calling Test Service
+//! - [`TestRequest`]
+//! - [`call_service`]
+//! - [`try_call_service`]
+//! - [`call_and_read_body`]
+//! - [`call_and_read_body_json`]
+//! - [`try_call_and_read_body_json`]
+//!
+//! # Reading Response Payloads
+//! - [`read_body`]
+//! - [`try_read_body`]
+//! - [`read_body_json`]
+//! - [`try_read_body_json`]
+
+// TODO: more docs on generally how testing works with these parts
+
+pub use actix_http::test::TestBuffer;
+
+mod test_request;
+mod test_services;
+mod test_utils;
+
+#[allow(deprecated)]
+pub use self::test_services::{default_service, ok_service, simple_service, status_service};
+#[cfg(test)]
+pub(crate) use self::test_utils::try_init_service;
+#[allow(deprecated)]
+pub use self::test_utils::{read_response, read_response_json};
+pub use self::{
+    test_request::TestRequest,
+    test_utils::{
+        call_and_read_body, call_and_read_body_json, call_service, init_service, read_body,
+        read_body_json, try_call_and_read_body_json, try_call_service, try_read_body,
+        try_read_body_json,
+    },
+};
+
+/// Reduces boilerplate code when testing expected response payloads.
+///
+/// Must be used inside an async test. Works for both `ServiceRequest` and `HttpRequest`.
+///
+/// # Examples
+/// ```
+/// use actix_web::{http::StatusCode, HttpResponse};
+///
+/// let res = HttpResponse::with_body(StatusCode::OK, "http response");
+/// assert_body_eq!(res, b"http response");
+/// ```
+#[cfg(test)]
+macro_rules! assert_body_eq {
+    ($res:ident, $expected:expr) => {
+        assert_eq!(
+            ::actix_http::body::to_bytes($res.into_body())
+                .await
+                .expect("error reading test response body"),
+            ::bytes::Bytes::from_static($expected),
+        )
+    };
+}
+
+#[cfg(test)]
+pub(crate) use assert_body_eq;
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::{http::StatusCode, service::ServiceResponse, HttpResponse};
+
+    #[actix_rt::test]
+    async fn assert_body_works_for_service_and_regular_response() {
+        let res = HttpResponse::with_body(StatusCode::OK, "http response");
+        assert_body_eq!(res, b"http response");
+
+        let req = TestRequest::default().to_http_request();
+        let res = HttpResponse::with_body(StatusCode::OK, "service response");
+        let res = ServiceResponse::new(req, res);
+        assert_body_eq!(res, b"service response");
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/test/test_request.rs.html b/src/actix_web/test/test_request.rs.html new file mode 100644 index 000000000..22d31e149 --- /dev/null +++ b/src/actix_web/test/test_request.rs.html @@ -0,0 +1,889 @@ +test_request.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
+
use std::{borrow::Cow, net::SocketAddr, rc::Rc};
+
+use actix_http::{test::TestRequest as HttpTestRequest, Request};
+use serde::Serialize;
+
+#[cfg(feature = "cookies")]
+use crate::cookie::{Cookie, CookieJar};
+use crate::{
+    app_service::AppInitServiceState,
+    config::AppConfig,
+    data::Data,
+    dev::{Extensions, Path, Payload, ResourceDef, Service, Url},
+    http::{
+        header::{ContentType, TryIntoHeaderPair},
+        Method, Uri, Version,
+    },
+    rmap::ResourceMap,
+    service::{ServiceRequest, ServiceResponse},
+    test,
+    web::Bytes,
+    HttpRequest, HttpResponse,
+};
+
+/// Test `Request` builder.
+///
+/// For unit testing, actix provides a request builder type and a simple handler runner. TestRequest implements a builder-like pattern.
+/// You can generate various types of request via TestRequest's methods:
+/// - [`TestRequest::to_request`] creates an [`actix_http::Request`](Request).
+/// - [`TestRequest::to_srv_request`] creates a [`ServiceRequest`], which is used for testing middlewares and chain adapters.
+/// - [`TestRequest::to_srv_response`] creates a [`ServiceResponse`].
+/// - [`TestRequest::to_http_request`] creates an [`HttpRequest`], which is used for testing handlers.
+///
+/// ```
+/// use actix_web::{test, HttpRequest, HttpResponse, HttpMessage};
+/// use actix_web::http::{header, StatusCode};
+///
+/// async fn handler(req: HttpRequest) -> HttpResponse {
+///     if let Some(hdr) = req.headers().get(header::CONTENT_TYPE) {
+///         HttpResponse::Ok().into()
+///     } else {
+///         HttpResponse::BadRequest().into()
+///     }
+/// }
+///
+/// #[actix_web::test]
+/// # // force rustdoc to display the correct thing and also compile check the test
+/// # async fn _test() {}
+/// async fn test_index() {
+///     let req = test::TestRequest::default()
+///         .insert_header(header::ContentType::plaintext())
+///         .to_http_request();
+///
+///     let resp = handler(req).await;
+///     assert_eq!(resp.status(), StatusCode::OK);
+///
+///     let req = test::TestRequest::default().to_http_request();
+///     let resp = handler(req).await;
+///     assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+/// }
+/// ```
+pub struct TestRequest {
+    req: HttpTestRequest,
+    rmap: ResourceMap,
+    config: AppConfig,
+    path: Path<Url>,
+    peer_addr: Option<SocketAddr>,
+    app_data: Extensions,
+    #[cfg(feature = "cookies")]
+    cookies: CookieJar,
+}
+
+impl Default for TestRequest {
+    fn default() -> TestRequest {
+        TestRequest {
+            req: HttpTestRequest::default(),
+            rmap: ResourceMap::new(ResourceDef::new("")),
+            config: AppConfig::default(),
+            path: Path::new(Url::new(Uri::default())),
+            peer_addr: None,
+            app_data: Extensions::new(),
+            #[cfg(feature = "cookies")]
+            cookies: CookieJar::new(),
+        }
+    }
+}
+
+#[allow(clippy::wrong_self_convention)]
+impl TestRequest {
+    /// Constructs test request and sets request URI.
+    pub fn with_uri(uri: &str) -> TestRequest {
+        TestRequest::default().uri(uri)
+    }
+
+    /// Constructs test request with GET method.
+    pub fn get() -> TestRequest {
+        TestRequest::default().method(Method::GET)
+    }
+
+    /// Constructs test request with POST method.
+    pub fn post() -> TestRequest {
+        TestRequest::default().method(Method::POST)
+    }
+
+    /// Constructs test request with PUT method.
+    pub fn put() -> TestRequest {
+        TestRequest::default().method(Method::PUT)
+    }
+
+    /// Constructs test request with PATCH method.
+    pub fn patch() -> TestRequest {
+        TestRequest::default().method(Method::PATCH)
+    }
+
+    /// Constructs test request with DELETE method.
+    pub fn delete() -> TestRequest {
+        TestRequest::default().method(Method::DELETE)
+    }
+
+    /// Sets HTTP version of this request.
+    pub fn version(mut self, ver: Version) -> Self {
+        self.req.version(ver);
+        self
+    }
+
+    /// Sets method of this request.
+    pub fn method(mut self, meth: Method) -> Self {
+        self.req.method(meth);
+        self
+    }
+
+    /// Sets URI of this request.
+    pub fn uri(mut self, path: &str) -> Self {
+        self.req.uri(path);
+        self
+    }
+
+    /// Inserts a header, replacing any that were set with an equivalent field name.
+    pub fn insert_header(mut self, header: impl TryIntoHeaderPair) -> Self {
+        self.req.insert_header(header);
+        self
+    }
+
+    /// Appends a header, keeping any that were set with an equivalent field name.
+    pub fn append_header(mut self, header: impl TryIntoHeaderPair) -> Self {
+        self.req.append_header(header);
+        self
+    }
+
+    /// Sets cookie for this request.
+    #[cfg(feature = "cookies")]
+    pub fn cookie(mut self, cookie: Cookie<'_>) -> Self {
+        self.cookies.add(cookie.into_owned());
+        self
+    }
+
+    /// Sets request path pattern parameter.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use actix_web::test::TestRequest;
+    ///
+    /// let req = TestRequest::default().param("foo", "bar");
+    /// let req = TestRequest::default().param("foo".to_owned(), "bar".to_owned());
+    /// ```
+    pub fn param(
+        mut self,
+        name: impl Into<Cow<'static, str>>,
+        value: impl Into<Cow<'static, str>>,
+    ) -> Self {
+        self.path.add_static(name, value);
+        self
+    }
+
+    /// Sets peer address.
+    pub fn peer_addr(mut self, addr: SocketAddr) -> Self {
+        self.peer_addr = Some(addr);
+        self
+    }
+
+    /// Sets request payload.
+    pub fn set_payload(mut self, data: impl Into<Bytes>) -> Self {
+        self.req.set_payload(data);
+        self
+    }
+
+    /// Serializes `data` to a URL encoded form and set it as the request payload.
+    ///
+    /// The `Content-Type` header is set to `application/x-www-form-urlencoded`.
+    pub fn set_form(mut self, data: impl Serialize) -> Self {
+        let bytes = serde_urlencoded::to_string(&data)
+            .expect("Failed to serialize test data as a urlencoded form");
+        self.req.set_payload(bytes);
+        self.req.insert_header(ContentType::form_url_encoded());
+        self
+    }
+
+    /// Serializes `data` to JSON and set it as the request payload.
+    ///
+    /// The `Content-Type` header is set to `application/json`.
+    pub fn set_json(mut self, data: impl Serialize) -> Self {
+        let bytes = serde_json::to_string(&data).expect("Failed to serialize test data to json");
+        self.req.set_payload(bytes);
+        self.req.insert_header(ContentType::json());
+        self
+    }
+
+    /// Inserts application data.
+    ///
+    /// This is equivalent of `App::app_data()` method for testing purpose.
+    pub fn app_data<T: 'static>(mut self, data: T) -> Self {
+        self.app_data.insert(data);
+        self
+    }
+
+    /// Inserts application data.
+    ///
+    /// This is equivalent of `App::data()` method for testing purpose.
+    #[doc(hidden)]
+    pub fn data<T: 'static>(mut self, data: T) -> Self {
+        self.app_data.insert(Data::new(data));
+        self
+    }
+
+    /// Sets resource map.
+    #[cfg(test)]
+    pub(crate) fn rmap(mut self, rmap: ResourceMap) -> Self {
+        self.rmap = rmap;
+        self
+    }
+
+    /// Finalizes test request.
+    ///
+    /// This request builder will be useless after calling `finish()`.
+    fn finish(&mut self) -> Request {
+        // mut used when cookie feature is enabled
+        #[allow(unused_mut)]
+        let mut req = self.req.finish();
+
+        #[cfg(feature = "cookies")]
+        {
+            use actix_http::header::{HeaderValue, COOKIE};
+
+            let cookie: String = self
+                .cookies
+                .delta()
+                // ensure only name=value is written to cookie header
+                .map(|c| c.stripped().encoded().to_string())
+                .collect::<Vec<_>>()
+                .join("; ");
+
+            if !cookie.is_empty() {
+                req.headers_mut()
+                    .insert(COOKIE, HeaderValue::from_str(&cookie).unwrap());
+            }
+        }
+
+        req
+    }
+
+    /// Finalizes request creation and returns `Request` instance.
+    pub fn to_request(mut self) -> Request {
+        let mut req = self.finish();
+        req.head_mut().peer_addr = self.peer_addr;
+        req
+    }
+
+    /// Finalizes request creation and returns `ServiceRequest` instance.
+    pub fn to_srv_request(mut self) -> ServiceRequest {
+        let (mut head, payload) = self.finish().into_parts();
+        head.peer_addr = self.peer_addr;
+        self.path.get_mut().update(&head.uri);
+
+        let app_state = AppInitServiceState::new(Rc::new(self.rmap), self.config.clone());
+
+        ServiceRequest::new(
+            HttpRequest::new(
+                self.path,
+                head,
+                app_state,
+                Rc::new(self.app_data),
+                None,
+                Default::default(),
+            ),
+            payload,
+        )
+    }
+
+    /// Finalizes request creation and returns `ServiceResponse` instance.
+    pub fn to_srv_response<B>(self, res: HttpResponse<B>) -> ServiceResponse<B> {
+        self.to_srv_request().into_response(res)
+    }
+
+    /// Finalizes request creation and returns `HttpRequest` instance.
+    pub fn to_http_request(mut self) -> HttpRequest {
+        let (mut head, _) = self.finish().into_parts();
+        head.peer_addr = self.peer_addr;
+        self.path.get_mut().update(&head.uri);
+
+        let app_state = AppInitServiceState::new(Rc::new(self.rmap), self.config.clone());
+
+        HttpRequest::new(
+            self.path,
+            head,
+            app_state,
+            Rc::new(self.app_data),
+            None,
+            Default::default(),
+        )
+    }
+
+    /// Finalizes request creation and returns `HttpRequest` and `Payload` pair.
+    pub fn to_http_parts(mut self) -> (HttpRequest, Payload) {
+        let (mut head, payload) = self.finish().into_parts();
+        head.peer_addr = self.peer_addr;
+        self.path.get_mut().update(&head.uri);
+
+        let app_state = AppInitServiceState::new(Rc::new(self.rmap), self.config.clone());
+
+        let req = HttpRequest::new(
+            self.path,
+            head,
+            app_state,
+            Rc::new(self.app_data),
+            None,
+            Default::default(),
+        );
+
+        (req, payload)
+    }
+
+    /// Finalizes request creation, calls service, and waits for response future completion.
+    pub async fn send_request<S, B, E>(self, app: &S) -> S::Response
+    where
+        S: Service<Request, Response = ServiceResponse<B>, Error = E>,
+        E: std::fmt::Debug,
+    {
+        let req = self.to_request();
+        test::call_service(app, req).await
+    }
+
+    #[cfg(test)]
+    pub fn set_server_hostname(&mut self, host: &str) {
+        self.config.set_host(host)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::time::SystemTime;
+
+    use super::*;
+    use crate::{http::header, test::init_service, web, App, Error, Responder};
+
+    #[actix_rt::test]
+    async fn test_basics() {
+        let req = TestRequest::default()
+            .version(Version::HTTP_2)
+            .insert_header(header::ContentType::json())
+            .insert_header(header::Date(SystemTime::now().into()))
+            .param("test", "123")
+            .data(10u32)
+            .app_data(20u64)
+            .peer_addr("127.0.0.1:8081".parse().unwrap())
+            .to_http_request();
+        assert!(req.headers().contains_key(header::CONTENT_TYPE));
+        assert!(req.headers().contains_key(header::DATE));
+        assert_eq!(
+            req.head().peer_addr,
+            Some("127.0.0.1:8081".parse().unwrap())
+        );
+        assert_eq!(&req.match_info()["test"], "123");
+        assert_eq!(req.version(), Version::HTTP_2);
+        let data = req.app_data::<Data<u32>>().unwrap();
+        assert!(req.app_data::<Data<u64>>().is_none());
+        assert_eq!(*data.get_ref(), 10);
+
+        assert!(req.app_data::<u32>().is_none());
+        let data = req.app_data::<u64>().unwrap();
+        assert_eq!(*data, 20);
+    }
+
+    #[actix_rt::test]
+    async fn test_send_request() {
+        let app = init_service(
+            App::new().service(
+                web::resource("/index.html")
+                    .route(web::get().to(|| HttpResponse::Ok().body("welcome!"))),
+            ),
+        )
+        .await;
+
+        let resp = TestRequest::get()
+            .uri("/index.html")
+            .send_request(&app)
+            .await;
+
+        let result = test::read_body(resp).await;
+        assert_eq!(result, Bytes::from_static(b"welcome!"));
+    }
+
+    #[actix_rt::test]
+    async fn test_async_with_block() {
+        async fn async_with_block() -> Result<HttpResponse, Error> {
+            let res = web::block(move || Some(4usize).ok_or("wrong")).await;
+
+            match res {
+                Ok(value) => Ok(HttpResponse::Ok()
+                    .content_type("text/plain")
+                    .body(format!("Async with block value: {:?}", value))),
+                Err(_) => panic!("Unexpected"),
+            }
+        }
+
+        let app =
+            init_service(App::new().service(web::resource("/index.html").to(async_with_block)))
+                .await;
+
+        let req = TestRequest::post().uri("/index.html").to_request();
+        let res = app.call(req).await.unwrap();
+        assert!(res.status().is_success());
+    }
+
+    // allow deprecated App::data
+    #[allow(deprecated)]
+    #[actix_rt::test]
+    async fn test_server_data() {
+        async fn handler(data: web::Data<usize>) -> impl Responder {
+            assert_eq!(**data, 10);
+            HttpResponse::Ok()
+        }
+
+        let app = init_service(
+            App::new()
+                .data(10usize)
+                .service(web::resource("/index.html").to(handler)),
+        )
+        .await;
+
+        let req = TestRequest::post().uri("/index.html").to_request();
+        let res = app.call(req).await.unwrap();
+        assert!(res.status().is_success());
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/test/test_services.rs.html b/src/actix_web/test/test_services.rs.html new file mode 100644 index 000000000..efe300a61 --- /dev/null +++ b/src/actix_web/test/test_services.rs.html @@ -0,0 +1,79 @@ +test_services.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
+
use actix_utils::future::ok;
+
+use crate::{
+    body::BoxBody,
+    dev::{fn_service, Service, ServiceRequest, ServiceResponse},
+    http::StatusCode,
+    Error, HttpResponseBuilder,
+};
+
+/// Creates service that always responds with `200 OK` and no body.
+pub fn ok_service(
+) -> impl Service<ServiceRequest, Response = ServiceResponse<BoxBody>, Error = Error> {
+    status_service(StatusCode::OK)
+}
+
+/// Creates service that always responds with given status code and no body.
+pub fn status_service(
+    status_code: StatusCode,
+) -> impl Service<ServiceRequest, Response = ServiceResponse<BoxBody>, Error = Error> {
+    fn_service(move |req: ServiceRequest| {
+        ok(req.into_response(HttpResponseBuilder::new(status_code).finish()))
+    })
+}
+
+#[doc(hidden)]
+#[deprecated(since = "4.0.0", note = "Renamed to `status_service`.")]
+pub fn simple_service(
+    status_code: StatusCode,
+) -> impl Service<ServiceRequest, Response = ServiceResponse<BoxBody>, Error = Error> {
+    status_service(status_code)
+}
+
+#[doc(hidden)]
+#[deprecated(since = "4.0.0", note = "Renamed to `status_service`.")]
+pub fn default_service(
+    status_code: StatusCode,
+) -> impl Service<ServiceRequest, Response = ServiceResponse<BoxBody>, Error = Error> {
+    status_service(status_code)
+}
+
\ No newline at end of file diff --git a/src/actix_web/test/test_utils.rs.html b/src/actix_web/test/test_utils.rs.html new file mode 100644 index 000000000..3725f57b0 --- /dev/null +++ b/src/actix_web/test/test_utils.rs.html @@ -0,0 +1,1187 @@ +test_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
+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
+
use std::error::Error as StdError;
+
+use actix_http::Request;
+use actix_service::IntoServiceFactory;
+use serde::de::DeserializeOwned;
+
+use crate::{
+    body::{self, MessageBody},
+    config::AppConfig,
+    dev::{Service, ServiceFactory},
+    service::ServiceResponse,
+    web::Bytes,
+    Error,
+};
+
+/// Initialize service from application builder instance.
+///
+/// # Examples
+/// ```
+/// use actix_service::Service;
+/// use actix_web::{test, web, App, HttpResponse, http::StatusCode};
+///
+/// #[actix_web::test]
+/// async fn test_init_service() {
+///     let app = test::init_service(
+///         App::new()
+///             .service(web::resource("/test").to(|| async { "OK" }))
+///     ).await;
+///
+///     // Create request object
+///     let req = test::TestRequest::with_uri("/test").to_request();
+///
+///     // Execute application
+///     let res = app.call(req).await.unwrap();
+///     assert_eq!(res.status(), StatusCode::OK);
+/// }
+/// ```
+///
+/// # Panics
+/// Panics if service initialization returns an error.
+pub async fn init_service<R, S, B, E>(
+    app: R,
+) -> impl Service<Request, Response = ServiceResponse<B>, Error = E>
+where
+    R: IntoServiceFactory<S, Request>,
+    S: ServiceFactory<Request, Config = AppConfig, Response = ServiceResponse<B>, Error = E>,
+    S::InitError: std::fmt::Debug,
+{
+    try_init_service(app)
+        .await
+        .expect("service initialization failed")
+}
+
+/// Fallible version of [`init_service`] that allows testing initialization errors.
+pub(crate) async fn try_init_service<R, S, B, E>(
+    app: R,
+) -> Result<impl Service<Request, Response = ServiceResponse<B>, Error = E>, S::InitError>
+where
+    R: IntoServiceFactory<S, Request>,
+    S: ServiceFactory<Request, Config = AppConfig, Response = ServiceResponse<B>, Error = E>,
+    S::InitError: std::fmt::Debug,
+{
+    let srv = app.into_factory();
+    srv.new_service(AppConfig::default()).await
+}
+
+/// Calls service and waits for response future completion.
+///
+/// # Examples
+/// ```
+/// use actix_web::{test, web, App, HttpResponse, http::StatusCode};
+///
+/// #[actix_web::test]
+/// async fn test_response() {
+///     let app = test::init_service(
+///         App::new()
+///             .service(web::resource("/test").to(|| async {
+///                 HttpResponse::Ok()
+///             }))
+///     ).await;
+///
+///     // Create request object
+///     let req = test::TestRequest::with_uri("/test").to_request();
+///
+///     // Call application
+///     let res = test::call_service(&app, req).await;
+///     assert_eq!(res.status(), StatusCode::OK);
+/// }
+/// ```
+///
+/// # Panics
+/// Panics if service call returns error. To handle errors use `app.call(req)`.
+pub async fn call_service<S, R, B, E>(app: &S, req: R) -> S::Response
+where
+    S: Service<R, Response = ServiceResponse<B>, Error = E>,
+    E: std::fmt::Debug,
+{
+    app.call(req)
+        .await
+        .expect("test service call returned error")
+}
+
+/// Fallible version of [`call_service`] that allows testing response completion errors.
+pub async fn try_call_service<S, R, B, E>(app: &S, req: R) -> Result<S::Response, E>
+where
+    S: Service<R, Response = ServiceResponse<B>, Error = E>,
+    E: std::fmt::Debug,
+{
+    app.call(req).await
+}
+
+/// Helper function that returns a response body of a TestRequest
+///
+/// # Examples
+/// ```
+/// use actix_web::{test, web, App, HttpResponse, http::header};
+/// use bytes::Bytes;
+///
+/// #[actix_web::test]
+/// async fn test_index() {
+///     let app = test::init_service(
+///         App::new().service(
+///             web::resource("/index.html")
+///                 .route(web::post().to(|| async {
+///                     HttpResponse::Ok().body("welcome!")
+///                 })))
+///     ).await;
+///
+///     let req = test::TestRequest::post()
+///         .uri("/index.html")
+///         .header(header::CONTENT_TYPE, "application/json")
+///         .to_request();
+///
+///     let result = test::call_and_read_body(&app, req).await;
+///     assert_eq!(result, Bytes::from_static(b"welcome!"));
+/// }
+/// ```
+///
+/// # Panics
+/// Panics if:
+/// - service call returns error;
+/// - body yields an error while it is being read.
+pub async fn call_and_read_body<S, B>(app: &S, req: Request) -> Bytes
+where
+    S: Service<Request, Response = ServiceResponse<B>, Error = Error>,
+    B: MessageBody,
+{
+    let res = call_service(app, req).await;
+    read_body(res).await
+}
+
+#[doc(hidden)]
+#[deprecated(since = "4.0.0", note = "Renamed to `call_and_read_body`.")]
+pub async fn read_response<S, B>(app: &S, req: Request) -> Bytes
+where
+    S: Service<Request, Response = ServiceResponse<B>, Error = Error>,
+    B: MessageBody,
+{
+    let res = call_service(app, req).await;
+    read_body(res).await
+}
+
+/// Helper function that returns a response body of a ServiceResponse.
+///
+/// # Examples
+/// ```
+/// use actix_web::{test, web, App, HttpResponse, http::header};
+/// use bytes::Bytes;
+///
+/// #[actix_web::test]
+/// async fn test_index() {
+///     let app = test::init_service(
+///         App::new().service(
+///             web::resource("/index.html")
+///                 .route(web::post().to(|| async {
+///                     HttpResponse::Ok().body("welcome!")
+///                 })))
+///     ).await;
+///
+///     let req = test::TestRequest::post()
+///         .uri("/index.html")
+///         .header(header::CONTENT_TYPE, "application/json")
+///         .to_request();
+///
+///     let res = test::call_service(&app, req).await;
+///     let result = test::read_body(res).await;
+///     assert_eq!(result, Bytes::from_static(b"welcome!"));
+/// }
+/// ```
+///
+/// # Panics
+/// Panics if body yields an error while it is being read.
+pub async fn read_body<B>(res: ServiceResponse<B>) -> Bytes
+where
+    B: MessageBody,
+{
+    try_read_body(res)
+        .await
+        .map_err(Into::<Box<dyn StdError>>::into)
+        .expect("error reading test response body")
+}
+
+/// Fallible version of [`read_body`] that allows testing MessageBody reading errors.
+pub async fn try_read_body<B>(res: ServiceResponse<B>) -> Result<Bytes, <B as MessageBody>::Error>
+where
+    B: MessageBody,
+{
+    let body = res.into_body();
+    body::to_bytes(body).await
+}
+
+/// Helper function that returns a deserialized response body of a ServiceResponse.
+///
+/// # Examples
+/// ```
+/// use actix_web::{App, test, web, HttpResponse, http::header};
+/// use serde::{Serialize, Deserialize};
+///
+/// #[derive(Serialize, Deserialize)]
+/// pub struct Person {
+///     id: String,
+///     name: String,
+/// }
+///
+/// #[actix_web::test]
+/// async fn test_post_person() {
+///     let app = test::init_service(
+///         App::new().service(
+///             web::resource("/people")
+///                 .route(web::post().to(|person: web::Json<Person>| async {
+///                     HttpResponse::Ok()
+///                         .json(person)})
+///                     ))
+///     ).await;
+///
+///     let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes();
+///
+///     let res = test::TestRequest::post()
+///         .uri("/people")
+///         .header(header::CONTENT_TYPE, "application/json")
+///         .set_payload(payload)
+///         .send_request(&mut app)
+///         .await;
+///
+///     assert!(res.status().is_success());
+///
+///     let result: Person = test::read_body_json(res).await;
+/// }
+/// ```
+///
+/// # Panics
+/// Panics if:
+/// - body yields an error while it is being read;
+/// - received body is not a valid JSON representation of `T`.
+pub async fn read_body_json<T, B>(res: ServiceResponse<B>) -> T
+where
+    B: MessageBody,
+    T: DeserializeOwned,
+{
+    try_read_body_json(res).await.unwrap_or_else(|err| {
+        panic!(
+            "could not deserialize body into a {}\nerr: {}",
+            std::any::type_name::<T>(),
+            err,
+        )
+    })
+}
+
+/// Fallible version of [`read_body_json`] that allows testing response deserialization errors.
+pub async fn try_read_body_json<T, B>(res: ServiceResponse<B>) -> Result<T, Box<dyn StdError>>
+where
+    B: MessageBody,
+    T: DeserializeOwned,
+{
+    let body = try_read_body(res)
+        .await
+        .map_err(Into::<Box<dyn StdError>>::into)?;
+    serde_json::from_slice(&body).map_err(Into::<Box<dyn StdError>>::into)
+}
+
+/// Helper function that returns a deserialized response body of a TestRequest
+///
+/// # Examples
+/// ```
+/// use actix_web::{App, test, web, HttpResponse, http::header};
+/// use serde::{Serialize, Deserialize};
+///
+/// #[derive(Serialize, Deserialize)]
+/// pub struct Person {
+///     id: String,
+///     name: String
+/// }
+///
+/// #[actix_web::test]
+/// async fn test_add_person() {
+///     let app = test::init_service(
+///         App::new().service(
+///             web::resource("/people")
+///                 .route(web::post().to(|person: web::Json<Person>| async {
+///                     HttpResponse::Ok()
+///                         .json(person)})
+///                     ))
+///     ).await;
+///
+///     let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes();
+///
+///     let req = test::TestRequest::post()
+///         .uri("/people")
+///         .header(header::CONTENT_TYPE, "application/json")
+///         .set_payload(payload)
+///         .to_request();
+///
+///     let result: Person = test::call_and_read_body_json(&mut app, req).await;
+/// }
+/// ```
+///
+/// # Panics
+/// Panics if:
+/// - service call returns an error body yields an error while it is being read;
+/// - body yields an error while it is being read;
+/// - received body is not a valid JSON representation of `T`.
+pub async fn call_and_read_body_json<S, B, T>(app: &S, req: Request) -> T
+where
+    S: Service<Request, Response = ServiceResponse<B>, Error = Error>,
+    B: MessageBody,
+    T: DeserializeOwned,
+{
+    try_call_and_read_body_json(app, req).await.unwrap()
+}
+
+/// Fallible version of [`call_and_read_body_json`] that allows testing service call errors.
+pub async fn try_call_and_read_body_json<S, B, T>(
+    app: &S,
+    req: Request,
+) -> Result<T, Box<dyn StdError>>
+where
+    S: Service<Request, Response = ServiceResponse<B>, Error = Error>,
+    B: MessageBody,
+    T: DeserializeOwned,
+{
+    let res = try_call_service(app, req)
+        .await
+        .map_err(Into::<Box<dyn StdError>>::into)?;
+    try_read_body_json(res).await
+}
+
+#[doc(hidden)]
+#[deprecated(since = "4.0.0", note = "Renamed to `call_and_read_body_json`.")]
+pub async fn read_response_json<S, B, T>(app: &S, req: Request) -> T
+where
+    S: Service<Request, Response = ServiceResponse<B>, Error = Error>,
+    B: MessageBody,
+    T: DeserializeOwned,
+{
+    call_and_read_body_json(app, req).await
+}
+
+#[cfg(test)]
+mod tests {
+    use serde::{Deserialize, Serialize};
+
+    use super::*;
+    use crate::{
+        dev::ServiceRequest, http::header, test::TestRequest, web, App, HttpMessage, HttpResponse,
+    };
+
+    #[actix_rt::test]
+    async fn test_request_methods() {
+        let app = init_service(
+            App::new().service(
+                web::resource("/index.html")
+                    .route(web::put().to(|| HttpResponse::Ok().body("put!")))
+                    .route(web::patch().to(|| HttpResponse::Ok().body("patch!")))
+                    .route(web::delete().to(|| HttpResponse::Ok().body("delete!"))),
+            ),
+        )
+        .await;
+
+        let put_req = TestRequest::put()
+            .uri("/index.html")
+            .insert_header((header::CONTENT_TYPE, "application/json"))
+            .to_request();
+
+        let result = call_and_read_body(&app, put_req).await;
+        assert_eq!(result, Bytes::from_static(b"put!"));
+
+        let patch_req = TestRequest::patch()
+            .uri("/index.html")
+            .insert_header((header::CONTENT_TYPE, "application/json"))
+            .to_request();
+
+        let result = call_and_read_body(&app, patch_req).await;
+        assert_eq!(result, Bytes::from_static(b"patch!"));
+
+        let delete_req = TestRequest::delete().uri("/index.html").to_request();
+        let result = call_and_read_body(&app, delete_req).await;
+        assert_eq!(result, Bytes::from_static(b"delete!"));
+    }
+
+    #[derive(Serialize, Deserialize, Debug)]
+    pub struct Person {
+        id: String,
+        name: String,
+    }
+
+    #[actix_rt::test]
+    async fn test_response_json() {
+        let app =
+            init_service(App::new().service(web::resource("/people").route(
+                web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
+            )))
+            .await;
+
+        let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes();
+
+        let req = TestRequest::post()
+            .uri("/people")
+            .insert_header((header::CONTENT_TYPE, "application/json"))
+            .set_payload(payload)
+            .to_request();
+
+        let result: Person = call_and_read_body_json(&app, req).await;
+        assert_eq!(&result.id, "12345");
+    }
+
+    #[actix_rt::test]
+    async fn test_try_response_json_error() {
+        let app =
+            init_service(App::new().service(web::resource("/people").route(
+                web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
+            )))
+            .await;
+
+        let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes();
+
+        let req = TestRequest::post()
+            .uri("/animals") // Not registered to ensure an error occurs.
+            .insert_header((header::CONTENT_TYPE, "application/json"))
+            .set_payload(payload)
+            .to_request();
+
+        let result: Result<Person, Box<dyn StdError>> =
+            try_call_and_read_body_json(&app, req).await;
+        assert!(result.is_err());
+    }
+
+    #[actix_rt::test]
+    async fn test_body_json() {
+        let app =
+            init_service(App::new().service(web::resource("/people").route(
+                web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
+            )))
+            .await;
+
+        let payload = r#"{"id":"12345","name":"User name"}"#.as_bytes();
+
+        let res = TestRequest::post()
+            .uri("/people")
+            .insert_header((header::CONTENT_TYPE, "application/json"))
+            .set_payload(payload)
+            .send_request(&app)
+            .await;
+
+        let result: Person = read_body_json(res).await;
+        assert_eq!(&result.name, "User name");
+    }
+
+    #[actix_rt::test]
+    async fn test_try_body_json_error() {
+        let app =
+            init_service(App::new().service(web::resource("/people").route(
+                web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
+            )))
+            .await;
+
+        // Use a number for id to cause a deserialization error.
+        let payload = r#"{"id":12345,"name":"User name"}"#.as_bytes();
+
+        let res = TestRequest::post()
+            .uri("/people")
+            .insert_header((header::CONTENT_TYPE, "application/json"))
+            .set_payload(payload)
+            .send_request(&app)
+            .await;
+
+        let result: Result<Person, Box<dyn StdError>> = try_read_body_json(res).await;
+        assert!(result.is_err());
+    }
+
+    #[actix_rt::test]
+    async fn test_request_response_form() {
+        let app =
+            init_service(App::new().service(web::resource("/people").route(
+                web::post().to(|person: web::Form<Person>| HttpResponse::Ok().json(person)),
+            )))
+            .await;
+
+        let payload = Person {
+            id: "12345".to_string(),
+            name: "User name".to_string(),
+        };
+
+        let req = TestRequest::post()
+            .uri("/people")
+            .set_form(&payload)
+            .to_request();
+
+        assert_eq!(req.content_type(), "application/x-www-form-urlencoded");
+
+        let result: Person = call_and_read_body_json(&app, req).await;
+        assert_eq!(&result.id, "12345");
+        assert_eq!(&result.name, "User name");
+    }
+
+    #[actix_rt::test]
+    async fn test_response() {
+        let app = init_service(
+            App::new().service(
+                web::resource("/index.html")
+                    .route(web::post().to(|| HttpResponse::Ok().body("welcome!"))),
+            ),
+        )
+        .await;
+
+        let req = TestRequest::post()
+            .uri("/index.html")
+            .insert_header((header::CONTENT_TYPE, "application/json"))
+            .to_request();
+
+        let result = call_and_read_body(&app, req).await;
+        assert_eq!(result, Bytes::from_static(b"welcome!"));
+    }
+
+    #[actix_rt::test]
+    async fn test_request_response_json() {
+        let app =
+            init_service(App::new().service(web::resource("/people").route(
+                web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
+            )))
+            .await;
+
+        let payload = Person {
+            id: "12345".to_string(),
+            name: "User name".to_string(),
+        };
+
+        let req = TestRequest::post()
+            .uri("/people")
+            .set_json(&payload)
+            .to_request();
+
+        assert_eq!(req.content_type(), "application/json");
+
+        let result: Person = call_and_read_body_json(&app, req).await;
+        assert_eq!(&result.id, "12345");
+        assert_eq!(&result.name, "User name");
+    }
+
+    #[actix_rt::test]
+    #[allow(dead_code)]
+    async fn return_opaque_types() {
+        fn test_app() -> App<
+            impl ServiceFactory<
+                ServiceRequest,
+                Config = (),
+                Response = ServiceResponse<impl MessageBody>,
+                Error = crate::Error,
+                InitError = (),
+            >,
+        > {
+            App::new().service(
+                web::resource("/people").route(
+                    web::post().to(|person: web::Json<Person>| HttpResponse::Ok().json(person)),
+                ),
+            )
+        }
+
+        async fn test_service(
+        ) -> impl Service<Request, Response = ServiceResponse<impl MessageBody>, Error = crate::Error>
+        {
+            init_service(test_app()).await
+        }
+
+        async fn compile_test(mut req: Vec<Request>) {
+            let svc = test_service().await;
+            call_service(&svc, req.pop().unwrap()).await;
+            call_and_read_body(&svc, req.pop().unwrap()).await;
+            read_body(call_service(&svc, req.pop().unwrap()).await).await;
+            let _: String = call_and_read_body_json(&svc, req.pop().unwrap()).await;
+            let _: String = read_body_json(call_service(&svc, req.pop().unwrap()).await).await;
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/types/either.rs.html b/src/actix_web/types/either.rs.html new file mode 100644 index 000000000..b6de2ef27 --- /dev/null +++ b/src/actix_web/types/either.rs.html @@ -0,0 +1,721 @@ +either.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
+
//! For either helper, see [`Either`].
+
+use std::{
+    future::Future,
+    mem,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use bytes::Bytes;
+use futures_core::ready;
+use pin_project_lite::pin_project;
+
+use crate::{
+    body::EitherBody,
+    dev,
+    web::{Form, Json},
+    Error, FromRequest, HttpRequest, HttpResponse, Responder,
+};
+
+/// Combines two extractor or responder types into a single type.
+///
+/// # Extractor
+/// Provides a mechanism for trying two extractors, a primary and a fallback. Useful for
+/// "polymorphic payloads" where, for example, a form might be JSON or URL encoded.
+///
+/// It is important to note that this extractor, by necessity, buffers the entire request payload
+/// as part of its implementation. Though, it does respect any `PayloadConfig` maximum size limits.
+///
+/// ```
+/// use actix_web::{post, web, Either};
+/// use serde::Deserialize;
+///
+/// #[derive(Deserialize)]
+/// struct Info {
+///     name: String,
+/// }
+///
+/// // handler that accepts form as JSON or form-urlencoded.
+/// #[post("/")]
+/// async fn index(form: Either<web::Json<Info>, web::Form<Info>>) -> String {
+///     let name: String = match form {
+///         Either::Left(json) => json.name.to_owned(),
+///         Either::Right(form) => form.name.to_owned(),
+///     };
+///
+///     format!("Welcome {}!", name)
+/// }
+/// ```
+///
+/// # Responder
+/// It may be desirable to use a concrete type for a response with multiple branches. As long as
+/// both types implement `Responder`, so will the `Either` type, enabling it to be used as a
+/// handler's return type.
+///
+/// All properties of a response are determined by the Responder branch returned.
+///
+/// ```
+/// use actix_web::{get, Either, Error, HttpResponse};
+///
+/// #[get("/")]
+/// async fn index() -> Either<&'static str, Result<HttpResponse, Error>> {
+///     if 1 == 2 {
+///         // respond with Left variant
+///         Either::Left("Bad data")
+///     } else {
+///         // respond with Right variant
+///         Either::Right(
+///             Ok(HttpResponse::Ok()
+///                 .content_type(mime::TEXT_HTML)
+///                 .body("<p>Hello!</p>"))
+///         )
+///     }
+/// }
+/// ```
+#[derive(Debug, PartialEq, Eq)]
+pub enum Either<L, R> {
+    /// A value of type `L`.
+    Left(L),
+
+    /// A value of type `R`.
+    Right(R),
+}
+
+impl<T> Either<Form<T>, Json<T>> {
+    pub fn into_inner(self) -> T {
+        match self {
+            Either::Left(form) => form.into_inner(),
+            Either::Right(form) => form.into_inner(),
+        }
+    }
+}
+
+impl<T> Either<Json<T>, Form<T>> {
+    pub fn into_inner(self) -> T {
+        match self {
+            Either::Left(form) => form.into_inner(),
+            Either::Right(form) => form.into_inner(),
+        }
+    }
+}
+
+#[cfg(test)]
+impl<L, R> Either<L, R> {
+    pub(self) fn unwrap_left(self) -> L {
+        match self {
+            Either::Left(data) => data,
+            Either::Right(_) => {
+                panic!("Cannot unwrap Left branch. Either contains an `R` type.")
+            }
+        }
+    }
+
+    pub(self) fn unwrap_right(self) -> R {
+        match self {
+            Either::Left(_) => {
+                panic!("Cannot unwrap Right branch. Either contains an `L` type.")
+            }
+            Either::Right(data) => data,
+        }
+    }
+}
+
+/// See [here](#responder) for example of usage as a handler return type.
+impl<L, R> Responder for Either<L, R>
+where
+    L: Responder,
+    R: Responder,
+{
+    type Body = EitherBody<L::Body, R::Body>;
+
+    fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body> {
+        match self {
+            Either::Left(a) => a.respond_to(req).map_into_left_body(),
+            Either::Right(b) => b.respond_to(req).map_into_right_body(),
+        }
+    }
+}
+
+/// A composite error resulting from failure to extract an `Either<L, R>`.
+///
+/// The implementation of `Into<actix_web::Error>` will return the payload buffering error or the
+/// error from the primary extractor. To access the fallback error, use a match clause.
+#[derive(Debug)]
+pub enum EitherExtractError<L, R> {
+    /// Error from payload buffering, such as exceeding payload max size limit.
+    Bytes(Error),
+
+    /// Error from primary and fallback extractors.
+    Extract(L, R),
+}
+
+impl<L, R> From<EitherExtractError<L, R>> for Error
+where
+    L: Into<Error>,
+    R: Into<Error>,
+{
+    fn from(err: EitherExtractError<L, R>) -> Error {
+        match err {
+            EitherExtractError::Bytes(err) => err,
+            EitherExtractError::Extract(a_err, _b_err) => a_err.into(),
+        }
+    }
+}
+
+/// See [here](#extractor) for example of usage as an extractor.
+impl<L, R> FromRequest for Either<L, R>
+where
+    L: FromRequest + 'static,
+    R: FromRequest + 'static,
+{
+    type Error = EitherExtractError<L::Error, R::Error>;
+    type Future = EitherExtractFut<L, R>;
+
+    fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
+        EitherExtractFut {
+            req: req.clone(),
+            state: EitherExtractState::Bytes {
+                bytes: Bytes::from_request(req, payload),
+            },
+        }
+    }
+}
+
+pin_project! {
+    pub struct EitherExtractFut<L, R>
+    where
+        R: FromRequest,
+        L: FromRequest,
+    {
+        req: HttpRequest,
+        #[pin]
+        state: EitherExtractState<L, R>,
+    }
+}
+
+pin_project! {
+    #[project = EitherExtractProj]
+    pub enum EitherExtractState<L, R>
+    where
+        L: FromRequest,
+        R: FromRequest,
+    {
+        Bytes {
+            #[pin]
+            bytes: <Bytes as FromRequest>::Future,
+        },
+        Left {
+            #[pin]
+            left: L::Future,
+            fallback: Bytes,
+        },
+        Right {
+            #[pin]
+            right: R::Future,
+            left_err: Option<L::Error>,
+        },
+    }
+}
+
+impl<R, RF, RE, L, LF, LE> Future for EitherExtractFut<L, R>
+where
+    L: FromRequest<Future = LF, Error = LE>,
+    R: FromRequest<Future = RF, Error = RE>,
+    LF: Future<Output = Result<L, LE>> + 'static,
+    RF: Future<Output = Result<R, RE>> + 'static,
+    LE: Into<Error>,
+    RE: Into<Error>,
+{
+    type Output = Result<Either<L, R>, EitherExtractError<LE, RE>>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let mut this = self.project();
+        let ready = loop {
+            let next = match this.state.as_mut().project() {
+                EitherExtractProj::Bytes { bytes } => {
+                    let res = ready!(bytes.poll(cx));
+                    match res {
+                        Ok(bytes) => {
+                            let fallback = bytes.clone();
+                            let left = L::from_request(this.req, &mut payload_from_bytes(bytes));
+                            EitherExtractState::Left { left, fallback }
+                        }
+                        Err(err) => break Err(EitherExtractError::Bytes(err)),
+                    }
+                }
+                EitherExtractProj::Left { left, fallback } => {
+                    let res = ready!(left.poll(cx));
+                    match res {
+                        Ok(extracted) => break Ok(Either::Left(extracted)),
+                        Err(left_err) => {
+                            let right = R::from_request(
+                                this.req,
+                                &mut payload_from_bytes(mem::take(fallback)),
+                            );
+                            EitherExtractState::Right {
+                                left_err: Some(left_err),
+                                right,
+                            }
+                        }
+                    }
+                }
+                EitherExtractProj::Right { right, left_err } => {
+                    let res = ready!(right.poll(cx));
+                    match res {
+                        Ok(data) => break Ok(Either::Right(data)),
+                        Err(err) => {
+                            break Err(EitherExtractError::Extract(left_err.take().unwrap(), err));
+                        }
+                    }
+                }
+            };
+            this.state.set(next);
+        };
+        Poll::Ready(ready)
+    }
+}
+
+fn payload_from_bytes(bytes: Bytes) -> dev::Payload {
+    let (_, mut h1_payload) = actix_http::h1::Payload::create(true);
+    h1_payload.unread_data(bytes);
+    dev::Payload::from(h1_payload)
+}
+
+#[cfg(test)]
+mod tests {
+    use serde::{Deserialize, Serialize};
+
+    use super::*;
+    use crate::test::TestRequest;
+
+    #[derive(Debug, Clone, Serialize, Deserialize)]
+    struct TestForm {
+        hello: String,
+    }
+
+    #[actix_rt::test]
+    async fn test_either_extract_first_try() {
+        let (req, mut pl) = TestRequest::default()
+            .set_form(TestForm {
+                hello: "world".to_owned(),
+            })
+            .to_http_parts();
+
+        let form = Either::<Form<TestForm>, Json<TestForm>>::from_request(&req, &mut pl)
+            .await
+            .unwrap()
+            .unwrap_left()
+            .into_inner();
+        assert_eq!(&form.hello, "world");
+    }
+
+    #[actix_rt::test]
+    async fn test_either_extract_fallback() {
+        let (req, mut pl) = TestRequest::default()
+            .set_json(TestForm {
+                hello: "world".to_owned(),
+            })
+            .to_http_parts();
+
+        let form = Either::<Form<TestForm>, Json<TestForm>>::from_request(&req, &mut pl)
+            .await
+            .unwrap()
+            .unwrap_right()
+            .into_inner();
+        assert_eq!(&form.hello, "world");
+    }
+
+    #[actix_rt::test]
+    async fn test_either_extract_recursive_fallback() {
+        let (req, mut pl) = TestRequest::default()
+            .set_payload(Bytes::from_static(b"!@$%^&*()"))
+            .to_http_parts();
+
+        let payload =
+            Either::<Either<Form<TestForm>, Json<TestForm>>, Bytes>::from_request(&req, &mut pl)
+                .await
+                .unwrap()
+                .unwrap_right();
+        assert_eq!(&payload.as_ref(), &b"!@$%^&*()");
+    }
+
+    #[actix_rt::test]
+    async fn test_either_extract_recursive_fallback_inner() {
+        let (req, mut pl) = TestRequest::default()
+            .set_json(TestForm {
+                hello: "world".to_owned(),
+            })
+            .to_http_parts();
+
+        let form =
+            Either::<Either<Form<TestForm>, Json<TestForm>>, Bytes>::from_request(&req, &mut pl)
+                .await
+                .unwrap()
+                .unwrap_left()
+                .unwrap_right()
+                .into_inner();
+        assert_eq!(&form.hello, "world");
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/types/form.rs.html b/src/actix_web/types/form.rs.html new file mode 100644 index 000000000..7597635d8 --- /dev/null +++ b/src/actix_web/types/form.rs.html @@ -0,0 +1,1119 @@ +form.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
+
//! For URL encoded form helper documentation, see [`Form`].
+
+use std::{
+    borrow::Cow,
+    fmt,
+    future::Future,
+    ops,
+    pin::Pin,
+    rc::Rc,
+    task::{Context, Poll},
+};
+
+use actix_http::Payload;
+use bytes::BytesMut;
+use encoding_rs::{Encoding, UTF_8};
+use futures_core::{future::LocalBoxFuture, ready};
+use futures_util::{FutureExt as _, StreamExt as _};
+use serde::{de::DeserializeOwned, Serialize};
+
+#[cfg(feature = "__compress")]
+use crate::dev::Decompress;
+use crate::{
+    body::EitherBody, error::UrlencodedError, extract::FromRequest, http::header::CONTENT_LENGTH,
+    web, Error, HttpMessage, HttpRequest, HttpResponse, Responder,
+};
+
+/// URL encoded payload extractor and responder.
+///
+/// `Form` has two uses: URL encoded responses, and extracting typed data from URL request payloads.
+///
+/// # Extractor
+/// To extract typed data from a request body, the inner type `T` must implement the
+/// [`DeserializeOwned`] trait.
+///
+/// Use [`FormConfig`] to configure extraction options.
+///
+/// ## Examples
+/// ```
+/// use actix_web::{post, web};
+/// use serde::Deserialize;
+///
+/// #[derive(Deserialize)]
+/// struct Info {
+///     name: String,
+/// }
+///
+/// // This handler is only called if:
+/// // - request headers declare the content type as `application/x-www-form-urlencoded`
+/// // - request payload deserializes into an `Info` struct from the URL encoded format
+/// #[post("/")]
+/// async fn index(web::Form(form): web::Form<Info>) -> String {
+///     format!("Welcome {}!", form.name)
+/// }
+/// ```
+///
+/// # Responder
+/// The `Form` type also allows you to create URL encoded responses by returning a value of type
+/// `Form<T>` where `T` is the type to be URL encoded, as long as `T` implements [`Serialize`].
+///
+/// ## Examples
+/// ```
+/// use actix_web::{get, web};
+/// use serde::Serialize;
+///
+/// #[derive(Serialize)]
+/// struct SomeForm {
+///     name: String,
+///     age: u8
+/// }
+///
+/// // Response will have:
+/// // - status: 200 OK
+/// // - header: `Content-Type: application/x-www-form-urlencoded`
+/// // - body: `name=actix&age=123`
+/// #[get("/")]
+/// async fn index() -> web::Form<SomeForm> {
+///     web::Form(SomeForm {
+///         name: "actix".to_owned(),
+///         age: 123
+///     })
+/// }
+/// ```
+///
+/// # Panics
+/// URL encoded forms consist of unordered `key=value` pairs, therefore they cannot be decoded into
+/// any type which depends upon data ordering (eg. tuples). Trying to do so will result in a panic.
+#[derive(PartialEq, Eq, PartialOrd, Ord, Debug)]
+pub struct Form<T>(pub T);
+
+impl<T> Form<T> {
+    /// Unwrap into inner `T` value.
+    pub fn into_inner(self) -> T {
+        self.0
+    }
+}
+
+impl<T> ops::Deref for Form<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &self.0
+    }
+}
+
+impl<T> ops::DerefMut for Form<T> {
+    fn deref_mut(&mut self) -> &mut T {
+        &mut self.0
+    }
+}
+
+impl<T> Serialize for Form<T>
+where
+    T: Serialize,
+{
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: serde::Serializer,
+    {
+        self.0.serialize(serializer)
+    }
+}
+
+/// See [here](#extractor) for example of usage as an extractor.
+impl<T> FromRequest for Form<T>
+where
+    T: DeserializeOwned + 'static,
+{
+    type Error = Error;
+    type Future = FormExtractFut<T>;
+
+    #[inline]
+    fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
+        let FormConfig { limit, err_handler } = FormConfig::from_req(req).clone();
+
+        FormExtractFut {
+            fut: UrlEncoded::new(req, payload).limit(limit),
+            req: req.clone(),
+            err_handler,
+        }
+    }
+}
+
+type FormErrHandler = Option<Rc<dyn Fn(UrlencodedError, &HttpRequest) -> Error>>;
+
+pub struct FormExtractFut<T> {
+    fut: UrlEncoded<T>,
+    err_handler: FormErrHandler,
+    req: HttpRequest,
+}
+
+impl<T> Future for FormExtractFut<T>
+where
+    T: DeserializeOwned + 'static,
+{
+    type Output = Result<Form<T>, Error>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.get_mut();
+
+        let res = ready!(Pin::new(&mut this.fut).poll(cx));
+
+        let res = match res {
+            Err(err) => match &this.err_handler {
+                Some(err_handler) => Err((err_handler)(err, &this.req)),
+                None => Err(err.into()),
+            },
+            Ok(item) => Ok(Form(item)),
+        };
+
+        Poll::Ready(res)
+    }
+}
+
+impl<T: fmt::Display> fmt::Display for Form<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.0.fmt(f)
+    }
+}
+
+/// See [here](#responder) for example of usage as a handler return type.
+impl<T: Serialize> Responder for Form<T> {
+    type Body = EitherBody<String>;
+
+    fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body> {
+        match serde_urlencoded::to_string(&self.0) {
+            Ok(body) => match HttpResponse::Ok()
+                .content_type(mime::APPLICATION_WWW_FORM_URLENCODED)
+                .message_body(body)
+            {
+                Ok(res) => res.map_into_left_body(),
+                Err(err) => HttpResponse::from_error(err).map_into_right_body(),
+            },
+
+            Err(err) => {
+                HttpResponse::from_error(UrlencodedError::Serialize(err)).map_into_right_body()
+            }
+        }
+    }
+}
+
+/// [`Form`] extractor configuration.
+///
+/// ```
+/// use actix_web::{post, web, App, FromRequest, Result};
+/// use serde::Deserialize;
+///
+/// #[derive(Deserialize)]
+/// struct Info {
+///     username: String,
+/// }
+///
+/// // Custom `FormConfig` is applied to App.
+/// // Max payload size for URL encoded forms is set to 4kB.
+/// #[post("/")]
+/// async fn index(form: web::Form<Info>) -> Result<String> {
+///     Ok(format!("Welcome {}!", form.username))
+/// }
+///
+/// App::new()
+///     .app_data(web::FormConfig::default().limit(4096))
+///     .service(index);
+/// ```
+#[derive(Clone)]
+pub struct FormConfig {
+    limit: usize,
+    err_handler: FormErrHandler,
+}
+
+impl FormConfig {
+    /// Set maximum accepted payload size. By default this limit is 16kB.
+    pub fn limit(mut self, limit: usize) -> Self {
+        self.limit = limit;
+        self
+    }
+
+    /// Set custom error handler
+    pub fn error_handler<F>(mut self, f: F) -> Self
+    where
+        F: Fn(UrlencodedError, &HttpRequest) -> Error + 'static,
+    {
+        self.err_handler = Some(Rc::new(f));
+        self
+    }
+
+    /// Extract payload config from app data.
+    ///
+    /// Checks both `T` and `Data<T>`, in that order, and falls back to the default payload config.
+    fn from_req(req: &HttpRequest) -> &Self {
+        req.app_data::<Self>()
+            .or_else(|| req.app_data::<web::Data<Self>>().map(|d| d.as_ref()))
+            .unwrap_or(&DEFAULT_CONFIG)
+    }
+}
+
+/// Allow shared refs used as default.
+const DEFAULT_CONFIG: FormConfig = FormConfig {
+    limit: 16_384, // 2^14 bytes (~16kB)
+    err_handler: None,
+};
+
+impl Default for FormConfig {
+    fn default() -> Self {
+        DEFAULT_CONFIG
+    }
+}
+
+/// Future that resolves to some `T` when parsed from a URL encoded payload.
+///
+/// Form can be deserialized from any type `T` that implements [`serde::Deserialize`].
+///
+/// Returns error if:
+/// - content type is not `application/x-www-form-urlencoded`
+/// - content length is greater than [limit](UrlEncoded::limit())
+pub struct UrlEncoded<T> {
+    #[cfg(feature = "__compress")]
+    stream: Option<Decompress<Payload>>,
+    #[cfg(not(feature = "__compress"))]
+    stream: Option<Payload>,
+
+    limit: usize,
+    length: Option<usize>,
+    encoding: &'static Encoding,
+    err: Option<UrlencodedError>,
+    fut: Option<LocalBoxFuture<'static, Result<T, UrlencodedError>>>,
+}
+
+#[allow(clippy::borrow_interior_mutable_const)]
+impl<T> UrlEncoded<T> {
+    /// Create a new future to decode a URL encoded request payload.
+    pub fn new(req: &HttpRequest, payload: &mut Payload) -> Self {
+        // check content type
+        if req.content_type().to_lowercase() != "application/x-www-form-urlencoded" {
+            return Self::err(UrlencodedError::ContentType);
+        }
+        let encoding = match req.encoding() {
+            Ok(enc) => enc,
+            Err(_) => return Self::err(UrlencodedError::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)
+                } else {
+                    return Self::err(UrlencodedError::UnknownLength);
+                }
+            } else {
+                return Self::err(UrlencodedError::UnknownLength);
+            }
+        };
+
+        let payload = {
+            cfg_if::cfg_if! {
+                if #[cfg(feature = "__compress")] {
+                    Decompress::from_headers(payload.take(), req.headers())
+                } else {
+                    payload.take()
+                }
+            }
+        };
+
+        UrlEncoded {
+            encoding,
+            stream: Some(payload),
+            limit: 32_768,
+            length: len,
+            fut: None,
+            err: None,
+        }
+    }
+
+    fn err(err: UrlencodedError) -> Self {
+        UrlEncoded {
+            stream: None,
+            limit: 32_768,
+            fut: None,
+            err: Some(err),
+            length: None,
+            encoding: UTF_8,
+        }
+    }
+
+    /// Set maximum accepted payload size. The default limit is 256kB.
+    pub fn limit(mut self, limit: usize) -> Self {
+        self.limit = limit;
+        self
+    }
+}
+
+impl<T> Future for UrlEncoded<T>
+where
+    T: DeserializeOwned + 'static,
+{
+    type Output = Result<T, UrlencodedError>;
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        if let Some(ref mut fut) = self.fut {
+            return Pin::new(fut).poll(cx);
+        }
+
+        if let Some(err) = self.err.take() {
+            return Poll::Ready(Err(err));
+        }
+
+        // payload size
+        let limit = self.limit;
+        if let Some(len) = self.length.take() {
+            if len > limit {
+                return Poll::Ready(Err(UrlencodedError::Overflow { size: len, limit }));
+            }
+        }
+
+        // future
+        let encoding = self.encoding;
+        let mut stream = self.stream.take().unwrap();
+
+        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(UrlencodedError::Overflow {
+                            size: body.len() + chunk.len(),
+                            limit,
+                        });
+                    } else {
+                        body.extend_from_slice(&chunk);
+                    }
+                }
+
+                if encoding == UTF_8 {
+                    serde_urlencoded::from_bytes::<T>(&body).map_err(UrlencodedError::Parse)
+                } else {
+                    let body = encoding
+                        .decode_without_bom_handling_and_without_replacement(&body)
+                        .map(Cow::into_owned)
+                        .ok_or(UrlencodedError::Encoding)?;
+
+                    serde_urlencoded::from_str::<T>(&body).map_err(UrlencodedError::Parse)
+                }
+            }
+            .boxed_local(),
+        );
+
+        self.poll(cx)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use bytes::Bytes;
+    use serde::{Deserialize, Serialize};
+
+    use super::*;
+    use crate::{
+        http::{
+            header::{HeaderValue, CONTENT_TYPE},
+            StatusCode,
+        },
+        test::{assert_body_eq, TestRequest},
+    };
+
+    #[derive(Deserialize, Serialize, Debug, PartialEq)]
+    struct Info {
+        hello: String,
+        counter: i64,
+    }
+
+    #[actix_rt::test]
+    async fn test_form() {
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((CONTENT_TYPE, "application/x-www-form-urlencoded"))
+            .insert_header((CONTENT_LENGTH, 11))
+            .set_payload(Bytes::from_static(b"hello=world&counter=123"))
+            .to_http_parts();
+
+        let Form(s) = Form::<Info>::from_request(&req, &mut pl).await.unwrap();
+        assert_eq!(
+            s,
+            Info {
+                hello: "world".into(),
+                counter: 123
+            }
+        );
+    }
+
+    fn eq(err: UrlencodedError, other: UrlencodedError) -> bool {
+        match err {
+            UrlencodedError::Overflow { .. } => {
+                matches!(other, UrlencodedError::Overflow { .. })
+            }
+            UrlencodedError::UnknownLength => matches!(other, UrlencodedError::UnknownLength),
+            UrlencodedError::ContentType => matches!(other, UrlencodedError::ContentType),
+            _ => false,
+        }
+    }
+
+    #[actix_rt::test]
+    async fn test_urlencoded_error() {
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((CONTENT_TYPE, "application/x-www-form-urlencoded"))
+            .insert_header((CONTENT_LENGTH, "xxxx"))
+            .to_http_parts();
+        let info = UrlEncoded::<Info>::new(&req, &mut pl).await;
+        assert!(eq(info.err().unwrap(), UrlencodedError::UnknownLength));
+
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((CONTENT_TYPE, "application/x-www-form-urlencoded"))
+            .insert_header((CONTENT_LENGTH, "1000000"))
+            .to_http_parts();
+        let info = UrlEncoded::<Info>::new(&req, &mut pl).await;
+        assert!(eq(
+            info.err().unwrap(),
+            UrlencodedError::Overflow { size: 0, limit: 0 }
+        ));
+
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((CONTENT_TYPE, "text/plain"))
+            .insert_header((CONTENT_LENGTH, 10))
+            .to_http_parts();
+        let info = UrlEncoded::<Info>::new(&req, &mut pl).await;
+        assert!(eq(info.err().unwrap(), UrlencodedError::ContentType));
+    }
+
+    #[actix_rt::test]
+    async fn test_urlencoded() {
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((CONTENT_TYPE, "application/x-www-form-urlencoded"))
+            .insert_header((CONTENT_LENGTH, 11))
+            .set_payload(Bytes::from_static(b"hello=world&counter=123"))
+            .to_http_parts();
+
+        let info = UrlEncoded::<Info>::new(&req, &mut pl).await.unwrap();
+        assert_eq!(
+            info,
+            Info {
+                hello: "world".to_owned(),
+                counter: 123
+            }
+        );
+
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((
+                CONTENT_TYPE,
+                "application/x-www-form-urlencoded; charset=utf-8",
+            ))
+            .insert_header((CONTENT_LENGTH, 11))
+            .set_payload(Bytes::from_static(b"hello=world&counter=123"))
+            .to_http_parts();
+
+        let info = UrlEncoded::<Info>::new(&req, &mut pl).await.unwrap();
+        assert_eq!(
+            info,
+            Info {
+                hello: "world".to_owned(),
+                counter: 123
+            }
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_responder() {
+        let req = TestRequest::default().to_http_request();
+
+        let form = Form(Info {
+            hello: "world".to_string(),
+            counter: 123,
+        });
+        let res = form.respond_to(&req);
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(CONTENT_TYPE).unwrap(),
+            HeaderValue::from_static("application/x-www-form-urlencoded")
+        );
+        assert_body_eq!(res, b"hello=world&counter=123");
+    }
+
+    #[actix_rt::test]
+    async fn test_with_config_in_data_wrapper() {
+        let ctype = HeaderValue::from_static("application/x-www-form-urlencoded");
+
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((CONTENT_TYPE, ctype))
+            .insert_header((CONTENT_LENGTH, HeaderValue::from_static("20")))
+            .set_payload(Bytes::from_static(b"hello=test&counter=4"))
+            .app_data(web::Data::new(FormConfig::default().limit(10)))
+            .to_http_parts();
+
+        let s = Form::<Info>::from_request(&req, &mut pl).await;
+        assert!(s.is_err());
+
+        let err_str = s.err().unwrap().to_string();
+        assert!(err_str.starts_with("URL encoded payload is larger"));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/types/header.rs.html b/src/actix_web/types/header.rs.html new file mode 100644 index 000000000..633d01e99 --- /dev/null +++ b/src/actix_web/types/header.rs.html @@ -0,0 +1,209 @@ +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
+104
+
//! For header extractor helper documentation, see [`Header`](crate::types::Header).
+
+use std::{fmt, ops};
+
+use actix_utils::future::{ready, Ready};
+
+use crate::{
+    dev::Payload, error::ParseError, extract::FromRequest, http::header::Header as ParseHeader,
+    HttpRequest,
+};
+
+/// Extract typed headers from the request.
+///
+/// To extract a header, the inner type `T` must implement the
+/// [`Header`](crate::http::header::Header) trait.
+///
+/// # Examples
+/// ```
+/// use actix_web::{get, web, http::header};
+///
+/// #[get("/")]
+/// async fn index(date: web::Header<header::Date>) -> String {
+///     format!("Request was sent at {}", date.to_string())
+/// }
+/// ```
+#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
+pub struct Header<T>(pub T);
+
+impl<T> Header<T> {
+    /// Unwrap into the inner `T` value.
+    pub fn into_inner(self) -> T {
+        self.0
+    }
+}
+
+impl<T> ops::Deref for Header<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &self.0
+    }
+}
+
+impl<T> ops::DerefMut for Header<T> {
+    fn deref_mut(&mut self) -> &mut T {
+        &mut self.0
+    }
+}
+
+impl<T> fmt::Display for Header<T>
+where
+    T: fmt::Display,
+{
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(&self.0, f)
+    }
+}
+
+impl<T> FromRequest for Header<T>
+where
+    T: ParseHeader,
+{
+    type Error = ParseError;
+    type Future = Ready<Result<Self, Self::Error>>;
+
+    #[inline]
+    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
+        match ParseHeader::parse(req) {
+            Ok(header) => ready(Ok(Header(header))),
+            Err(err) => ready(Err(err)),
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::{
+        http::{header, Method},
+        test::TestRequest,
+    };
+
+    #[actix_rt::test]
+    async fn test_header_extract() {
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((header::CONTENT_TYPE, mime::APPLICATION_JSON))
+            .insert_header((header::ALLOW, header::Allow(vec![Method::GET])))
+            .to_http_parts();
+
+        let s = Header::<header::ContentType>::from_request(&req, &mut pl)
+            .await
+            .unwrap();
+        assert_eq!(s.into_inner().0, mime::APPLICATION_JSON);
+
+        let s = Header::<header::Allow>::from_request(&req, &mut pl)
+            .await
+            .unwrap();
+        assert_eq!(s.into_inner().0, vec![Method::GET]);
+
+        assert!(Header::<header::Date>::from_request(&req, &mut pl)
+            .await
+            .is_err());
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/types/json.rs.html b/src/actix_web/types/json.rs.html new file mode 100644 index 000000000..89a3dfbfd --- /dev/null +++ b/src/actix_web/types/json.rs.html @@ -0,0 +1,1539 @@ +json.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
+
//! For JSON helper documentation, see [`Json`].
+
+use std::{
+    fmt,
+    future::Future,
+    marker::PhantomData,
+    ops,
+    pin::Pin,
+    sync::Arc,
+    task::{Context, Poll},
+};
+
+use actix_http::Payload;
+use bytes::BytesMut;
+use futures_core::{ready, Stream as _};
+use serde::{de::DeserializeOwned, Serialize};
+
+#[cfg(feature = "__compress")]
+use crate::dev::Decompress;
+use crate::{
+    body::EitherBody,
+    error::{Error, JsonPayloadError},
+    extract::FromRequest,
+    http::header::{ContentLength, Header as _},
+    request::HttpRequest,
+    web, HttpMessage, HttpResponse, Responder,
+};
+
+/// JSON extractor and responder.
+///
+/// `Json` has two uses: JSON responses, and extracting typed data from JSON request payloads.
+///
+/// # Extractor
+/// To extract typed data from a request body, the inner type `T` must implement the
+/// [`serde::Deserialize`] trait.
+///
+/// Use [`JsonConfig`] to configure extraction options.
+///
+/// ```
+/// use actix_web::{post, web, App};
+/// use serde::Deserialize;
+///
+/// #[derive(Deserialize)]
+/// struct Info {
+///     username: String,
+/// }
+///
+/// /// deserialize `Info` from request's body
+/// #[post("/")]
+/// async fn index(info: web::Json<Info>) -> String {
+///     format!("Welcome {}!", info.username)
+/// }
+/// ```
+///
+/// # Responder
+/// The `Json` type  JSON formatted responses. A handler may return a value of type
+/// `Json<T>` where `T` is the type of a structure to serialize into JSON. The type `T` must
+/// implement [`serde::Serialize`].
+///
+/// ```
+/// use actix_web::{post, web, HttpRequest};
+/// use serde::Serialize;
+///
+/// #[derive(Serialize)]
+/// struct Info {
+///     name: String,
+/// }
+///
+/// #[post("/{name}")]
+/// async fn index(req: HttpRequest) -> web::Json<Info> {
+///     web::Json(Info {
+///         name: req.match_info().get("name").unwrap().to_owned(),
+///     })
+/// }
+/// ```
+#[derive(Debug)]
+pub struct Json<T>(pub T);
+
+impl<T> Json<T> {
+    /// Unwrap into inner `T` value.
+    pub fn into_inner(self) -> T {
+        self.0
+    }
+}
+
+impl<T> ops::Deref for Json<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &self.0
+    }
+}
+
+impl<T> ops::DerefMut for Json<T> {
+    fn deref_mut(&mut self) -> &mut T {
+        &mut self.0
+    }
+}
+
+impl<T: fmt::Display> fmt::Display for Json<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(&self.0, f)
+    }
+}
+
+impl<T: Serialize> Serialize for Json<T> {
+    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+    where
+        S: serde::Serializer,
+    {
+        self.0.serialize(serializer)
+    }
+}
+
+/// Creates response with OK status code, correct content type header, and serialized JSON payload.
+///
+/// If serialization failed
+impl<T: Serialize> Responder for Json<T> {
+    type Body = EitherBody<String>;
+
+    fn respond_to(self, _: &HttpRequest) -> HttpResponse<Self::Body> {
+        match serde_json::to_string(&self.0) {
+            Ok(body) => match HttpResponse::Ok()
+                .content_type(mime::APPLICATION_JSON)
+                .message_body(body)
+            {
+                Ok(res) => res.map_into_left_body(),
+                Err(err) => HttpResponse::from_error(err).map_into_right_body(),
+            },
+
+            Err(err) => {
+                HttpResponse::from_error(JsonPayloadError::Serialize(err)).map_into_right_body()
+            }
+        }
+    }
+}
+
+/// See [here](#extractor) for example of usage as an extractor.
+impl<T: DeserializeOwned> FromRequest for Json<T> {
+    type Error = Error;
+    type Future = JsonExtractFut<T>;
+
+    #[inline]
+    fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
+        let config = JsonConfig::from_req(req);
+
+        let limit = config.limit;
+        let ctype_required = config.content_type_required;
+        let ctype_fn = config.content_type.as_deref();
+        let err_handler = config.err_handler.clone();
+
+        JsonExtractFut {
+            req: Some(req.clone()),
+            fut: JsonBody::new(req, payload, ctype_fn, ctype_required).limit(limit),
+            err_handler,
+        }
+    }
+}
+
+type JsonErrorHandler = Option<Arc<dyn Fn(JsonPayloadError, &HttpRequest) -> Error + Send + Sync>>;
+
+pub struct JsonExtractFut<T> {
+    req: Option<HttpRequest>,
+    fut: JsonBody<T>,
+    err_handler: JsonErrorHandler,
+}
+
+impl<T: DeserializeOwned> Future for JsonExtractFut<T> {
+    type Output = Result<Json<T>, Error>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.get_mut();
+
+        let res = ready!(Pin::new(&mut this.fut).poll(cx));
+
+        let res = match res {
+            Err(err) => {
+                let req = this.req.take().unwrap();
+                log::debug!(
+                    "Failed to deserialize Json from payload. \
+                         Request path: {}",
+                    req.path()
+                );
+
+                if let Some(err_handler) = this.err_handler.as_ref() {
+                    Err((*err_handler)(err, &req))
+                } else {
+                    Err(err.into())
+                }
+            }
+            Ok(data) => Ok(Json(data)),
+        };
+
+        Poll::Ready(res)
+    }
+}
+
+/// `Json` extractor configuration.
+///
+/// # Examples
+/// ```
+/// use actix_web::{error, post, web, App, FromRequest, HttpResponse};
+/// use serde::Deserialize;
+///
+/// #[derive(Deserialize)]
+/// struct Info {
+///     name: String,
+/// }
+///
+/// // `Json` extraction is bound by custom `JsonConfig` applied to App.
+/// #[post("/")]
+/// async fn index(info: web::Json<Info>) -> String {
+///     format!("Welcome {}!", info.name)
+/// }
+///
+/// // custom `Json` extractor configuration
+/// let json_cfg = web::JsonConfig::default()
+///     // limit request payload size
+///     .limit(4096)
+///     // only accept text/plain content type
+///     .content_type(|mime| mime == mime::TEXT_PLAIN)
+///     // use custom error handler
+///     .error_handler(|err, req| {
+///         error::InternalError::from_response(err, HttpResponse::Conflict().into()).into()
+///     });
+///
+/// App::new()
+///     .app_data(json_cfg)
+///     .service(index);
+/// ```
+#[derive(Clone)]
+pub struct JsonConfig {
+    limit: usize,
+    err_handler: JsonErrorHandler,
+    content_type: Option<Arc<dyn Fn(mime::Mime) -> bool + Send + Sync>>,
+    content_type_required: bool,
+}
+
+impl JsonConfig {
+    /// Set maximum accepted payload size. By default this limit is 2MB.
+    pub fn limit(mut self, limit: usize) -> Self {
+        self.limit = limit;
+        self
+    }
+
+    /// Set custom error handler.
+    pub fn error_handler<F>(mut self, f: F) -> Self
+    where
+        F: Fn(JsonPayloadError, &HttpRequest) -> Error + Send + Sync + 'static,
+    {
+        self.err_handler = Some(Arc::new(f));
+        self
+    }
+
+    /// Set predicate for allowed content types.
+    pub fn content_type<F>(mut self, predicate: F) -> Self
+    where
+        F: Fn(mime::Mime) -> bool + Send + Sync + 'static,
+    {
+        self.content_type = Some(Arc::new(predicate));
+        self
+    }
+
+    /// Sets whether or not the request must have a `Content-Type` header to be parsed.
+    pub fn content_type_required(mut self, content_type_required: bool) -> Self {
+        self.content_type_required = content_type_required;
+        self
+    }
+
+    /// Extract payload config from app data. Check both `T` and `Data<T>`, in that order, and fall
+    /// back to the default payload config.
+    fn from_req(req: &HttpRequest) -> &Self {
+        req.app_data::<Self>()
+            .or_else(|| req.app_data::<web::Data<Self>>().map(|d| d.as_ref()))
+            .unwrap_or(&DEFAULT_CONFIG)
+    }
+}
+
+const DEFAULT_LIMIT: usize = 2_097_152; // 2 mb
+
+/// Allow shared refs used as default.
+const DEFAULT_CONFIG: JsonConfig = JsonConfig {
+    limit: DEFAULT_LIMIT,
+    err_handler: None,
+    content_type: None,
+    content_type_required: true,
+};
+
+impl Default for JsonConfig {
+    fn default() -> Self {
+        DEFAULT_CONFIG
+    }
+}
+
+/// Future that resolves to some `T` when parsed from a JSON payload.
+///
+/// Can deserialize any type `T` that implements [`Deserialize`][serde::Deserialize].
+///
+/// Returns error if:
+/// - `Content-Type` is not `application/json` when `ctype_required` (passed to [`new`][Self::new])
+///   is `true`.
+/// - `Content-Length` is greater than [limit](JsonBody::limit()).
+/// - The payload, when consumed, is not valid JSON.
+pub enum JsonBody<T> {
+    Error(Option<JsonPayloadError>),
+    Body {
+        limit: usize,
+        /// Length as reported by `Content-Length` header, if present.
+        length: Option<usize>,
+        #[cfg(feature = "__compress")]
+        payload: Decompress<Payload>,
+        #[cfg(not(feature = "__compress"))]
+        payload: Payload,
+        buf: BytesMut,
+        _res: PhantomData<T>,
+    },
+}
+
+impl<T> Unpin for JsonBody<T> {}
+
+impl<T: DeserializeOwned> JsonBody<T> {
+    /// Create a new future to decode a JSON request payload.
+    #[allow(clippy::borrow_interior_mutable_const)]
+    pub fn new(
+        req: &HttpRequest,
+        payload: &mut Payload,
+        ctype_fn: Option<&(dyn Fn(mime::Mime) -> bool + Send + Sync)>,
+        ctype_required: bool,
+    ) -> Self {
+        // check content-type
+        let can_parse_json = match (ctype_required, req.mime_type()) {
+            (true, Ok(Some(mime))) => {
+                mime.subtype() == mime::JSON
+                    || mime.suffix() == Some(mime::JSON)
+                    || ctype_fn.map_or(false, |predicate| predicate(mime))
+            }
+
+            // if content-type is expected but not parsable as mime type, bail
+            (true, _) => false,
+
+            // if content-type validation is disabled, assume payload is JSON
+            // even when content-type header is missing or invalid mime type
+            (false, _) => true,
+        };
+
+        if !can_parse_json {
+            return JsonBody::Error(Some(JsonPayloadError::ContentType));
+        }
+
+        let length = ContentLength::parse(req).ok().map(|x| x.0);
+
+        // Notice the content-length is not checked against limit of json config here.
+        // As the internal usage always call JsonBody::limit after JsonBody::new.
+        // And limit check to return an error variant of JsonBody happens there.
+
+        let payload = {
+            cfg_if::cfg_if! {
+                if #[cfg(feature = "__compress")] {
+                    Decompress::from_headers(payload.take(), req.headers())
+                } else {
+                    payload.take()
+                }
+            }
+        };
+
+        JsonBody::Body {
+            limit: DEFAULT_LIMIT,
+            length,
+            payload,
+            buf: BytesMut::with_capacity(8192),
+            _res: PhantomData,
+        }
+    }
+
+    /// Set maximum accepted payload size. The default limit is 2MB.
+    pub fn limit(self, limit: usize) -> Self {
+        match self {
+            JsonBody::Body {
+                length,
+                payload,
+                buf,
+                ..
+            } => {
+                if let Some(len) = length {
+                    if len > limit {
+                        return JsonBody::Error(Some(JsonPayloadError::OverflowKnownLength {
+                            length: len,
+                            limit,
+                        }));
+                    }
+                }
+
+                JsonBody::Body {
+                    limit,
+                    length,
+                    payload,
+                    buf,
+                    _res: PhantomData,
+                }
+            }
+            JsonBody::Error(e) => JsonBody::Error(e),
+        }
+    }
+}
+
+impl<T: DeserializeOwned> Future for JsonBody<T> {
+    type Output = Result<T, JsonPayloadError>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.get_mut();
+
+        match this {
+            JsonBody::Body {
+                limit,
+                buf,
+                payload,
+                ..
+            } => loop {
+                let res = ready!(Pin::new(&mut *payload).poll_next(cx));
+                match res {
+                    Some(chunk) => {
+                        let chunk = chunk?;
+                        let buf_len = buf.len() + chunk.len();
+                        if buf_len > *limit {
+                            return Poll::Ready(Err(JsonPayloadError::Overflow { limit: *limit }));
+                        } else {
+                            buf.extend_from_slice(&chunk);
+                        }
+                    }
+                    None => {
+                        let json = serde_json::from_slice::<T>(buf)
+                            .map_err(JsonPayloadError::Deserialize)?;
+                        return Poll::Ready(Ok(json));
+                    }
+                }
+            },
+            JsonBody::Error(e) => Poll::Ready(Err(e.take().unwrap())),
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use bytes::Bytes;
+    use serde::{Deserialize, Serialize};
+
+    use super::*;
+    use crate::{
+        body,
+        error::InternalError,
+        http::{
+            header::{self, CONTENT_LENGTH, CONTENT_TYPE},
+            StatusCode,
+        },
+        test::{assert_body_eq, TestRequest},
+    };
+
+    #[derive(Serialize, Deserialize, PartialEq, Debug)]
+    struct MyObject {
+        name: String,
+    }
+
+    fn json_eq(err: JsonPayloadError, other: JsonPayloadError) -> bool {
+        match err {
+            JsonPayloadError::Overflow { .. } => {
+                matches!(other, JsonPayloadError::Overflow { .. })
+            }
+            JsonPayloadError::OverflowKnownLength { .. } => {
+                matches!(other, JsonPayloadError::OverflowKnownLength { .. })
+            }
+            JsonPayloadError::ContentType => matches!(other, JsonPayloadError::ContentType),
+            _ => false,
+        }
+    }
+
+    #[actix_rt::test]
+    async fn test_responder() {
+        let req = TestRequest::default().to_http_request();
+
+        let j = Json(MyObject {
+            name: "test".to_string(),
+        });
+        let res = j.respond_to(&req);
+        assert_eq!(res.status(), StatusCode::OK);
+        assert_eq!(
+            res.headers().get(header::CONTENT_TYPE).unwrap(),
+            header::HeaderValue::from_static("application/json")
+        );
+        assert_body_eq!(res, b"{\"name\":\"test\"}");
+    }
+
+    #[actix_rt::test]
+    async fn test_custom_error_responder() {
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((
+                header::CONTENT_TYPE,
+                header::HeaderValue::from_static("application/json"),
+            ))
+            .insert_header((
+                header::CONTENT_LENGTH,
+                header::HeaderValue::from_static("16"),
+            ))
+            .set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
+            .app_data(JsonConfig::default().limit(10).error_handler(|err, _| {
+                let msg = MyObject {
+                    name: "invalid request".to_string(),
+                };
+                let resp = HttpResponse::BadRequest().body(serde_json::to_string(&msg).unwrap());
+                InternalError::from_response(err, resp).into()
+            }))
+            .to_http_parts();
+
+        let s = Json::<MyObject>::from_request(&req, &mut pl).await;
+        let resp = HttpResponse::from_error(s.unwrap_err());
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+
+        let body = body::to_bytes(resp.into_body()).await.unwrap();
+        let msg: MyObject = serde_json::from_slice(&body).unwrap();
+        assert_eq!(msg.name, "invalid request");
+    }
+
+    #[actix_rt::test]
+    async fn test_extract() {
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((
+                header::CONTENT_TYPE,
+                header::HeaderValue::from_static("application/json"),
+            ))
+            .insert_header((
+                header::CONTENT_LENGTH,
+                header::HeaderValue::from_static("16"),
+            ))
+            .set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
+            .to_http_parts();
+
+        let s = Json::<MyObject>::from_request(&req, &mut pl).await.unwrap();
+        assert_eq!(s.name, "test");
+        assert_eq!(
+            s.into_inner(),
+            MyObject {
+                name: "test".to_string()
+            }
+        );
+
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((
+                header::CONTENT_TYPE,
+                header::HeaderValue::from_static("application/json"),
+            ))
+            .insert_header((
+                header::CONTENT_LENGTH,
+                header::HeaderValue::from_static("16"),
+            ))
+            .set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
+            .app_data(JsonConfig::default().limit(10))
+            .to_http_parts();
+
+        let s = Json::<MyObject>::from_request(&req, &mut pl).await;
+        assert!(format!("{}", s.err().unwrap())
+            .contains("JSON payload (16 bytes) is larger than allowed (limit: 10 bytes)."));
+
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((
+                header::CONTENT_TYPE,
+                header::HeaderValue::from_static("application/json"),
+            ))
+            .insert_header((
+                header::CONTENT_LENGTH,
+                header::HeaderValue::from_static("16"),
+            ))
+            .set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
+            .app_data(
+                JsonConfig::default()
+                    .limit(10)
+                    .error_handler(|_, _| JsonPayloadError::ContentType.into()),
+            )
+            .to_http_parts();
+        let s = Json::<MyObject>::from_request(&req, &mut pl).await;
+        assert!(format!("{}", s.err().unwrap()).contains("Content type error"));
+    }
+
+    #[actix_rt::test]
+    async fn test_json_body() {
+        let (req, mut pl) = TestRequest::default().to_http_parts();
+        let json = JsonBody::<MyObject>::new(&req, &mut pl, None, true).await;
+        assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType));
+
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((
+                header::CONTENT_TYPE,
+                header::HeaderValue::from_static("application/text"),
+            ))
+            .to_http_parts();
+        let json = JsonBody::<MyObject>::new(&req, &mut pl, None, true).await;
+        assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType));
+
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((
+                header::CONTENT_TYPE,
+                header::HeaderValue::from_static("application/json"),
+            ))
+            .insert_header((
+                header::CONTENT_LENGTH,
+                header::HeaderValue::from_static("10000"),
+            ))
+            .to_http_parts();
+
+        let json = JsonBody::<MyObject>::new(&req, &mut pl, None, true)
+            .limit(100)
+            .await;
+        assert!(json_eq(
+            json.err().unwrap(),
+            JsonPayloadError::OverflowKnownLength {
+                length: 10000,
+                limit: 100
+            }
+        ));
+
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((
+                header::CONTENT_TYPE,
+                header::HeaderValue::from_static("application/json"),
+            ))
+            .set_payload(Bytes::from_static(&[0u8; 1000]))
+            .to_http_parts();
+
+        let json = JsonBody::<MyObject>::new(&req, &mut pl, None, true)
+            .limit(100)
+            .await;
+
+        assert!(json_eq(
+            json.err().unwrap(),
+            JsonPayloadError::Overflow { limit: 100 }
+        ));
+
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((
+                header::CONTENT_TYPE,
+                header::HeaderValue::from_static("application/json"),
+            ))
+            .insert_header((
+                header::CONTENT_LENGTH,
+                header::HeaderValue::from_static("16"),
+            ))
+            .set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
+            .to_http_parts();
+
+        let json = JsonBody::<MyObject>::new(&req, &mut pl, None, true).await;
+        assert_eq!(
+            json.ok().unwrap(),
+            MyObject {
+                name: "test".to_owned()
+            }
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_with_json_and_bad_content_type() {
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((
+                header::CONTENT_TYPE,
+                header::HeaderValue::from_static("text/plain"),
+            ))
+            .insert_header((
+                header::CONTENT_LENGTH,
+                header::HeaderValue::from_static("16"),
+            ))
+            .set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
+            .app_data(JsonConfig::default().limit(4096))
+            .to_http_parts();
+
+        let s = Json::<MyObject>::from_request(&req, &mut pl).await;
+        assert!(s.is_err())
+    }
+
+    #[actix_rt::test]
+    async fn test_with_json_and_good_custom_content_type() {
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((
+                header::CONTENT_TYPE,
+                header::HeaderValue::from_static("text/plain"),
+            ))
+            .insert_header((
+                header::CONTENT_LENGTH,
+                header::HeaderValue::from_static("16"),
+            ))
+            .set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
+            .app_data(JsonConfig::default().content_type(|mime: mime::Mime| {
+                mime.type_() == mime::TEXT && mime.subtype() == mime::PLAIN
+            }))
+            .to_http_parts();
+
+        let s = Json::<MyObject>::from_request(&req, &mut pl).await;
+        assert!(s.is_ok())
+    }
+
+    #[actix_rt::test]
+    async fn test_with_json_and_bad_custom_content_type() {
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((
+                header::CONTENT_TYPE,
+                header::HeaderValue::from_static("text/html"),
+            ))
+            .insert_header((
+                header::CONTENT_LENGTH,
+                header::HeaderValue::from_static("16"),
+            ))
+            .set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
+            .app_data(JsonConfig::default().content_type(|mime: mime::Mime| {
+                mime.type_() == mime::TEXT && mime.subtype() == mime::PLAIN
+            }))
+            .to_http_parts();
+
+        let s = Json::<MyObject>::from_request(&req, &mut pl).await;
+        assert!(s.is_err())
+    }
+
+    #[actix_rt::test]
+    async fn test_json_with_no_content_type() {
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((
+                header::CONTENT_LENGTH,
+                header::HeaderValue::from_static("16"),
+            ))
+            .set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
+            .app_data(JsonConfig::default().content_type_required(false))
+            .to_http_parts();
+
+        let s = Json::<MyObject>::from_request(&req, &mut pl).await;
+        assert!(s.is_ok())
+    }
+
+    #[actix_rt::test]
+    async fn test_json_ignoring_content_type() {
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((
+                header::CONTENT_LENGTH,
+                header::HeaderValue::from_static("16"),
+            ))
+            .insert_header((
+                header::CONTENT_TYPE,
+                header::HeaderValue::from_static("invalid/value"),
+            ))
+            .set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
+            .app_data(JsonConfig::default().content_type_required(false))
+            .to_http_parts();
+
+        let s = Json::<MyObject>::from_request(&req, &mut pl).await;
+        assert!(s.is_ok());
+    }
+
+    #[actix_rt::test]
+    async fn test_with_config_in_data_wrapper() {
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((CONTENT_TYPE, mime::APPLICATION_JSON))
+            .insert_header((CONTENT_LENGTH, 16))
+            .set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
+            .app_data(web::Data::new(JsonConfig::default().limit(10)))
+            .to_http_parts();
+
+        let s = Json::<MyObject>::from_request(&req, &mut pl).await;
+        assert!(s.is_err());
+
+        let err_str = s.err().unwrap().to_string();
+        assert!(
+            err_str.contains("JSON payload (16 bytes) is larger than allowed (limit: 10 bytes).")
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/types/mod.rs.html b/src/actix_web/types/mod.rs.html new file mode 100644 index 000000000..ebf24ad29 --- /dev/null +++ b/src/actix_web/types/mod.rs.html @@ -0,0 +1,43 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+
//! Common extractors and responders.
+
+mod either;
+mod form;
+mod header;
+mod json;
+mod path;
+mod payload;
+mod query;
+mod readlines;
+
+pub use self::{
+    either::Either,
+    form::{Form, FormConfig, UrlEncoded},
+    header::Header,
+    json::{Json, JsonBody, JsonConfig},
+    path::{Path, PathConfig},
+    payload::{Payload, PayloadConfig},
+    query::{Query, QueryConfig},
+    readlines::Readlines,
+};
+
\ No newline at end of file diff --git a/src/actix_web/types/path.rs.html b/src/actix_web/types/path.rs.html new file mode 100644 index 000000000..b49da1fd7 --- /dev/null +++ b/src/actix_web/types/path.rs.html @@ -0,0 +1,579 @@ +path.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
+
//! For path segment extractor documentation, see [`Path`].
+
+use std::sync::Arc;
+
+use actix_router::PathDeserializer;
+use actix_utils::future::{ready, Ready};
+use derive_more::{AsRef, Deref, DerefMut, Display, From};
+use serde::de;
+
+use crate::{
+    dev::Payload,
+    error::{Error, ErrorNotFound, PathError},
+    web::Data,
+    FromRequest, HttpRequest,
+};
+
+/// Extract typed data from request path segments.
+///
+/// Use [`PathConfig`] to configure extraction option.
+///
+/// Unlike, [`HttpRequest::match_info`], this extractor will fully percent-decode dynamic segments,
+/// including `/`, `%`, and `+`.
+///
+/// # Examples
+/// ```
+/// use actix_web::{get, web};
+///
+/// // extract path info from "/{name}/{count}/index.html" into tuple
+/// // {name}  - deserialize a String
+/// // {count} - deserialize a u32
+/// #[get("/{name}/{count}/index.html")]
+/// async fn index(path: web::Path<(String, u32)>) -> String {
+///     let (name, count) = path.into_inner();
+///     format!("Welcome {}! {}", name, count)
+/// }
+/// ```
+///
+/// Path segments also can be deserialized into any type that implements [`serde::Deserialize`].
+/// Path segment labels will be matched with struct field names.
+///
+/// ```
+/// use actix_web::{get, web};
+/// use serde::Deserialize;
+///
+/// #[derive(Deserialize)]
+/// struct Info {
+///     name: String,
+/// }
+///
+/// // extract `Info` from a path using serde
+/// #[get("/{name}")]
+/// async fn index(info: web::Path<Info>) -> String {
+///     format!("Welcome {}!", info.name)
+/// }
+/// ```
+#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Deref, DerefMut, AsRef, Display, From)]
+pub struct Path<T>(T);
+
+impl<T> Path<T> {
+    /// Unwrap into inner `T` value.
+    pub fn into_inner(self) -> T {
+        self.0
+    }
+}
+
+/// See [here](#Examples) for example of usage as an extractor.
+impl<T> FromRequest for Path<T>
+where
+    T: de::DeserializeOwned,
+{
+    type Error = Error;
+    type Future = Ready<Result<Self, Self::Error>>;
+
+    #[inline]
+    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
+        let error_handler = req
+            .app_data::<PathConfig>()
+            .or_else(|| req.app_data::<Data<PathConfig>>().map(Data::get_ref))
+            .and_then(|c| c.err_handler.clone());
+
+        ready(
+            de::Deserialize::deserialize(PathDeserializer::new(req.match_info()))
+                .map(Path)
+                .map_err(move |err| {
+                    log::debug!(
+                        "Failed during Path extractor deserialization. \
+                         Request path: {:?}",
+                        req.path()
+                    );
+
+                    if let Some(error_handler) = error_handler {
+                        let e = PathError::Deserialize(err);
+                        (error_handler)(e, req)
+                    } else {
+                        ErrorNotFound(err)
+                    }
+                }),
+        )
+    }
+}
+
+/// Path extractor configuration
+///
+/// ```
+/// use actix_web::web::PathConfig;
+/// use actix_web::{error, web, App, FromRequest, HttpResponse};
+/// use serde::Deserialize;
+///
+/// #[derive(Deserialize, Debug)]
+/// enum Folder {
+///     #[serde(rename = "inbox")]
+///     Inbox,
+///
+///     #[serde(rename = "outbox")]
+///     Outbox,
+/// }
+///
+/// // deserialize `Info` from request's path
+/// async fn index(folder: web::Path<Folder>) -> String {
+///     format!("Selected folder: {:?}!", folder)
+/// }
+///
+/// let app = App::new().service(
+///     web::resource("/messages/{folder}")
+///         .app_data(PathConfig::default().error_handler(|err, req| {
+///             error::InternalError::from_response(
+///                 err,
+///                 HttpResponse::Conflict().into(),
+///             )
+///             .into()
+///         }))
+///         .route(web::post().to(index)),
+/// );
+/// ```
+#[derive(Clone, Default)]
+pub struct PathConfig {
+    #[allow(clippy::type_complexity)]
+    err_handler: Option<Arc<dyn Fn(PathError, &HttpRequest) -> Error + Send + Sync>>,
+}
+
+impl PathConfig {
+    /// Set custom error handler.
+    pub fn error_handler<F>(mut self, f: F) -> Self
+    where
+        F: Fn(PathError, &HttpRequest) -> Error + Send + Sync + 'static,
+    {
+        self.err_handler = Some(Arc::new(f));
+        self
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_router::ResourceDef;
+    use derive_more::Display;
+    use serde::Deserialize;
+
+    use super::*;
+    use crate::{error, http, test::TestRequest, HttpResponse};
+
+    #[derive(Deserialize, Debug, Display)]
+    #[display(fmt = "MyStruct({}, {})", key, value)]
+    struct MyStruct {
+        key: String,
+        value: String,
+    }
+
+    #[derive(Deserialize)]
+    struct Test2 {
+        key: String,
+        value: u32,
+    }
+
+    #[actix_rt::test]
+    async fn test_extract_path_single() {
+        let resource = ResourceDef::new("/{value}/");
+
+        let mut req = TestRequest::with_uri("/32/").to_srv_request();
+        resource.capture_match_info(req.match_info_mut());
+
+        let (req, mut pl) = req.into_parts();
+        assert_eq!(*Path::<i8>::from_request(&req, &mut pl).await.unwrap(), 32);
+        assert!(Path::<MyStruct>::from_request(&req, &mut pl).await.is_err());
+    }
+
+    #[allow(clippy::let_unit_value)]
+    #[actix_rt::test]
+    async fn test_tuple_extract() {
+        let resource = ResourceDef::new("/{key}/{value}/");
+
+        let mut req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request();
+        resource.capture_match_info(req.match_info_mut());
+
+        let (req, mut pl) = req.into_parts();
+        let (Path(res),) = <(Path<(String, String)>,)>::from_request(&req, &mut pl)
+            .await
+            .unwrap();
+        assert_eq!(res.0, "name");
+        assert_eq!(res.1, "user1");
+
+        let (Path(a), Path(b)) =
+            <(Path<(String, String)>, Path<(String, String)>)>::from_request(&req, &mut pl)
+                .await
+                .unwrap();
+        assert_eq!(a.0, "name");
+        assert_eq!(a.1, "user1");
+        assert_eq!(b.0, "name");
+        assert_eq!(b.1, "user1");
+
+        let () = <()>::from_request(&req, &mut pl).await.unwrap();
+    }
+
+    #[actix_rt::test]
+    async fn test_request_extract() {
+        let mut req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request();
+
+        let resource = ResourceDef::new("/{key}/{value}/");
+        resource.capture_match_info(req.match_info_mut());
+
+        let (req, mut pl) = req.into_parts();
+        let mut s = Path::<MyStruct>::from_request(&req, &mut pl).await.unwrap();
+        assert_eq!(s.key, "name");
+        assert_eq!(s.value, "user1");
+        s.value = "user2".to_string();
+        assert_eq!(s.value, "user2");
+        assert_eq!(
+            format!("{}, {:?}", s, s),
+            "MyStruct(name, user2), Path(MyStruct { key: \"name\", value: \"user2\" })"
+        );
+        let s = s.into_inner();
+        assert_eq!(s.value, "user2");
+
+        let Path(s) = Path::<(String, String)>::from_request(&req, &mut pl)
+            .await
+            .unwrap();
+        assert_eq!(s.0, "name");
+        assert_eq!(s.1, "user1");
+
+        let mut req = TestRequest::with_uri("/name/32/").to_srv_request();
+        let resource = ResourceDef::new("/{key}/{value}/");
+        resource.capture_match_info(req.match_info_mut());
+
+        let (req, mut pl) = req.into_parts();
+        let s = Path::<Test2>::from_request(&req, &mut pl).await.unwrap();
+        assert_eq!(s.as_ref().key, "name");
+        assert_eq!(s.value, 32);
+
+        let Path(s) = Path::<(String, u8)>::from_request(&req, &mut pl)
+            .await
+            .unwrap();
+        assert_eq!(s.0, "name");
+        assert_eq!(s.1, 32);
+
+        let res = Path::<Vec<String>>::from_request(&req, &mut pl)
+            .await
+            .unwrap();
+        assert_eq!(res[0], "name".to_owned());
+        assert_eq!(res[1], "32".to_owned());
+    }
+
+    #[actix_rt::test]
+    async fn paths_decoded() {
+        let resource = ResourceDef::new("/{key}/{value}");
+        let mut req = TestRequest::with_uri("/na%2Bme/us%2Fer%254%32").to_srv_request();
+        resource.capture_match_info(req.match_info_mut());
+
+        let (req, mut pl) = req.into_parts();
+        let path_items = Path::<MyStruct>::from_request(&req, &mut pl).await.unwrap();
+        assert_eq!(path_items.key, "na+me");
+        assert_eq!(path_items.value, "us/er%42");
+        assert_eq!(req.match_info().as_str(), "/na%2Bme/us%2Fer%2542");
+    }
+
+    #[actix_rt::test]
+    async fn test_custom_err_handler() {
+        let (req, mut pl) = TestRequest::with_uri("/name/user1/")
+            .app_data(PathConfig::default().error_handler(|err, _| {
+                error::InternalError::from_response(err, HttpResponse::Conflict().finish()).into()
+            }))
+            .to_http_parts();
+
+        let s = Path::<(usize,)>::from_request(&req, &mut pl)
+            .await
+            .unwrap_err();
+        let res = HttpResponse::from_error(s);
+
+        assert_eq!(res.status(), http::StatusCode::CONFLICT);
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/types/payload.rs.html b/src/actix_web/types/payload.rs.html new file mode 100644 index 000000000..b578f841b --- /dev/null +++ b/src/actix_web/types/payload.rs.html @@ -0,0 +1,1295 @@ +payload.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
+
//! Basic binary and string payload extractors.
+
+use std::{
+    borrow::Cow,
+    future::Future,
+    pin::Pin,
+    str,
+    task::{Context, Poll},
+};
+
+use actix_http::error::PayloadError;
+use actix_utils::future::{ready, Either, Ready};
+use bytes::{Bytes, BytesMut};
+use encoding_rs::{Encoding, UTF_8};
+use futures_core::{ready, stream::Stream};
+use mime::Mime;
+
+use crate::{
+    body, dev, error::ErrorBadRequest, http::header, web, Error, FromRequest, HttpMessage,
+    HttpRequest,
+};
+
+/// Extract a request's raw payload stream.
+///
+/// See [`PayloadConfig`] for important notes when using this advanced extractor.
+///
+/// # Examples
+/// ```
+/// use std::future::Future;
+/// use futures_util::StreamExt as _;
+/// use actix_web::{post, web};
+///
+/// // `body: web::Payload` parameter extracts raw payload stream from request
+/// #[post("/")]
+/// async fn index(mut body: web::Payload) -> actix_web::Result<String> {
+///     // for demonstration only; in a normal case use the `Bytes` extractor
+///     // collect payload stream into a bytes object
+///     let mut bytes = web::BytesMut::new();
+///     while let Some(item) = body.next().await {
+///         bytes.extend_from_slice(&item?);
+///     }
+///
+///     Ok(format!("Request Body Bytes:\n{:?}", bytes))
+/// }
+/// ```
+pub struct Payload(dev::Payload);
+
+impl Payload {
+    /// Unwrap to inner Payload type.
+    #[inline]
+    pub fn into_inner(self) -> dev::Payload {
+        self.0
+    }
+
+    /// Buffers payload from request up to `limit` bytes.
+    ///
+    /// This method is preferred over [`Payload::to_bytes()`] since it will not lead to unexpected
+    /// memory exhaustion from massive payloads. Note that the other primitive extractors such as
+    /// [`Bytes`] and [`String`], as well as extractors built on top of them, already have this sort
+    /// of protection according to the configured (or default) [`PayloadConfig`].
+    ///
+    /// # Errors
+    ///
+    /// - The outer error type, [`BodyLimitExceeded`](body::BodyLimitExceeded), is returned when the
+    ///   payload is larger than `limit`.
+    /// - The inner error type is [the normal Actix Web error](crate::Error) and is only returned if
+    ///   the payload stream yields an error for some reason. Such cases are usually caused by
+    ///   unrecoverable connection issues.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use actix_web::{error, web::Payload, Responder};
+    ///
+    /// async fn limited_payload_handler(pl: Payload) -> actix_web::Result<impl Responder> {
+    ///     match pl.to_bytes_limited(5).await {
+    ///         Ok(res) => res,
+    ///         Err(err) => Err(error::ErrorPayloadTooLarge(err)),
+    ///     }
+    /// }
+    /// ```
+    pub async fn to_bytes_limited(
+        self,
+        limit: usize,
+    ) -> Result<crate::Result<Bytes>, body::BodyLimitExceeded> {
+        let stream = body::BodyStream::new(self.0);
+
+        match body::to_bytes_limited(stream, limit).await {
+            Ok(Ok(body)) => Ok(Ok(body)),
+            Ok(Err(err)) => Ok(Err(err.into())),
+            Err(err) => Err(err),
+        }
+    }
+
+    /// Buffers entire payload from request.
+    ///
+    /// Use of this method is discouraged unless you know for certain that requests will not be
+    /// large enough to exhaust memory. If this is not known, prefer [`Payload::to_bytes_limited()`]
+    /// or one of the higher level extractors like [`Bytes`] or [`String`] that implement size
+    /// limits according to the configured (or default) [`PayloadConfig`].
+    ///
+    /// # Errors
+    ///
+    /// An error is only returned if the payload stream yields an error for some reason. Such cases
+    /// are usually caused by unrecoverable connection issues.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use actix_web::{error, web::Payload, Responder};
+    ///
+    /// async fn payload_handler(pl: Payload) -> actix_web::Result<impl Responder> {
+    ///     pl.to_bytes().await
+    /// }
+    /// ```
+    pub async fn to_bytes(self) -> crate::Result<Bytes> {
+        let stream = body::BodyStream::new(self.0);
+        Ok(body::to_bytes(stream).await?)
+    }
+}
+
+impl Stream for Payload {
+    type Item = Result<Bytes, PayloadError>;
+
+    #[inline]
+    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        Pin::new(&mut self.0).poll_next(cx)
+    }
+}
+
+/// See [here](#Examples) for example of usage as an extractor.
+impl FromRequest for Payload {
+    type Error = Error;
+    type Future = Ready<Result<Self, Self::Error>>;
+
+    #[inline]
+    fn from_request(_: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
+        ready(Ok(Payload(payload.take())))
+    }
+}
+
+/// Extract binary data from a request's payload.
+///
+/// Collects request payload stream into a [Bytes] instance.
+///
+/// Use [`PayloadConfig`] to configure extraction process.
+///
+/// # Examples
+/// ```
+/// use actix_web::{post, web};
+///
+/// /// extract binary data from request
+/// #[post("/")]
+/// async fn index(body: web::Bytes) -> String {
+///     format!("Body {:?}!", body)
+/// }
+/// ```
+impl FromRequest for Bytes {
+    type Error = Error;
+    type Future = Either<BytesExtractFut, Ready<Result<Bytes, Error>>>;
+
+    #[inline]
+    fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
+        // allow both Config and Data<Config>
+        let cfg = PayloadConfig::from_req(req);
+
+        if let Err(err) = cfg.check_mimetype(req) {
+            return Either::right(ready(Err(err)));
+        }
+
+        Either::left(BytesExtractFut {
+            body_fut: HttpMessageBody::new(req, payload).limit(cfg.limit),
+        })
+    }
+}
+
+/// Future for `Bytes` extractor.
+pub struct BytesExtractFut {
+    body_fut: HttpMessageBody,
+}
+
+impl Future for BytesExtractFut {
+    type Output = Result<Bytes, Error>;
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        Pin::new(&mut self.body_fut).poll(cx).map_err(Into::into)
+    }
+}
+
+/// Extract text information from a request's body.
+///
+/// Text extractor automatically decode body according to the request's charset.
+///
+/// Use [`PayloadConfig`] to configure extraction process.
+///
+/// # Examples
+/// ```
+/// use actix_web::{post, web, FromRequest};
+///
+/// // extract text data from request
+/// #[post("/")]
+/// async fn index(text: String) -> String {
+///     format!("Body {}!", text)
+/// }
+impl FromRequest for String {
+    type Error = Error;
+    type Future = Either<StringExtractFut, Ready<Result<String, Error>>>;
+
+    #[inline]
+    fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {
+        let cfg = PayloadConfig::from_req(req);
+
+        // check content-type
+        if let Err(err) = cfg.check_mimetype(req) {
+            return Either::right(ready(Err(err)));
+        }
+
+        // check charset
+        let encoding = match req.encoding() {
+            Ok(enc) => enc,
+            Err(err) => return Either::right(ready(Err(err.into()))),
+        };
+        let limit = cfg.limit;
+        let body_fut = HttpMessageBody::new(req, payload).limit(limit);
+
+        Either::left(StringExtractFut { body_fut, encoding })
+    }
+}
+
+/// Future for `String` extractor.
+pub struct StringExtractFut {
+    body_fut: HttpMessageBody,
+    encoding: &'static Encoding,
+}
+
+impl Future for StringExtractFut {
+    type Output = Result<String, Error>;
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let encoding = self.encoding;
+
+        Pin::new(&mut self.body_fut).poll(cx).map(|out| {
+            let body = out?;
+            bytes_to_string(body, encoding)
+        })
+    }
+}
+
+fn bytes_to_string(body: Bytes, encoding: &'static Encoding) -> Result<String, Error> {
+    if encoding == UTF_8 {
+        Ok(str::from_utf8(body.as_ref())
+            .map_err(|_| ErrorBadRequest("Can not decode body"))?
+            .to_owned())
+    } else {
+        Ok(encoding
+            .decode_without_bom_handling_and_without_replacement(&body)
+            .map(Cow::into_owned)
+            .ok_or_else(|| ErrorBadRequest("Can not decode body"))?)
+    }
+}
+
+/// Configuration for request payloads.
+///
+/// Applies to the built-in [`Bytes`] and [`String`] extractors.
+/// Note that the [`Payload`] extractor does not automatically check
+/// conformance with this configuration to allow more flexibility when
+/// building extractors on top of [`Payload`].
+///
+/// By default, the payload size limit is 256kB and there is no mime type condition.
+///
+/// To use this, add an instance of it to your [`app`](crate::App), [`scope`](crate::Scope)
+/// or [`resource`](crate::Resource) through the associated `.app_data()` method.
+#[derive(Clone)]
+pub struct PayloadConfig {
+    limit: usize,
+    mimetype: Option<Mime>,
+}
+
+impl PayloadConfig {
+    /// Create new instance with a size limit (in bytes) and no mime type condition.
+    pub fn new(limit: usize) -> Self {
+        Self {
+            limit,
+            ..Default::default()
+        }
+    }
+
+    /// Set maximum accepted payload size in bytes. The default limit is 256KiB.
+    pub fn limit(mut self, limit: usize) -> Self {
+        self.limit = limit;
+        self
+    }
+
+    /// Set required mime type of the request. By default mime type is not enforced.
+    pub fn mimetype(mut self, mt: Mime) -> Self {
+        self.mimetype = Some(mt);
+        self
+    }
+
+    fn check_mimetype(&self, req: &HttpRequest) -> Result<(), Error> {
+        // check content-type
+        if let Some(ref mt) = self.mimetype {
+            match req.mime_type() {
+                Ok(Some(ref req_mt)) => {
+                    if mt != req_mt {
+                        return Err(ErrorBadRequest("Unexpected Content-Type"));
+                    }
+                }
+                Ok(None) => {
+                    return Err(ErrorBadRequest("Content-Type is expected"));
+                }
+                Err(err) => {
+                    return Err(err.into());
+                }
+            }
+        }
+
+        Ok(())
+    }
+
+    /// Extract payload config from app data. Check both `T` and `Data<T>`, in that order, and fall
+    /// back to the default payload config if neither is found.
+    fn from_req(req: &HttpRequest) -> &Self {
+        req.app_data::<Self>()
+            .or_else(|| req.app_data::<web::Data<Self>>().map(|d| d.as_ref()))
+            .unwrap_or(&DEFAULT_CONFIG)
+    }
+}
+
+const DEFAULT_CONFIG_LIMIT: usize = 262_144; // 2^18 bytes (~256kB)
+
+/// Allow shared refs used as defaults.
+const DEFAULT_CONFIG: PayloadConfig = PayloadConfig {
+    limit: DEFAULT_CONFIG_LIMIT,
+    mimetype: None,
+};
+
+impl Default for PayloadConfig {
+    fn default() -> Self {
+        DEFAULT_CONFIG
+    }
+}
+
+/// Future that resolves to a complete HTTP body payload.
+///
+/// By default only 256kB payload is accepted before `PayloadError::Overflow` is returned.
+/// Use `MessageBody::limit()` method to change upper limit.
+pub struct HttpMessageBody {
+    limit: usize,
+    length: Option<usize>,
+    #[cfg(feature = "__compress")]
+    stream: dev::Decompress<dev::Payload>,
+    #[cfg(not(feature = "__compress"))]
+    stream: dev::Payload,
+    buf: BytesMut,
+    err: Option<PayloadError>,
+}
+
+impl HttpMessageBody {
+    /// Create `MessageBody` for request.
+    #[allow(clippy::borrow_interior_mutable_const)]
+    pub fn new(req: &HttpRequest, payload: &mut dev::Payload) -> HttpMessageBody {
+        let mut length = None;
+        let mut err = None;
+
+        if let Some(l) = req.headers().get(&header::CONTENT_LENGTH) {
+            match l.to_str() {
+                Ok(s) => match s.parse::<usize>() {
+                    Ok(l) => {
+                        if l > DEFAULT_CONFIG_LIMIT {
+                            err = Some(PayloadError::Overflow);
+                        }
+                        length = Some(l)
+                    }
+                    Err(_) => err = Some(PayloadError::UnknownLength),
+                },
+                Err(_) => err = Some(PayloadError::UnknownLength),
+            }
+        }
+
+        let stream = {
+            cfg_if::cfg_if! {
+                if #[cfg(feature = "__compress")] {
+                    dev::Decompress::from_headers(payload.take(), req.headers())
+                } else {
+                    payload.take()
+                }
+            }
+        };
+
+        HttpMessageBody {
+            stream,
+            limit: DEFAULT_CONFIG_LIMIT,
+            length,
+            buf: BytesMut::with_capacity(8192),
+            err,
+        }
+    }
+
+    /// Change max size of payload. By default max size is 256kB
+    pub fn limit(mut self, limit: usize) -> Self {
+        if let Some(l) = self.length {
+            self.err = if l > limit {
+                Some(PayloadError::Overflow)
+            } else {
+                None
+            };
+        }
+        self.limit = limit;
+        self
+    }
+}
+
+impl Future for HttpMessageBody {
+    type Output = Result<Bytes, PayloadError>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.get_mut();
+
+        if let Some(err) = this.err.take() {
+            return Poll::Ready(Err(err));
+        }
+
+        loop {
+            let res = ready!(Pin::new(&mut this.stream).poll_next(cx));
+            match res {
+                Some(chunk) => {
+                    let chunk = chunk?;
+                    if this.buf.len() + chunk.len() > this.limit {
+                        return Poll::Ready(Err(PayloadError::Overflow));
+                    } else {
+                        this.buf.extend_from_slice(&chunk);
+                    }
+                }
+                None => return Poll::Ready(Ok(this.buf.split().freeze())),
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::{
+        http::StatusCode,
+        test::{call_service, init_service, read_body, TestRequest},
+        App, Responder,
+    };
+
+    #[actix_rt::test]
+    async fn payload_to_bytes() {
+        async fn payload_handler(pl: Payload) -> crate::Result<impl Responder> {
+            pl.to_bytes().await
+        }
+
+        async fn limited_payload_handler(pl: Payload) -> crate::Result<impl Responder> {
+            match pl.to_bytes_limited(5).await {
+                Ok(res) => res,
+                Err(_limited) => Err(ErrorBadRequest("too big")),
+            }
+        }
+
+        let srv = init_service(
+            App::new()
+                .route("/all", web::to(payload_handler))
+                .route("limited", web::to(limited_payload_handler)),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/all")
+            .set_payload("1234567890")
+            .to_request();
+        let res = call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+        let body = read_body(res).await;
+        assert_eq!(body, "1234567890");
+
+        let req = TestRequest::with_uri("/limited")
+            .set_payload("1234567890")
+            .to_request();
+        let res = call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::BAD_REQUEST);
+
+        let req = TestRequest::with_uri("/limited")
+            .set_payload("12345")
+            .to_request();
+        let res = call_service(&srv, req).await;
+        assert_eq!(res.status(), StatusCode::OK);
+        let body = read_body(res).await;
+        assert_eq!(body, "12345");
+    }
+
+    #[actix_rt::test]
+    async fn test_payload_config() {
+        let req = TestRequest::default().to_http_request();
+        let cfg = PayloadConfig::default().mimetype(mime::APPLICATION_JSON);
+        assert!(cfg.check_mimetype(&req).is_err());
+
+        let req = TestRequest::default()
+            .insert_header((header::CONTENT_TYPE, "application/x-www-form-urlencoded"))
+            .to_http_request();
+        assert!(cfg.check_mimetype(&req).is_err());
+
+        let req = TestRequest::default()
+            .insert_header((header::CONTENT_TYPE, "application/json"))
+            .to_http_request();
+        assert!(cfg.check_mimetype(&req).is_ok());
+    }
+
+    // allow deprecated App::data
+    #[allow(deprecated)]
+    #[actix_rt::test]
+    async fn test_config_recall_locations() {
+        async fn bytes_handler(_: Bytes) -> impl Responder {
+            "payload is probably json bytes"
+        }
+
+        async fn string_handler(_: String) -> impl Responder {
+            "payload is probably json string"
+        }
+
+        let srv = init_service(
+            App::new()
+                .service(
+                    web::resource("/bytes-app-data")
+                        .app_data(PayloadConfig::default().mimetype(mime::APPLICATION_JSON))
+                        .route(web::get().to(bytes_handler)),
+                )
+                .service(
+                    web::resource("/bytes-data")
+                        .data(PayloadConfig::default().mimetype(mime::APPLICATION_JSON))
+                        .route(web::get().to(bytes_handler)),
+                )
+                .service(
+                    web::resource("/string-app-data")
+                        .app_data(PayloadConfig::default().mimetype(mime::APPLICATION_JSON))
+                        .route(web::get().to(string_handler)),
+                )
+                .service(
+                    web::resource("/string-data")
+                        .data(PayloadConfig::default().mimetype(mime::APPLICATION_JSON))
+                        .route(web::get().to(string_handler)),
+                ),
+        )
+        .await;
+
+        let req = TestRequest::with_uri("/bytes-app-data").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+
+        let req = TestRequest::with_uri("/bytes-data").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+
+        let req = TestRequest::with_uri("/string-app-data").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+
+        let req = TestRequest::with_uri("/string-data").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
+
+        let req = TestRequest::with_uri("/bytes-app-data")
+            .insert_header(header::ContentType(mime::APPLICATION_JSON))
+            .to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/bytes-data")
+            .insert_header(header::ContentType(mime::APPLICATION_JSON))
+            .to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/string-app-data")
+            .insert_header(header::ContentType(mime::APPLICATION_JSON))
+            .to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let req = TestRequest::with_uri("/string-data")
+            .insert_header(header::ContentType(mime::APPLICATION_JSON))
+            .to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+    }
+
+    #[actix_rt::test]
+    async fn test_bytes() {
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((header::CONTENT_LENGTH, "11"))
+            .set_payload(Bytes::from_static(b"hello=world"))
+            .to_http_parts();
+
+        let s = Bytes::from_request(&req, &mut pl).await.unwrap();
+        assert_eq!(s, Bytes::from_static(b"hello=world"));
+    }
+
+    #[actix_rt::test]
+    async fn test_string() {
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((header::CONTENT_LENGTH, "11"))
+            .set_payload(Bytes::from_static(b"hello=world"))
+            .to_http_parts();
+
+        let s = String::from_request(&req, &mut pl).await.unwrap();
+        assert_eq!(s, "hello=world");
+    }
+
+    #[actix_rt::test]
+    async fn test_message_body() {
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((header::CONTENT_LENGTH, "xxxx"))
+            .to_srv_request()
+            .into_parts();
+        let res = HttpMessageBody::new(&req, &mut pl).await;
+        match res.err().unwrap() {
+            PayloadError::UnknownLength => {}
+            _ => unreachable!("error"),
+        }
+
+        let (req, mut pl) = TestRequest::default()
+            .insert_header((header::CONTENT_LENGTH, "1000000"))
+            .to_srv_request()
+            .into_parts();
+        let res = HttpMessageBody::new(&req, &mut pl).await;
+        match res.err().unwrap() {
+            PayloadError::Overflow => {}
+            _ => unreachable!("error"),
+        }
+
+        let (req, mut pl) = TestRequest::default()
+            .set_payload(Bytes::from_static(b"test"))
+            .to_http_parts();
+        let res = HttpMessageBody::new(&req, &mut pl).await;
+        assert_eq!(res.ok().unwrap(), Bytes::from_static(b"test"));
+
+        let (req, mut pl) = TestRequest::default()
+            .set_payload(Bytes::from_static(b"11111111111111"))
+            .to_http_parts();
+        let res = HttpMessageBody::new(&req, &mut pl).limit(5).await;
+        match res.err().unwrap() {
+            PayloadError::Overflow => {}
+            _ => unreachable!("error"),
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/types/query.rs.html b/src/actix_web/types/query.rs.html new file mode 100644 index 000000000..c9d095180 --- /dev/null +++ b/src/actix_web/types/query.rs.html @@ -0,0 +1,549 @@ +query.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
+
//! For query parameter extractor documentation, see [`Query`].
+
+use std::{fmt, ops, sync::Arc};
+
+use actix_utils::future::{err, ok, Ready};
+use serde::de::DeserializeOwned;
+
+use crate::{dev::Payload, error::QueryPayloadError, Error, FromRequest, HttpRequest};
+
+/// Extract typed information from the request's query.
+///
+/// To extract typed data from the URL query string, the inner type `T` must implement the
+/// [`DeserializeOwned`] trait.
+///
+/// Use [`QueryConfig`] to configure extraction process.
+///
+/// # Panics
+/// A query string consists of unordered `key=value` pairs, therefore it cannot be decoded into any
+/// type which depends upon data ordering (eg. tuples). Trying to do so will result in a panic.
+///
+/// # Examples
+/// ```
+/// use actix_web::{get, web};
+/// use serde::Deserialize;
+///
+/// #[derive(Debug, Deserialize)]
+/// pub enum ResponseType {
+///    Token,
+///    Code
+/// }
+///
+/// #[derive(Debug, Deserialize)]
+/// pub struct AuthRequest {
+///    id: u64,
+///    response_type: ResponseType,
+/// }
+///
+/// // Deserialize `AuthRequest` struct from query string.
+/// // This handler gets called only if the request's query parameters contain both fields.
+/// // A valid request path for this handler would be `/?id=64&response_type=Code"`.
+/// #[get("/")]
+/// async fn index(info: web::Query<AuthRequest>) -> String {
+///     format!("Authorization request for id={} and type={:?}!", info.id, info.response_type)
+/// }
+///
+/// // To access the entire underlying query struct, use `.into_inner()`.
+/// #[get("/debug1")]
+/// async fn debug1(info: web::Query<AuthRequest>) -> String {
+///     dbg!("Authorization object = {:?}", info.into_inner());
+///     "OK".to_string()
+/// }
+///
+/// // Or use destructuring, which is equivalent to `.into_inner()`.
+/// #[get("/debug2")]
+/// async fn debug2(web::Query(info): web::Query<AuthRequest>) -> String {
+///     dbg!("Authorization object = {:?}", info);
+///     "OK".to_string()
+/// }
+/// ```
+#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Query<T>(pub T);
+
+impl<T> Query<T> {
+    /// Unwrap into inner `T` value.
+    pub fn into_inner(self) -> T {
+        self.0
+    }
+}
+
+impl<T: DeserializeOwned> Query<T> {
+    /// Deserialize a `T` from the URL encoded query parameter string.
+    ///
+    /// ```
+    /// # use std::collections::HashMap;
+    /// # use actix_web::web::Query;
+    /// let numbers = Query::<HashMap<String, u32>>::from_query("one=1&two=2").unwrap();
+    /// assert_eq!(numbers.get("one"), Some(&1));
+    /// assert_eq!(numbers.get("two"), Some(&2));
+    /// assert!(numbers.get("three").is_none());
+    /// ```
+    pub fn from_query(query_str: &str) -> Result<Self, QueryPayloadError> {
+        serde_urlencoded::from_str::<T>(query_str)
+            .map(Self)
+            .map_err(QueryPayloadError::Deserialize)
+    }
+}
+
+impl<T> ops::Deref for Query<T> {
+    type Target = T;
+
+    fn deref(&self) -> &T {
+        &self.0
+    }
+}
+
+impl<T> ops::DerefMut for Query<T> {
+    fn deref_mut(&mut self) -> &mut T {
+        &mut self.0
+    }
+}
+
+impl<T: fmt::Display> fmt::Display for Query<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.0.fmt(f)
+    }
+}
+
+/// See [here](#Examples) for example of usage as an extractor.
+impl<T: DeserializeOwned> FromRequest for Query<T> {
+    type Error = Error;
+    type Future = Ready<Result<Self, Error>>;
+
+    #[inline]
+    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {
+        let error_handler = req
+            .app_data::<QueryConfig>()
+            .and_then(|c| c.err_handler.clone());
+
+        serde_urlencoded::from_str::<T>(req.query_string())
+            .map(|val| ok(Query(val)))
+            .unwrap_or_else(move |e| {
+                let e = QueryPayloadError::Deserialize(e);
+
+                log::debug!(
+                    "Failed during Query extractor deserialization. \
+                     Request path: {:?}",
+                    req.path()
+                );
+
+                let e = if let Some(error_handler) = error_handler {
+                    (error_handler)(e, req)
+                } else {
+                    e.into()
+                };
+
+                err(e)
+            })
+    }
+}
+
+/// Query extractor configuration.
+///
+/// # Examples
+/// ```
+/// use actix_web::{error, get, web, App, FromRequest, HttpResponse};
+/// use serde::Deserialize;
+///
+/// #[derive(Deserialize)]
+/// struct Info {
+///     username: String,
+/// }
+///
+/// /// deserialize `Info` from request's querystring
+/// #[get("/")]
+/// async fn index(info: web::Query<Info>) -> String {
+///     format!("Welcome {}!", info.username)
+/// }
+///
+/// // custom `Query` extractor configuration
+/// let query_cfg = web::QueryConfig::default()
+///     // use custom error handler
+///     .error_handler(|err, req| {
+///         error::InternalError::from_response(err, HttpResponse::Conflict().finish()).into()
+///     });
+///
+/// App::new()
+///     .app_data(query_cfg)
+///     .service(index);
+/// ```
+#[derive(Clone, Default)]
+pub struct QueryConfig {
+    #[allow(clippy::type_complexity)]
+    err_handler: Option<Arc<dyn Fn(QueryPayloadError, &HttpRequest) -> Error + Send + Sync>>,
+}
+
+impl QueryConfig {
+    /// Set custom error handler
+    pub fn error_handler<F>(mut self, f: F) -> Self
+    where
+        F: Fn(QueryPayloadError, &HttpRequest) -> Error + Send + Sync + 'static,
+    {
+        self.err_handler = Some(Arc::new(f));
+        self
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_http::StatusCode;
+    use derive_more::Display;
+    use serde::Deserialize;
+
+    use super::*;
+    use crate::{error::InternalError, test::TestRequest, HttpResponse};
+
+    #[derive(Deserialize, Debug, Display)]
+    struct Id {
+        id: String,
+    }
+
+    #[actix_rt::test]
+    async fn test_service_request_extract() {
+        let req = TestRequest::with_uri("/name/user1/").to_srv_request();
+        assert!(Query::<Id>::from_query(req.query_string()).is_err());
+
+        let req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request();
+        let mut s = Query::<Id>::from_query(req.query_string()).unwrap();
+
+        assert_eq!(s.id, "test");
+        assert_eq!(
+            format!("{}, {:?}", s, s),
+            "test, Query(Id { id: \"test\" })"
+        );
+
+        s.id = "test1".to_string();
+        let s = s.into_inner();
+        assert_eq!(s.id, "test1");
+    }
+
+    #[actix_rt::test]
+    async fn test_request_extract() {
+        let req = TestRequest::with_uri("/name/user1/").to_srv_request();
+        let (req, mut pl) = req.into_parts();
+        assert!(Query::<Id>::from_request(&req, &mut pl).await.is_err());
+
+        let req = TestRequest::with_uri("/name/user1/?id=test").to_srv_request();
+        let (req, mut pl) = req.into_parts();
+
+        let mut s = Query::<Id>::from_request(&req, &mut pl).await.unwrap();
+        assert_eq!(s.id, "test");
+        assert_eq!(
+            format!("{}, {:?}", s, s),
+            "test, Query(Id { id: \"test\" })"
+        );
+
+        s.id = "test1".to_string();
+        let s = s.into_inner();
+        assert_eq!(s.id, "test1");
+    }
+
+    #[actix_rt::test]
+    #[should_panic]
+    async fn test_tuple_panic() {
+        let req = TestRequest::with_uri("/?one=1&two=2").to_srv_request();
+        let (req, mut pl) = req.into_parts();
+
+        Query::<(u32, u32)>::from_request(&req, &mut pl)
+            .await
+            .unwrap();
+    }
+
+    #[actix_rt::test]
+    async fn test_custom_error_responder() {
+        let req = TestRequest::with_uri("/name/user1/")
+            .app_data(QueryConfig::default().error_handler(|e, _| {
+                let resp = HttpResponse::UnprocessableEntity().finish();
+                InternalError::from_response(e, resp).into()
+            }))
+            .to_srv_request();
+
+        let (req, mut pl) = req.into_parts();
+        let query = Query::<Id>::from_request(&req, &mut pl).await;
+
+        assert!(query.is_err());
+        assert_eq!(
+            query
+                .unwrap_err()
+                .as_response_error()
+                .error_response()
+                .status(),
+            StatusCode::UNPROCESSABLE_ENTITY
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/types/readlines.rs.html b/src/actix_web/types/readlines.rs.html new file mode 100644 index 000000000..410af90a9 --- /dev/null +++ b/src/actix_web/types/readlines.rs.html @@ -0,0 +1,423 @@ +readlines.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
+
//! For request line reader documentation, see [`Readlines`].
+
+use std::{
+    borrow::Cow,
+    pin::Pin,
+    str,
+    task::{Context, Poll},
+};
+
+use bytes::{Bytes, BytesMut};
+use encoding_rs::{Encoding, UTF_8};
+use futures_core::{ready, stream::Stream};
+
+use crate::{
+    dev::Payload,
+    error::{PayloadError, ReadlinesError},
+    HttpMessage,
+};
+
+/// Stream that reads request line by line.
+pub struct Readlines<T: HttpMessage> {
+    stream: Payload<T::Stream>,
+    buf: BytesMut,
+    limit: usize,
+    checked_buff: bool,
+    encoding: &'static Encoding,
+    err: Option<ReadlinesError>,
+}
+
+impl<T> Readlines<T>
+where
+    T: HttpMessage,
+    T::Stream: Stream<Item = Result<Bytes, PayloadError>> + Unpin,
+{
+    /// Create a new stream to read request line by line.
+    pub fn new(req: &mut T) -> Self {
+        let encoding = match req.encoding() {
+            Ok(enc) => enc,
+            Err(err) => return Self::err(err.into()),
+        };
+
+        Readlines {
+            stream: req.take_payload(),
+            buf: BytesMut::with_capacity(262_144),
+            limit: 262_144,
+            checked_buff: true,
+            err: None,
+            encoding,
+        }
+    }
+
+    /// Set maximum accepted payload size. The default limit is 256kB.
+    pub fn limit(mut self, limit: usize) -> Self {
+        self.limit = limit;
+        self
+    }
+
+    fn err(err: ReadlinesError) -> Self {
+        Readlines {
+            stream: Payload::None,
+            buf: BytesMut::new(),
+            limit: 262_144,
+            checked_buff: true,
+            encoding: UTF_8,
+            err: Some(err),
+        }
+    }
+}
+
+impl<T> Stream for Readlines<T>
+where
+    T: HttpMessage,
+    T::Stream: Stream<Item = Result<Bytes, PayloadError>> + Unpin,
+{
+    type Item = Result<String, ReadlinesError>;
+
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        let this = self.get_mut();
+
+        if let Some(err) = this.err.take() {
+            return Poll::Ready(Some(Err(err)));
+        }
+
+        // check if there is a newline in the buffer
+        if !this.checked_buff {
+            let mut found: Option<usize> = None;
+            for (ind, b) in this.buf.iter().enumerate() {
+                if *b == b'\n' {
+                    found = Some(ind);
+                    break;
+                }
+            }
+            if let Some(ind) = found {
+                // check if line is longer than limit
+                if ind + 1 > this.limit {
+                    return Poll::Ready(Some(Err(ReadlinesError::LimitOverflow)));
+                }
+                let line = if this.encoding == UTF_8 {
+                    str::from_utf8(&this.buf.split_to(ind + 1))
+                        .map_err(|_| ReadlinesError::EncodingError)?
+                        .to_owned()
+                } else {
+                    this.encoding
+                        .decode_without_bom_handling_and_without_replacement(
+                            &this.buf.split_to(ind + 1),
+                        )
+                        .map(Cow::into_owned)
+                        .ok_or(ReadlinesError::EncodingError)?
+                };
+                return Poll::Ready(Some(Ok(line)));
+            }
+            this.checked_buff = true;
+        }
+
+        // poll req for more bytes
+        match ready!(Pin::new(&mut this.stream).poll_next(cx)) {
+            Some(Ok(mut bytes)) => {
+                // check if there is a newline in bytes
+                let mut found: Option<usize> = None;
+                for (ind, b) in bytes.iter().enumerate() {
+                    if *b == b'\n' {
+                        found = Some(ind);
+                        break;
+                    }
+                }
+                if let Some(ind) = found {
+                    // check if line is longer than limit
+                    if ind + 1 > this.limit {
+                        return Poll::Ready(Some(Err(ReadlinesError::LimitOverflow)));
+                    }
+                    let line = if this.encoding == UTF_8 {
+                        str::from_utf8(&bytes.split_to(ind + 1))
+                            .map_err(|_| ReadlinesError::EncodingError)?
+                            .to_owned()
+                    } else {
+                        this.encoding
+                            .decode_without_bom_handling_and_without_replacement(
+                                &bytes.split_to(ind + 1),
+                            )
+                            .map(Cow::into_owned)
+                            .ok_or(ReadlinesError::EncodingError)?
+                    };
+                    // extend buffer with rest of the bytes;
+                    this.buf.extend_from_slice(&bytes);
+                    this.checked_buff = false;
+                    return Poll::Ready(Some(Ok(line)));
+                }
+                this.buf.extend_from_slice(&bytes);
+                Poll::Pending
+            }
+
+            None => {
+                if this.buf.is_empty() {
+                    return Poll::Ready(None);
+                }
+                if this.buf.len() > this.limit {
+                    return Poll::Ready(Some(Err(ReadlinesError::LimitOverflow)));
+                }
+                let line = if this.encoding == UTF_8 {
+                    str::from_utf8(&this.buf)
+                        .map_err(|_| ReadlinesError::EncodingError)?
+                        .to_owned()
+                } else {
+                    this.encoding
+                        .decode_without_bom_handling_and_without_replacement(&this.buf)
+                        .map(Cow::into_owned)
+                        .ok_or(ReadlinesError::EncodingError)?
+                };
+                this.buf.clear();
+                Poll::Ready(Some(Ok(line)))
+            }
+
+            Some(Err(err)) => Poll::Ready(Some(Err(ReadlinesError::from(err)))),
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use futures_util::StreamExt as _;
+
+    use super::*;
+    use crate::test::TestRequest;
+
+    #[actix_rt::test]
+    async fn test_readlines() {
+        let mut req = TestRequest::default()
+            .set_payload(Bytes::from_static(
+                b"Lorem Ipsum is simply dummy text of the printing and typesetting\n\
+                  industry. Lorem Ipsum has been the industry's standard dummy\n\
+                  Contrary to popular belief, Lorem Ipsum is not simply random text.",
+            ))
+            .to_request();
+
+        let mut stream = Readlines::new(&mut req);
+        assert_eq!(
+            stream.next().await.unwrap().unwrap(),
+            "Lorem Ipsum is simply dummy text of the printing and typesetting\n"
+        );
+
+        assert_eq!(
+            stream.next().await.unwrap().unwrap(),
+            "industry. Lorem Ipsum has been the industry's standard dummy\n"
+        );
+
+        assert_eq!(
+            stream.next().await.unwrap().unwrap(),
+            "Contrary to popular belief, Lorem Ipsum is not simply random text."
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web/web.rs.html b/src/actix_web/web.rs.html new file mode 100644 index 000000000..ef51ec304 --- /dev/null +++ b/src/actix_web/web.rs.html @@ -0,0 +1,427 @@ +web.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
+
//! Essentials helper functions and types for application registration.
+//!
+//! # Request Extractors
+//! - [`Data`]: Application data item
+//! - [`ReqData`]: Request-local data item
+//! - [`Path`]: URL path parameters / dynamic segments
+//! - [`Query`]: URL query parameters
+//! - [`Header`]: Typed header
+//! - [`Json`]: JSON payload
+//! - [`Form`]: URL-encoded payload
+//! - [`Bytes`]: Raw payload
+//!
+//! # Responders
+//! - [`Json`]: JSON response
+//! - [`Form`]: URL-encoded response
+//! - [`Bytes`]: Raw bytes response
+//! - [`Redirect`](Redirect::to): Convenient redirect responses
+
+use std::{borrow::Cow, future::Future};
+
+use actix_router::IntoPatterns;
+pub use bytes::{Buf, BufMut, Bytes, BytesMut};
+
+pub use crate::{
+    config::ServiceConfig, data::Data, redirect::Redirect, request_data::ReqData, types::*,
+};
+use crate::{
+    error::BlockingError, http::Method, service::WebService, FromRequest, Handler, Resource,
+    Responder, Route, Scope,
+};
+
+/// Creates a new resource for a specific path.
+///
+/// Resources may have dynamic path segments. For example, a resource with the path `/a/{name}/c`
+/// would match all incoming requests with paths such as `/a/b/c`, `/a/1/c`, or `/a/etc/c`.
+///
+/// A dynamic segment is specified in the form `{identifier}`, where the identifier can be used
+/// later in a request handler to access the matched value for that segment. This is done by looking
+/// up the identifier in the `Path` object returned by [`HttpRequest.match_info()`] method.
+///
+/// By default, each segment matches the regular expression `[^{}/]+`.
+///
+/// You can also specify a custom regex in the form `{identifier:regex}`:
+///
+/// For instance, to route `GET`-requests on any route matching `/users/{userid}/{friend}` and store
+/// `userid` and `friend` in the exposed `Path` object:
+///
+/// # Examples
+/// ```
+/// use actix_web::{web, App, HttpResponse};
+///
+/// let app = App::new().service(
+///     web::resource("/users/{userid}/{friend}")
+///         .route(web::get().to(|| HttpResponse::Ok()))
+///         .route(web::head().to(|| HttpResponse::MethodNotAllowed()))
+/// );
+/// ```
+pub fn resource<T: IntoPatterns>(path: T) -> Resource {
+    Resource::new(path)
+}
+
+/// Creates scope for common path prefix.
+///
+/// Scopes collect multiple paths under a common path prefix. The scope's path can contain dynamic
+/// path segments.
+///
+/// # Avoid Trailing Slashes
+/// Avoid using trailing slashes in the scope prefix (e.g., `web::scope("/scope/")`). It will almost
+/// certainly not have the expected behavior. See the [documentation on resource definitions][pat]
+/// to understand why this is the case and how to correctly construct scope/prefix definitions.
+///
+/// # Examples
+/// In this example, three routes are set up (and will handle any method):
+/// - `/{project_id}/path1`
+/// - `/{project_id}/path2`
+/// - `/{project_id}/path3`
+///
+/// # Examples
+/// ```
+/// use actix_web::{web, App, HttpResponse};
+///
+/// let app = App::new().service(
+///     web::scope("/{project_id}")
+///         .service(web::resource("/path1").to(|| HttpResponse::Ok()))
+///         .service(web::resource("/path2").to(|| HttpResponse::Ok()))
+///         .service(web::resource("/path3").to(|| HttpResponse::MethodNotAllowed()))
+/// );
+/// ```
+///
+/// [pat]: crate::dev::ResourceDef#prefix-resources
+pub fn scope(path: &str) -> Scope {
+    Scope::new(path)
+}
+
+/// Creates a new un-configured route.
+pub fn route() -> Route {
+    Route::new()
+}
+
+macro_rules! method_route {
+    ($method_fn:ident, $method_const:ident) => {
+        #[doc = concat!(" Creates a new route with `", stringify!($method_const), "` method guard.")]
+        ///
+        /// # Examples
+        #[doc = concat!(" In this example, one `", stringify!($method_const), " /{project_id}` route is set up:")]
+        /// ```
+        /// use actix_web::{web, App, HttpResponse};
+        ///
+        /// let app = App::new().service(
+        ///     web::resource("/{project_id}")
+        #[doc = concat!("         .route(web::", stringify!($method_fn), "().to(|| HttpResponse::Ok()))")]
+        ///
+        /// );
+        /// ```
+        pub fn $method_fn() -> Route {
+            method(Method::$method_const)
+        }
+    };
+}
+
+method_route!(get, GET);
+method_route!(post, POST);
+method_route!(put, PUT);
+method_route!(patch, PATCH);
+method_route!(delete, DELETE);
+method_route!(head, HEAD);
+method_route!(trace, TRACE);
+
+/// Creates a new route with specified method guard.
+///
+/// # Examples
+/// In this example, one `GET /{project_id}` route is set up:
+///
+/// ```
+/// use actix_web::{web, http, App, HttpResponse};
+///
+/// let app = App::new().service(
+///     web::resource("/{project_id}")
+///         .route(web::method(http::Method::GET).to(|| HttpResponse::Ok()))
+/// );
+/// ```
+pub fn method(method: Method) -> Route {
+    Route::new().method(method)
+}
+
+/// Creates a new any-method route with handler.
+///
+/// ```
+/// use actix_web::{web, App, HttpResponse, Responder};
+///
+/// async fn index() -> impl Responder {
+///    HttpResponse::Ok()
+/// }
+///
+/// App::new().service(
+///     web::resource("/").route(
+///         web::to(index))
+/// );
+/// ```
+pub fn to<F, Args>(handler: F) -> Route
+where
+    F: Handler<Args>,
+    Args: FromRequest + 'static,
+    F::Output: Responder + 'static,
+{
+    Route::new().to(handler)
+}
+
+/// Creates a raw service for a specific path.
+///
+/// ```
+/// use actix_web::{dev, web, guard, App, Error, HttpResponse};
+///
+/// async fn my_service(req: dev::ServiceRequest) -> Result<dev::ServiceResponse, Error> {
+///     Ok(req.into_response(HttpResponse::Ok().finish()))
+/// }
+///
+/// let app = App::new().service(
+///     web::service("/users/*")
+///         .guard(guard::Header("content-type", "text/plain"))
+///         .finish(my_service)
+/// );
+/// ```
+pub fn service<T: IntoPatterns>(path: T) -> WebService {
+    WebService::new(path)
+}
+
+/// Create a relative or absolute redirect.
+///
+/// See [`Redirect`] docs for usage details.
+///
+/// # Examples
+/// ```
+/// use actix_web::{web, App};
+///
+/// let app = App::new()
+///     // the client will resolve this redirect to /api/to-path
+///     .service(web::redirect("/api/from-path", "to-path"));
+/// ```
+pub fn redirect(from: impl Into<Cow<'static, str>>, to: impl Into<Cow<'static, str>>) -> Redirect {
+    Redirect::new(from, to)
+}
+
+/// Executes blocking function on a thread pool, returns future that resolves to result of the
+/// function execution.
+pub fn block<F, R>(f: F) -> impl Future<Output = Result<R, BlockingError>>
+where
+    F: FnOnce() -> R + Send + 'static,
+    R: Send + 'static,
+{
+    let fut = actix_rt::task::spawn_blocking(f);
+    async { fut.await.map_err(|_| BlockingError) }
+}
+
\ No newline at end of file diff --git a/src/actix_web_actors/context.rs.html b/src/actix_web_actors/context.rs.html new file mode 100644 index 000000000..9800fea44 --- /dev/null +++ b/src/actix_web_actors/context.rs.html @@ -0,0 +1,595 @@ +context.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
+
use std::{
+    collections::VecDeque,
+    future::Future,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use actix::{
+    dev::{AsyncContextParts, ContextFut, ContextParts, Envelope, Mailbox, ToEnvelope},
+    fut::ActorFuture,
+    Actor, ActorContext, ActorState, Addr, AsyncContext, Handler, Message, SpawnHandle,
+};
+use actix_web::error::Error;
+use bytes::Bytes;
+use futures_core::Stream;
+use tokio::sync::oneshot::Sender;
+
+/// Execution context for HTTP actors
+///
+/// # Example
+///
+/// A demonstration of [server-sent events](https://developer.mozilla.org/docs/Web/API/Server-sent_events) using actors:
+///
+/// ```no_run
+/// use std::time::Duration;
+///
+/// use actix::{Actor, AsyncContext};
+/// use actix_web::{get, http::header, App, HttpResponse, HttpServer};
+/// use actix_web_actors::HttpContext;
+/// use bytes::Bytes;
+///
+/// struct MyActor {
+///     count: usize,
+/// }
+///
+/// impl Actor for MyActor {
+///     type Context = HttpContext<Self>;
+///
+///     fn started(&mut self, ctx: &mut Self::Context) {
+///         ctx.run_later(Duration::from_millis(100), Self::write);
+///     }
+/// }
+///
+/// impl MyActor {
+///     fn write(&mut self, ctx: &mut HttpContext<Self>) {
+///         self.count += 1;
+///         if self.count > 3 {
+///             ctx.write_eof()
+///         } else {
+///             ctx.write(Bytes::from(format!("event: count\ndata: {}\n\n", self.count)));
+///             ctx.run_later(Duration::from_millis(100), Self::write);
+///         }
+///     }
+/// }
+///
+/// #[get("/")]
+/// async fn index() -> HttpResponse {
+///     HttpResponse::Ok()
+///         .insert_header(header::ContentType(mime::TEXT_EVENT_STREAM))
+///         .streaming(HttpContext::create(MyActor { count: 0 }))
+/// }
+///
+/// #[actix_web::main]
+/// async fn main() -> std::io::Result<()> {
+///     HttpServer::new(|| App::new().service(index))
+///         .bind(("127.0.0.1", 8080))?
+///         .run()
+///         .await
+/// }
+/// ```
+pub struct HttpContext<A>
+where
+    A: Actor<Context = HttpContext<A>>,
+{
+    inner: ContextParts<A>,
+    stream: VecDeque<Option<Bytes>>,
+}
+
+impl<A> ActorContext for HttpContext<A>
+where
+    A: Actor<Context = Self>,
+{
+    fn stop(&mut self) {
+        self.inner.stop();
+    }
+    fn terminate(&mut self) {
+        self.inner.terminate()
+    }
+    fn state(&self) -> ActorState {
+        self.inner.state()
+    }
+}
+
+impl<A> AsyncContext<A> for HttpContext<A>
+where
+    A: Actor<Context = Self>,
+{
+    #[inline]
+    fn spawn<F>(&mut self, fut: F) -> SpawnHandle
+    where
+        F: ActorFuture<A, Output = ()> + 'static,
+    {
+        self.inner.spawn(fut)
+    }
+
+    #[inline]
+    fn wait<F>(&mut self, fut: F)
+    where
+        F: ActorFuture<A, Output = ()> + 'static,
+    {
+        self.inner.wait(fut)
+    }
+
+    #[doc(hidden)]
+    #[inline]
+    fn waiting(&self) -> bool {
+        self.inner.waiting()
+            || self.inner.state() == ActorState::Stopping
+            || self.inner.state() == ActorState::Stopped
+    }
+
+    #[inline]
+    fn cancel_future(&mut self, handle: SpawnHandle) -> bool {
+        self.inner.cancel_future(handle)
+    }
+
+    #[inline]
+    fn address(&self) -> Addr<A> {
+        self.inner.address()
+    }
+}
+
+impl<A> HttpContext<A>
+where
+    A: Actor<Context = Self>,
+{
+    #[inline]
+    /// Create a new HTTP Context from a request and an actor
+    pub fn create(actor: A) -> impl Stream<Item = Result<Bytes, Error>> {
+        let mb = Mailbox::default();
+        let ctx = HttpContext {
+            inner: ContextParts::new(mb.sender_producer()),
+            stream: VecDeque::new(),
+        };
+        HttpContextFut::new(ctx, actor, mb)
+    }
+
+    /// Create a new HTTP Context
+    pub fn with_factory<F>(f: F) -> impl Stream<Item = Result<Bytes, Error>>
+    where
+        F: FnOnce(&mut Self) -> A + 'static,
+    {
+        let mb = Mailbox::default();
+        let mut ctx = HttpContext {
+            inner: ContextParts::new(mb.sender_producer()),
+            stream: VecDeque::new(),
+        };
+
+        let act = f(&mut ctx);
+        HttpContextFut::new(ctx, act, mb)
+    }
+}
+
+impl<A> HttpContext<A>
+where
+    A: Actor<Context = Self>,
+{
+    /// Write payload
+    #[inline]
+    pub fn write(&mut self, data: Bytes) {
+        self.stream.push_back(Some(data));
+    }
+
+    /// Indicate end of streaming payload. Also this method calls `Self::close`.
+    #[inline]
+    pub fn write_eof(&mut self) {
+        self.stream.push_back(None);
+    }
+
+    /// Handle of the running future
+    ///
+    /// SpawnHandle is the handle returned by `AsyncContext::spawn()` method.
+    pub fn handle(&self) -> SpawnHandle {
+        self.inner.curr_handle()
+    }
+}
+
+impl<A> AsyncContextParts<A> for HttpContext<A>
+where
+    A: Actor<Context = Self>,
+{
+    fn parts(&mut self) -> &mut ContextParts<A> {
+        &mut self.inner
+    }
+}
+
+struct HttpContextFut<A>
+where
+    A: Actor<Context = HttpContext<A>>,
+{
+    fut: ContextFut<A, HttpContext<A>>,
+}
+
+impl<A> HttpContextFut<A>
+where
+    A: Actor<Context = HttpContext<A>>,
+{
+    fn new(ctx: HttpContext<A>, act: A, mailbox: Mailbox<A>) -> Self {
+        let fut = ContextFut::new(ctx, act, mailbox);
+        HttpContextFut { fut }
+    }
+}
+
+impl<A> Stream for HttpContextFut<A>
+where
+    A: Actor<Context = HttpContext<A>>,
+{
+    type Item = Result<Bytes, Error>;
+
+    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        if self.fut.alive() {
+            let _ = Pin::new(&mut self.fut).poll(cx);
+        }
+
+        // frames
+        if let Some(data) = self.fut.ctx().stream.pop_front() {
+            Poll::Ready(data.map(Ok))
+        } else if self.fut.alive() {
+            Poll::Pending
+        } else {
+            Poll::Ready(None)
+        }
+    }
+}
+
+impl<A, M> ToEnvelope<A, M> for HttpContext<A>
+where
+    A: Actor<Context = HttpContext<A>> + Handler<M>,
+    M: Message + Send + 'static,
+    M::Result: Send,
+{
+    fn pack(msg: M, tx: Option<Sender<M::Result>>) -> Envelope<A> {
+        Envelope::new(msg, tx)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::time::Duration;
+
+    use actix_web::{
+        http::StatusCode,
+        test::{call_service, init_service, read_body, TestRequest},
+        web, App, HttpResponse,
+    };
+
+    use super::*;
+
+    struct MyActor {
+        count: usize,
+    }
+
+    impl Actor for MyActor {
+        type Context = HttpContext<Self>;
+
+        fn started(&mut self, ctx: &mut Self::Context) {
+            ctx.run_later(Duration::from_millis(100), Self::write);
+        }
+    }
+
+    impl MyActor {
+        fn write(&mut self, ctx: &mut HttpContext<Self>) {
+            self.count += 1;
+            if self.count > 3 {
+                ctx.write_eof()
+            } else {
+                ctx.write(Bytes::from(format!("LINE-{}", self.count)));
+                ctx.run_later(Duration::from_millis(100), Self::write);
+            }
+        }
+    }
+
+    #[actix_rt::test]
+    async fn test_default_resource() {
+        let srv = init_service(App::new().service(web::resource("/test").to(|| async {
+            HttpResponse::Ok().streaming(HttpContext::create(MyActor { count: 0 }))
+        })))
+        .await;
+
+        let req = TestRequest::with_uri("/test").to_request();
+        let resp = call_service(&srv, req).await;
+        assert_eq!(resp.status(), StatusCode::OK);
+
+        let body = read_body(resp).await;
+        assert_eq!(body, Bytes::from_static(b"LINE-1LINE-2LINE-3"));
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web_actors/lib.rs.html b/src/actix_web_actors/lib.rs.html new file mode 100644 index 000000000..c59586507 --- /dev/null +++ b/src/actix_web_actors/lib.rs.html @@ -0,0 +1,135 @@ +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
+
//! Actix actors support for Actix Web.
+//!
+//! # Examples
+//!
+//! ```no_run
+//! use actix::{Actor, StreamHandler};
+//! use actix_web::{get, web, App, Error, HttpRequest, HttpResponse, HttpServer};
+//! use actix_web_actors::ws;
+//!
+//! /// Define Websocket actor
+//! struct MyWs;
+//!
+//! impl Actor for MyWs {
+//!     type Context = ws::WebsocketContext<Self>;
+//! }
+//!
+//! /// Handler for ws::Message message
+//! impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for MyWs {
+//!     fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, ctx: &mut Self::Context) {
+//!         match msg {
+//!             Ok(ws::Message::Ping(msg)) => ctx.pong(&msg),
+//!             Ok(ws::Message::Text(text)) => ctx.text(text),
+//!             Ok(ws::Message::Binary(bin)) => ctx.binary(bin),
+//!             _ => (),
+//!         }
+//!     }
+//! }
+//!
+//! #[get("/ws")]
+//! async fn index(req: HttpRequest, stream: web::Payload) -> Result<HttpResponse, Error> {
+//!     ws::start(MyWs, &req, stream)
+//! }
+//!
+//! #[actix_web::main]
+//! async fn main() -> std::io::Result<()> {
+//!     HttpServer::new(|| App::new().service(index))
+//!         .bind(("127.0.0.1", 8080))?
+//!         .run()
+//!         .await
+//! }
+//! ```
+//!
+//! # Documentation & Community Resources
+//! In addition to this API documentation, several other resources are available:
+//!
+//! * [Website & User Guide](https://actix.rs/)
+//! * [Documentation for `actix_web`](actix_web)
+//! * [Examples Repository](https://github.com/actix/examples)
+//! * [Community Chat on Discord](https://discord.gg/NWpN5mmg3x)
+//!
+//! To get started navigating the API docs, you may consider looking at the following pages first:
+//!
+//! * [`ws`]: This module provides actor support for WebSockets.
+//!
+//! * [`HttpContext`]: This struct provides actor support for streaming HTTP responses.
+//!
+
+#![deny(rust_2018_idioms, nonstandard_style)]
+#![warn(future_incompatible)]
+#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
+#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+
+mod context;
+pub mod ws;
+
+pub use self::context::HttpContext;
+
\ No newline at end of file diff --git a/src/actix_web_actors/ws.rs.html b/src/actix_web_actors/ws.rs.html new file mode 100644 index 000000000..f47cbe91b --- /dev/null +++ b/src/actix_web_actors/ws.rs.html @@ -0,0 +1,2119 @@ +ws.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
+
//! Websocket integration.
+//!
+//! # Examples
+//!
+//! ```no_run
+//! use actix::{Actor, StreamHandler};
+//! use actix_web::{get, web, App, Error, HttpRequest, HttpResponse, HttpServer};
+//! use actix_web_actors::ws;
+//!
+//! /// Define Websocket actor
+//! struct MyWs;
+//!
+//! impl Actor for MyWs {
+//!     type Context = ws::WebsocketContext<Self>;
+//! }
+//!
+//! /// Handler for ws::Message message
+//! impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for MyWs {
+//!     fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, ctx: &mut Self::Context) {
+//!         match msg {
+//!             Ok(ws::Message::Ping(msg)) => ctx.pong(&msg),
+//!             Ok(ws::Message::Text(text)) => ctx.text(text),
+//!             Ok(ws::Message::Binary(bin)) => ctx.binary(bin),
+//!             _ => (),
+//!         }
+//!     }
+//! }
+//!
+//! #[get("/ws")]
+//! async fn websocket(req: HttpRequest, stream: web::Payload) -> Result<HttpResponse, Error> {
+//!     ws::start(MyWs, &req, stream)
+//! }
+//!
+//! const MAX_FRAME_SIZE: usize = 16_384; // 16KiB
+//!
+//! #[get("/custom-ws")]
+//! async fn custom_websocket(req: HttpRequest, stream: web::Payload) -> Result<HttpResponse, Error> {
+//!     // Create a Websocket session with a specific max frame size, and protocols.
+//!     ws::WsResponseBuilder::new(MyWs, &req, stream)
+//!         .frame_size(MAX_FRAME_SIZE)
+//!         .protocols(&["A", "B"])
+//!         .start()
+//! }
+//!
+//! #[actix_web::main]
+//! async fn main() -> std::io::Result<()> {
+//!     HttpServer::new(|| {
+//!             App::new()
+//!                 .service(websocket)
+//!                 .service(custom_websocket)
+//!         })
+//!         .bind(("127.0.0.1", 8080))?
+//!         .run()
+//!         .await
+//! }
+//! ```
+//!
+
+use std::{
+    collections::VecDeque,
+    future::Future,
+    io, mem,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use actix::{
+    dev::{
+        AsyncContextParts, ContextFut, ContextParts, Envelope, Mailbox, StreamHandler, ToEnvelope,
+    },
+    fut::ActorFuture,
+    Actor, ActorContext, ActorState, Addr, AsyncContext, Handler, Message as ActixMessage,
+    SpawnHandle,
+};
+use actix_http::ws::{hash_key, Codec};
+pub use actix_http::ws::{CloseCode, CloseReason, Frame, HandshakeError, Message, ProtocolError};
+use actix_web::{
+    error::{Error, PayloadError},
+    http::{
+        header::{self, HeaderValue},
+        Method, StatusCode,
+    },
+    HttpRequest, HttpResponse, HttpResponseBuilder,
+};
+use bytes::{Bytes, BytesMut};
+use bytestring::ByteString;
+use futures_core::Stream;
+use pin_project_lite::pin_project;
+use tokio::sync::oneshot;
+use tokio_util::codec::{Decoder as _, Encoder as _};
+
+/// Builder for Websocket session response.
+///
+/// # Examples
+///
+/// ```no_run
+/// # use actix::{Actor, StreamHandler};
+/// # use actix_web::{get, web, App, Error, HttpRequest, HttpResponse, HttpServer};
+/// # use actix_web_actors::ws;
+/// #
+/// # struct MyWs;
+/// #
+/// # impl Actor for MyWs {
+/// #     type Context = ws::WebsocketContext<Self>;
+/// # }
+/// #
+/// # /// Handler for ws::Message message
+/// # impl StreamHandler<Result<ws::Message, ws::ProtocolError>> for MyWs {
+/// #     fn handle(&mut self, msg: Result<ws::Message, ws::ProtocolError>, ctx: &mut Self::Context) {}
+/// # }
+/// #
+/// #[get("/ws")]
+/// async fn websocket(req: HttpRequest, stream: web::Payload) -> Result<HttpResponse, Error> {
+///     ws::WsResponseBuilder::new(MyWs, &req, stream).start()
+/// }
+///
+/// const MAX_FRAME_SIZE: usize = 16_384; // 16KiB
+///
+/// #[get("/custom-ws")]
+/// async fn custom_websocket(req: HttpRequest, stream: web::Payload) -> Result<HttpResponse, Error> {
+///     // Create a Websocket session with a specific max frame size, codec, and protocols.
+///     ws::WsResponseBuilder::new(MyWs, &req, stream)
+///         .codec(actix_http::ws::Codec::new())
+///         // This will overwrite the codec's max frame-size
+///         .frame_size(MAX_FRAME_SIZE)
+///         .protocols(&["A", "B"])
+///         .start()
+/// }
+/// #
+/// # #[actix_web::main]
+/// # async fn main() -> std::io::Result<()> {
+/// #     HttpServer::new(|| {
+/// #             App::new()
+/// #                 .service(websocket)
+/// #                 .service(custom_websocket)
+/// #         })
+/// #         .bind(("127.0.0.1", 8080))?
+/// #         .run()
+/// #         .await
+/// # }
+/// ```
+pub struct WsResponseBuilder<'a, A, T>
+where
+    A: Actor<Context = WebsocketContext<A>> + StreamHandler<Result<Message, ProtocolError>>,
+    T: Stream<Item = Result<Bytes, PayloadError>> + 'static,
+{
+    actor: A,
+    req: &'a HttpRequest,
+    stream: T,
+    codec: Option<Codec>,
+    protocols: Option<&'a [&'a str]>,
+    frame_size: Option<usize>,
+}
+
+impl<'a, A, T> WsResponseBuilder<'a, A, T>
+where
+    A: Actor<Context = WebsocketContext<A>> + StreamHandler<Result<Message, ProtocolError>>,
+    T: Stream<Item = Result<Bytes, PayloadError>> + 'static,
+{
+    /// Construct a new `WsResponseBuilder` with actor, request, and payload stream.
+    ///
+    /// For usage example, see docs on [`WsResponseBuilder`] struct.
+    pub fn new(actor: A, req: &'a HttpRequest, stream: T) -> Self {
+        WsResponseBuilder {
+            actor,
+            req,
+            stream,
+            codec: None,
+            protocols: None,
+            frame_size: None,
+        }
+    }
+
+    /// Set the protocols for the session.
+    pub fn protocols(mut self, protocols: &'a [&'a str]) -> Self {
+        self.protocols = Some(protocols);
+        self
+    }
+
+    /// Set the max frame size for each message (in bytes).
+    ///
+    /// **Note**: This will override any given [`Codec`]'s max frame size.
+    pub fn frame_size(mut self, frame_size: usize) -> Self {
+        self.frame_size = Some(frame_size);
+        self
+    }
+
+    /// Set the [`Codec`] for the session. If [`Self::frame_size`] is also set, the given
+    /// [`Codec`]'s max frame size will be overridden.
+    pub fn codec(mut self, codec: Codec) -> Self {
+        self.codec = Some(codec);
+        self
+    }
+
+    fn handshake_resp(&self) -> Result<HttpResponseBuilder, HandshakeError> {
+        match self.protocols {
+            Some(protocols) => handshake_with_protocols(self.req, protocols),
+            None => handshake(self.req),
+        }
+    }
+
+    fn set_frame_size(&mut self) {
+        if let Some(frame_size) = self.frame_size {
+            match &mut self.codec {
+                Some(codec) => {
+                    // modify existing codec's max frame size
+                    let orig_codec = mem::take(codec);
+                    *codec = orig_codec.max_size(frame_size);
+                }
+
+                None => {
+                    // create a new codec with the given size
+                    self.codec = Some(Codec::new().max_size(frame_size));
+                }
+            }
+        }
+    }
+
+    /// Create a new Websocket context from an actor, request stream, and codec.
+    ///
+    /// Returns a pair, where the first item is an addr for the created actor, and the second item
+    /// is a stream intended to be set as part of the response
+    /// via [`HttpResponseBuilder::streaming()`].
+    fn create_with_codec_addr<S>(
+        actor: A,
+        stream: S,
+        codec: Codec,
+    ) -> (Addr<A>, impl Stream<Item = Result<Bytes, Error>>)
+    where
+        A: StreamHandler<Result<Message, ProtocolError>>,
+        S: Stream<Item = Result<Bytes, PayloadError>> + 'static,
+    {
+        let mb = Mailbox::default();
+        let mut ctx = WebsocketContext {
+            inner: ContextParts::new(mb.sender_producer()),
+            messages: VecDeque::new(),
+        };
+        ctx.add_stream(WsStream::new(stream, codec.clone()));
+
+        let addr = ctx.address();
+
+        (addr, WebsocketContextFut::new(ctx, actor, mb, codec))
+    }
+
+    /// Perform WebSocket handshake and start actor.
+    ///
+    /// `req` is an [`HttpRequest`] that should be requesting a websocket protocol change.
+    /// `stream` should be a [`Bytes`] stream (such as `actix_web::web::Payload`) that contains a
+    /// stream of the body request.
+    ///
+    /// If there is a problem with the handshake, an error is returned.
+    ///
+    /// If successful, consume the [`WsResponseBuilder`] and return a [`HttpResponse`] wrapped in
+    /// a [`Result`].
+    pub fn start(mut self) -> Result<HttpResponse, Error> {
+        let mut res = self.handshake_resp()?;
+        self.set_frame_size();
+
+        match self.codec {
+            Some(codec) => {
+                let out_stream = WebsocketContext::with_codec(self.actor, self.stream, codec);
+                Ok(res.streaming(out_stream))
+            }
+            None => {
+                let out_stream = WebsocketContext::create(self.actor, self.stream);
+                Ok(res.streaming(out_stream))
+            }
+        }
+    }
+
+    /// Perform WebSocket handshake and start actor.
+    ///
+    /// `req` is an [`HttpRequest`] that should be requesting a websocket protocol change.
+    /// `stream` should be a [`Bytes`] stream (such as `actix_web::web::Payload`) that contains a
+    /// stream of the body request.
+    ///
+    /// If there is a problem with the handshake, an error is returned.
+    ///
+    /// If successful, returns a pair where the first item is an address for the created actor and
+    /// the second item is the [`HttpResponse`] that should be returned from the websocket request.
+    pub fn start_with_addr(mut self) -> Result<(Addr<A>, HttpResponse), Error> {
+        let mut res = self.handshake_resp()?;
+        self.set_frame_size();
+
+        match self.codec {
+            Some(codec) => {
+                let (addr, out_stream) =
+                    Self::create_with_codec_addr(self.actor, self.stream, codec);
+                Ok((addr, res.streaming(out_stream)))
+            }
+            None => {
+                let (addr, out_stream) =
+                    WebsocketContext::create_with_addr(self.actor, self.stream);
+                Ok((addr, res.streaming(out_stream)))
+            }
+        }
+    }
+}
+
+/// Perform WebSocket handshake and start actor.
+///
+/// To customize options, see [`WsResponseBuilder`].
+pub fn start<A, T>(actor: A, req: &HttpRequest, stream: T) -> Result<HttpResponse, Error>
+where
+    A: Actor<Context = WebsocketContext<A>> + StreamHandler<Result<Message, ProtocolError>>,
+    T: Stream<Item = Result<Bytes, PayloadError>> + 'static,
+{
+    let mut res = handshake(req)?;
+    Ok(res.streaming(WebsocketContext::create(actor, stream)))
+}
+
+/// Perform WebSocket handshake and start actor.
+///
+/// `req` is an HTTP Request that should be requesting a websocket protocol change. `stream` should
+/// be a `Bytes` stream (such as `actix_web::web::Payload`) that contains a stream of the
+/// body request.
+///
+/// If there is a problem with the handshake, an error is returned.
+///
+/// If successful, returns a pair where the first item is an address for the created actor and the
+/// second item is the response that should be returned from the WebSocket request.
+#[deprecated(since = "4.0.0", note = "Prefer `WsResponseBuilder::start_with_addr`.")]
+pub fn start_with_addr<A, T>(
+    actor: A,
+    req: &HttpRequest,
+    stream: T,
+) -> Result<(Addr<A>, HttpResponse), Error>
+where
+    A: Actor<Context = WebsocketContext<A>> + StreamHandler<Result<Message, ProtocolError>>,
+    T: Stream<Item = Result<Bytes, PayloadError>> + 'static,
+{
+    let mut res = handshake(req)?;
+    let (addr, out_stream) = WebsocketContext::create_with_addr(actor, stream);
+    Ok((addr, res.streaming(out_stream)))
+}
+
+/// Do WebSocket handshake and start ws actor.
+///
+/// `protocols` is a sequence of known protocols.
+#[deprecated(
+    since = "4.0.0",
+    note = "Prefer `WsResponseBuilder` for setting protocols."
+)]
+pub fn start_with_protocols<A, T>(
+    actor: A,
+    protocols: &[&str],
+    req: &HttpRequest,
+    stream: T,
+) -> Result<HttpResponse, Error>
+where
+    A: Actor<Context = WebsocketContext<A>> + StreamHandler<Result<Message, ProtocolError>>,
+    T: Stream<Item = Result<Bytes, PayloadError>> + 'static,
+{
+    let mut res = handshake_with_protocols(req, protocols)?;
+    Ok(res.streaming(WebsocketContext::create(actor, stream)))
+}
+
+/// Prepare WebSocket handshake response.
+///
+/// This function returns handshake `HttpResponse`, ready to send to peer. It does not perform
+/// any IO.
+pub fn handshake(req: &HttpRequest) -> Result<HttpResponseBuilder, HandshakeError> {
+    handshake_with_protocols(req, &[])
+}
+
+/// Prepare WebSocket handshake response.
+///
+/// This function returns handshake `HttpResponse`, ready to send to peer. It does not perform
+/// any IO.
+///
+/// `protocols` is a sequence of known protocols. On successful handshake, the returned response
+/// headers contain the first protocol in this list which the server also knows.
+pub fn handshake_with_protocols(
+    req: &HttpRequest,
+    protocols: &[&str],
+) -> Result<HttpResponseBuilder, HandshakeError> {
+    // WebSocket accepts only GET
+    if *req.method() != Method::GET {
+        return Err(HandshakeError::GetMethodRequired);
+    }
+
+    // check for "UPGRADE" to WebSocket header
+    let has_hdr = if let Some(hdr) = req.headers().get(&header::UPGRADE) {
+        if let Ok(s) = hdr.to_str() {
+            s.to_ascii_lowercase().contains("websocket")
+        } else {
+            false
+        }
+    } else {
+        false
+    };
+    if !has_hdr {
+        return Err(HandshakeError::NoWebsocketUpgrade);
+    }
+
+    // Upgrade connection
+    if !req.head().upgrade() {
+        return Err(HandshakeError::NoConnectionUpgrade);
+    }
+
+    // check supported version
+    if !req.headers().contains_key(&header::SEC_WEBSOCKET_VERSION) {
+        return Err(HandshakeError::NoVersionHeader);
+    }
+    let supported_ver = {
+        if let Some(hdr) = req.headers().get(&header::SEC_WEBSOCKET_VERSION) {
+            hdr == "13" || hdr == "8" || hdr == "7"
+        } else {
+            false
+        }
+    };
+    if !supported_ver {
+        return Err(HandshakeError::UnsupportedVersion);
+    }
+
+    // check client handshake for validity
+    if !req.headers().contains_key(&header::SEC_WEBSOCKET_KEY) {
+        return Err(HandshakeError::BadWebsocketKey);
+    }
+    let key = {
+        let key = req.headers().get(&header::SEC_WEBSOCKET_KEY).unwrap();
+        hash_key(key.as_ref())
+    };
+
+    // check requested protocols
+    let protocol = req
+        .headers()
+        .get(&header::SEC_WEBSOCKET_PROTOCOL)
+        .and_then(|req_protocols| {
+            let req_protocols = req_protocols.to_str().ok()?;
+            req_protocols
+                .split(',')
+                .map(|req_p| req_p.trim())
+                .find(|req_p| protocols.iter().any(|p| p == req_p))
+        });
+
+    let mut response = HttpResponse::build(StatusCode::SWITCHING_PROTOCOLS)
+        .upgrade("websocket")
+        .insert_header((
+            header::SEC_WEBSOCKET_ACCEPT,
+            // key is known to be header value safe ascii
+            HeaderValue::from_bytes(&key).unwrap(),
+        ))
+        .take();
+
+    if let Some(protocol) = protocol {
+        response.insert_header((header::SEC_WEBSOCKET_PROTOCOL, protocol));
+    }
+
+    Ok(response)
+}
+
+/// Execution context for `WebSockets` actors
+pub struct WebsocketContext<A>
+where
+    A: Actor<Context = WebsocketContext<A>>,
+{
+    inner: ContextParts<A>,
+    messages: VecDeque<Option<Message>>,
+}
+
+impl<A> ActorContext for WebsocketContext<A>
+where
+    A: Actor<Context = Self>,
+{
+    fn stop(&mut self) {
+        self.inner.stop();
+    }
+
+    fn terminate(&mut self) {
+        self.inner.terminate()
+    }
+
+    fn state(&self) -> ActorState {
+        self.inner.state()
+    }
+}
+
+impl<A> AsyncContext<A> for WebsocketContext<A>
+where
+    A: Actor<Context = Self>,
+{
+    fn spawn<F>(&mut self, fut: F) -> SpawnHandle
+    where
+        F: ActorFuture<A, Output = ()> + 'static,
+    {
+        self.inner.spawn(fut)
+    }
+
+    fn wait<F>(&mut self, fut: F)
+    where
+        F: ActorFuture<A, Output = ()> + 'static,
+    {
+        self.inner.wait(fut)
+    }
+
+    #[doc(hidden)]
+    #[inline]
+    fn waiting(&self) -> bool {
+        self.inner.waiting()
+            || self.inner.state() == ActorState::Stopping
+            || self.inner.state() == ActorState::Stopped
+    }
+
+    fn cancel_future(&mut self, handle: SpawnHandle) -> bool {
+        self.inner.cancel_future(handle)
+    }
+
+    #[inline]
+    fn address(&self) -> Addr<A> {
+        self.inner.address()
+    }
+}
+
+impl<A> WebsocketContext<A>
+where
+    A: Actor<Context = Self>,
+{
+    /// Create a new Websocket context from a request and an actor.
+    #[inline]
+    pub fn create<S>(actor: A, stream: S) -> impl Stream<Item = Result<Bytes, Error>>
+    where
+        A: StreamHandler<Result<Message, ProtocolError>>,
+        S: Stream<Item = Result<Bytes, PayloadError>> + 'static,
+    {
+        let (_, stream) = WebsocketContext::create_with_addr(actor, stream);
+        stream
+    }
+
+    /// Create a new Websocket context from a request and an actor.
+    ///
+    /// Returns a pair, where the first item is an addr for the created actor, and the second item
+    /// is a stream intended to be set as part of the response
+    /// via [`HttpResponseBuilder::streaming()`].
+    pub fn create_with_addr<S>(
+        actor: A,
+        stream: S,
+    ) -> (Addr<A>, impl Stream<Item = Result<Bytes, Error>>)
+    where
+        A: StreamHandler<Result<Message, ProtocolError>>,
+        S: Stream<Item = Result<Bytes, PayloadError>> + 'static,
+    {
+        let mb = Mailbox::default();
+        let mut ctx = WebsocketContext {
+            inner: ContextParts::new(mb.sender_producer()),
+            messages: VecDeque::new(),
+        };
+        ctx.add_stream(WsStream::new(stream, Codec::new()));
+
+        let addr = ctx.address();
+
+        (addr, WebsocketContextFut::new(ctx, actor, mb, Codec::new()))
+    }
+
+    /// Create a new Websocket context from a request, an actor, and a codec
+    pub fn with_codec<S>(
+        actor: A,
+        stream: S,
+        codec: Codec,
+    ) -> impl Stream<Item = Result<Bytes, Error>>
+    where
+        A: StreamHandler<Result<Message, ProtocolError>>,
+        S: Stream<Item = Result<Bytes, PayloadError>> + 'static,
+    {
+        let mb = Mailbox::default();
+        let mut ctx = WebsocketContext {
+            inner: ContextParts::new(mb.sender_producer()),
+            messages: VecDeque::new(),
+        };
+        ctx.add_stream(WsStream::new(stream, codec.clone()));
+
+        WebsocketContextFut::new(ctx, actor, mb, codec)
+    }
+
+    /// Create a new Websocket context
+    pub fn with_factory<S, F>(stream: S, f: F) -> impl Stream<Item = Result<Bytes, Error>>
+    where
+        F: FnOnce(&mut Self) -> A + 'static,
+        A: StreamHandler<Result<Message, ProtocolError>>,
+        S: Stream<Item = Result<Bytes, PayloadError>> + 'static,
+    {
+        let mb = Mailbox::default();
+        let mut ctx = WebsocketContext {
+            inner: ContextParts::new(mb.sender_producer()),
+            messages: VecDeque::new(),
+        };
+        ctx.add_stream(WsStream::new(stream, Codec::new()));
+
+        let act = f(&mut ctx);
+
+        WebsocketContextFut::new(ctx, act, mb, Codec::new())
+    }
+}
+
+impl<A> WebsocketContext<A>
+where
+    A: Actor<Context = Self>,
+{
+    /// Write payload
+    ///
+    /// This is a low-level function that accepts framed messages that should
+    /// be created using `Frame::message()`. If you want to send text or binary
+    /// data you should prefer the `text()` or `binary()` convenience functions
+    /// that handle the framing for you.
+    #[inline]
+    pub fn write_raw(&mut self, msg: Message) {
+        self.messages.push_back(Some(msg));
+    }
+
+    /// Send text frame
+    #[inline]
+    pub fn text(&mut self, text: impl Into<ByteString>) {
+        self.write_raw(Message::Text(text.into()));
+    }
+
+    /// Send binary frame
+    #[inline]
+    pub fn binary(&mut self, data: impl Into<Bytes>) {
+        self.write_raw(Message::Binary(data.into()));
+    }
+
+    /// Send ping frame
+    #[inline]
+    pub fn ping(&mut self, message: &[u8]) {
+        self.write_raw(Message::Ping(Bytes::copy_from_slice(message)));
+    }
+
+    /// Send pong frame
+    #[inline]
+    pub fn pong(&mut self, message: &[u8]) {
+        self.write_raw(Message::Pong(Bytes::copy_from_slice(message)));
+    }
+
+    /// Send close frame
+    #[inline]
+    pub fn close(&mut self, reason: Option<CloseReason>) {
+        self.write_raw(Message::Close(reason));
+    }
+
+    /// Handle of the running future
+    ///
+    /// SpawnHandle is the handle returned by `AsyncContext::spawn()` method.
+    pub fn handle(&self) -> SpawnHandle {
+        self.inner.curr_handle()
+    }
+
+    /// Set mailbox capacity
+    ///
+    /// By default mailbox capacity is 16 messages.
+    pub fn set_mailbox_capacity(&mut self, cap: usize) {
+        self.inner.set_mailbox_capacity(cap)
+    }
+}
+
+impl<A> AsyncContextParts<A> for WebsocketContext<A>
+where
+    A: Actor<Context = Self>,
+{
+    fn parts(&mut self) -> &mut ContextParts<A> {
+        &mut self.inner
+    }
+}
+
+struct WebsocketContextFut<A>
+where
+    A: Actor<Context = WebsocketContext<A>>,
+{
+    fut: ContextFut<A, WebsocketContext<A>>,
+    encoder: Codec,
+    buf: BytesMut,
+    closed: bool,
+}
+
+impl<A> WebsocketContextFut<A>
+where
+    A: Actor<Context = WebsocketContext<A>>,
+{
+    fn new(ctx: WebsocketContext<A>, act: A, mailbox: Mailbox<A>, codec: Codec) -> Self {
+        let fut = ContextFut::new(ctx, act, mailbox);
+        WebsocketContextFut {
+            fut,
+            encoder: codec,
+            buf: BytesMut::new(),
+            closed: false,
+        }
+    }
+}
+
+impl<A> Stream for WebsocketContextFut<A>
+where
+    A: Actor<Context = WebsocketContext<A>>,
+{
+    type Item = Result<Bytes, Error>;
+
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        let this = self.get_mut();
+
+        if this.fut.alive() {
+            let _ = Pin::new(&mut this.fut).poll(cx);
+        }
+
+        // encode messages
+        while let Some(item) = this.fut.ctx().messages.pop_front() {
+            if let Some(msg) = item {
+                this.encoder.encode(msg, &mut this.buf)?;
+            } else {
+                this.closed = true;
+                break;
+            }
+        }
+
+        if !this.buf.is_empty() {
+            Poll::Ready(Some(Ok(this.buf.split().freeze())))
+        } else if this.fut.alive() && !this.closed {
+            Poll::Pending
+        } else {
+            Poll::Ready(None)
+        }
+    }
+}
+
+impl<A, M> ToEnvelope<A, M> for WebsocketContext<A>
+where
+    A: Actor<Context = WebsocketContext<A>> + Handler<M>,
+    M: ActixMessage + Send + 'static,
+    M::Result: Send,
+{
+    fn pack(msg: M, tx: Option<oneshot::Sender<M::Result>>) -> Envelope<A> {
+        Envelope::new(msg, tx)
+    }
+}
+
+pin_project! {
+    #[derive(Debug)]
+    struct WsStream<S> {
+        #[pin]
+        stream: S,
+        decoder: Codec,
+        buf: BytesMut,
+        closed: bool,
+    }
+}
+
+impl<S> WsStream<S>
+where
+    S: Stream<Item = Result<Bytes, PayloadError>>,
+{
+    fn new(stream: S, codec: Codec) -> Self {
+        Self {
+            stream,
+            decoder: codec,
+            buf: BytesMut::new(),
+            closed: false,
+        }
+    }
+}
+
+impl<S> Stream for WsStream<S>
+where
+    S: Stream<Item = Result<Bytes, PayloadError>>,
+{
+    type Item = Result<Message, ProtocolError>;
+
+    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        let mut this = self.as_mut().project();
+
+        if !*this.closed {
+            loop {
+                match Pin::new(&mut this.stream).poll_next(cx) {
+                    Poll::Ready(Some(Ok(chunk))) => {
+                        this.buf.extend_from_slice(&chunk[..]);
+                    }
+                    Poll::Ready(None) => {
+                        *this.closed = true;
+                        break;
+                    }
+                    Poll::Pending => break,
+                    Poll::Ready(Some(Err(err))) => {
+                        return Poll::Ready(Some(Err(ProtocolError::Io(io::Error::new(
+                            io::ErrorKind::Other,
+                            format!("{err}"),
+                        )))));
+                    }
+                }
+            }
+        }
+
+        match this.decoder.decode(this.buf)? {
+            None => {
+                if *this.closed {
+                    Poll::Ready(None)
+                } else {
+                    Poll::Pending
+                }
+            }
+            Some(frm) => {
+                let msg = match frm {
+                    Frame::Text(data) => {
+                        Message::Text(ByteString::try_from(data).map_err(|e| {
+                            ProtocolError::Io(io::Error::new(
+                                io::ErrorKind::Other,
+                                format!("{}", e),
+                            ))
+                        })?)
+                    }
+                    Frame::Binary(data) => Message::Binary(data),
+                    Frame::Ping(s) => Message::Ping(s),
+                    Frame::Pong(s) => Message::Pong(s),
+                    Frame::Close(reason) => Message::Close(reason),
+                    Frame::Continuation(item) => Message::Continuation(item),
+                };
+                Poll::Ready(Some(Ok(msg)))
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_web::test::TestRequest;
+
+    use super::*;
+
+    #[test]
+    fn test_handshake() {
+        let req = TestRequest::default()
+            .method(Method::POST)
+            .to_http_request();
+        assert_eq!(
+            HandshakeError::GetMethodRequired,
+            handshake(&req).err().unwrap()
+        );
+
+        let req = TestRequest::default().to_http_request();
+        assert_eq!(
+            HandshakeError::NoWebsocketUpgrade,
+            handshake(&req).err().unwrap()
+        );
+
+        let req = TestRequest::default()
+            .insert_header((header::UPGRADE, header::HeaderValue::from_static("test")))
+            .to_http_request();
+        assert_eq!(
+            HandshakeError::NoWebsocketUpgrade,
+            handshake(&req).err().unwrap()
+        );
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::UPGRADE,
+                header::HeaderValue::from_static("websocket"),
+            ))
+            .to_http_request();
+        assert_eq!(
+            HandshakeError::NoConnectionUpgrade,
+            handshake(&req).err().unwrap()
+        );
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::UPGRADE,
+                header::HeaderValue::from_static("websocket"),
+            ))
+            .insert_header((
+                header::CONNECTION,
+                header::HeaderValue::from_static("upgrade"),
+            ))
+            .to_http_request();
+        assert_eq!(
+            HandshakeError::NoVersionHeader,
+            handshake(&req).err().unwrap()
+        );
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::UPGRADE,
+                header::HeaderValue::from_static("websocket"),
+            ))
+            .insert_header((
+                header::CONNECTION,
+                header::HeaderValue::from_static("upgrade"),
+            ))
+            .insert_header((
+                header::SEC_WEBSOCKET_VERSION,
+                header::HeaderValue::from_static("5"),
+            ))
+            .to_http_request();
+        assert_eq!(
+            HandshakeError::UnsupportedVersion,
+            handshake(&req).err().unwrap()
+        );
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::UPGRADE,
+                header::HeaderValue::from_static("websocket"),
+            ))
+            .insert_header((
+                header::CONNECTION,
+                header::HeaderValue::from_static("upgrade"),
+            ))
+            .insert_header((
+                header::SEC_WEBSOCKET_VERSION,
+                header::HeaderValue::from_static("13"),
+            ))
+            .to_http_request();
+        assert_eq!(
+            HandshakeError::BadWebsocketKey,
+            handshake(&req).err().unwrap()
+        );
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::UPGRADE,
+                header::HeaderValue::from_static("websocket"),
+            ))
+            .insert_header((
+                header::CONNECTION,
+                header::HeaderValue::from_static("upgrade"),
+            ))
+            .insert_header((
+                header::SEC_WEBSOCKET_VERSION,
+                header::HeaderValue::from_static("13"),
+            ))
+            .insert_header((
+                header::SEC_WEBSOCKET_KEY,
+                header::HeaderValue::from_static("13"),
+            ))
+            .to_http_request();
+
+        let resp = handshake(&req).unwrap().finish();
+        assert_eq!(StatusCode::SWITCHING_PROTOCOLS, resp.status());
+        assert_eq!(None, resp.headers().get(&header::CONTENT_LENGTH));
+        assert_eq!(None, resp.headers().get(&header::TRANSFER_ENCODING));
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::UPGRADE,
+                header::HeaderValue::from_static("websocket"),
+            ))
+            .insert_header((
+                header::CONNECTION,
+                header::HeaderValue::from_static("upgrade"),
+            ))
+            .insert_header((
+                header::SEC_WEBSOCKET_VERSION,
+                header::HeaderValue::from_static("13"),
+            ))
+            .insert_header((
+                header::SEC_WEBSOCKET_KEY,
+                header::HeaderValue::from_static("13"),
+            ))
+            .insert_header((
+                header::SEC_WEBSOCKET_PROTOCOL,
+                header::HeaderValue::from_static("graphql"),
+            ))
+            .to_http_request();
+
+        let protocols = ["graphql"];
+
+        assert_eq!(
+            StatusCode::SWITCHING_PROTOCOLS,
+            handshake_with_protocols(&req, &protocols)
+                .unwrap()
+                .finish()
+                .status()
+        );
+        assert_eq!(
+            Some(&header::HeaderValue::from_static("graphql")),
+            handshake_with_protocols(&req, &protocols)
+                .unwrap()
+                .finish()
+                .headers()
+                .get(&header::SEC_WEBSOCKET_PROTOCOL)
+        );
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::UPGRADE,
+                header::HeaderValue::from_static("websocket"),
+            ))
+            .insert_header((
+                header::CONNECTION,
+                header::HeaderValue::from_static("upgrade"),
+            ))
+            .insert_header((
+                header::SEC_WEBSOCKET_VERSION,
+                header::HeaderValue::from_static("13"),
+            ))
+            .insert_header((
+                header::SEC_WEBSOCKET_KEY,
+                header::HeaderValue::from_static("13"),
+            ))
+            .insert_header((
+                header::SEC_WEBSOCKET_PROTOCOL,
+                header::HeaderValue::from_static("p1, p2, p3"),
+            ))
+            .to_http_request();
+
+        let protocols = vec!["p3", "p2"];
+
+        assert_eq!(
+            StatusCode::SWITCHING_PROTOCOLS,
+            handshake_with_protocols(&req, &protocols)
+                .unwrap()
+                .finish()
+                .status()
+        );
+        assert_eq!(
+            Some(&header::HeaderValue::from_static("p2")),
+            handshake_with_protocols(&req, &protocols)
+                .unwrap()
+                .finish()
+                .headers()
+                .get(&header::SEC_WEBSOCKET_PROTOCOL)
+        );
+
+        let req = TestRequest::default()
+            .insert_header((
+                header::UPGRADE,
+                header::HeaderValue::from_static("websocket"),
+            ))
+            .insert_header((
+                header::CONNECTION,
+                header::HeaderValue::from_static("upgrade"),
+            ))
+            .insert_header((
+                header::SEC_WEBSOCKET_VERSION,
+                header::HeaderValue::from_static("13"),
+            ))
+            .insert_header((
+                header::SEC_WEBSOCKET_KEY,
+                header::HeaderValue::from_static("13"),
+            ))
+            .insert_header((
+                header::SEC_WEBSOCKET_PROTOCOL,
+                header::HeaderValue::from_static("p1,p2,p3"),
+            ))
+            .to_http_request();
+
+        let protocols = vec!["p3", "p2"];
+
+        assert_eq!(
+            StatusCode::SWITCHING_PROTOCOLS,
+            handshake_with_protocols(&req, &protocols)
+                .unwrap()
+                .finish()
+                .status()
+        );
+        assert_eq!(
+            Some(&header::HeaderValue::from_static("p2")),
+            handshake_with_protocols(&req, &protocols)
+                .unwrap()
+                .finish()
+                .headers()
+                .get(&header::SEC_WEBSOCKET_PROTOCOL)
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/actix_web_codegen/lib.rs.html b/src/actix_web_codegen/lib.rs.html new file mode 100644 index 000000000..323f2da76 --- /dev/null +++ b/src/actix_web_codegen/lib.rs.html @@ -0,0 +1,485 @@ +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
+
//! Routing and runtime macros for Actix Web.
+//!
+//! # Actix Web Re-exports
+//! Actix Web re-exports a version of this crate in it's entirety so you usually don't have to
+//! specify a dependency on this crate explicitly. Sometimes, however, updates are made to this
+//! crate before the actix-web dependency is updated. Therefore, code examples here will show
+//! explicit imports. Check the latest [actix-web attributes docs] to see which macros
+//! are re-exported.
+//!
+//! # Runtime Setup
+//! Used for setting up the actix async runtime. See [macro@main] macro docs.
+//!
+//! ```
+//! #[actix_web_codegen::main] // or `#[actix_web::main]` in Actix Web apps
+//! async fn main() {
+//!     async { println!("Hello world"); }.await
+//! }
+//! ```
+//!
+//! # Single Method Handler
+//! There is a macro to set up a handler for each of the most common HTTP methods that also define
+//! additional guards and route-specific middleware.
+//!
+//! See docs for: [GET], [POST], [PATCH], [PUT], [DELETE], [HEAD], [CONNECT], [OPTIONS], [TRACE]
+//!
+//! ```
+//! # use actix_web::HttpResponse;
+//! # use actix_web_codegen::get;
+//! #[get("/test")]
+//! async fn get_handler() -> HttpResponse {
+//!     HttpResponse::Ok().finish()
+//! }
+//! ```
+//!
+//! # Multiple Method Handlers
+//! Similar to the single method handler macro but takes one or more arguments for the HTTP methods
+//! it should respond to. See [macro@route] macro docs.
+//!
+//! ```
+//! # use actix_web::HttpResponse;
+//! # use actix_web_codegen::route;
+//! #[route("/test", method = "GET", method = "HEAD")]
+//! async fn get_and_head_handler() -> HttpResponse {
+//!     HttpResponse::Ok().finish()
+//! }
+//! ```
+//!
+//! # Multiple Path Handlers
+//! Acts as a wrapper for multiple single method handler macros. It takes no arguments and
+//! delegates those to the macros for the individual methods. See [macro@routes] macro docs.
+//!
+//! ```
+//! # use actix_web::HttpResponse;
+//! # use actix_web_codegen::routes;
+//! #[routes]
+//! #[get("/test")]
+//! #[get("/test2")]
+//! #[delete("/test")]
+//! async fn example() -> HttpResponse {
+//!     HttpResponse::Ok().finish()
+//! }
+//! ```
+//!
+//! [actix-web attributes docs]: https://docs.rs/actix-web/latest/actix_web/#attributes
+//! [GET]: macro@get
+//! [POST]: macro@post
+//! [PUT]: macro@put
+//! [HEAD]: macro@head
+//! [CONNECT]: macro@macro@connect
+//! [OPTIONS]: macro@options
+//! [TRACE]: macro@trace
+//! [PATCH]: macro@patch
+//! [DELETE]: macro@delete
+
+#![recursion_limit = "512"]
+#![deny(rust_2018_idioms, nonstandard_style)]
+#![warn(future_incompatible)]
+#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
+#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+
+use proc_macro::TokenStream;
+use quote::quote;
+
+mod route;
+
+/// Creates resource handler, allowing multiple HTTP method guards.
+///
+/// # Syntax
+/// ```plain
+/// #[route("path", method="HTTP_METHOD"[, attributes])]
+/// ```
+///
+/// # Attributes
+/// - `"path"`: Raw literal string with path for which to register handler.
+/// - `name = "resource_name"`: Specifies resource name for the handler. If not set, the function
+///   name of handler is used.
+/// - `method = "HTTP_METHOD"`: Registers HTTP method to provide guard for. Upper-case string,
+///   "GET", "POST" for example.
+/// - `guard = "function_name"`: Registers function as guard using `actix_web::guard::fn_guard`.
+/// - `wrap = "Middleware"`: Registers a resource middleware.
+///
+/// # Notes
+/// Function name can be specified as any expression that is going to be accessible to the generate
+/// code, e.g `my_guard` or `my_module::my_guard`.
+///
+/// # Examples
+/// ```
+/// # use actix_web::HttpResponse;
+/// # use actix_web_codegen::route;
+/// #[route("/test", method = "GET", method = "HEAD", method = "CUSTOM")]
+/// async fn example() -> HttpResponse {
+///     HttpResponse::Ok().finish()
+/// }
+/// ```
+#[proc_macro_attribute]
+pub fn route(args: TokenStream, input: TokenStream) -> TokenStream {
+    route::with_method(None, args, input)
+}
+
+/// Creates resource handler, allowing multiple HTTP methods and paths.
+///
+/// # Syntax
+/// ```plain
+/// #[routes]
+/// #[<method>("path", ...)]
+/// #[<method>("path", ...)]
+/// ...
+/// ```
+///
+/// # Attributes
+/// The `routes` macro itself has no parameters, but allows specifying the attribute macros for
+/// the multiple paths and/or methods, e.g. [`GET`](macro@get) and [`POST`](macro@post).
+///
+/// These helper attributes take the same parameters as the [single method handlers](crate#single-method-handler).
+///
+/// # Examples
+/// ```
+/// # use actix_web::HttpResponse;
+/// # use actix_web_codegen::routes;
+/// #[routes]
+/// #[get("/test")]
+/// #[get("/test2")]
+/// #[delete("/test")]
+/// async fn example() -> HttpResponse {
+///     HttpResponse::Ok().finish()
+/// }
+/// ```
+#[proc_macro_attribute]
+pub fn routes(_: TokenStream, input: TokenStream) -> TokenStream {
+    route::with_methods(input)
+}
+
+macro_rules! method_macro {
+    ($variant:ident, $method:ident) => {
+        #[doc = concat!("Creates route handler with `actix_web::guard::", stringify!($variant), "`.")]
+        ///
+        /// # Syntax
+        /// ```plain
+        #[doc = concat!("#[", stringify!($method), r#"("path"[, attributes])]"#)]
+        /// ```
+        ///
+        /// # Attributes
+        /// - `"path"`: Raw literal string with path for which to register handler.
+        /// - `name = "resource_name"`: Specifies resource name for the handler. If not set, the
+        ///   function name of handler is used.
+        /// - `guard = "function_name"`: Registers function as guard using `actix_web::guard::fn_guard`.
+        /// - `wrap = "Middleware"`: Registers a resource middleware.
+        ///
+        /// # Notes
+        /// Function name can be specified as any expression that is going to be accessible to the
+        /// generate code, e.g `my_guard` or `my_module::my_guard`.
+        ///
+        /// # Examples
+        /// ```
+        /// # use actix_web::HttpResponse;
+        #[doc = concat!("# use actix_web_codegen::", stringify!($method), ";")]
+        #[doc = concat!("#[", stringify!($method), r#"("/")]"#)]
+        /// async fn example() -> HttpResponse {
+        ///     HttpResponse::Ok().finish()
+        /// }
+        /// ```
+        #[proc_macro_attribute]
+        pub fn $method(args: TokenStream, input: TokenStream) -> TokenStream {
+            route::with_method(Some(route::MethodType::$variant), args, input)
+        }
+    };
+}
+
+method_macro!(Get, get);
+method_macro!(Post, post);
+method_macro!(Put, put);
+method_macro!(Delete, delete);
+method_macro!(Head, head);
+method_macro!(Connect, connect);
+method_macro!(Options, options);
+method_macro!(Trace, trace);
+method_macro!(Patch, patch);
+
+/// Marks async main function as the Actix Web system entry-point.
+///
+/// Note that Actix Web also works under `#[tokio::main]` since version 4.0. However, this macro is
+/// still necessary for actor support (since actors use a `System`). Read more in the
+/// [`actix_web::rt`](https://docs.rs/actix-web/4/actix_web/rt) module docs.
+///
+/// # Examples
+/// ```
+/// #[actix_web::main]
+/// async fn main() {
+///     async { println!("Hello world"); }.await
+/// }
+/// ```
+#[proc_macro_attribute]
+pub fn main(_: TokenStream, item: TokenStream) -> TokenStream {
+    let mut output: TokenStream = (quote! {
+        #[::actix_web::rt::main(system = "::actix_web::rt::System")]
+    })
+    .into();
+
+    output.extend(item);
+    output
+}
+
+/// Marks async test functions to use the Actix Web system entry-point.
+///
+/// # Examples
+/// ```
+/// #[actix_web::test]
+/// async fn test() {
+///     assert_eq!(async { "Hello world" }.await, "Hello world");
+/// }
+/// ```
+#[proc_macro_attribute]
+pub fn test(_: TokenStream, item: TokenStream) -> TokenStream {
+    let mut output: TokenStream = (quote! {
+        #[::actix_web::rt::test(system = "::actix_web::rt::System")]
+    })
+    .into();
+
+    output.extend(item);
+    output
+}
+
\ No newline at end of file diff --git a/src/actix_web_codegen/route.rs.html b/src/actix_web_codegen/route.rs.html new file mode 100644 index 000000000..466e9b7e6 --- /dev/null +++ b/src/actix_web_codegen/route.rs.html @@ -0,0 +1,1113 @@ +route.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
+
use std::collections::HashSet;
+
+use actix_router::ResourceDef;
+use proc_macro::TokenStream;
+use proc_macro2::{Span, TokenStream as TokenStream2};
+use quote::{quote, ToTokens, TokenStreamExt};
+use syn::{punctuated::Punctuated, Ident, LitStr, Path, Token};
+
+#[derive(Debug)]
+pub struct RouteArgs {
+    path: syn::LitStr,
+    options: Punctuated<syn::MetaNameValue, Token![,]>,
+}
+
+impl syn::parse::Parse for RouteArgs {
+    fn parse(input: syn::parse::ParseStream<'_>) -> syn::Result<Self> {
+        // path to match: "/foo"
+        let path = input.parse::<syn::LitStr>().map_err(|mut err| {
+            err.combine(syn::Error::new(
+                err.span(),
+                r#"invalid service definition, expected #[<method>("<path>")]"#,
+            ));
+
+            err
+        })?;
+
+        // verify that path pattern is valid
+        let _ = ResourceDef::new(path.value());
+
+        // if there's no comma, assume that no options are provided
+        if !input.peek(Token![,]) {
+            return Ok(Self {
+                path,
+                options: Punctuated::new(),
+            });
+        }
+
+        // advance past comma separator
+        input.parse::<Token![,]>()?;
+
+        // if next char is a literal, assume that it is a string and show multi-path error
+        if input.cursor().literal().is_some() {
+            return Err(syn::Error::new(
+                Span::call_site(),
+                r#"Multiple paths specified! There should be only one."#,
+            ));
+        }
+
+        // zero or more options: name = "foo"
+        let options = input.parse_terminated(syn::MetaNameValue::parse, Token![,])?;
+
+        Ok(Self { path, options })
+    }
+}
+
+macro_rules! standard_method_type {
+    (
+        $($variant:ident, $upper:ident, $lower:ident,)+
+    ) => {
+        #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+        pub enum MethodType {
+            $(
+                $variant,
+            )+
+        }
+
+        impl MethodType {
+            fn as_str(&self) -> &'static str {
+                match self {
+                    $(Self::$variant => stringify!($variant),)+
+                }
+            }
+
+            fn parse(method: &str) -> Result<Self, String> {
+                match method {
+                    $(stringify!($upper) => Ok(Self::$variant),)+
+                    _ => Err(format!("HTTP method must be uppercase: `{}`", method)),
+                }
+            }
+
+            fn from_path(method: &Path) -> Result<Self, ()> {
+                match () {
+                    $(_ if method.is_ident(stringify!($lower)) => Ok(Self::$variant),)+
+                    _ => Err(()),
+                }
+            }
+        }
+    };
+}
+
+standard_method_type! {
+    Get,       GET,     get,
+    Post,      POST,    post,
+    Put,       PUT,     put,
+    Delete,    DELETE,  delete,
+    Head,      HEAD,    head,
+    Connect,   CONNECT, connect,
+    Options,   OPTIONS, options,
+    Trace,     TRACE,   trace,
+    Patch,     PATCH,   patch,
+}
+
+impl TryFrom<&syn::LitStr> for MethodType {
+    type Error = syn::Error;
+
+    fn try_from(value: &syn::LitStr) -> Result<Self, Self::Error> {
+        Self::parse(value.value().as_str())
+            .map_err(|message| syn::Error::new_spanned(value, message))
+    }
+}
+
+impl ToTokens for MethodType {
+    fn to_tokens(&self, stream: &mut TokenStream2) {
+        let ident = Ident::new(self.as_str(), Span::call_site());
+        stream.append(ident);
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+enum MethodTypeExt {
+    Standard(MethodType),
+    Custom(LitStr),
+}
+
+impl MethodTypeExt {
+    /// Returns a single method guard token stream.
+    fn to_tokens_single_guard(&self) -> TokenStream2 {
+        match self {
+            MethodTypeExt::Standard(method) => {
+                quote! {
+                    .guard(::actix_web::guard::#method())
+                }
+            }
+            MethodTypeExt::Custom(lit) => {
+                quote! {
+                    .guard(::actix_web::guard::Method(
+                        ::actix_web::http::Method::from_bytes(#lit.as_bytes()).unwrap()
+                    ))
+                }
+            }
+        }
+    }
+
+    /// Returns a multi-method guard chain token stream.
+    fn to_tokens_multi_guard(&self, or_chain: Vec<impl ToTokens>) -> TokenStream2 {
+        debug_assert!(
+            !or_chain.is_empty(),
+            "empty or_chain passed to multi-guard constructor"
+        );
+
+        match self {
+            MethodTypeExt::Standard(method) => {
+                quote! {
+                    .guard(
+                        ::actix_web::guard::Any(::actix_web::guard::#method())
+                            #(#or_chain)*
+                    )
+                }
+            }
+            MethodTypeExt::Custom(lit) => {
+                quote! {
+                    .guard(
+                        ::actix_web::guard::Any(
+                            ::actix_web::guard::Method(
+                                ::actix_web::http::Method::from_bytes(#lit.as_bytes()).unwrap()
+                            )
+                        )
+                        #(#or_chain)*
+                    )
+                }
+            }
+        }
+    }
+
+    /// Returns a token stream containing the `.or` chain to be passed in to
+    /// [`MethodTypeExt::to_tokens_multi_guard()`].
+    fn to_tokens_multi_guard_or_chain(&self) -> TokenStream2 {
+        match self {
+            MethodTypeExt::Standard(method_type) => {
+                quote! {
+                    .or(::actix_web::guard::#method_type())
+                }
+            }
+            MethodTypeExt::Custom(lit) => {
+                quote! {
+                    .or(
+                        ::actix_web::guard::Method(
+                            ::actix_web::http::Method::from_bytes(#lit.as_bytes()).unwrap()
+                        )
+                    )
+                }
+            }
+        }
+    }
+}
+
+impl ToTokens for MethodTypeExt {
+    fn to_tokens(&self, stream: &mut TokenStream2) {
+        match self {
+            MethodTypeExt::Custom(lit_str) => {
+                let ident = Ident::new(lit_str.value().as_str(), Span::call_site());
+                stream.append(ident);
+            }
+            MethodTypeExt::Standard(method) => method.to_tokens(stream),
+        }
+    }
+}
+
+impl TryFrom<&syn::LitStr> for MethodTypeExt {
+    type Error = syn::Error;
+
+    fn try_from(value: &syn::LitStr) -> Result<Self, Self::Error> {
+        match MethodType::try_from(value) {
+            Ok(method) => Ok(MethodTypeExt::Standard(method)),
+            Err(_) if value.value().chars().all(|c| c.is_ascii_uppercase()) => {
+                Ok(MethodTypeExt::Custom(value.clone()))
+            }
+            Err(err) => Err(err),
+        }
+    }
+}
+
+struct Args {
+    path: syn::LitStr,
+    resource_name: Option<syn::LitStr>,
+    guards: Vec<Path>,
+    wrappers: Vec<syn::Expr>,
+    methods: HashSet<MethodTypeExt>,
+}
+
+impl Args {
+    fn new(args: RouteArgs, method: Option<MethodType>) -> syn::Result<Self> {
+        let mut resource_name = None;
+        let mut guards = Vec::new();
+        let mut wrappers = Vec::new();
+        let mut methods = HashSet::new();
+
+        let is_route_macro = method.is_none();
+        if let Some(method) = method {
+            methods.insert(MethodTypeExt::Standard(method));
+        }
+
+        for nv in args.options {
+            if nv.path.is_ident("name") {
+                if let syn::Expr::Lit(syn::ExprLit {
+                    lit: syn::Lit::Str(lit),
+                    ..
+                }) = nv.value
+                {
+                    resource_name = Some(lit);
+                } else {
+                    return Err(syn::Error::new_spanned(
+                        nv.value,
+                        "Attribute name expects literal string",
+                    ));
+                }
+            } else if nv.path.is_ident("guard") {
+                if let syn::Expr::Lit(syn::ExprLit {
+                    lit: syn::Lit::Str(lit),
+                    ..
+                }) = nv.value
+                {
+                    guards.push(lit.parse::<Path>()?);
+                } else {
+                    return Err(syn::Error::new_spanned(
+                        nv.value,
+                        "Attribute guard expects literal string",
+                    ));
+                }
+            } else if nv.path.is_ident("wrap") {
+                if let syn::Expr::Lit(syn::ExprLit {
+                    lit: syn::Lit::Str(lit),
+                    ..
+                }) = nv.value
+                {
+                    wrappers.push(lit.parse()?);
+                } else {
+                    return Err(syn::Error::new_spanned(
+                        nv.value,
+                        "Attribute wrap expects type",
+                    ));
+                }
+            } else if nv.path.is_ident("method") {
+                if !is_route_macro {
+                    return Err(syn::Error::new_spanned(
+                        &nv,
+                        "HTTP method forbidden here; to handle multiple methods, use `route` instead",
+                    ));
+                } else if let syn::Expr::Lit(syn::ExprLit {
+                    lit: syn::Lit::Str(lit),
+                    ..
+                }) = nv.value.clone()
+                {
+                    if !methods.insert(MethodTypeExt::try_from(&lit)?) {
+                        return Err(syn::Error::new_spanned(
+                            nv.value,
+                            format!("HTTP method defined more than once: `{}`", lit.value()),
+                        ));
+                    }
+                } else {
+                    return Err(syn::Error::new_spanned(
+                        nv.value,
+                        "Attribute method expects literal string",
+                    ));
+                }
+            } else {
+                return Err(syn::Error::new_spanned(
+                    nv.path,
+                    "Unknown attribute key is specified; allowed: guard, method and wrap",
+                ));
+            }
+        }
+
+        Ok(Args {
+            path: args.path,
+            resource_name,
+            guards,
+            wrappers,
+            methods,
+        })
+    }
+}
+
+pub struct Route {
+    /// Name of the handler function being annotated.
+    name: syn::Ident,
+
+    /// Args passed to routing macro.
+    ///
+    /// When using `#[routes]`, this will contain args for each specific routing macro.
+    args: Vec<Args>,
+
+    /// AST of the handler function being annotated.
+    ast: syn::ItemFn,
+
+    /// The doc comment attributes to copy to generated struct, if any.
+    doc_attributes: Vec<syn::Attribute>,
+}
+
+impl Route {
+    pub fn new(args: RouteArgs, ast: syn::ItemFn, method: Option<MethodType>) -> syn::Result<Self> {
+        let name = ast.sig.ident.clone();
+
+        // Try and pull out the doc comments so that we can reapply them to the generated struct.
+        // Note that multi line doc comments are converted to multiple doc attributes.
+        let doc_attributes = ast
+            .attrs
+            .iter()
+            .filter(|attr| attr.path().is_ident("doc"))
+            .cloned()
+            .collect();
+
+        let args = Args::new(args, method)?;
+
+        if args.methods.is_empty() {
+            return Err(syn::Error::new(
+                Span::call_site(),
+                "The #[route(..)] macro requires at least one `method` attribute",
+            ));
+        }
+
+        if matches!(ast.sig.output, syn::ReturnType::Default) {
+            return Err(syn::Error::new_spanned(
+                ast,
+                "Function has no return type. Cannot be used as handler",
+            ));
+        }
+
+        Ok(Self {
+            name,
+            args: vec![args],
+            ast,
+            doc_attributes,
+        })
+    }
+
+    fn multiple(args: Vec<Args>, ast: syn::ItemFn) -> syn::Result<Self> {
+        let name = ast.sig.ident.clone();
+
+        // Try and pull out the doc comments so that we can reapply them to the generated struct.
+        // Note that multi line doc comments are converted to multiple doc attributes.
+        let doc_attributes = ast
+            .attrs
+            .iter()
+            .filter(|attr| attr.path().is_ident("doc"))
+            .cloned()
+            .collect();
+
+        if matches!(ast.sig.output, syn::ReturnType::Default) {
+            return Err(syn::Error::new_spanned(
+                ast,
+                "Function has no return type. Cannot be used as handler",
+            ));
+        }
+
+        Ok(Self {
+            name,
+            args,
+            ast,
+            doc_attributes,
+        })
+    }
+}
+
+impl ToTokens for Route {
+    fn to_tokens(&self, output: &mut TokenStream2) {
+        let Self {
+            name,
+            ast,
+            args,
+            doc_attributes,
+        } = self;
+
+        let registrations: TokenStream2 = args
+            .iter()
+            .map(|args| {
+                let Args {
+                    path,
+                    resource_name,
+                    guards,
+                    wrappers,
+                    methods,
+                } = args;
+
+                let resource_name = resource_name
+                    .as_ref()
+                    .map_or_else(|| name.to_string(), LitStr::value);
+
+                let method_guards = {
+                    debug_assert!(!methods.is_empty(), "Args::methods should not be empty");
+
+                    let mut others = methods.iter();
+                    let first = others.next().unwrap();
+
+                    if methods.len() > 1 {
+                        let other_method_guards = others
+                            .map(|method_ext| method_ext.to_tokens_multi_guard_or_chain())
+                            .collect();
+
+                        first.to_tokens_multi_guard(other_method_guards)
+                    } else {
+                        first.to_tokens_single_guard()
+                    }
+                };
+
+                quote! {
+                    let __resource = ::actix_web::Resource::new(#path)
+                        .name(#resource_name)
+                        #method_guards
+                        #(.guard(::actix_web::guard::fn_guard(#guards)))*
+                        #(.wrap(#wrappers))*
+                        .to(#name);
+                    ::actix_web::dev::HttpServiceFactory::register(__resource, __config);
+                }
+            })
+            .collect();
+
+        let stream = quote! {
+            #(#doc_attributes)*
+            #[allow(non_camel_case_types, missing_docs)]
+            pub struct #name;
+
+            impl ::actix_web::dev::HttpServiceFactory for #name {
+                fn register(self, __config: &mut actix_web::dev::AppService) {
+                    #ast
+                    #registrations
+                }
+            }
+        };
+
+        output.extend(stream);
+    }
+}
+
+pub(crate) fn with_method(
+    method: Option<MethodType>,
+    args: TokenStream,
+    input: TokenStream,
+) -> TokenStream {
+    let args = match syn::parse(args) {
+        Ok(args) => args,
+        // on parse error, make IDEs happy; see fn docs
+        Err(err) => return input_and_compile_error(input, err),
+    };
+
+    let ast = match syn::parse::<syn::ItemFn>(input.clone()) {
+        Ok(ast) => ast,
+        // on parse error, make IDEs happy; see fn docs
+        Err(err) => return input_and_compile_error(input, err),
+    };
+
+    match Route::new(args, ast, method) {
+        Ok(route) => route.into_token_stream().into(),
+        // on macro related error, make IDEs happy; see fn docs
+        Err(err) => input_and_compile_error(input, err),
+    }
+}
+
+pub(crate) fn with_methods(input: TokenStream) -> TokenStream {
+    let mut ast = match syn::parse::<syn::ItemFn>(input.clone()) {
+        Ok(ast) => ast,
+        // on parse error, make IDEs happy; see fn docs
+        Err(err) => return input_and_compile_error(input, err),
+    };
+
+    let (methods, others) = ast
+        .attrs
+        .into_iter()
+        .map(|attr| match MethodType::from_path(attr.path()) {
+            Ok(method) => Ok((method, attr)),
+            Err(_) => Err(attr),
+        })
+        .partition::<Vec<_>, _>(Result::is_ok);
+
+    ast.attrs = others.into_iter().map(Result::unwrap_err).collect();
+
+    let methods = match methods
+        .into_iter()
+        .map(Result::unwrap)
+        .map(|(method, attr)| {
+            attr.parse_args()
+                .and_then(|args| Args::new(args, Some(method)))
+        })
+        .collect::<Result<Vec<_>, _>>()
+    {
+        Ok(methods) if methods.is_empty() => {
+            return input_and_compile_error(
+                input,
+                syn::Error::new(
+                    Span::call_site(),
+                    "The #[routes] macro requires at least one `#[<method>(..)]` attribute.",
+                ),
+            )
+        }
+        Ok(methods) => methods,
+        Err(err) => return input_and_compile_error(input, err),
+    };
+
+    match Route::multiple(methods, ast) {
+        Ok(route) => route.into_token_stream().into(),
+        // on macro related error, make IDEs happy; see fn docs
+        Err(err) => input_and_compile_error(input, err),
+    }
+}
+
+/// Converts the error to a token stream and appends it to the original input.
+///
+/// Returning the original input in addition to the error is good for IDEs which can gracefully
+/// recover and show more precise errors within the macro body.
+///
+/// See <https://github.com/rust-analyzer/rust-analyzer/issues/10468> for more info.
+fn input_and_compile_error(mut item: TokenStream, err: syn::Error) -> TokenStream {
+    let compile_err = TokenStream::from(err.to_compile_error());
+    item.extend(compile_err);
+    item
+}
+
\ No newline at end of file diff --git a/src/awc/any_body.rs.html b/src/awc/any_body.rs.html new file mode 100644 index 000000000..87a0084c3 --- /dev/null +++ b/src/awc/any_body.rs.html @@ -0,0 +1,383 @@ +any_body.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
+
use std::{
+    fmt, mem,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use actix_http::body::{BodySize, BoxBody, MessageBody};
+use bytes::Bytes;
+use pin_project_lite::pin_project;
+
+pin_project! {
+    /// Represents various types of HTTP message body.
+    #[derive(Clone)]
+    #[project = AnyBodyProj]
+    pub enum AnyBody<B = BoxBody> {
+        /// Empty response. `Content-Length` header is not set.
+        None,
+
+        /// Complete, in-memory response body.
+        Bytes { body: Bytes },
+
+        /// Generic / Other message body.
+        Body { #[pin] body: B },
+    }
+}
+
+impl AnyBody {
+    /// Constructs a "body" representing an empty response.
+    pub fn none() -> Self {
+        Self::None
+    }
+
+    /// Constructs a new, 0-length body.
+    pub fn empty() -> Self {
+        Self::Bytes { body: Bytes::new() }
+    }
+
+    /// Create boxed body from generic message body.
+    pub fn new_boxed<B>(body: B) -> Self
+    where
+        B: MessageBody + 'static,
+    {
+        Self::Body { body: body.boxed() }
+    }
+
+    /// Constructs new `AnyBody` instance from a slice of bytes by copying it.
+    ///
+    /// If your bytes container is owned, it may be cheaper to use a `From` impl.
+    pub fn copy_from_slice(s: &[u8]) -> Self {
+        Self::Bytes {
+            body: Bytes::copy_from_slice(s),
+        }
+    }
+
+    #[doc(hidden)]
+    #[deprecated(since = "4.0.0", note = "Renamed to `copy_from_slice`.")]
+    pub fn from_slice(s: &[u8]) -> Self {
+        Self::Bytes {
+            body: Bytes::copy_from_slice(s),
+        }
+    }
+}
+
+impl<B> AnyBody<B> {
+    /// Create body from generic message body.
+    pub fn new(body: B) -> Self {
+        Self::Body { body }
+    }
+}
+
+impl<B> AnyBody<B>
+where
+    B: MessageBody + 'static,
+{
+    /// Converts a [`MessageBody`] type into the best possible representation.
+    ///
+    /// Checks size for `None` and tries to convert to `Bytes`. Otherwise, uses the `Body` variant.
+    pub fn from_message_body(body: B) -> Self
+    where
+        B: MessageBody,
+    {
+        if matches!(body.size(), BodySize::None) {
+            return Self::None;
+        }
+
+        match body.try_into_bytes() {
+            Ok(body) => Self::Bytes { body },
+            Err(body) => Self::new(body),
+        }
+    }
+
+    pub fn into_boxed(self) -> AnyBody {
+        match self {
+            Self::None => AnyBody::None,
+            Self::Bytes { body } => AnyBody::Bytes { body },
+            Self::Body { body } => AnyBody::new_boxed(body),
+        }
+    }
+}
+
+impl<B> MessageBody for AnyBody<B>
+where
+    B: MessageBody,
+{
+    type Error = crate::BoxError;
+
+    fn size(&self) -> BodySize {
+        match self {
+            AnyBody::None => BodySize::None,
+            AnyBody::Bytes { ref body } => BodySize::Sized(body.len() as u64),
+            AnyBody::Body { ref body } => body.size(),
+        }
+    }
+
+    fn poll_next(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+    ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+        match self.project() {
+            AnyBodyProj::None => Poll::Ready(None),
+            AnyBodyProj::Bytes { body } => {
+                let len = body.len();
+                if len == 0 {
+                    Poll::Ready(None)
+                } else {
+                    Poll::Ready(Some(Ok(mem::take(body))))
+                }
+            }
+
+            AnyBodyProj::Body { body } => body.poll_next(cx).map_err(|err| err.into()),
+        }
+    }
+}
+
+impl PartialEq for AnyBody {
+    fn eq(&self, other: &AnyBody) -> bool {
+        match self {
+            AnyBody::None => matches!(*other, AnyBody::None),
+            AnyBody::Bytes { body } => match other {
+                AnyBody::Bytes { body: b2 } => body == b2,
+                _ => false,
+            },
+            AnyBody::Body { .. } => false,
+        }
+    }
+}
+
+impl<S: fmt::Debug> fmt::Debug for AnyBody<S> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match *self {
+            AnyBody::None => write!(f, "AnyBody::None"),
+            AnyBody::Bytes { ref body } => write!(f, "AnyBody::Bytes({:?})", body),
+            AnyBody::Body { ref body } => write!(f, "AnyBody::Message({:?})", body),
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::marker::PhantomPinned;
+
+    use static_assertions::{assert_impl_all, assert_not_impl_any};
+
+    use super::*;
+
+    struct PinType(PhantomPinned);
+
+    impl MessageBody for PinType {
+        type Error = crate::BoxError;
+
+        fn size(&self) -> BodySize {
+            unimplemented!()
+        }
+
+        fn poll_next(
+            self: Pin<&mut Self>,
+            _cx: &mut Context<'_>,
+        ) -> Poll<Option<Result<Bytes, Self::Error>>> {
+            unimplemented!()
+        }
+    }
+
+    assert_impl_all!(AnyBody<()>: Send, Sync, Unpin, fmt::Debug, MessageBody);
+    assert_impl_all!(AnyBody<AnyBody<()>>: Send, Sync, Unpin, fmt::Debug, MessageBody);
+    assert_impl_all!(AnyBody<Bytes>: Send, Sync, Unpin, fmt::Debug, MessageBody);
+    assert_impl_all!(AnyBody: Unpin, fmt::Debug, MessageBody);
+    assert_impl_all!(AnyBody<PinType>: Send, Sync, MessageBody);
+
+    assert_not_impl_any!(AnyBody: Send, Sync);
+    assert_not_impl_any!(AnyBody<PinType>: Unpin);
+}
+
\ No newline at end of file diff --git a/src/awc/builder.rs.html b/src/awc/builder.rs.html new file mode 100644 index 000000000..9df936460 --- /dev/null +++ b/src/awc/builder.rs.html @@ -0,0 +1,681 @@ +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
+
use std::{fmt, net::IpAddr, rc::Rc, time::Duration};
+
+use actix_http::{
+    error::HttpError,
+    header::{self, HeaderMap, HeaderName, TryIntoHeaderPair},
+    Uri,
+};
+use actix_rt::net::{ActixStream, TcpStream};
+use actix_service::{boxed, Service};
+use base64::prelude::*;
+
+use crate::{
+    client::{
+        ClientConfig, ConnectInfo, Connector, ConnectorService, TcpConnectError, TcpConnection,
+    },
+    connect::DefaultConnector,
+    error::SendRequestError,
+    middleware::{NestTransform, Redirect, Transform},
+    Client, ConnectRequest, ConnectResponse,
+};
+
+/// An HTTP Client builder
+///
+/// This type can be used to construct an instance of `Client` through a
+/// builder-like pattern.
+pub struct ClientBuilder<S = (), M = ()> {
+    max_http_version: Option<http::Version>,
+    stream_window_size: Option<u32>,
+    conn_window_size: Option<u32>,
+    fundamental_headers: bool,
+    default_headers: HeaderMap,
+    timeout: Option<Duration>,
+    connector: Connector<S>,
+    middleware: M,
+    local_address: Option<IpAddr>,
+    max_redirects: u8,
+}
+
+impl ClientBuilder {
+    /// Create a new ClientBuilder with default settings
+    ///
+    /// Note: If the `rustls-0_23` feature is enabled and neither `rustls-0_23-native-roots` nor
+    /// `rustls-0_23-webpki-roots` are enabled, this ClientBuilder will build without TLS. In order
+    /// to enable TLS in this scenario, a custom `Connector` _must_ be added to the builder before
+    /// finishing construction.
+    #[allow(clippy::new_ret_no_self)]
+    pub fn new() -> ClientBuilder<
+        impl Service<
+                ConnectInfo<Uri>,
+                Response = TcpConnection<Uri, TcpStream>,
+                Error = TcpConnectError,
+            > + Clone,
+        (),
+    > {
+        ClientBuilder {
+            max_http_version: None,
+            stream_window_size: None,
+            conn_window_size: None,
+            fundamental_headers: true,
+            default_headers: HeaderMap::new(),
+            timeout: Some(Duration::from_secs(5)),
+            connector: Connector::new(),
+            middleware: (),
+            local_address: None,
+            max_redirects: 10,
+        }
+    }
+}
+
+impl<S, Io, M> ClientBuilder<S, M>
+where
+    S: Service<ConnectInfo<Uri>, Response = TcpConnection<Uri, Io>, Error = TcpConnectError>
+        + Clone
+        + 'static,
+    Io: ActixStream + fmt::Debug + 'static,
+{
+    /// Use custom connector service.
+    pub fn connector<S1, Io1>(self, connector: Connector<S1>) -> ClientBuilder<S1, M>
+    where
+        S1: Service<ConnectInfo<Uri>, Response = TcpConnection<Uri, Io1>, Error = TcpConnectError>
+            + Clone
+            + 'static,
+        Io1: ActixStream + fmt::Debug + 'static,
+    {
+        ClientBuilder {
+            middleware: self.middleware,
+            fundamental_headers: self.fundamental_headers,
+            default_headers: self.default_headers,
+            timeout: self.timeout,
+            local_address: self.local_address,
+            connector,
+            max_http_version: self.max_http_version,
+            stream_window_size: self.stream_window_size,
+            conn_window_size: self.conn_window_size,
+            max_redirects: self.max_redirects,
+        }
+    }
+
+    /// Set request timeout
+    ///
+    /// Request timeout is the total time before a response must be received.
+    /// Default value is 5 seconds.
+    pub fn timeout(mut self, timeout: Duration) -> Self {
+        self.timeout = Some(timeout);
+        self
+    }
+
+    /// Disable request timeout.
+    pub fn disable_timeout(mut self) -> Self {
+        self.timeout = None;
+        self
+    }
+
+    /// Set local IP Address the connector would use for establishing connection.
+    pub fn local_address(mut self, addr: IpAddr) -> Self {
+        self.local_address = Some(addr);
+        self
+    }
+
+    /// Maximum supported HTTP major version.
+    ///
+    /// Supported versions are HTTP/1.1 and HTTP/2.
+    pub fn max_http_version(mut self, val: http::Version) -> Self {
+        self.max_http_version = Some(val);
+        self
+    }
+
+    /// Do not follow redirects.
+    ///
+    /// Redirects are allowed by default.
+    pub fn disable_redirects(mut self) -> Self {
+        self.max_redirects = 0;
+        self
+    }
+
+    /// Set max number of redirects.
+    ///
+    /// Max redirects is set to 10 by default.
+    pub fn max_redirects(mut self, num: u8) -> Self {
+        self.max_redirects = num;
+        self
+    }
+
+    /// Indicates the initial window size (in octets) for
+    /// HTTP2 stream-level flow control for received data.
+    ///
+    /// The default value is 65,535 and is good for APIs, but not for big objects.
+    pub fn initial_window_size(mut self, size: u32) -> Self {
+        self.stream_window_size = Some(size);
+        self
+    }
+
+    /// Indicates the initial window size (in octets) for
+    /// HTTP2 connection-level flow control for received data.
+    ///
+    /// The default value is 65,535 and is good for APIs, but not for big objects.
+    pub fn initial_connection_window_size(mut self, size: u32) -> Self {
+        self.conn_window_size = Some(size);
+        self
+    }
+
+    /// Do not add fundamental default request headers.
+    ///
+    /// By default `Date` and `User-Agent` headers are set.
+    pub fn no_default_headers(mut self) -> Self {
+        self.fundamental_headers = false;
+        self
+    }
+
+    /// Add default header.
+    ///
+    /// Headers added by this method get added to every request unless overridden by other methods.
+    ///
+    /// # Panics
+    /// Panics if header name or value is invalid.
+    pub fn add_default_header(mut self, header: impl TryIntoHeaderPair) -> Self {
+        match header.try_into_pair() {
+            Ok((key, value)) => self.default_headers.append(key, value),
+            Err(err) => panic!("Header error: {:?}", err.into()),
+        }
+
+        self
+    }
+
+    #[doc(hidden)]
+    #[deprecated(since = "3.0.0", note = "Prefer `add_default_header((key, value))`.")]
+    pub fn header<K, V>(mut self, key: K, value: V) -> Self
+    where
+        HeaderName: TryFrom<K>,
+        <HeaderName as TryFrom<K>>::Error: fmt::Debug + Into<HttpError>,
+        V: header::TryIntoHeaderValue,
+        V::Error: fmt::Debug,
+    {
+        match HeaderName::try_from(key) {
+            Ok(key) => match value.try_into_value() {
+                Ok(value) => {
+                    self.default_headers.append(key, value);
+                }
+                Err(err) => log::error!("Header value error: {:?}", err),
+            },
+            Err(err) => log::error!("Header name error: {:?}", err),
+        }
+        self
+    }
+
+    /// Set client wide HTTP basic authorization header
+    pub fn basic_auth<N>(self, username: N, password: Option<&str>) -> Self
+    where
+        N: fmt::Display,
+    {
+        let auth = match password {
+            Some(password) => format!("{}:{}", username, password),
+            None => format!("{}:", username),
+        };
+        self.add_default_header((
+            header::AUTHORIZATION,
+            format!("Basic {}", BASE64_STANDARD.encode(auth)),
+        ))
+    }
+
+    /// Set client wide HTTP bearer authentication header
+    pub fn bearer_auth<T>(self, token: T) -> Self
+    where
+        T: fmt::Display,
+    {
+        self.add_default_header((header::AUTHORIZATION, format!("Bearer {}", token)))
+    }
+
+    /// Registers middleware, in the form of a middleware component (type), that runs during inbound
+    /// and/or outbound processing in the request life-cycle (request -> response),
+    /// modifying request/response as necessary, across all requests managed by the `Client`.
+    pub fn wrap<S1, M1>(self, mw: M1) -> ClientBuilder<S, NestTransform<M, M1, S1, ConnectRequest>>
+    where
+        M: Transform<S1, ConnectRequest>,
+        M1: Transform<M::Transform, ConnectRequest>,
+    {
+        ClientBuilder {
+            middleware: NestTransform::new(self.middleware, mw),
+            fundamental_headers: self.fundamental_headers,
+            max_http_version: self.max_http_version,
+            stream_window_size: self.stream_window_size,
+            conn_window_size: self.conn_window_size,
+            default_headers: self.default_headers,
+            timeout: self.timeout,
+            connector: self.connector,
+            local_address: self.local_address,
+            max_redirects: self.max_redirects,
+        }
+    }
+
+    /// Finish build process and create `Client` instance.
+    pub fn finish(self) -> Client
+    where
+        M: Transform<DefaultConnector<ConnectorService<S, Io>>, ConnectRequest> + 'static,
+        M::Transform: Service<ConnectRequest, Response = ConnectResponse, Error = SendRequestError>,
+    {
+        let max_redirects = self.max_redirects;
+
+        if max_redirects > 0 {
+            self.wrap(Redirect::new().max_redirect_times(max_redirects))
+                ._finish()
+        } else {
+            self._finish()
+        }
+    }
+
+    fn _finish(self) -> Client
+    where
+        M: Transform<DefaultConnector<ConnectorService<S, Io>>, ConnectRequest> + 'static,
+        M::Transform: Service<ConnectRequest, Response = ConnectResponse, Error = SendRequestError>,
+    {
+        let mut connector = self.connector;
+
+        if let Some(val) = self.max_http_version {
+            connector = connector.max_http_version(val);
+        };
+        if let Some(val) = self.conn_window_size {
+            connector = connector.initial_connection_window_size(val)
+        };
+        if let Some(val) = self.stream_window_size {
+            connector = connector.initial_window_size(val)
+        };
+        if let Some(val) = self.local_address {
+            connector = connector.local_address(val);
+        }
+
+        let connector = DefaultConnector::new(connector.finish());
+        let connector = boxed::rc_service(self.middleware.new_transform(connector));
+
+        Client(ClientConfig {
+            default_headers: Rc::new(self.default_headers),
+            timeout: self.timeout,
+            connector,
+        })
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn client_basic_auth() {
+        let client = ClientBuilder::new().basic_auth("username", Some("password"));
+        assert_eq!(
+            client
+                .default_headers
+                .get(header::AUTHORIZATION)
+                .unwrap()
+                .to_str()
+                .unwrap(),
+            "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
+        );
+
+        let client = ClientBuilder::new().basic_auth("username", None);
+        assert_eq!(
+            client
+                .default_headers
+                .get(header::AUTHORIZATION)
+                .unwrap()
+                .to_str()
+                .unwrap(),
+            "Basic dXNlcm5hbWU6"
+        );
+    }
+
+    #[test]
+    fn client_bearer_auth() {
+        let client = ClientBuilder::new().bearer_auth("someS3cr3tAutht0k3n");
+        assert_eq!(
+            client
+                .default_headers
+                .get(header::AUTHORIZATION)
+                .unwrap()
+                .to_str()
+                .unwrap(),
+            "Bearer someS3cr3tAutht0k3n"
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/client/config.rs.html b/src/awc/client/config.rs.html new file mode 100644 index 000000000..37ff8f62c --- /dev/null +++ b/src/awc/client/config.rs.html @@ -0,0 +1,85 @@ +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
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+
use std::{net::IpAddr, time::Duration};
+
+const DEFAULT_H2_CONN_WINDOW: u32 = 1024 * 1024 * 2; // 2MB
+const DEFAULT_H2_STREAM_WINDOW: u32 = 1024 * 1024; // 1MB
+
+/// Connector configuration
+#[derive(Clone)]
+pub(crate) struct ConnectorConfig {
+    pub(crate) timeout: Duration,
+    pub(crate) handshake_timeout: Duration,
+    pub(crate) conn_lifetime: Duration,
+    pub(crate) conn_keep_alive: Duration,
+    pub(crate) disconnect_timeout: Option<Duration>,
+    pub(crate) limit: usize,
+    pub(crate) conn_window_size: u32,
+    pub(crate) stream_window_size: u32,
+    pub(crate) local_address: Option<IpAddr>,
+}
+
+impl Default for ConnectorConfig {
+    fn default() -> Self {
+        Self {
+            timeout: Duration::from_secs(5),
+            handshake_timeout: Duration::from_secs(5),
+            conn_lifetime: Duration::from_secs(75),
+            conn_keep_alive: Duration::from_secs(15),
+            disconnect_timeout: Some(Duration::from_millis(3000)),
+            limit: 100,
+            conn_window_size: DEFAULT_H2_CONN_WINDOW,
+            stream_window_size: DEFAULT_H2_STREAM_WINDOW,
+            local_address: None,
+        }
+    }
+}
+
+impl ConnectorConfig {
+    pub(crate) fn no_disconnect_timeout(&self) -> Self {
+        let mut res = self.clone();
+        res.disconnect_timeout = None;
+        res
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/client/connection.rs.html b/src/awc/client/connection.rs.html new file mode 100644 index 000000000..0970fec23 --- /dev/null +++ b/src/awc/client/connection.rs.html @@ -0,0 +1,909 @@ +connection.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
+
use std::{
+    io,
+    ops::{Deref, DerefMut},
+    pin::Pin,
+    task::{Context, Poll},
+    time,
+};
+
+use actix_codec::{AsyncRead, AsyncWrite, Framed, ReadBuf};
+use actix_http::{body::MessageBody, h1::ClientCodec, Payload, RequestHeadType, ResponseHead};
+use actix_rt::task::JoinHandle;
+use bytes::Bytes;
+use futures_core::future::LocalBoxFuture;
+use h2::client::SendRequest;
+
+use super::{error::SendRequestError, h1proto, h2proto, pool::Acquired};
+use crate::BoxError;
+
+/// Trait alias for types impl [tokio::io::AsyncRead] and [tokio::io::AsyncWrite].
+pub trait ConnectionIo: AsyncRead + AsyncWrite + Unpin + 'static {}
+
+impl<T: AsyncRead + AsyncWrite + Unpin + 'static> ConnectionIo for T {}
+
+/// HTTP client connection
+pub struct H1Connection<Io: ConnectionIo> {
+    io: Option<Io>,
+    created: time::Instant,
+    acquired: Acquired<Io>,
+}
+
+impl<Io: ConnectionIo> H1Connection<Io> {
+    /// close or release the connection to pool based on flag input
+    pub(super) fn on_release(&mut self, keep_alive: bool) {
+        if keep_alive {
+            self.release();
+        } else {
+            self.close();
+        }
+    }
+
+    /// Close connection
+    fn close(&mut self) {
+        let io = self.io.take().unwrap();
+        self.acquired.close(ConnectionInnerType::H1(io));
+    }
+
+    /// Release this connection to the connection pool
+    fn release(&mut self) {
+        let io = self.io.take().unwrap();
+        self.acquired
+            .release(ConnectionInnerType::H1(io), self.created);
+    }
+
+    fn io_pin_mut(self: Pin<&mut Self>) -> Pin<&mut Io> {
+        Pin::new(self.get_mut().io.as_mut().unwrap())
+    }
+}
+
+impl<Io: ConnectionIo> AsyncRead for H1Connection<Io> {
+    fn poll_read(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+        buf: &mut ReadBuf<'_>,
+    ) -> Poll<io::Result<()>> {
+        self.io_pin_mut().poll_read(cx, buf)
+    }
+}
+
+impl<Io: ConnectionIo> AsyncWrite for H1Connection<Io> {
+    fn poll_write(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+        buf: &[u8],
+    ) -> Poll<io::Result<usize>> {
+        self.io_pin_mut().poll_write(cx, buf)
+    }
+
+    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
+        self.io_pin_mut().poll_flush(cx)
+    }
+
+    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
+        self.io_pin_mut().poll_shutdown(cx)
+    }
+
+    fn poll_write_vectored(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+        bufs: &[io::IoSlice<'_>],
+    ) -> Poll<io::Result<usize>> {
+        self.io_pin_mut().poll_write_vectored(cx, bufs)
+    }
+
+    fn is_write_vectored(&self) -> bool {
+        self.io.as_ref().unwrap().is_write_vectored()
+    }
+}
+
+/// HTTP2 client connection
+pub struct H2Connection<Io: ConnectionIo> {
+    io: Option<H2ConnectionInner>,
+    created: time::Instant,
+    acquired: Acquired<Io>,
+}
+
+impl<Io: ConnectionIo> Deref for H2Connection<Io> {
+    type Target = SendRequest<Bytes>;
+
+    fn deref(&self) -> &Self::Target {
+        &self.io.as_ref().unwrap().sender
+    }
+}
+
+impl<Io: ConnectionIo> DerefMut for H2Connection<Io> {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.io.as_mut().unwrap().sender
+    }
+}
+
+impl<Io: ConnectionIo> H2Connection<Io> {
+    /// close or release the connection to pool based on flag input
+    pub(super) fn on_release(&mut self, close: bool) {
+        if close {
+            self.close();
+        } else {
+            self.release();
+        }
+    }
+
+    /// Close connection
+    fn close(&mut self) {
+        let io = self.io.take().unwrap();
+        self.acquired.close(ConnectionInnerType::H2(io));
+    }
+
+    /// Release this connection to the connection pool
+    fn release(&mut self) {
+        let io = self.io.take().unwrap();
+        self.acquired
+            .release(ConnectionInnerType::H2(io), self.created);
+    }
+}
+
+/// `H2ConnectionInner` has two parts: `SendRequest` and `Connection`.
+///
+/// `Connection` is spawned as an async task on runtime and `H2ConnectionInner` holds a handle
+/// for this task. Therefore, it can wake up and quit the task when SendRequest is dropped.
+pub(super) struct H2ConnectionInner {
+    handle: JoinHandle<()>,
+    sender: SendRequest<Bytes>,
+}
+
+impl H2ConnectionInner {
+    pub(super) fn new<Io: ConnectionIo>(
+        sender: SendRequest<Bytes>,
+        connection: h2::client::Connection<Io>,
+    ) -> Self {
+        let handle = actix_rt::spawn(async move {
+            let _ = connection.await;
+        });
+
+        Self { handle, sender }
+    }
+}
+
+/// Cancel spawned connection task on drop.
+impl Drop for H2ConnectionInner {
+    fn drop(&mut self) {
+        // TODO: this can end up sending extraneous requests; see if there is a better way to handle
+        if self
+            .sender
+            .send_request(http::Request::new(()), true)
+            .is_err()
+        {
+            self.handle.abort();
+        }
+    }
+}
+
+/// Unified connection type cover HTTP/1 Plain/TLS and HTTP/2 protocols.
+#[allow(dead_code)]
+pub enum Connection<A, B = Box<dyn ConnectionIo>>
+where
+    A: ConnectionIo,
+    B: ConnectionIo,
+{
+    Tcp(ConnectionType<A>),
+    Tls(ConnectionType<B>),
+}
+
+/// Unified connection type cover Http1/2 protocols
+pub enum ConnectionType<Io: ConnectionIo> {
+    H1(H1Connection<Io>),
+    H2(H2Connection<Io>),
+}
+
+/// Helper type for storing connection types in pool.
+pub(super) enum ConnectionInnerType<Io> {
+    H1(Io),
+    H2(H2ConnectionInner),
+}
+
+impl<Io: ConnectionIo> ConnectionType<Io> {
+    pub(super) fn from_pool(
+        inner: ConnectionInnerType<Io>,
+        created: time::Instant,
+        acquired: Acquired<Io>,
+    ) -> Self {
+        match inner {
+            ConnectionInnerType::H1(io) => Self::from_h1(io, created, acquired),
+            ConnectionInnerType::H2(io) => Self::from_h2(io, created, acquired),
+        }
+    }
+
+    pub(super) fn from_h1(io: Io, created: time::Instant, acquired: Acquired<Io>) -> Self {
+        Self::H1(H1Connection {
+            io: Some(io),
+            created,
+            acquired,
+        })
+    }
+
+    pub(super) fn from_h2(
+        io: H2ConnectionInner,
+        created: time::Instant,
+        acquired: Acquired<Io>,
+    ) -> Self {
+        Self::H2(H2Connection {
+            io: Some(io),
+            created,
+            acquired,
+        })
+    }
+}
+
+impl<A, B> Connection<A, B>
+where
+    A: ConnectionIo,
+    B: ConnectionIo,
+{
+    /// Send a request through connection.
+    pub fn send_request<RB, H>(
+        self,
+        head: H,
+        body: RB,
+    ) -> LocalBoxFuture<'static, Result<(ResponseHead, Payload), SendRequestError>>
+    where
+        H: Into<RequestHeadType> + 'static,
+        RB: MessageBody + 'static,
+        RB::Error: Into<BoxError>,
+    {
+        Box::pin(async move {
+            match self {
+                Connection::Tcp(ConnectionType::H1(conn)) => {
+                    h1proto::send_request(conn, head.into(), body).await
+                }
+                Connection::Tls(ConnectionType::H1(conn)) => {
+                    h1proto::send_request(conn, head.into(), body).await
+                }
+                Connection::Tls(ConnectionType::H2(conn)) => {
+                    h2proto::send_request(conn, head.into(), body).await
+                }
+                _ => {
+                    unreachable!("Plain TCP connection can be used only with HTTP/1.1 protocol")
+                }
+            }
+        })
+    }
+
+    /// Send request, returns Response and Framed tunnel.
+    pub fn open_tunnel<H: Into<RequestHeadType> + 'static>(
+        self,
+        head: H,
+    ) -> LocalBoxFuture<
+        'static,
+        Result<(ResponseHead, Framed<Connection<A, B>, ClientCodec>), SendRequestError>,
+    > {
+        Box::pin(async move {
+            match self {
+                Connection::Tcp(ConnectionType::H1(ref _conn)) => {
+                    let (head, framed) = h1proto::open_tunnel(self, head.into()).await?;
+                    Ok((head, framed))
+                }
+                Connection::Tls(ConnectionType::H1(ref _conn)) => {
+                    let (head, framed) = h1proto::open_tunnel(self, head.into()).await?;
+                    Ok((head, framed))
+                }
+                Connection::Tls(ConnectionType::H2(mut conn)) => {
+                    conn.release();
+                    Err(SendRequestError::TunnelNotSupported)
+                }
+                Connection::Tcp(ConnectionType::H2(_)) => {
+                    unreachable!("Plain Tcp connection can be used only in Http1 protocol")
+                }
+            }
+        })
+    }
+}
+
+impl<A, B> AsyncRead for Connection<A, B>
+where
+    A: ConnectionIo,
+    B: ConnectionIo,
+{
+    fn poll_read(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+        buf: &mut ReadBuf<'_>,
+    ) -> Poll<io::Result<()>> {
+        match self.get_mut() {
+            Connection::Tcp(ConnectionType::H1(conn)) => Pin::new(conn).poll_read(cx, buf),
+            Connection::Tls(ConnectionType::H1(conn)) => Pin::new(conn).poll_read(cx, buf),
+            _ => unreachable!("H2Connection can not impl AsyncRead trait"),
+        }
+    }
+}
+
+const H2_UNREACHABLE_WRITE: &str = "H2Connection can not impl AsyncWrite trait";
+
+impl<A, B> AsyncWrite for Connection<A, B>
+where
+    A: ConnectionIo,
+    B: ConnectionIo,
+{
+    fn poll_write(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+        buf: &[u8],
+    ) -> Poll<io::Result<usize>> {
+        match self.get_mut() {
+            Connection::Tcp(ConnectionType::H1(conn)) => Pin::new(conn).poll_write(cx, buf),
+            Connection::Tls(ConnectionType::H1(conn)) => Pin::new(conn).poll_write(cx, buf),
+            _ => unreachable!("{}", H2_UNREACHABLE_WRITE),
+        }
+    }
+
+    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
+        match self.get_mut() {
+            Connection::Tcp(ConnectionType::H1(conn)) => Pin::new(conn).poll_flush(cx),
+            Connection::Tls(ConnectionType::H1(conn)) => Pin::new(conn).poll_flush(cx),
+            _ => unreachable!("{}", H2_UNREACHABLE_WRITE),
+        }
+    }
+
+    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
+        match self.get_mut() {
+            Connection::Tcp(ConnectionType::H1(conn)) => Pin::new(conn).poll_shutdown(cx),
+            Connection::Tls(ConnectionType::H1(conn)) => Pin::new(conn).poll_shutdown(cx),
+            _ => unreachable!("{}", H2_UNREACHABLE_WRITE),
+        }
+    }
+
+    fn poll_write_vectored(
+        self: Pin<&mut Self>,
+        cx: &mut Context<'_>,
+        bufs: &[io::IoSlice<'_>],
+    ) -> Poll<io::Result<usize>> {
+        match self.get_mut() {
+            Connection::Tcp(ConnectionType::H1(conn)) => {
+                Pin::new(conn).poll_write_vectored(cx, bufs)
+            }
+            Connection::Tls(ConnectionType::H1(conn)) => {
+                Pin::new(conn).poll_write_vectored(cx, bufs)
+            }
+            _ => unreachable!("{}", H2_UNREACHABLE_WRITE),
+        }
+    }
+
+    fn is_write_vectored(&self) -> bool {
+        match *self {
+            Connection::Tcp(ConnectionType::H1(ref conn)) => conn.is_write_vectored(),
+            Connection::Tls(ConnectionType::H1(ref conn)) => conn.is_write_vectored(),
+            _ => unreachable!("{}", H2_UNREACHABLE_WRITE),
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use std::{
+        future::Future,
+        net,
+        time::{Duration, Instant},
+    };
+
+    use actix_rt::{
+        net::TcpStream,
+        time::{interval, Interval},
+    };
+
+    use super::*;
+
+    #[actix_rt::test]
+    async fn test_h2_connection_drop() {
+        env_logger::try_init().ok();
+
+        let addr = "127.0.0.1:0".parse::<net::SocketAddr>().unwrap();
+        let listener = net::TcpListener::bind(addr).unwrap();
+        let local = listener.local_addr().unwrap();
+
+        std::thread::spawn(move || while listener.accept().is_ok() {});
+
+        let tcp = TcpStream::connect(local).await.unwrap();
+        let (sender, connection) = h2::client::handshake(tcp).await.unwrap();
+        let conn = H2ConnectionInner::new(sender.clone(), connection);
+
+        assert!(sender.clone().ready().await.is_ok());
+        assert!(h2::client::SendRequest::clone(&conn.sender)
+            .ready()
+            .await
+            .is_ok());
+
+        drop(conn);
+
+        struct DropCheck {
+            sender: h2::client::SendRequest<Bytes>,
+            interval: Interval,
+            start_from: Instant,
+        }
+
+        impl Future for DropCheck {
+            type Output = ();
+
+            fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+                let this = self.get_mut();
+                match futures_core::ready!(this.sender.poll_ready(cx)) {
+                    Ok(()) => {
+                        if this.start_from.elapsed() > Duration::from_secs(10) {
+                            panic!("connection should be gone and can not be ready");
+                        } else {
+                            match this.interval.poll_tick(cx) {
+                                Poll::Ready(_) => {
+                                    // prevents spurious test hang
+                                    this.interval.reset();
+
+                                    Poll::Pending
+                                }
+                                Poll::Pending => Poll::Pending,
+                            }
+                        }
+                    }
+                    Err(_) => Poll::Ready(()),
+                }
+            }
+        }
+
+        DropCheck {
+            sender,
+            interval: interval(Duration::from_millis(100)),
+            start_from: Instant::now(),
+        }
+        .await;
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/client/connector.rs.html b/src/awc/client/connector.rs.html new file mode 100644 index 000000000..1a7073347 --- /dev/null +++ b/src/awc/client/connector.rs.html @@ -0,0 +1,2305 @@ +connector.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
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+
use std::{
+    fmt,
+    future::Future,
+    net::IpAddr,
+    pin::Pin,
+    rc::Rc,
+    task::{Context, Poll},
+    time::Duration,
+};
+
+use actix_http::Protocol;
+use actix_rt::{
+    net::{ActixStream, TcpStream},
+    time::{sleep, Sleep},
+};
+use actix_service::Service;
+use actix_tls::connect::{
+    ConnectError as TcpConnectError, ConnectInfo, Connection as TcpConnection,
+    Connector as TcpConnector, Resolver,
+};
+use futures_core::{future::LocalBoxFuture, ready};
+use http::Uri;
+use pin_project_lite::pin_project;
+
+use super::{
+    config::ConnectorConfig,
+    connection::{Connection, ConnectionIo},
+    error::ConnectError,
+    pool::ConnectionPool,
+    Connect,
+};
+
+enum OurTlsConnector {
+    #[allow(dead_code)] // only dead when no TLS feature is enabled
+    None,
+
+    #[cfg(feature = "openssl")]
+    Openssl(actix_tls::connect::openssl::reexports::SslConnector),
+
+    /// Provided because building the OpenSSL context on newer versions can be very slow.
+    /// This prevents unnecessary calls to `.build()` while constructing the client connector.
+    #[cfg(feature = "openssl")]
+    #[allow(dead_code)] // false positive; used in build_tls
+    OpensslBuilder(actix_tls::connect::openssl::reexports::SslConnectorBuilder),
+
+    #[cfg(feature = "rustls-0_20")]
+    #[allow(dead_code)] // false positive; used in build_tls
+    Rustls020(std::sync::Arc<actix_tls::connect::rustls_0_20::reexports::ClientConfig>),
+
+    #[cfg(feature = "rustls-0_21")]
+    #[allow(dead_code)] // false positive; used in build_tls
+    Rustls021(std::sync::Arc<actix_tls::connect::rustls_0_21::reexports::ClientConfig>),
+
+    #[cfg(any(
+        feature = "rustls-0_22-webpki-roots",
+        feature = "rustls-0_22-native-roots",
+    ))]
+    #[allow(dead_code)] // false positive; used in build_tls
+    Rustls022(std::sync::Arc<actix_tls::connect::rustls_0_22::reexports::ClientConfig>),
+
+    #[cfg(feature = "rustls-0_23")]
+    #[allow(dead_code)] // false positive; used in build_tls
+    Rustls023(std::sync::Arc<actix_tls::connect::rustls_0_23::reexports::ClientConfig>),
+}
+
+/// Manages HTTP client network connectivity.
+///
+/// The `Connector` type uses a builder-like combinator pattern for service construction that
+/// finishes by calling the `.finish()` method.
+///
+/// ```no_run
+/// use std::time::Duration;
+///
+/// let connector = awc::Connector::new()
+///      .timeout(Duration::from_secs(5))
+///      .finish();
+/// ```
+pub struct Connector<T> {
+    connector: T,
+    config: ConnectorConfig,
+
+    #[allow(dead_code)] // only dead when no TLS feature is enabled
+    tls: OurTlsConnector,
+}
+
+impl Connector<()> {
+    /// Create a new connector with default TLS settings
+    ///
+    /// # Panics
+    ///
+    /// - When the `rustls-0_23-webpki-roots` or `rustls-0_23-native-roots` features are enabled
+    ///     and no default crypto provider has been loaded, this method will panic.
+    /// - When the `rustls-0_23-native-roots` or `rustls-0_22-native-roots` features are enabled
+    ///     and the runtime system has no native root certificates, this method will panic.
+    #[allow(clippy::new_ret_no_self, clippy::let_unit_value)]
+    pub fn new() -> Connector<
+        impl Service<
+                ConnectInfo<Uri>,
+                Response = TcpConnection<Uri, TcpStream>,
+                Error = actix_tls::connect::ConnectError,
+            > + Clone,
+    > {
+        Connector {
+            connector: TcpConnector::new(resolver::resolver()).service(),
+            config: ConnectorConfig::default(),
+            tls: Self::build_tls(vec![b"h2".to_vec(), b"http/1.1".to_vec()]),
+        }
+    }
+
+    cfg_if::cfg_if! {
+        if #[cfg(any(feature = "rustls-0_23-webpki-roots", feature = "rustls-0_23-native-roots"))] {
+            /// Build TLS connector with Rustls v0.23, based on supplied ALPN protocols.
+            ///
+            /// Note that if other TLS crate features are enabled, Rustls v0.23 will be used.
+            fn build_tls(protocols: Vec<Vec<u8>>) -> OurTlsConnector {
+                use actix_tls::connect::rustls_0_23::{self, reexports::ClientConfig};
+
+                cfg_if::cfg_if! {
+                    if #[cfg(feature = "rustls-0_23-webpki-roots")] {
+                        let certs = rustls_0_23::webpki_roots_cert_store();
+                    } else if #[cfg(feature = "rustls-0_23-native-roots")] {
+                        let certs = rustls_0_23::native_roots_cert_store().expect("Failed to find native root certificates");
+                    }
+                }
+
+                let mut config = ClientConfig::builder()
+                    .with_root_certificates(certs)
+                    .with_no_client_auth();
+
+                config.alpn_protocols = protocols;
+
+                OurTlsConnector::Rustls023(std::sync::Arc::new(config))
+            }
+        } else if #[cfg(any(feature = "rustls-0_22-webpki-roots", feature = "rustls-0_22-native-roots"))] {
+            /// Build TLS connector with Rustls v0.22, based on supplied ALPN protocols.
+            fn build_tls(protocols: Vec<Vec<u8>>) -> OurTlsConnector {
+                use actix_tls::connect::rustls_0_22::{self, reexports::ClientConfig};
+
+                cfg_if::cfg_if! {
+                    if #[cfg(feature = "rustls-0_22-webpki-roots")] {
+                        let certs = rustls_0_22::webpki_roots_cert_store();
+                    } else if #[cfg(feature = "rustls-0_22-native-roots")] {
+                        let certs = rustls_0_22::native_roots_cert_store().expect("Failed to find native root certificates");
+                    }
+                }
+
+                let mut config = ClientConfig::builder()
+                    .with_root_certificates(certs)
+                    .with_no_client_auth();
+
+                config.alpn_protocols = protocols;
+
+                OurTlsConnector::Rustls022(std::sync::Arc::new(config))
+            }
+        } else if #[cfg(feature = "rustls-0_21")] {
+            /// Build TLS connector with Rustls v0.21, based on supplied ALPN protocols.
+            fn build_tls(protocols: Vec<Vec<u8>>) -> OurTlsConnector {
+                use actix_tls::connect::rustls_0_21::{reexports::ClientConfig, webpki_roots_cert_store};
+
+                let mut config = ClientConfig::builder()
+                    .with_safe_defaults()
+                    .with_root_certificates(webpki_roots_cert_store())
+                    .with_no_client_auth();
+
+                config.alpn_protocols = protocols;
+
+                OurTlsConnector::Rustls021(std::sync::Arc::new(config))
+            }
+        } else if #[cfg(feature = "rustls-0_20")] {
+            /// Build TLS connector with Rustls v0.20, based on supplied ALPN protocols.
+            fn build_tls(protocols: Vec<Vec<u8>>) -> OurTlsConnector {
+                use actix_tls::connect::rustls_0_20::{reexports::ClientConfig, webpki_roots_cert_store};
+
+                let mut config = ClientConfig::builder()
+                    .with_safe_defaults()
+                    .with_root_certificates(webpki_roots_cert_store())
+                    .with_no_client_auth();
+
+                config.alpn_protocols = protocols;
+
+                OurTlsConnector::Rustls020(std::sync::Arc::new(config))
+            }
+        } else if #[cfg(feature = "openssl")] {
+            /// Build TLS connector with OpenSSL, based on supplied ALPN protocols.
+            fn build_tls(protocols: Vec<Vec<u8>>) -> OurTlsConnector {
+                use actix_tls::connect::openssl::reexports::{SslConnector, SslMethod};
+                use bytes::{BufMut, BytesMut};
+
+                let mut alpn = BytesMut::with_capacity(20);
+                for proto in &protocols {
+                    alpn.put_u8(proto.len() as u8);
+                    alpn.put(proto.as_slice());
+                }
+
+                let mut ssl = SslConnector::builder(SslMethod::tls()).unwrap();
+                if let Err(err) = ssl.set_alpn_protos(&alpn) {
+                    log::error!("Can not set ALPN protocol: {err:?}");
+                }
+
+                OurTlsConnector::OpensslBuilder(ssl)
+            }
+        } else {
+            /// Provides an empty TLS connector when no TLS feature is enabled, or when only the
+            /// `rustls-0_23` crate feature is enabled.
+            fn build_tls(_: Vec<Vec<u8>>) -> OurTlsConnector {
+                OurTlsConnector::None
+            }
+        }
+    }
+}
+
+impl<S> Connector<S> {
+    /// Sets custom connector.
+    pub fn connector<S1, Io1>(self, connector: S1) -> Connector<S1>
+    where
+        Io1: ActixStream + fmt::Debug + 'static,
+        S1: Service<ConnectInfo<Uri>, Response = TcpConnection<Uri, Io1>, Error = TcpConnectError>
+            + Clone,
+    {
+        Connector {
+            connector,
+            config: self.config,
+            tls: self.tls,
+        }
+    }
+}
+
+impl<S, IO> Connector<S>
+where
+    // Note:
+    // Input Io type is bound to ActixStream trait but internally in client module they
+    // are bound to ConnectionIo trait alias. And latter is the trait exposed to public
+    // in the form of Box<dyn ConnectionIo> type.
+    //
+    // This remap is to hide ActixStream's trait methods. They are not meant to be called
+    // from user code.
+    IO: ActixStream + fmt::Debug + 'static,
+    S: Service<ConnectInfo<Uri>, Response = TcpConnection<Uri, IO>, Error = TcpConnectError>
+        + Clone
+        + 'static,
+{
+    /// Sets TCP connection timeout.
+    ///
+    /// This is the max time allowed to connect to remote host, including DNS name resolution.
+    ///
+    /// By default, the timeout is 5 seconds.
+    pub fn timeout(mut self, timeout: Duration) -> Self {
+        self.config.timeout = timeout;
+        self
+    }
+
+    /// Sets TLS handshake timeout.
+    ///
+    /// This is the max time allowed to perform the TLS handshake with remote host after TCP
+    /// connection is established.
+    ///
+    /// By default, the timeout is 5 seconds.
+    pub fn handshake_timeout(mut self, timeout: Duration) -> Self {
+        self.config.handshake_timeout = timeout;
+        self
+    }
+
+    /// Sets custom OpenSSL `SslConnector` instance.
+    #[cfg(feature = "openssl")]
+    pub fn openssl(
+        mut self,
+        connector: actix_tls::connect::openssl::reexports::SslConnector,
+    ) -> Self {
+        self.tls = OurTlsConnector::Openssl(connector);
+        self
+    }
+
+    /// See docs for [`Connector::openssl`].
+    #[doc(hidden)]
+    #[cfg(feature = "openssl")]
+    #[deprecated(since = "3.0.0", note = "Renamed to `Connector::openssl`.")]
+    pub fn ssl(mut self, connector: actix_tls::connect::openssl::reexports::SslConnector) -> Self {
+        self.tls = OurTlsConnector::Openssl(connector);
+        self
+    }
+
+    /// Sets custom Rustls v0.20 `ClientConfig` instance.
+    #[cfg(feature = "rustls-0_20")]
+    pub fn rustls(
+        mut self,
+        connector: std::sync::Arc<actix_tls::connect::rustls_0_20::reexports::ClientConfig>,
+    ) -> Self {
+        self.tls = OurTlsConnector::Rustls020(connector);
+        self
+    }
+
+    /// Sets custom Rustls v0.21 `ClientConfig` instance.
+    #[cfg(feature = "rustls-0_21")]
+    pub fn rustls_021(
+        mut self,
+        connector: std::sync::Arc<actix_tls::connect::rustls_0_21::reexports::ClientConfig>,
+    ) -> Self {
+        self.tls = OurTlsConnector::Rustls021(connector);
+        self
+    }
+
+    /// Sets custom Rustls v0.22 `ClientConfig` instance.
+    #[cfg(any(
+        feature = "rustls-0_22-webpki-roots",
+        feature = "rustls-0_22-native-roots",
+    ))]
+    pub fn rustls_0_22(
+        mut self,
+        connector: std::sync::Arc<actix_tls::connect::rustls_0_22::reexports::ClientConfig>,
+    ) -> Self {
+        self.tls = OurTlsConnector::Rustls022(connector);
+        self
+    }
+
+    /// Sets custom Rustls v0.23 `ClientConfig` instance.
+    ///
+    /// In order to enable ALPN, set the `.alpn_protocols` field on the ClientConfig to the
+    /// following:
+    ///
+    /// ```no_run
+    /// vec![b"h2".to_vec(), b"http/1.1".to_vec()]
+    /// # ;
+    /// ```
+    #[cfg(feature = "rustls-0_23")]
+    pub fn rustls_0_23(
+        mut self,
+        connector: std::sync::Arc<actix_tls::connect::rustls_0_23::reexports::ClientConfig>,
+    ) -> Self {
+        self.tls = OurTlsConnector::Rustls023(connector);
+        self
+    }
+
+    /// Sets maximum supported HTTP major version.
+    ///
+    /// Supported versions are HTTP/1.1 and HTTP/2.
+    pub fn max_http_version(mut self, val: http::Version) -> Self {
+        let versions = match val {
+            http::Version::HTTP_11 => vec![b"http/1.1".to_vec()],
+            http::Version::HTTP_2 => vec![b"h2".to_vec(), b"http/1.1".to_vec()],
+            _ => {
+                unimplemented!("actix-http client only supports versions http/1.1 & http/2")
+            }
+        };
+        self.tls = Connector::build_tls(versions);
+        self
+    }
+
+    /// Sets the initial window size (in bytes) for HTTP/2 stream-level flow control for received
+    /// data.
+    ///
+    /// The default value is 65,535 and is good for APIs, but not for big objects.
+    pub fn initial_window_size(mut self, size: u32) -> Self {
+        self.config.stream_window_size = size;
+        self
+    }
+
+    /// Sets the initial window size (in bytes) for HTTP/2 connection-level flow control for
+    /// received data.
+    ///
+    /// The default value is 65,535 and is good for APIs, but not for big objects.
+    pub fn initial_connection_window_size(mut self, size: u32) -> Self {
+        self.config.conn_window_size = size;
+        self
+    }
+
+    /// Set total number of simultaneous connections per type of scheme.
+    ///
+    /// If limit is 0, the connector has no limit.
+    ///
+    /// The default limit size is 100.
+    pub fn limit(mut self, limit: usize) -> Self {
+        if limit == 0 {
+            self.config.limit = u32::MAX as usize;
+        } else {
+            self.config.limit = limit;
+        }
+
+        self
+    }
+
+    /// Set keep-alive period for opened connection.
+    ///
+    /// Keep-alive period is the period between connection usage. If
+    /// the delay between repeated usages of the same connection
+    /// exceeds this period, the connection is closed.
+    /// Default keep-alive period is 15 seconds.
+    pub fn conn_keep_alive(mut self, dur: Duration) -> Self {
+        self.config.conn_keep_alive = dur;
+        self
+    }
+
+    /// Set max lifetime period for connection.
+    ///
+    /// Connection lifetime is max lifetime of any opened connection
+    /// until it is closed regardless of keep-alive period.
+    /// Default lifetime period is 75 seconds.
+    pub fn conn_lifetime(mut self, dur: Duration) -> Self {
+        self.config.conn_lifetime = dur;
+        self
+    }
+
+    /// Set server connection disconnect timeout in milliseconds.
+    ///
+    /// Defines a timeout for disconnect connection. If a disconnect procedure does not complete
+    /// within this time, the socket get dropped. This timeout affects only secure connections.
+    ///
+    /// To disable timeout set value to 0.
+    ///
+    /// By default disconnect timeout is set to 3000 milliseconds.
+    pub fn disconnect_timeout(mut self, dur: Duration) -> Self {
+        self.config.disconnect_timeout = Some(dur);
+        self
+    }
+
+    /// Set local IP Address the connector would use for establishing connection.
+    pub fn local_address(mut self, addr: IpAddr) -> Self {
+        self.config.local_address = Some(addr);
+        self
+    }
+
+    /// Finish configuration process and create connector service.
+    ///
+    /// The `Connector` builder always concludes by calling `finish()` last in its combinator chain.
+    pub fn finish(self) -> ConnectorService<S, IO> {
+        let local_address = self.config.local_address;
+        let timeout = self.config.timeout;
+
+        let tcp_service_inner =
+            TcpConnectorInnerService::new(self.connector, timeout, local_address);
+
+        #[allow(clippy::redundant_clone)]
+        let tcp_service = TcpConnectorService {
+            service: tcp_service_inner.clone(),
+        };
+
+        let tls = match self.tls {
+            #[cfg(feature = "openssl")]
+            OurTlsConnector::OpensslBuilder(builder) => OurTlsConnector::Openssl(builder.build()),
+            tls => tls,
+        };
+
+        let tls_service = match tls {
+            OurTlsConnector::None => {
+                #[cfg(not(feature = "dangerous-h2c"))]
+                {
+                    None
+                }
+
+                #[cfg(feature = "dangerous-h2c")]
+                {
+                    use std::io;
+
+                    use actix_tls::connect::Connection;
+                    use actix_utils::future::{ready, Ready};
+
+                    #[allow(non_local_definitions)]
+                    impl IntoConnectionIo for TcpConnection<Uri, Box<dyn ConnectionIo>> {
+                        fn into_connection_io(self) -> (Box<dyn ConnectionIo>, Protocol) {
+                            let io = self.into_parts().0;
+                            (io, Protocol::Http2)
+                        }
+                    }
+
+                    /// With the `dangerous-h2c` feature enabled, this connector uses a no-op TLS
+                    /// connection service that passes through plain TCP as a TLS connection.
+                    ///
+                    /// The protocol version of this fake TLS connection is set to be HTTP/2.
+                    #[derive(Clone)]
+                    struct NoOpTlsConnectorService;
+
+                    impl<R, IO> Service<Connection<R, IO>> for NoOpTlsConnectorService
+                    where
+                        IO: ActixStream + 'static,
+                    {
+                        type Response = Connection<R, Box<dyn ConnectionIo>>;
+                        type Error = io::Error;
+                        type Future = Ready<Result<Self::Response, Self::Error>>;
+
+                        actix_service::always_ready!();
+
+                        fn call(&self, connection: Connection<R, IO>) -> Self::Future {
+                            let (io, connection) = connection.replace_io(());
+                            let (_, connection) = connection.replace_io(Box::new(io) as _);
+
+                            ready(Ok(connection))
+                        }
+                    }
+
+                    let handshake_timeout = self.config.handshake_timeout;
+
+                    let tls_service = TlsConnectorService {
+                        tcp_service: tcp_service_inner,
+                        tls_service: NoOpTlsConnectorService,
+                        timeout: handshake_timeout,
+                    };
+
+                    Some(actix_service::boxed::rc_service(tls_service))
+                }
+            }
+
+            #[cfg(feature = "openssl")]
+            OurTlsConnector::Openssl(tls) => {
+                const H2: &[u8] = b"h2";
+
+                use actix_tls::connect::openssl::{reexports::AsyncSslStream, TlsConnector};
+
+                #[allow(non_local_definitions)]
+                impl<IO: ConnectionIo> IntoConnectionIo for TcpConnection<Uri, AsyncSslStream<IO>> {
+                    fn into_connection_io(self) -> (Box<dyn ConnectionIo>, Protocol) {
+                        let sock = self.into_parts().0;
+                        let h2 = sock
+                            .ssl()
+                            .selected_alpn_protocol()
+                            .map_or(false, |protos| protos.windows(2).any(|w| w == H2));
+                        if h2 {
+                            (Box::new(sock), Protocol::Http2)
+                        } else {
+                            (Box::new(sock), Protocol::Http1)
+                        }
+                    }
+                }
+
+                let handshake_timeout = self.config.handshake_timeout;
+
+                let tls_service = TlsConnectorService {
+                    tcp_service: tcp_service_inner,
+                    tls_service: TlsConnector::service(tls),
+                    timeout: handshake_timeout,
+                };
+
+                Some(actix_service::boxed::rc_service(tls_service))
+            }
+
+            #[cfg(feature = "openssl")]
+            OurTlsConnector::OpensslBuilder(_) => {
+                unreachable!("OpenSSL builder is built before this match.");
+            }
+
+            #[cfg(feature = "rustls-0_20")]
+            OurTlsConnector::Rustls020(tls) => {
+                const H2: &[u8] = b"h2";
+
+                use actix_tls::connect::rustls_0_20::{reexports::AsyncTlsStream, TlsConnector};
+
+                #[allow(non_local_definitions)]
+                impl<Io: ConnectionIo> IntoConnectionIo for TcpConnection<Uri, AsyncTlsStream<Io>> {
+                    fn into_connection_io(self) -> (Box<dyn ConnectionIo>, Protocol) {
+                        let sock = self.into_parts().0;
+                        let h2 = sock
+                            .get_ref()
+                            .1
+                            .alpn_protocol()
+                            .map_or(false, |protos| protos.windows(2).any(|w| w == H2));
+                        if h2 {
+                            (Box::new(sock), Protocol::Http2)
+                        } else {
+                            (Box::new(sock), Protocol::Http1)
+                        }
+                    }
+                }
+
+                let handshake_timeout = self.config.handshake_timeout;
+
+                let tls_service = TlsConnectorService {
+                    tcp_service: tcp_service_inner,
+                    tls_service: TlsConnector::service(tls),
+                    timeout: handshake_timeout,
+                };
+
+                Some(actix_service::boxed::rc_service(tls_service))
+            }
+
+            #[cfg(feature = "rustls-0_21")]
+            OurTlsConnector::Rustls021(tls) => {
+                const H2: &[u8] = b"h2";
+
+                use actix_tls::connect::rustls_0_21::{reexports::AsyncTlsStream, TlsConnector};
+
+                #[allow(non_local_definitions)]
+                impl<Io: ConnectionIo> IntoConnectionIo for TcpConnection<Uri, AsyncTlsStream<Io>> {
+                    fn into_connection_io(self) -> (Box<dyn ConnectionIo>, Protocol) {
+                        let sock = self.into_parts().0;
+                        let h2 = sock
+                            .get_ref()
+                            .1
+                            .alpn_protocol()
+                            .map_or(false, |protos| protos.windows(2).any(|w| w == H2));
+                        if h2 {
+                            (Box::new(sock), Protocol::Http2)
+                        } else {
+                            (Box::new(sock), Protocol::Http1)
+                        }
+                    }
+                }
+
+                let handshake_timeout = self.config.handshake_timeout;
+
+                let tls_service = TlsConnectorService {
+                    tcp_service: tcp_service_inner,
+                    tls_service: TlsConnector::service(tls),
+                    timeout: handshake_timeout,
+                };
+
+                Some(actix_service::boxed::rc_service(tls_service))
+            }
+
+            #[cfg(any(
+                feature = "rustls-0_22-webpki-roots",
+                feature = "rustls-0_22-native-roots",
+            ))]
+            OurTlsConnector::Rustls022(tls) => {
+                const H2: &[u8] = b"h2";
+
+                use actix_tls::connect::rustls_0_22::{reexports::AsyncTlsStream, TlsConnector};
+
+                #[allow(non_local_definitions)]
+                impl<Io: ConnectionIo> IntoConnectionIo for TcpConnection<Uri, AsyncTlsStream<Io>> {
+                    fn into_connection_io(self) -> (Box<dyn ConnectionIo>, Protocol) {
+                        let sock = self.into_parts().0;
+                        let h2 = sock
+                            .get_ref()
+                            .1
+                            .alpn_protocol()
+                            .map_or(false, |protos| protos.windows(2).any(|w| w == H2));
+                        if h2 {
+                            (Box::new(sock), Protocol::Http2)
+                        } else {
+                            (Box::new(sock), Protocol::Http1)
+                        }
+                    }
+                }
+
+                let handshake_timeout = self.config.handshake_timeout;
+
+                let tls_service = TlsConnectorService {
+                    tcp_service: tcp_service_inner,
+                    tls_service: TlsConnector::service(tls),
+                    timeout: handshake_timeout,
+                };
+
+                Some(actix_service::boxed::rc_service(tls_service))
+            }
+
+            #[cfg(feature = "rustls-0_23")]
+            OurTlsConnector::Rustls023(tls) => {
+                const H2: &[u8] = b"h2";
+
+                use actix_tls::connect::rustls_0_23::{reexports::AsyncTlsStream, TlsConnector};
+
+                #[allow(non_local_definitions)]
+                impl<Io: ConnectionIo> IntoConnectionIo for TcpConnection<Uri, AsyncTlsStream<Io>> {
+                    fn into_connection_io(self) -> (Box<dyn ConnectionIo>, Protocol) {
+                        let sock = self.into_parts().0;
+                        let h2 = sock
+                            .get_ref()
+                            .1
+                            .alpn_protocol()
+                            .map_or(false, |protos| protos.windows(2).any(|w| w == H2));
+                        if h2 {
+                            (Box::new(sock), Protocol::Http2)
+                        } else {
+                            (Box::new(sock), Protocol::Http1)
+                        }
+                    }
+                }
+
+                let handshake_timeout = self.config.handshake_timeout;
+
+                let tls_service = TlsConnectorService {
+                    tcp_service: tcp_service_inner,
+                    tls_service: TlsConnector::service(tls),
+                    timeout: handshake_timeout,
+                };
+
+                Some(actix_service::boxed::rc_service(tls_service))
+            }
+        };
+
+        let tcp_config = self.config.no_disconnect_timeout();
+
+        let tcp_pool = ConnectionPool::new(tcp_service, tcp_config);
+
+        let tls_config = self.config;
+        let tls_pool =
+            tls_service.map(move |tls_service| ConnectionPool::new(tls_service, tls_config));
+
+        ConnectorServicePriv { tcp_pool, tls_pool }
+    }
+}
+
+/// tcp service for map `TcpConnection<Uri, Io>` type to `(Io, Protocol)`
+#[derive(Clone)]
+pub struct TcpConnectorService<S: Clone> {
+    service: S,
+}
+
+impl<S, Io> Service<Connect> for TcpConnectorService<S>
+where
+    S: Service<Connect, Response = TcpConnection<Uri, Io>, Error = ConnectError> + Clone + 'static,
+{
+    type Response = (Io, Protocol);
+    type Error = ConnectError;
+    type Future = TcpConnectorFuture<S::Future>;
+
+    actix_service::forward_ready!(service);
+
+    fn call(&self, req: Connect) -> Self::Future {
+        TcpConnectorFuture {
+            fut: self.service.call(req),
+        }
+    }
+}
+
+pin_project! {
+    #[project = TcpConnectorFutureProj]
+    pub struct TcpConnectorFuture<Fut> {
+        #[pin]
+        fut: Fut,
+    }
+}
+
+impl<Fut, Io> Future for TcpConnectorFuture<Fut>
+where
+    Fut: Future<Output = Result<TcpConnection<Uri, Io>, ConnectError>>,
+{
+    type Output = Result<(Io, Protocol), ConnectError>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        self.project()
+            .fut
+            .poll(cx)
+            .map_ok(|res| (res.into_parts().0, Protocol::Http1))
+    }
+}
+
+/// service for establish tcp connection and do client tls handshake.
+/// operation is canceled when timeout limit reached.
+#[cfg(any(
+    feature = "dangerous-h2c",
+    feature = "openssl",
+    feature = "rustls-0_20",
+    feature = "rustls-0_21",
+    feature = "rustls-0_22-webpki-roots",
+    feature = "rustls-0_22-native-roots",
+    feature = "rustls-0_23",
+    feature = "rustls-0_23-webpki-roots",
+    feature = "rustls-0_23-native-roots"
+))]
+struct TlsConnectorService<Tcp, Tls> {
+    /// TCP connection is canceled on `TcpConnectorInnerService`'s timeout setting.
+    tcp_service: Tcp,
+
+    /// TLS connection is canceled on `TlsConnectorService`'s timeout setting.
+    tls_service: Tls,
+
+    timeout: Duration,
+}
+
+#[cfg(any(
+    feature = "dangerous-h2c",
+    feature = "openssl",
+    feature = "rustls-0_20",
+    feature = "rustls-0_21",
+    feature = "rustls-0_22-webpki-roots",
+    feature = "rustls-0_22-native-roots",
+    feature = "rustls-0_23",
+))]
+impl<Tcp, Tls, IO> Service<Connect> for TlsConnectorService<Tcp, Tls>
+where
+    Tcp:
+        Service<Connect, Response = TcpConnection<Uri, IO>, Error = ConnectError> + Clone + 'static,
+    Tls: Service<TcpConnection<Uri, IO>, Error = std::io::Error> + Clone + 'static,
+    Tls::Response: IntoConnectionIo,
+    IO: ConnectionIo,
+{
+    type Response = (Box<dyn ConnectionIo>, Protocol);
+    type Error = ConnectError;
+    type Future = TlsConnectorFuture<Tls, Tcp::Future, Tls::Future>;
+
+    fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        ready!(self.tcp_service.poll_ready(cx))?;
+        ready!(self.tls_service.poll_ready(cx))?;
+        Poll::Ready(Ok(()))
+    }
+
+    fn call(&self, req: Connect) -> Self::Future {
+        let fut = self.tcp_service.call(req);
+        let tls_service = self.tls_service.clone();
+        let timeout = self.timeout;
+
+        TlsConnectorFuture::TcpConnect {
+            fut,
+            tls_service: Some(tls_service),
+            timeout,
+        }
+    }
+}
+
+pin_project! {
+    #[project = TlsConnectorProj]
+    #[allow(clippy::large_enum_variant)]
+    enum TlsConnectorFuture<S, Fut1, Fut2> {
+        TcpConnect {
+            #[pin]
+            fut: Fut1,
+            tls_service: Option<S>,
+            timeout: Duration,
+        },
+        TlsConnect {
+            #[pin]
+            fut: Fut2,
+            #[pin]
+            timeout: Sleep,
+        },
+    }
+
+}
+/// helper trait for generic over different TlsStream types between tls crates.
+trait IntoConnectionIo {
+    fn into_connection_io(self) -> (Box<dyn ConnectionIo>, Protocol);
+}
+
+impl<S, Io, Fut1, Fut2, Res> Future for TlsConnectorFuture<S, Fut1, Fut2>
+where
+    S: Service<TcpConnection<Uri, Io>, Response = Res, Error = std::io::Error, Future = Fut2>,
+    S::Response: IntoConnectionIo,
+    Fut1: Future<Output = Result<TcpConnection<Uri, Io>, ConnectError>>,
+    Fut2: Future<Output = Result<S::Response, S::Error>>,
+    Io: ConnectionIo,
+{
+    type Output = Result<(Box<dyn ConnectionIo>, Protocol), ConnectError>;
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        match self.as_mut().project() {
+            TlsConnectorProj::TcpConnect {
+                fut,
+                tls_service,
+                timeout,
+            } => {
+                let res = ready!(fut.poll(cx))?;
+                let fut = tls_service
+                    .take()
+                    .expect("TlsConnectorFuture polled after complete")
+                    .call(res);
+                let timeout = sleep(*timeout);
+                self.set(TlsConnectorFuture::TlsConnect { fut, timeout });
+                self.poll(cx)
+            }
+            TlsConnectorProj::TlsConnect { fut, timeout } => match fut.poll(cx)? {
+                Poll::Ready(res) => Poll::Ready(Ok(res.into_connection_io())),
+                Poll::Pending => timeout.poll(cx).map(|_| Err(ConnectError::Timeout)),
+            },
+        }
+    }
+}
+
+/// service for establish tcp connection.
+/// operation is canceled when timeout limit reached.
+#[derive(Clone)]
+pub struct TcpConnectorInnerService<S: Clone> {
+    service: S,
+    timeout: Duration,
+    local_address: Option<std::net::IpAddr>,
+}
+
+impl<S: Clone> TcpConnectorInnerService<S> {
+    fn new(service: S, timeout: Duration, local_address: Option<std::net::IpAddr>) -> Self {
+        Self {
+            service,
+            timeout,
+            local_address,
+        }
+    }
+}
+
+impl<S, Io> Service<Connect> for TcpConnectorInnerService<S>
+where
+    S: Service<ConnectInfo<Uri>, Response = TcpConnection<Uri, Io>, Error = TcpConnectError>
+        + Clone
+        + 'static,
+{
+    type Response = S::Response;
+    type Error = ConnectError;
+    type Future = TcpConnectorInnerFuture<S::Future>;
+
+    actix_service::forward_ready!(service);
+
+    fn call(&self, req: Connect) -> Self::Future {
+        let mut req = ConnectInfo::new(req.uri).set_addr(req.addr);
+
+        if let Some(local_addr) = self.local_address {
+            req = req.set_local_addr(local_addr);
+        }
+
+        TcpConnectorInnerFuture {
+            fut: self.service.call(req),
+            timeout: sleep(self.timeout),
+        }
+    }
+}
+
+pin_project! {
+    #[project = TcpConnectorInnerFutureProj]
+    pub struct TcpConnectorInnerFuture<Fut> {
+        #[pin]
+        fut: Fut,
+        #[pin]
+        timeout: Sleep,
+    }
+}
+
+impl<Fut, Io> Future for TcpConnectorInnerFuture<Fut>
+where
+    Fut: Future<Output = Result<TcpConnection<Uri, Io>, TcpConnectError>>,
+{
+    type Output = Result<TcpConnection<Uri, Io>, ConnectError>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.project();
+        match this.fut.poll(cx) {
+            Poll::Ready(res) => Poll::Ready(res.map_err(ConnectError::from)),
+            Poll::Pending => this.timeout.poll(cx).map(|_| Err(ConnectError::Timeout)),
+        }
+    }
+}
+
+/// Connector service for pooled Plain/Tls Tcp connections.
+pub type ConnectorService<Svc, IO> = ConnectorServicePriv<
+    TcpConnectorService<TcpConnectorInnerService<Svc>>,
+    Rc<
+        dyn Service<
+            Connect,
+            Response = (Box<dyn ConnectionIo>, Protocol),
+            Error = ConnectError,
+            Future = LocalBoxFuture<
+                'static,
+                Result<(Box<dyn ConnectionIo>, Protocol), ConnectError>,
+            >,
+        >,
+    >,
+    IO,
+    Box<dyn ConnectionIo>,
+>;
+
+pub struct ConnectorServicePriv<S1, S2, Io1, Io2>
+where
+    S1: Service<Connect, Response = (Io1, Protocol), Error = ConnectError>,
+    S2: Service<Connect, Response = (Io2, Protocol), Error = ConnectError>,
+    Io1: ConnectionIo,
+    Io2: ConnectionIo,
+{
+    tcp_pool: ConnectionPool<S1, Io1>,
+    tls_pool: Option<ConnectionPool<S2, Io2>>,
+}
+
+impl<S1, S2, Io1, Io2> Service<Connect> for ConnectorServicePriv<S1, S2, Io1, Io2>
+where
+    S1: Service<Connect, Response = (Io1, Protocol), Error = ConnectError> + Clone + 'static,
+    S2: Service<Connect, Response = (Io2, Protocol), Error = ConnectError> + Clone + 'static,
+    Io1: ConnectionIo,
+    Io2: ConnectionIo,
+{
+    type Response = Connection<Io1, Io2>;
+    type Error = ConnectError;
+    type Future = ConnectorServiceFuture<S1, S2, Io1, Io2>;
+
+    fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
+        ready!(self.tcp_pool.poll_ready(cx))?;
+        if let Some(ref tls_pool) = self.tls_pool {
+            ready!(tls_pool.poll_ready(cx))?;
+        }
+        Poll::Ready(Ok(()))
+    }
+
+    fn call(&self, req: Connect) -> Self::Future {
+        match req.uri.scheme_str() {
+            Some("https") | Some("wss") => match self.tls_pool {
+                None => ConnectorServiceFuture::SslIsNotSupported,
+                Some(ref pool) => ConnectorServiceFuture::Tls {
+                    fut: pool.call(req),
+                },
+            },
+            _ => ConnectorServiceFuture::Tcp {
+                fut: self.tcp_pool.call(req),
+            },
+        }
+    }
+}
+
+pin_project! {
+    #[project = ConnectorServiceFutureProj]
+    pub enum ConnectorServiceFuture<S1, S2, Io1, Io2>
+    where
+        S1: Service<Connect, Response = (Io1, Protocol), Error = ConnectError>,
+        S1: Clone,
+        S1: 'static,
+        S2: Service<Connect, Response = (Io2, Protocol), Error = ConnectError>,
+        S2: Clone,
+        S2: 'static,
+        Io1: ConnectionIo,
+        Io2: ConnectionIo,
+    {
+        Tcp {
+            #[pin]
+            fut: <ConnectionPool<S1, Io1> as Service<Connect>>::Future
+        },
+        Tls {
+            #[pin]
+            fut:  <ConnectionPool<S2, Io2> as Service<Connect>>::Future
+        },
+        SslIsNotSupported
+    }
+}
+
+impl<S1, S2, Io1, Io2> Future for ConnectorServiceFuture<S1, S2, Io1, Io2>
+where
+    S1: Service<Connect, Response = (Io1, Protocol), Error = ConnectError> + Clone + 'static,
+    S2: Service<Connect, Response = (Io2, Protocol), Error = ConnectError> + Clone + 'static,
+    Io1: ConnectionIo,
+    Io2: ConnectionIo,
+{
+    type Output = Result<Connection<Io1, Io2>, ConnectError>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        match self.project() {
+            ConnectorServiceFutureProj::Tcp { fut } => fut.poll(cx).map_ok(Connection::Tcp),
+            ConnectorServiceFutureProj::Tls { fut } => fut.poll(cx).map_ok(Connection::Tls),
+            ConnectorServiceFutureProj::SslIsNotSupported => {
+                Poll::Ready(Err(ConnectError::SslIsNotSupported))
+            }
+        }
+    }
+}
+
+#[cfg(not(feature = "trust-dns"))]
+mod resolver {
+    use super::*;
+
+    pub(super) fn resolver() -> Resolver {
+        Resolver::default()
+    }
+}
+
+#[cfg(feature = "trust-dns")]
+mod resolver {
+    use std::{cell::RefCell, net::SocketAddr};
+
+    use actix_tls::connect::Resolve;
+    use trust_dns_resolver::{
+        config::{ResolverConfig, ResolverOpts},
+        system_conf::read_system_conf,
+        TokioAsyncResolver,
+    };
+
+    use super::*;
+
+    pub(super) fn resolver() -> Resolver {
+        // new type for impl Resolve trait for TokioAsyncResolver.
+        struct TrustDnsResolver(TokioAsyncResolver);
+
+        impl Resolve for TrustDnsResolver {
+            fn lookup<'a>(
+                &'a self,
+                host: &'a str,
+                port: u16,
+            ) -> LocalBoxFuture<'a, Result<Vec<SocketAddr>, Box<dyn std::error::Error>>>
+            {
+                Box::pin(async move {
+                    let res = self
+                        .0
+                        .lookup_ip(host)
+                        .await?
+                        .iter()
+                        .map(|ip| SocketAddr::new(ip, port))
+                        .collect();
+                    Ok(res)
+                })
+            }
+        }
+
+        // resolver struct is cached in thread local so new clients can reuse the existing instance
+        thread_local! {
+            static TRUST_DNS_RESOLVER: RefCell<Option<Resolver>> = RefCell::new(None);
+        }
+
+        // get from thread local or construct a new trust-dns resolver.
+        TRUST_DNS_RESOLVER.with(|local| {
+            let resolver = local.borrow().as_ref().map(Clone::clone);
+
+            match resolver {
+                Some(resolver) => resolver,
+
+                None => {
+                    let (cfg, opts) = match read_system_conf() {
+                        Ok((cfg, opts)) => (cfg, opts),
+                        Err(err) => {
+                            log::error!("Trust-DNS can not load system config: {err}");
+                            (ResolverConfig::default(), ResolverOpts::default())
+                        }
+                    };
+
+                    let resolver = TokioAsyncResolver::tokio(cfg, opts);
+
+                    // box trust dns resolver and put it in thread local.
+                    let resolver = Resolver::custom(TrustDnsResolver(resolver));
+                    *local.borrow_mut() = Some(resolver.clone());
+
+                    resolver
+                }
+            }
+        })
+    }
+}
+
+#[cfg(feature = "dangerous-h2c")]
+#[cfg(test)]
+mod tests {
+    use std::convert::Infallible;
+
+    use actix_http::{HttpService, Request, Response, Version};
+    use actix_http_test::test_server;
+    use actix_service::ServiceFactoryExt as _;
+
+    use super::*;
+    use crate::Client;
+
+    #[actix_rt::test]
+    async fn h2c_connector() {
+        let mut srv = test_server(|| {
+            HttpService::build()
+                .h2(|_req: Request| async { Ok::<_, Infallible>(Response::ok()) })
+                .tcp()
+                .map_err(|_| ())
+        })
+        .await;
+
+        let connector = Connector {
+            connector: TcpConnector::new(resolver::resolver()).service(),
+            config: ConnectorConfig::default(),
+            tls: OurTlsConnector::None,
+        };
+
+        let client = Client::builder().connector(connector).finish();
+
+        let request = client.get(srv.surl("/")).send();
+        let response = request.await.unwrap();
+        assert!(response.status().is_success());
+        assert_eq!(response.version(), Version::HTTP_2);
+
+        srv.stop().await;
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/client/error.rs.html b/src/awc/client/error.rs.html new file mode 100644 index 000000000..ceda70cd8 --- /dev/null +++ b/src/awc/client/error.rs.html @@ -0,0 +1,311 @@ +error.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+
use std::{fmt, io};
+
+use actix_http::error::{HttpError, ParseError};
+#[cfg(feature = "openssl")]
+use actix_tls::accept::openssl::reexports::Error as OpensslError;
+use derive_more::{Display, From};
+
+use crate::BoxError;
+
+/// A set of errors that can occur while connecting to an HTTP host
+#[derive(Debug, Display, From)]
+#[non_exhaustive]
+pub enum ConnectError {
+    /// SSL feature is not enabled
+    #[display(fmt = "SSL is not supported")]
+    SslIsNotSupported,
+
+    /// SSL error
+    #[cfg(feature = "openssl")]
+    #[display(fmt = "{}", _0)]
+    SslError(OpensslError),
+
+    /// Failed to resolve the hostname
+    #[display(fmt = "Failed resolving hostname: {}", _0)]
+    Resolver(Box<dyn std::error::Error>),
+
+    /// No dns records
+    #[display(fmt = "No DNS records found for the input")]
+    NoRecords,
+
+    /// Http2 error
+    #[display(fmt = "{}", _0)]
+    H2(h2::Error),
+
+    /// Connecting took too long
+    #[display(fmt = "Timeout while establishing connection")]
+    Timeout,
+
+    /// Connector has been disconnected
+    #[display(fmt = "Internal error: connector has been disconnected")]
+    Disconnected,
+
+    /// Unresolved host name
+    #[display(fmt = "Connector received `Connect` method with unresolved host")]
+    Unresolved,
+
+    /// Connection io error
+    #[display(fmt = "{}", _0)]
+    Io(io::Error),
+}
+
+impl std::error::Error for ConnectError {}
+
+impl From<actix_tls::connect::ConnectError> for ConnectError {
+    fn from(err: actix_tls::connect::ConnectError) -> ConnectError {
+        match err {
+            actix_tls::connect::ConnectError::Resolver(e) => ConnectError::Resolver(e),
+            actix_tls::connect::ConnectError::NoRecords => ConnectError::NoRecords,
+            actix_tls::connect::ConnectError::InvalidInput => panic!(),
+            actix_tls::connect::ConnectError::Unresolved => ConnectError::Unresolved,
+            actix_tls::connect::ConnectError::Io(e) => ConnectError::Io(e),
+        }
+    }
+}
+
+#[derive(Debug, Display, From)]
+#[non_exhaustive]
+pub enum InvalidUrl {
+    #[display(fmt = "Missing URL scheme")]
+    MissingScheme,
+
+    #[display(fmt = "Unknown URL scheme")]
+    UnknownScheme,
+
+    #[display(fmt = "Missing host name")]
+    MissingHost,
+
+    #[display(fmt = "URL parse error: {}", _0)]
+    HttpError(http::Error),
+}
+
+impl std::error::Error for InvalidUrl {}
+
+/// A set of errors that can occur during request sending and response reading
+#[derive(Debug, Display, From)]
+#[non_exhaustive]
+pub enum SendRequestError {
+    /// Invalid URL
+    #[display(fmt = "Invalid URL: {}", _0)]
+    Url(InvalidUrl),
+
+    /// Failed to connect to host
+    #[display(fmt = "Failed to connect to host: {}", _0)]
+    Connect(ConnectError),
+
+    /// Error sending request
+    Send(io::Error),
+
+    /// Error parsing response
+    Response(ParseError),
+
+    /// Http error
+    #[display(fmt = "{}", _0)]
+    Http(HttpError),
+
+    /// Http2 error
+    #[display(fmt = "{}", _0)]
+    H2(h2::Error),
+
+    /// Response took too long
+    #[display(fmt = "Timeout while waiting for response")]
+    Timeout,
+
+    /// Tunnels are not supported for HTTP/2 connection
+    #[display(fmt = "Tunnels are not supported for http2 connection")]
+    TunnelNotSupported,
+
+    /// Error sending request body
+    Body(BoxError),
+
+    /// Other errors that can occur after submitting a request.
+    #[display(fmt = "{:?}: {}", _1, _0)]
+    Custom(BoxError, Box<dyn fmt::Debug>),
+}
+
+impl std::error::Error for SendRequestError {}
+
+/// A set of errors that can occur during freezing a request
+#[derive(Debug, Display, From)]
+#[non_exhaustive]
+pub enum FreezeRequestError {
+    /// Invalid URL
+    #[display(fmt = "Invalid URL: {}", _0)]
+    Url(InvalidUrl),
+
+    /// HTTP error
+    #[display(fmt = "{}", _0)]
+    Http(HttpError),
+
+    /// Other errors that can occur after submitting a request.
+    #[display(fmt = "{:?}: {}", _1, _0)]
+    Custom(BoxError, Box<dyn fmt::Debug>),
+}
+
+impl std::error::Error for FreezeRequestError {}
+
+impl From<FreezeRequestError> for SendRequestError {
+    fn from(err: FreezeRequestError) -> Self {
+        match err {
+            FreezeRequestError::Url(err) => err.into(),
+            FreezeRequestError::Http(err) => err.into(),
+            FreezeRequestError::Custom(err, msg) => SendRequestError::Custom(err, msg),
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/client/h1proto.rs.html b/src/awc/client/h1proto.rs.html new file mode 100644 index 000000000..9fceee7c6 --- /dev/null +++ b/src/awc/client/h1proto.rs.html @@ -0,0 +1,473 @@ +h1proto.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
+
use std::{
+    io::Write,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use actix_codec::Framed;
+use actix_http::{
+    body::{BodySize, MessageBody},
+    error::PayloadError,
+    h1,
+    header::{HeaderMap, TryIntoHeaderValue, EXPECT, HOST},
+    Payload, RequestHeadType, ResponseHead, StatusCode,
+};
+use actix_utils::future::poll_fn;
+use bytes::{buf::BufMut, Bytes, BytesMut};
+use futures_core::{ready, Stream};
+use futures_util::SinkExt as _;
+use pin_project_lite::pin_project;
+
+use super::{
+    connection::{ConnectionIo, H1Connection},
+    error::{ConnectError, SendRequestError},
+};
+use crate::BoxError;
+
+pub(crate) async fn send_request<Io, B>(
+    io: H1Connection<Io>,
+    mut head: RequestHeadType,
+    body: B,
+) -> Result<(ResponseHead, Payload), SendRequestError>
+where
+    Io: ConnectionIo,
+    B: MessageBody,
+    B::Error: Into<BoxError>,
+{
+    // set request host header
+    if !head.as_ref().headers.contains_key(HOST)
+        && !head.extra_headers().iter().any(|h| h.contains_key(HOST))
+    {
+        if let Some(host) = head.as_ref().uri.host() {
+            let mut wrt = BytesMut::with_capacity(host.len() + 5).writer();
+
+            match head.as_ref().uri.port_u16() {
+                None | Some(80) | Some(443) => write!(wrt, "{}", host)?,
+                Some(port) => write!(wrt, "{}:{}", host, port)?,
+            };
+
+            match wrt.get_mut().split().freeze().try_into_value() {
+                Ok(value) => match head {
+                    RequestHeadType::Owned(ref mut head) => {
+                        head.headers.insert(HOST, value);
+                    }
+                    RequestHeadType::Rc(_, ref mut extra_headers) => {
+                        let headers = extra_headers.get_or_insert(HeaderMap::new());
+                        headers.insert(HOST, value);
+                    }
+                },
+                Err(err) => log::error!("Can not set HOST header {err}"),
+            }
+        }
+    }
+
+    // create Framed and prepare sending request
+    let mut framed = Framed::new(io, h1::ClientCodec::default());
+
+    // Check EXPECT header and enable expect handle flag accordingly.
+    // See https://datatracker.ietf.org/doc/html/rfc7231#section-5.1.1
+    let is_expect = if head.as_ref().headers.contains_key(EXPECT) {
+        match body.size() {
+            BodySize::None | BodySize::Sized(0) => {
+                let keep_alive = framed.codec_ref().keep_alive();
+                framed.io_mut().on_release(keep_alive);
+
+                // TODO: use a new variant or a new type better describing error violate
+                // `Requirements for clients` session of above RFC
+                return Err(SendRequestError::Connect(ConnectError::Disconnected));
+            }
+            _ => true,
+        }
+    } else {
+        false
+    };
+
+    let mut pin_framed = Pin::new(&mut framed);
+
+    // special handle for EXPECT request.
+    let (do_send, mut res_head) = if is_expect {
+        pin_framed.send((head, body.size()).into()).await?;
+
+        let head = poll_fn(|cx| pin_framed.as_mut().poll_next(cx))
+            .await
+            .ok_or(ConnectError::Disconnected)??;
+
+        // return response head in case status code is not continue
+        // and current head would be used as final response head.
+        (head.status == StatusCode::CONTINUE, Some(head))
+    } else {
+        pin_framed.feed((head, body.size()).into()).await?;
+
+        (true, None)
+    };
+
+    if do_send {
+        // send request body
+        match body.size() {
+            BodySize::None | BodySize::Sized(0) => {
+                poll_fn(|cx| pin_framed.as_mut().flush(cx)).await?;
+            }
+            _ => send_body(body, pin_framed.as_mut()).await?,
+        };
+
+        // read response and init read body
+        let head = poll_fn(|cx| pin_framed.as_mut().poll_next(cx))
+            .await
+            .ok_or(ConnectError::Disconnected)??;
+
+        res_head = Some(head);
+    }
+
+    let head = res_head.unwrap();
+
+    match pin_framed.codec_ref().message_type() {
+        h1::MessageType::None => {
+            let keep_alive = pin_framed.codec_ref().keep_alive();
+            pin_framed.io_mut().on_release(keep_alive);
+
+            Ok((head, Payload::None))
+        }
+        _ => Ok((
+            head,
+            Payload::Stream {
+                payload: Box::pin(PlStream::new(framed)),
+            },
+        )),
+    }
+}
+
+pub(crate) async fn open_tunnel<Io>(
+    io: Io,
+    head: RequestHeadType,
+) -> Result<(ResponseHead, Framed<Io, h1::ClientCodec>), SendRequestError>
+where
+    Io: ConnectionIo,
+{
+    // create Framed and send request.
+    let mut framed = Framed::new(io, h1::ClientCodec::default());
+    framed.send((head, BodySize::None).into()).await?;
+
+    // read response head.
+    let head = poll_fn(|cx| Pin::new(&mut framed).poll_next(cx))
+        .await
+        .ok_or(ConnectError::Disconnected)??;
+
+    Ok((head, framed))
+}
+
+/// send request body to the peer
+pub(crate) async fn send_body<Io, B>(
+    body: B,
+    mut framed: Pin<&mut Framed<Io, h1::ClientCodec>>,
+) -> Result<(), SendRequestError>
+where
+    Io: ConnectionIo,
+    B: MessageBody,
+    B::Error: Into<BoxError>,
+{
+    actix_rt::pin!(body);
+
+    let mut eof = false;
+    while !eof {
+        while !eof && !framed.as_ref().is_write_buf_full() {
+            match poll_fn(|cx| body.as_mut().poll_next(cx)).await {
+                Some(Ok(chunk)) => {
+                    framed.as_mut().write(h1::Message::Chunk(Some(chunk)))?;
+                }
+                Some(Err(err)) => return Err(SendRequestError::Body(err.into())),
+                None => {
+                    eof = true;
+                    framed.as_mut().write(h1::Message::Chunk(None))?;
+                }
+            }
+        }
+
+        if !framed.as_ref().is_write_buf_empty() {
+            poll_fn(|cx| match framed.as_mut().flush(cx) {
+                Poll::Ready(Ok(_)) => Poll::Ready(Ok(())),
+                Poll::Ready(Err(err)) => Poll::Ready(Err(err)),
+                Poll::Pending => {
+                    if !framed.as_ref().is_write_buf_full() {
+                        Poll::Ready(Ok(()))
+                    } else {
+                        Poll::Pending
+                    }
+                }
+            })
+            .await?;
+        }
+    }
+
+    framed.get_mut().flush().await?;
+    Ok(())
+}
+
+pin_project! {
+    pub(crate) struct PlStream<Io: ConnectionIo> {
+        #[pin]
+        framed: Framed<H1Connection<Io>, h1::ClientPayloadCodec>,
+    }
+}
+
+impl<Io: ConnectionIo> PlStream<Io> {
+    fn new(framed: Framed<H1Connection<Io>, h1::ClientCodec>) -> Self {
+        let framed = framed.into_map_codec(|codec| codec.into_payload_codec());
+
+        PlStream { framed }
+    }
+}
+
+impl<Io: ConnectionIo> Stream for PlStream<Io> {
+    type Item = Result<Bytes, PayloadError>;
+
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        let mut this = self.project();
+
+        match ready!(this.framed.as_mut().next_item(cx)?) {
+            Some(Some(chunk)) => Poll::Ready(Some(Ok(chunk))),
+            Some(None) => {
+                let keep_alive = this.framed.codec_ref().keep_alive();
+                this.framed.io_mut().on_release(keep_alive);
+                Poll::Ready(None)
+            }
+            None => Poll::Ready(None),
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/client/h2proto.rs.html b/src/awc/client/h2proto.rs.html new file mode 100644 index 000000000..de59567e0 --- /dev/null +++ b/src/awc/client/h2proto.rs.html @@ -0,0 +1,395 @@ +h2proto.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::future::Future;
+
+use actix_http::{
+    body::{BodySize, MessageBody},
+    header::HeaderMap,
+    Payload, RequestHeadType, ResponseHead,
+};
+use actix_utils::future::poll_fn;
+use bytes::Bytes;
+use h2::{
+    client::{Builder, Connection, SendRequest},
+    SendStream,
+};
+use http::{
+    header::{HeaderValue, CONNECTION, CONTENT_LENGTH, TRANSFER_ENCODING},
+    request::Request,
+    Method, Version,
+};
+use log::trace;
+
+use super::{
+    config::ConnectorConfig,
+    connection::{ConnectionIo, H2Connection},
+    error::SendRequestError,
+};
+use crate::BoxError;
+
+pub(crate) async fn send_request<Io, B>(
+    mut io: H2Connection<Io>,
+    head: RequestHeadType,
+    body: B,
+) -> Result<(ResponseHead, Payload), SendRequestError>
+where
+    Io: ConnectionIo,
+    B: MessageBody,
+    B::Error: Into<BoxError>,
+{
+    trace!("Sending client request: {:?} {:?}", head, body.size());
+
+    let head_req = head.as_ref().method == Method::HEAD;
+    let length = body.size();
+    let eof = matches!(length, BodySize::None | BodySize::Sized(0));
+
+    let mut req = Request::new(());
+    *req.uri_mut() = head.as_ref().uri.clone();
+    *req.method_mut() = head.as_ref().method.clone();
+    *req.version_mut() = Version::HTTP_2;
+
+    let mut skip_len = true;
+    // let mut has_date = false;
+
+    // Content length
+    let _ = match length {
+        BodySize::None => None,
+
+        BodySize::Sized(0) => {
+            #[allow(clippy::declare_interior_mutable_const)]
+            const HV_ZERO: HeaderValue = HeaderValue::from_static("0");
+            req.headers_mut().insert(CONTENT_LENGTH, HV_ZERO)
+        }
+
+        BodySize::Sized(len) => {
+            let mut buf = itoa::Buffer::new();
+
+            req.headers_mut().insert(
+                CONTENT_LENGTH,
+                HeaderValue::from_str(buf.format(len)).unwrap(),
+            )
+        }
+
+        BodySize::Stream => {
+            skip_len = false;
+            None
+        }
+    };
+
+    // Extracting extra headers from RequestHeadType. HeaderMap::new() does not allocate.
+    let (head, extra_headers) = match head {
+        RequestHeadType::Owned(head) => (RequestHeadType::Owned(head), HeaderMap::new()),
+        RequestHeadType::Rc(head, extra_headers) => (
+            RequestHeadType::Rc(head, None),
+            extra_headers.unwrap_or_else(HeaderMap::new),
+        ),
+    };
+
+    // merging headers from head and extra headers.
+    let headers = head
+        .as_ref()
+        .headers
+        .iter()
+        .filter(|(name, _)| !extra_headers.contains_key(*name))
+        .chain(extra_headers.iter());
+
+    // copy headers
+    for (key, value) in headers {
+        match *key {
+            // TODO: consider skipping other headers according to:
+            //       https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2.2
+            // omit HTTP/1.x only headers
+            CONNECTION | TRANSFER_ENCODING => continue,
+            CONTENT_LENGTH if skip_len => continue,
+            // DATE => has_date = true,
+            _ => {}
+        }
+        req.headers_mut().append(key, value.clone());
+    }
+
+    let res = poll_fn(|cx| io.poll_ready(cx)).await;
+    if let Err(err) = res {
+        io.on_release(err.is_io());
+        return Err(SendRequestError::from(err));
+    }
+
+    let resp = match io.send_request(req, eof) {
+        Ok((fut, send)) => {
+            io.on_release(false);
+
+            if !eof {
+                send_body(body, send).await?;
+            }
+            fut.await.map_err(SendRequestError::from)?
+        }
+        Err(err) => {
+            io.on_release(err.is_io());
+            return Err(err.into());
+        }
+    };
+
+    let (parts, body) = resp.into_parts();
+    let payload = if head_req { Payload::None } else { body.into() };
+
+    let mut head = ResponseHead::new(parts.status);
+    head.version = parts.version;
+    head.headers = parts.headers.into();
+    Ok((head, payload))
+}
+
+async fn send_body<B>(body: B, mut send: SendStream<Bytes>) -> Result<(), SendRequestError>
+where
+    B: MessageBody,
+    B::Error: Into<BoxError>,
+{
+    let mut buf = None;
+
+    actix_rt::pin!(body);
+
+    loop {
+        if buf.is_none() {
+            match poll_fn(|cx| body.as_mut().poll_next(cx)).await {
+                Some(Ok(b)) => {
+                    send.reserve_capacity(b.len());
+                    buf = Some(b);
+                }
+                Some(Err(err)) => return Err(SendRequestError::Body(err.into())),
+                None => {
+                    if let Err(err) = send.send_data(Bytes::new(), true) {
+                        return Err(err.into());
+                    }
+                    send.reserve_capacity(0);
+                    return Ok(());
+                }
+            }
+        }
+
+        match poll_fn(|cx| send.poll_capacity(cx)).await {
+            None => return Ok(()),
+            Some(Ok(cap)) => {
+                let b = buf.as_mut().unwrap();
+                let len = b.len();
+                let bytes = b.split_to(std::cmp::min(cap, len));
+
+                if let Err(err) = send.send_data(bytes, false) {
+                    return Err(err.into());
+                }
+                if !b.is_empty() {
+                    send.reserve_capacity(b.len());
+                } else {
+                    buf = None;
+                }
+                continue;
+            }
+            Some(Err(err)) => return Err(err.into()),
+        }
+    }
+}
+
+pub(crate) fn handshake<Io: ConnectionIo>(
+    io: Io,
+    config: &ConnectorConfig,
+) -> impl Future<Output = Result<(SendRequest<Bytes>, Connection<Io, Bytes>), h2::Error>> {
+    let mut builder = Builder::new();
+    builder
+        .initial_window_size(config.stream_window_size)
+        .initial_connection_window_size(config.conn_window_size)
+        .enable_push(false);
+    builder.handshake(io)
+}
+
\ No newline at end of file diff --git a/src/awc/client/mod.rs.html b/src/awc/client/mod.rs.html new file mode 100644 index 000000000..c371209d5 --- /dev/null +++ b/src/awc/client/mod.rs.html @@ -0,0 +1,411 @@ +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
+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
+
//! HTTP client.
+
+use std::{rc::Rc, time::Duration};
+
+use actix_http::{error::HttpError, header::HeaderMap, Method, RequestHead, Uri};
+use actix_rt::net::TcpStream;
+use actix_service::Service;
+pub use actix_tls::connect::{
+    ConnectError as TcpConnectError, ConnectInfo, Connection as TcpConnection,
+};
+
+use crate::{ws, BoxConnectorService, ClientBuilder, ClientRequest};
+
+mod config;
+mod connection;
+mod connector;
+mod error;
+mod h1proto;
+mod h2proto;
+mod pool;
+
+pub use self::{
+    connection::{Connection, ConnectionIo},
+    connector::{Connector, ConnectorService},
+    error::{ConnectError, FreezeRequestError, InvalidUrl, SendRequestError},
+};
+
+#[derive(Clone)]
+pub struct Connect {
+    pub uri: Uri,
+    pub addr: Option<std::net::SocketAddr>,
+}
+
+/// An asynchronous HTTP and WebSocket client.
+///
+/// You should take care to create, at most, one `Client` per thread. Otherwise, expect higher CPU
+/// and memory usage.
+///
+/// # Examples
+/// ```
+/// use awc::Client;
+///
+/// #[actix_rt::main]
+/// async fn main() {
+///     let mut client = Client::default();
+///
+///     let res = client.get("http://www.rust-lang.org")
+///         .insert_header(("User-Agent", "my-app/1.2"))
+///         .send()
+///         .await;
+///
+///      println!("Response: {:?}", res);
+/// }
+/// ```
+#[derive(Clone)]
+pub struct Client(pub(crate) ClientConfig);
+
+#[derive(Clone)]
+pub(crate) struct ClientConfig {
+    pub(crate) connector: BoxConnectorService,
+    pub(crate) default_headers: Rc<HeaderMap>,
+    pub(crate) timeout: Option<Duration>,
+}
+
+impl Default for Client {
+    fn default() -> Self {
+        ClientBuilder::new().finish()
+    }
+}
+
+impl Client {
+    /// Constructs new client instance with default settings.
+    pub fn new() -> Client {
+        Client::default()
+    }
+
+    /// Constructs new `Client` builder.
+    ///
+    /// This function is equivalent of `ClientBuilder::new()`.
+    pub fn builder() -> ClientBuilder<
+        impl Service<
+                ConnectInfo<Uri>,
+                Response = TcpConnection<Uri, TcpStream>,
+                Error = TcpConnectError,
+            > + Clone,
+    > {
+        ClientBuilder::new()
+    }
+
+    /// Construct HTTP request.
+    pub fn request<U>(&self, method: Method, url: U) -> ClientRequest
+    where
+        Uri: TryFrom<U>,
+        <Uri as TryFrom<U>>::Error: Into<HttpError>,
+    {
+        let mut req = ClientRequest::new(method, url, self.0.clone());
+
+        for header in self.0.default_headers.iter() {
+            req = req.append_header(header);
+        }
+
+        req
+    }
+
+    /// Create `ClientRequest` from `RequestHead`
+    ///
+    /// It is useful for proxy requests. This implementation
+    /// copies all headers and the method.
+    pub fn request_from<U>(&self, url: U, head: &RequestHead) -> ClientRequest
+    where
+        Uri: TryFrom<U>,
+        <Uri as TryFrom<U>>::Error: Into<HttpError>,
+    {
+        let mut req = self.request(head.method.clone(), url);
+        for header in head.headers.iter() {
+            req = req.insert_header_if_none(header);
+        }
+        req
+    }
+
+    /// Construct HTTP *GET* request.
+    pub fn get<U>(&self, url: U) -> ClientRequest
+    where
+        Uri: TryFrom<U>,
+        <Uri as TryFrom<U>>::Error: Into<HttpError>,
+    {
+        self.request(Method::GET, url)
+    }
+
+    /// Construct HTTP *HEAD* request.
+    pub fn head<U>(&self, url: U) -> ClientRequest
+    where
+        Uri: TryFrom<U>,
+        <Uri as TryFrom<U>>::Error: Into<HttpError>,
+    {
+        self.request(Method::HEAD, url)
+    }
+
+    /// Construct HTTP *PUT* request.
+    pub fn put<U>(&self, url: U) -> ClientRequest
+    where
+        Uri: TryFrom<U>,
+        <Uri as TryFrom<U>>::Error: Into<HttpError>,
+    {
+        self.request(Method::PUT, url)
+    }
+
+    /// Construct HTTP *POST* request.
+    pub fn post<U>(&self, url: U) -> ClientRequest
+    where
+        Uri: TryFrom<U>,
+        <Uri as TryFrom<U>>::Error: Into<HttpError>,
+    {
+        self.request(Method::POST, url)
+    }
+
+    /// Construct HTTP *PATCH* request.
+    pub fn patch<U>(&self, url: U) -> ClientRequest
+    where
+        Uri: TryFrom<U>,
+        <Uri as TryFrom<U>>::Error: Into<HttpError>,
+    {
+        self.request(Method::PATCH, url)
+    }
+
+    /// Construct HTTP *DELETE* request.
+    pub fn delete<U>(&self, url: U) -> ClientRequest
+    where
+        Uri: TryFrom<U>,
+        <Uri as TryFrom<U>>::Error: Into<HttpError>,
+    {
+        self.request(Method::DELETE, url)
+    }
+
+    /// Construct HTTP *OPTIONS* request.
+    pub fn options<U>(&self, url: U) -> ClientRequest
+    where
+        Uri: TryFrom<U>,
+        <Uri as TryFrom<U>>::Error: Into<HttpError>,
+    {
+        self.request(Method::OPTIONS, url)
+    }
+
+    /// Initialize a WebSocket connection.
+    /// Returns a WebSocket connection builder.
+    pub fn ws<U>(&self, url: U) -> ws::WebsocketsRequest
+    where
+        Uri: TryFrom<U>,
+        <Uri as TryFrom<U>>::Error: Into<HttpError>,
+    {
+        let mut req = ws::WebsocketsRequest::new(url, self.0.clone());
+        for (key, value) in self.0.default_headers.iter() {
+            req.head.headers.insert(key.clone(), value.clone());
+        }
+        req
+    }
+
+    /// Get default HeaderMap of Client.
+    ///
+    /// Returns Some(&mut HeaderMap) when Client object is unique
+    /// (No other clone of client exists at the same time).
+    pub fn headers(&mut self) -> Option<&mut HeaderMap> {
+        Rc::get_mut(&mut self.0.default_headers)
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/client/pool.rs.html b/src/awc/client/pool.rs.html new file mode 100644 index 000000000..8f9845bc4 --- /dev/null +++ b/src/awc/client/pool.rs.html @@ -0,0 +1,1321 @@ +pool.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
+
//! Client connection pooling keyed on the authority part of the connection URI.
+
+use std::{
+    cell::RefCell,
+    collections::{HashMap, VecDeque},
+    future::Future,
+    io,
+    ops::Deref,
+    pin::Pin,
+    rc::Rc,
+    sync::Arc,
+    task::{Context, Poll},
+    time::{Duration, Instant},
+};
+
+use actix_codec::{AsyncRead, AsyncWrite, ReadBuf};
+use actix_http::Protocol;
+use actix_rt::time::{sleep, Sleep};
+use actix_service::Service;
+use futures_core::future::LocalBoxFuture;
+use futures_util::FutureExt as _;
+use http::uri::Authority;
+use pin_project_lite::pin_project;
+use tokio::sync::{OwnedSemaphorePermit, Semaphore};
+
+use super::{
+    config::ConnectorConfig,
+    connection::{ConnectionInnerType, ConnectionIo, ConnectionType, H2ConnectionInner},
+    error::ConnectError,
+    h2proto::handshake,
+    Connect,
+};
+
+#[derive(Hash, Eq, PartialEq, Clone, Debug)]
+pub struct Key {
+    authority: Authority,
+}
+
+impl From<Authority> for Key {
+    fn from(authority: Authority) -> Key {
+        Key { authority }
+    }
+}
+
+#[doc(hidden)]
+/// Connections pool for reuse Io type for certain [`http::uri::Authority`] as key.
+pub struct ConnectionPool<S, Io>
+where
+    Io: AsyncWrite + Unpin + 'static,
+{
+    connector: S,
+    inner: ConnectionPoolInner<Io>,
+}
+
+/// wrapper type for check the ref count of Rc.
+pub struct ConnectionPoolInner<Io>(Rc<ConnectionPoolInnerPriv<Io>>)
+where
+    Io: AsyncWrite + Unpin + 'static;
+
+impl<Io> ConnectionPoolInner<Io>
+where
+    Io: AsyncWrite + Unpin + 'static,
+{
+    fn new(config: ConnectorConfig) -> Self {
+        let permits = Arc::new(Semaphore::new(config.limit));
+        let available = RefCell::new(HashMap::default());
+
+        Self(Rc::new(ConnectionPoolInnerPriv {
+            config,
+            available,
+            permits,
+        }))
+    }
+
+    /// spawn a async for graceful shutdown h1 Io type with a timeout.
+    fn close(&self, conn: ConnectionInnerType<Io>) {
+        if let Some(timeout) = self.config.disconnect_timeout {
+            if let ConnectionInnerType::H1(io) = conn {
+                actix_rt::spawn(CloseConnection::new(io, timeout));
+            }
+        }
+    }
+}
+
+impl<Io> Clone for ConnectionPoolInner<Io>
+where
+    Io: AsyncWrite + Unpin + 'static,
+{
+    fn clone(&self) -> Self {
+        Self(Rc::clone(&self.0))
+    }
+}
+
+impl<Io> Deref for ConnectionPoolInner<Io>
+where
+    Io: AsyncWrite + Unpin + 'static,
+{
+    type Target = ConnectionPoolInnerPriv<Io>;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
+
+impl<Io> Drop for ConnectionPoolInner<Io>
+where
+    Io: AsyncWrite + Unpin + 'static,
+{
+    fn drop(&mut self) {
+        // When strong count is one it means the pool is dropped
+        // remove and drop all Io types.
+        if Rc::strong_count(&self.0) == 1 {
+            self.permits.close();
+            std::mem::take(&mut *self.available.borrow_mut())
+                .into_iter()
+                .for_each(|(_, conns)| {
+                    conns.into_iter().for_each(|pooled| self.close(pooled.conn))
+                });
+        }
+    }
+}
+
+pub struct ConnectionPoolInnerPriv<Io>
+where
+    Io: AsyncWrite + Unpin + 'static,
+{
+    config: ConnectorConfig,
+    available: RefCell<HashMap<Key, VecDeque<PooledConnection<Io>>>>,
+    permits: Arc<Semaphore>,
+}
+
+impl<S, Io> ConnectionPool<S, Io>
+where
+    Io: AsyncWrite + Unpin + 'static,
+{
+    /// Construct a new connection pool.
+    ///
+    /// [`super::config::ConnectorConfig`]'s `limit` is used as the max permits allowed for
+    /// in-flight connections.
+    ///
+    /// The pool can only have equal to `limit` amount of requests spawning/using Io type
+    /// concurrently.
+    ///
+    /// Any requests beyond limit would be wait in fifo order and get notified in async manner
+    /// by [`tokio::sync::Semaphore`]
+    pub(crate) fn new(connector: S, config: ConnectorConfig) -> Self {
+        let inner = ConnectionPoolInner::new(config);
+
+        Self { connector, inner }
+    }
+}
+
+impl<S, Io> Service<Connect> for ConnectionPool<S, Io>
+where
+    S: Service<Connect, Response = (Io, Protocol), Error = ConnectError> + Clone + 'static,
+    Io: ConnectionIo,
+{
+    type Response = ConnectionType<Io>;
+    type Error = ConnectError;
+    type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
+
+    actix_service::forward_ready!(connector);
+
+    fn call(&self, req: Connect) -> Self::Future {
+        let connector = self.connector.clone();
+        let inner = self.inner.clone();
+
+        Box::pin(async move {
+            let key = if let Some(authority) = req.uri.authority() {
+                authority.clone().into()
+            } else {
+                return Err(ConnectError::Unresolved);
+            };
+
+            // acquire an owned permit and carry it with connection
+            let permit = inner.permits.clone().acquire_owned().await.map_err(|_| {
+                ConnectError::Io(io::Error::new(
+                    io::ErrorKind::Other,
+                    "failed to acquire semaphore on client connection pool",
+                ))
+            })?;
+
+            let conn = {
+                let mut conn = None;
+
+                // check if there is idle connection for given key.
+                let mut map = inner.available.borrow_mut();
+
+                if let Some(conns) = map.get_mut(&key) {
+                    let now = Instant::now();
+
+                    while let Some(mut c) = conns.pop_front() {
+                        let config = &inner.config;
+                        let idle_dur = now - c.used;
+                        let age = now - c.created;
+                        let conn_ineligible =
+                            idle_dur > config.conn_keep_alive || age > config.conn_lifetime;
+
+                        if conn_ineligible {
+                            // drop connections that are too old
+                            inner.close(c.conn);
+                        } else {
+                            // check if the connection is still usable
+                            if let ConnectionInnerType::H1(ref mut io) = c.conn {
+                                let check = ConnectionCheckFuture { io };
+                                match check.now_or_never().expect(
+                                    "ConnectionCheckFuture must never yield with Poll::Pending.",
+                                ) {
+                                    ConnectionState::Tainted => {
+                                        inner.close(c.conn);
+                                        continue;
+                                    }
+                                    ConnectionState::Skip => continue,
+                                    ConnectionState::Live => conn = Some(c),
+                                }
+                            } else {
+                                conn = Some(c);
+                            }
+
+                            break;
+                        }
+                    }
+                };
+
+                conn
+            };
+
+            // construct acquired. It's used to put Io type back to pool/ close the Io type.
+            // permit is carried with the whole lifecycle of Acquired.
+            let acquired = Acquired { key, inner, permit };
+
+            // match the connection and spawn new one if did not get anything.
+            match conn {
+                Some(conn) => Ok(ConnectionType::from_pool(conn.conn, conn.created, acquired)),
+                None => {
+                    let (io, proto) = connector.call(req).await?;
+
+                    // NOTE: remove when http3 is added in support.
+                    assert!(proto != Protocol::Http3);
+
+                    if proto == Protocol::Http1 {
+                        Ok(ConnectionType::from_h1(io, Instant::now(), acquired))
+                    } else {
+                        let config = &acquired.inner.config;
+                        let (sender, connection) = handshake(io, config).await?;
+                        let inner = H2ConnectionInner::new(sender, connection);
+                        Ok(ConnectionType::from_h2(inner, Instant::now(), acquired))
+                    }
+                }
+            }
+        })
+    }
+}
+
+/// Type for check the connection and determine if it's usable.
+struct ConnectionCheckFuture<'a, Io> {
+    io: &'a mut Io,
+}
+
+enum ConnectionState {
+    /// IO is pending and a new request would wake it.
+    Live,
+
+    /// IO unexpectedly has unread data and should be dropped.
+    Tainted,
+
+    /// IO should be skipped but not dropped.
+    Skip,
+}
+
+impl<Io> Future for ConnectionCheckFuture<'_, Io>
+where
+    Io: AsyncRead + Unpin,
+{
+    type Output = ConnectionState;
+
+    // this future is only used to get access to Context.
+    // It should never return Poll::Pending.
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.get_mut();
+        let mut buf = [0; 2];
+        let mut read_buf = ReadBuf::new(&mut buf);
+
+        let state = match Pin::new(&mut this.io).poll_read(cx, &mut read_buf) {
+            Poll::Ready(Ok(())) if !read_buf.filled().is_empty() => ConnectionState::Tainted,
+
+            Poll::Pending => ConnectionState::Live,
+            _ => ConnectionState::Skip,
+        };
+
+        Poll::Ready(state)
+    }
+}
+
+struct PooledConnection<Io> {
+    conn: ConnectionInnerType<Io>,
+    used: Instant,
+    created: Instant,
+}
+
+pin_project! {
+    #[project = CloseConnectionProj]
+    struct CloseConnection<Io> {
+        io: Io,
+        #[pin]
+        timeout: Sleep,
+    }
+}
+
+impl<Io> CloseConnection<Io>
+where
+    Io: AsyncWrite + Unpin,
+{
+    fn new(io: Io, timeout: Duration) -> Self {
+        CloseConnection {
+            io,
+            timeout: sleep(timeout),
+        }
+    }
+}
+
+impl<Io> Future for CloseConnection<Io>
+where
+    Io: AsyncWrite + Unpin,
+{
+    type Output = ();
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
+        let this = self.project();
+
+        match this.timeout.poll(cx) {
+            Poll::Ready(_) => Poll::Ready(()),
+            Poll::Pending => Pin::new(this.io).poll_shutdown(cx).map(|_| ()),
+        }
+    }
+}
+
+pub struct Acquired<Io>
+where
+    Io: AsyncWrite + Unpin + 'static,
+{
+    /// authority key for identify connection.
+    key: Key,
+    /// handle to connection pool.
+    inner: ConnectionPoolInner<Io>,
+    /// permit for limit concurrent in-flight connection for a Client object.
+    permit: OwnedSemaphorePermit,
+}
+
+impl<Io: ConnectionIo> Acquired<Io> {
+    /// Close the IO.
+    pub(super) fn close(&self, conn: ConnectionInnerType<Io>) {
+        self.inner.close(conn);
+    }
+
+    /// Release IO back into pool.
+    pub(super) fn release(&self, conn: ConnectionInnerType<Io>, created: Instant) {
+        let Acquired { key, inner, .. } = self;
+
+        inner
+            .available
+            .borrow_mut()
+            .entry(key.clone())
+            .or_insert_with(VecDeque::new)
+            .push_back(PooledConnection {
+                conn,
+                created,
+                used: Instant::now(),
+            });
+
+        let _ = &self.permit;
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use std::cell::Cell;
+
+    use http::Uri;
+
+    use super::*;
+
+    /// A stream type that always returns pending on async read.
+    ///
+    /// Mocks an idle TCP stream that is ready to be used for client connections.
+    struct TestStream(Rc<Cell<usize>>);
+
+    impl Drop for TestStream {
+        fn drop(&mut self) {
+            self.0.set(self.0.get() - 1);
+        }
+    }
+
+    impl AsyncRead for TestStream {
+        fn poll_read(
+            self: Pin<&mut Self>,
+            _: &mut Context<'_>,
+            _: &mut ReadBuf<'_>,
+        ) -> Poll<io::Result<()>> {
+            Poll::Pending
+        }
+    }
+
+    impl AsyncWrite for TestStream {
+        fn poll_write(
+            self: Pin<&mut Self>,
+            _: &mut Context<'_>,
+            _: &[u8],
+        ) -> Poll<io::Result<usize>> {
+            unimplemented!()
+        }
+
+        fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
+            unimplemented!()
+        }
+
+        fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<io::Result<()>> {
+            Poll::Ready(Ok(()))
+        }
+    }
+
+    #[derive(Clone)]
+    struct TestPoolConnector {
+        generated: Rc<Cell<usize>>,
+    }
+
+    impl Service<Connect> for TestPoolConnector {
+        type Response = (TestStream, Protocol);
+        type Error = ConnectError;
+        type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
+
+        actix_service::always_ready!();
+
+        fn call(&self, _: Connect) -> Self::Future {
+            self.generated.set(self.generated.get() + 1);
+            let generated = self.generated.clone();
+            Box::pin(async { Ok((TestStream(generated), Protocol::Http1)) })
+        }
+    }
+
+    fn release<T>(conn: ConnectionType<T>)
+    where
+        T: AsyncRead + AsyncWrite + Unpin + 'static,
+    {
+        match conn {
+            ConnectionType::H1(mut conn) => conn.on_release(true),
+            ConnectionType::H2(mut conn) => conn.on_release(false),
+        }
+    }
+
+    #[actix_rt::test]
+    async fn test_pool_limit() {
+        let connector = TestPoolConnector {
+            generated: Rc::new(Cell::new(0)),
+        };
+
+        let config = ConnectorConfig {
+            limit: 1,
+            ..Default::default()
+        };
+
+        let pool = super::ConnectionPool::new(connector, config);
+
+        let req = Connect {
+            uri: Uri::from_static("http://localhost"),
+            addr: None,
+        };
+
+        let conn = pool.call(req.clone()).await.unwrap();
+
+        let waiting = Rc::new(Cell::new(true));
+
+        let waiting_clone = waiting.clone();
+        actix_rt::spawn(async move {
+            actix_rt::time::sleep(Duration::from_millis(100)).await;
+            waiting_clone.set(false);
+            drop(conn);
+        });
+
+        assert!(waiting.get());
+
+        let now = Instant::now();
+        let conn = pool.call(req).await.unwrap();
+
+        release(conn);
+        assert!(!waiting.get());
+        assert!(now.elapsed() >= Duration::from_millis(100));
+    }
+
+    #[actix_rt::test]
+    async fn test_pool_keep_alive() {
+        let generated = Rc::new(Cell::new(0));
+        let generated_clone = generated.clone();
+
+        let connector = TestPoolConnector { generated };
+
+        let config = ConnectorConfig {
+            conn_keep_alive: Duration::from_secs(1),
+            ..Default::default()
+        };
+
+        let pool = super::ConnectionPool::new(connector, config);
+
+        let req = Connect {
+            uri: Uri::from_static("http://localhost"),
+            addr: None,
+        };
+
+        let conn = pool.call(req.clone()).await.unwrap();
+        assert_eq!(1, generated_clone.get());
+        release(conn);
+
+        let conn = pool.call(req.clone()).await.unwrap();
+        assert_eq!(1, generated_clone.get());
+        release(conn);
+
+        actix_rt::time::sleep(Duration::from_millis(1500)).await;
+        actix_rt::task::yield_now().await;
+
+        let conn = pool.call(req).await.unwrap();
+        // Note: spawned recycle connection is not ran yet.
+        // This is tokio current thread runtime specific behavior.
+        assert_eq!(2, generated_clone.get());
+
+        // yield task so the old connection is properly dropped.
+        actix_rt::task::yield_now().await;
+        assert_eq!(1, generated_clone.get());
+
+        release(conn);
+    }
+
+    #[actix_rt::test]
+    async fn test_pool_lifetime() {
+        let generated = Rc::new(Cell::new(0));
+        let generated_clone = generated.clone();
+
+        let connector = TestPoolConnector { generated };
+
+        let config = ConnectorConfig {
+            conn_lifetime: Duration::from_secs(1),
+            ..Default::default()
+        };
+
+        let pool = super::ConnectionPool::new(connector, config);
+
+        let req = Connect {
+            uri: Uri::from_static("http://localhost"),
+            addr: None,
+        };
+
+        let conn = pool.call(req.clone()).await.unwrap();
+        assert_eq!(1, generated_clone.get());
+        release(conn);
+
+        let conn = pool.call(req.clone()).await.unwrap();
+        assert_eq!(1, generated_clone.get());
+        release(conn);
+
+        actix_rt::time::sleep(Duration::from_millis(1500)).await;
+        actix_rt::task::yield_now().await;
+
+        let conn = pool.call(req).await.unwrap();
+        // Note: spawned recycle connection is not ran yet.
+        // This is tokio current thread runtime specific behavior.
+        assert_eq!(2, generated_clone.get());
+
+        // yield task so the old connection is properly dropped.
+        actix_rt::task::yield_now().await;
+        assert_eq!(1, generated_clone.get());
+
+        release(conn);
+    }
+
+    #[actix_rt::test]
+    async fn test_pool_authority_key() {
+        let generated = Rc::new(Cell::new(0));
+        let generated_clone = generated.clone();
+
+        let connector = TestPoolConnector { generated };
+
+        let config = ConnectorConfig::default();
+
+        let pool = super::ConnectionPool::new(connector, config);
+
+        let req = Connect {
+            uri: Uri::from_static("https://crates.io"),
+            addr: None,
+        };
+
+        let conn = pool.call(req.clone()).await.unwrap();
+        assert_eq!(1, generated_clone.get());
+        release(conn);
+
+        let conn = pool.call(req).await.unwrap();
+        assert_eq!(1, generated_clone.get());
+        release(conn);
+
+        let req = Connect {
+            uri: Uri::from_static("https://google.com"),
+            addr: None,
+        };
+
+        let conn = pool.call(req.clone()).await.unwrap();
+        assert_eq!(2, generated_clone.get());
+        release(conn);
+        let conn = pool.call(req).await.unwrap();
+        assert_eq!(2, generated_clone.get());
+        release(conn);
+    }
+
+    #[actix_rt::test]
+    async fn test_pool_drop() {
+        let generated = Rc::new(Cell::new(0));
+        let generated_clone = generated.clone();
+
+        let connector = TestPoolConnector { generated };
+
+        let config = ConnectorConfig::default();
+
+        let pool = Rc::new(super::ConnectionPool::new(connector, config));
+
+        let req = Connect {
+            uri: Uri::from_static("https://crates.io"),
+            addr: None,
+        };
+
+        let conn = pool.call(req.clone()).await.unwrap();
+        assert_eq!(1, generated_clone.get());
+        release(conn);
+
+        let req = Connect {
+            uri: Uri::from_static("https://google.com"),
+            addr: None,
+        };
+        let conn = pool.call(req.clone()).await.unwrap();
+        assert_eq!(2, generated_clone.get());
+        release(conn);
+
+        let clone1 = pool.clone();
+        let clone2 = clone1.clone();
+
+        drop(clone2);
+        for _ in 0..2 {
+            actix_rt::task::yield_now().await;
+        }
+        assert_eq!(2, generated_clone.get());
+
+        drop(clone1);
+        for _ in 0..2 {
+            actix_rt::task::yield_now().await;
+        }
+        assert_eq!(2, generated_clone.get());
+
+        drop(pool);
+        for _ in 0..2 {
+            actix_rt::task::yield_now().await;
+        }
+        assert_eq!(0, generated_clone.get());
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/connect.rs.html b/src/awc/connect.rs.html new file mode 100644 index 000000000..a4de15a3a --- /dev/null +++ b/src/awc/connect.rs.html @@ -0,0 +1,395 @@ +connect.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::{
+    future::Future,
+    net,
+    pin::Pin,
+    rc::Rc,
+    task::{Context, Poll},
+};
+
+use actix_codec::Framed;
+use actix_http::{h1::ClientCodec, Payload, RequestHead, RequestHeadType, ResponseHead};
+use actix_service::Service;
+use futures_core::{future::LocalBoxFuture, ready};
+
+use crate::{
+    any_body::AnyBody,
+    client::{Connect as ClientConnect, ConnectError, Connection, ConnectionIo, SendRequestError},
+    ClientResponse,
+};
+
+pub type BoxConnectorService = Rc<
+    dyn Service<
+        ConnectRequest,
+        Response = ConnectResponse,
+        Error = SendRequestError,
+        Future = LocalBoxFuture<'static, Result<ConnectResponse, SendRequestError>>,
+    >,
+>;
+
+pub type BoxedSocket = Box<dyn ConnectionIo>;
+
+/// Combined HTTP and WebSocket request type received by connection service.
+pub enum ConnectRequest {
+    /// Standard HTTP request.
+    ///
+    /// Contains the request head, body type, and optional pre-resolved socket address.
+    Client(RequestHeadType, AnyBody, Option<net::SocketAddr>),
+
+    /// Tunnel used by WebSocket connection requests.
+    ///
+    /// Contains the request head and optional pre-resolved socket address.
+    Tunnel(RequestHead, Option<net::SocketAddr>),
+}
+
+/// Combined HTTP response & WebSocket tunnel type returned from connection service.
+pub enum ConnectResponse {
+    /// Standard HTTP response.
+    Client(ClientResponse),
+
+    /// Tunnel used for WebSocket communication.
+    ///
+    /// Contains response head and framed HTTP/1.1 codec.
+    Tunnel(ResponseHead, Framed<BoxedSocket, ClientCodec>),
+}
+
+impl ConnectResponse {
+    /// Unwraps type into HTTP response.
+    ///
+    /// # Panics
+    /// Panics if enum variant is not `Client`.
+    pub fn into_client_response(self) -> ClientResponse {
+        match self {
+            ConnectResponse::Client(res) => res,
+            _ => {
+                panic!("ClientResponse only reachable with ConnectResponse::ClientResponse variant")
+            }
+        }
+    }
+
+    /// Unwraps type into WebSocket tunnel response.
+    ///
+    /// # Panics
+    /// Panics if enum variant is not `Tunnel`.
+    pub fn into_tunnel_response(self) -> (ResponseHead, Framed<BoxedSocket, ClientCodec>) {
+        match self {
+            ConnectResponse::Tunnel(head, framed) => (head, framed),
+            _ => {
+                panic!("TunnelResponse only reachable with ConnectResponse::TunnelResponse variant")
+            }
+        }
+    }
+}
+
+pub struct DefaultConnector<S> {
+    connector: S,
+}
+
+impl<S> DefaultConnector<S> {
+    pub(crate) fn new(connector: S) -> Self {
+        Self { connector }
+    }
+}
+
+impl<S, Io> Service<ConnectRequest> for DefaultConnector<S>
+where
+    S: Service<ClientConnect, Error = ConnectError, Response = Connection<Io>>,
+    Io: ConnectionIo,
+{
+    type Response = ConnectResponse;
+    type Error = SendRequestError;
+    type Future = ConnectRequestFuture<S::Future, Io>;
+
+    actix_service::forward_ready!(connector);
+
+    fn call(&self, req: ConnectRequest) -> Self::Future {
+        // connect to the host
+        let fut = match req {
+            ConnectRequest::Client(ref head, .., addr) => self.connector.call(ClientConnect {
+                uri: head.as_ref().uri.clone(),
+                addr,
+            }),
+            ConnectRequest::Tunnel(ref head, addr) => self.connector.call(ClientConnect {
+                uri: head.uri.clone(),
+                addr,
+            }),
+        };
+
+        ConnectRequestFuture::Connection {
+            fut,
+            req: Some(req),
+        }
+    }
+}
+
+pin_project_lite::pin_project! {
+    #[project = ConnectRequestProj]
+    pub enum ConnectRequestFuture<Fut, Io>
+    where
+        Io: ConnectionIo
+    {
+        Connection {
+            #[pin]
+            fut: Fut,
+            req: Option<ConnectRequest>
+        },
+        Client {
+            fut: LocalBoxFuture<'static, Result<(ResponseHead, Payload), SendRequestError>>
+        },
+        Tunnel {
+            fut: LocalBoxFuture<
+                'static,
+                Result<(ResponseHead, Framed<Connection<Io>, ClientCodec>), SendRequestError>,
+            >,
+        }
+    }
+}
+
+impl<Fut, Io> Future for ConnectRequestFuture<Fut, Io>
+where
+    Fut: Future<Output = Result<Connection<Io>, ConnectError>>,
+    Io: ConnectionIo,
+{
+    type Output = Result<ConnectResponse, SendRequestError>;
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        match self.as_mut().project() {
+            ConnectRequestProj::Connection { fut, req } => {
+                let connection = ready!(fut.poll(cx))?;
+                let req = req.take().unwrap();
+
+                match req {
+                    ConnectRequest::Client(head, body, ..) => {
+                        // send request
+                        let fut = ConnectRequestFuture::Client {
+                            fut: connection.send_request(head, body),
+                        };
+
+                        self.set(fut);
+                    }
+
+                    ConnectRequest::Tunnel(head, ..) => {
+                        // send request
+                        let fut = ConnectRequestFuture::Tunnel {
+                            fut: connection.open_tunnel(RequestHeadType::from(head)),
+                        };
+
+                        self.set(fut);
+                    }
+                }
+
+                self.poll(cx)
+            }
+
+            ConnectRequestProj::Client { fut } => {
+                let (head, payload) = ready!(fut.as_mut().poll(cx))?;
+                Poll::Ready(Ok(ConnectResponse::Client(ClientResponse::new(
+                    head, payload,
+                ))))
+            }
+
+            ConnectRequestProj::Tunnel { fut } => {
+                let (head, framed) = ready!(fut.as_mut().poll(cx))?;
+                let framed = framed.into_map_io(|io| Box::new(io) as _);
+                Poll::Ready(Ok(ConnectResponse::Tunnel(head, framed)))
+            }
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/error.rs.html b/src/awc/error.rs.html new file mode 100644 index 000000000..09e4d042d --- /dev/null +++ b/src/awc/error.rs.html @@ -0,0 +1,163 @@ +error.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+
//! HTTP client errors
+
+// TODO: figure out how best to expose http::Error vs actix_http::Error
+pub use actix_http::{
+    error::{HttpError, PayloadError},
+    header::HeaderValue,
+    ws::{HandshakeError as WsHandshakeError, ProtocolError as WsProtocolError},
+    StatusCode,
+};
+use derive_more::{Display, From};
+use serde_json::error::Error as JsonError;
+
+pub use crate::client::{ConnectError, FreezeRequestError, InvalidUrl, SendRequestError};
+
+// TODO: address display, error, and from impls
+
+/// Websocket client error
+#[derive(Debug, Display, From)]
+pub enum WsClientError {
+    /// Invalid response status
+    #[display(fmt = "Invalid response status")]
+    InvalidResponseStatus(StatusCode),
+
+    /// Invalid upgrade header
+    #[display(fmt = "Invalid upgrade header")]
+    InvalidUpgradeHeader,
+
+    /// Invalid connection header
+    #[display(fmt = "Invalid connection header")]
+    InvalidConnectionHeader(HeaderValue),
+
+    /// Missing Connection header
+    #[display(fmt = "Missing Connection header")]
+    MissingConnectionHeader,
+
+    /// Missing Sec-Websocket-Accept header
+    #[display(fmt = "Missing Sec-Websocket-Accept header")]
+    MissingWebSocketAcceptHeader,
+
+    /// Invalid challenge response
+    #[display(fmt = "Invalid challenge response")]
+    InvalidChallengeResponse([u8; 28], HeaderValue),
+
+    /// Protocol error
+    #[display(fmt = "{}", _0)]
+    Protocol(WsProtocolError),
+
+    /// Send request error
+    #[display(fmt = "{}", _0)]
+    SendRequest(SendRequestError),
+}
+
+impl std::error::Error for WsClientError {}
+
+impl From<InvalidUrl> for WsClientError {
+    fn from(err: InvalidUrl) -> Self {
+        WsClientError::SendRequest(err.into())
+    }
+}
+
+impl From<HttpError> for WsClientError {
+    fn from(err: HttpError) -> Self {
+        WsClientError::SendRequest(err.into())
+    }
+}
+
+/// A set of errors that can occur during parsing json payloads
+#[derive(Debug, Display, From)]
+pub enum JsonPayloadError {
+    /// Content type error
+    #[display(fmt = "Content type error")]
+    ContentType,
+    /// Deserialize error
+    #[display(fmt = "Json deserialize error: {}", _0)]
+    Deserialize(JsonError),
+    /// Payload error
+    #[display(fmt = "Error that occur during reading payload: {}", _0)]
+    Payload(PayloadError),
+}
+
+impl std::error::Error for JsonPayloadError {}
+
\ No newline at end of file diff --git a/src/awc/frozen.rs.html b/src/awc/frozen.rs.html new file mode 100644 index 000000000..893c62ba2 --- /dev/null +++ b/src/awc/frozen.rs.html @@ -0,0 +1,451 @@ +frozen.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
+
use std::{net, rc::Rc, time::Duration};
+
+use actix_http::{
+    body::MessageBody,
+    error::HttpError,
+    header::{HeaderMap, TryIntoHeaderPair},
+    Method, RequestHead, Uri,
+};
+use bytes::Bytes;
+use futures_core::Stream;
+use serde::Serialize;
+
+use crate::{
+    client::ClientConfig,
+    sender::{RequestSender, SendClientRequest},
+    BoxError,
+};
+
+/// `FrozenClientRequest` struct represents cloneable client request.
+///
+/// It could be used to send same request multiple times.
+#[derive(Clone)]
+pub struct FrozenClientRequest {
+    pub(crate) head: Rc<RequestHead>,
+    pub(crate) addr: Option<net::SocketAddr>,
+    pub(crate) response_decompress: bool,
+    pub(crate) timeout: Option<Duration>,
+    pub(crate) config: ClientConfig,
+}
+
+impl FrozenClientRequest {
+    /// Get HTTP URI of request
+    pub fn get_uri(&self) -> &Uri {
+        &self.head.uri
+    }
+
+    /// Get HTTP method of this request
+    pub fn get_method(&self) -> &Method {
+        &self.head.method
+    }
+
+    /// Returns request's headers.
+    pub fn headers(&self) -> &HeaderMap {
+        &self.head.headers
+    }
+
+    /// Send a body.
+    pub fn send_body<B>(&self, body: B) -> SendClientRequest
+    where
+        B: MessageBody + 'static,
+    {
+        RequestSender::Rc(self.head.clone(), None).send_body(
+            self.addr,
+            self.response_decompress,
+            self.timeout,
+            &self.config,
+            body,
+        )
+    }
+
+    /// Send a json body.
+    pub fn send_json<T: Serialize>(&self, value: &T) -> SendClientRequest {
+        RequestSender::Rc(self.head.clone(), None).send_json(
+            self.addr,
+            self.response_decompress,
+            self.timeout,
+            &self.config,
+            value,
+        )
+    }
+
+    /// Send an urlencoded body.
+    pub fn send_form<T: Serialize>(&self, value: &T) -> SendClientRequest {
+        RequestSender::Rc(self.head.clone(), None).send_form(
+            self.addr,
+            self.response_decompress,
+            self.timeout,
+            &self.config,
+            value,
+        )
+    }
+
+    /// Send a streaming body.
+    pub fn send_stream<S, E>(&self, stream: S) -> SendClientRequest
+    where
+        S: Stream<Item = Result<Bytes, E>> + 'static,
+        E: Into<BoxError> + 'static,
+    {
+        RequestSender::Rc(self.head.clone(), None).send_stream(
+            self.addr,
+            self.response_decompress,
+            self.timeout,
+            &self.config,
+            stream,
+        )
+    }
+
+    /// Send an empty body.
+    pub fn send(&self) -> SendClientRequest {
+        RequestSender::Rc(self.head.clone(), None).send(
+            self.addr,
+            self.response_decompress,
+            self.timeout,
+            &self.config,
+        )
+    }
+
+    /// Clones this `FrozenClientRequest`, returning a new one with extra headers added.
+    pub fn extra_headers(&self, extra_headers: HeaderMap) -> FrozenSendBuilder {
+        FrozenSendBuilder::new(self.clone(), extra_headers)
+    }
+
+    /// Clones this `FrozenClientRequest`, returning a new one with the extra header added.
+    pub fn extra_header(&self, header: impl TryIntoHeaderPair) -> FrozenSendBuilder {
+        self.extra_headers(HeaderMap::new()).extra_header(header)
+    }
+}
+
+/// Builder that allows to modify extra headers.
+pub struct FrozenSendBuilder {
+    req: FrozenClientRequest,
+    extra_headers: HeaderMap,
+    err: Option<HttpError>,
+}
+
+impl FrozenSendBuilder {
+    pub(crate) fn new(req: FrozenClientRequest, extra_headers: HeaderMap) -> Self {
+        Self {
+            req,
+            extra_headers,
+            err: None,
+        }
+    }
+
+    /// Insert a header, it overrides existing header in `FrozenClientRequest`.
+    pub fn extra_header(mut self, header: impl TryIntoHeaderPair) -> Self {
+        match header.try_into_pair() {
+            Ok((key, value)) => {
+                self.extra_headers.insert(key, value);
+            }
+
+            Err(err) => self.err = Some(err.into()),
+        }
+
+        self
+    }
+
+    /// Complete request construction and send a body.
+    pub fn send_body(self, body: impl MessageBody + 'static) -> SendClientRequest {
+        if let Some(e) = self.err {
+            return e.into();
+        }
+
+        RequestSender::Rc(self.req.head, Some(self.extra_headers)).send_body(
+            self.req.addr,
+            self.req.response_decompress,
+            self.req.timeout,
+            &self.req.config,
+            body,
+        )
+    }
+
+    /// Complete request construction and send a json body.
+    pub fn send_json(self, value: impl Serialize) -> SendClientRequest {
+        if let Some(err) = self.err {
+            return err.into();
+        }
+
+        RequestSender::Rc(self.req.head, Some(self.extra_headers)).send_json(
+            self.req.addr,
+            self.req.response_decompress,
+            self.req.timeout,
+            &self.req.config,
+            value,
+        )
+    }
+
+    /// Complete request construction and send an urlencoded body.
+    pub fn send_form(self, value: impl Serialize) -> SendClientRequest {
+        if let Some(e) = self.err {
+            return e.into();
+        }
+
+        RequestSender::Rc(self.req.head, Some(self.extra_headers)).send_form(
+            self.req.addr,
+            self.req.response_decompress,
+            self.req.timeout,
+            &self.req.config,
+            value,
+        )
+    }
+
+    /// Complete request construction and send a streaming body.
+    pub fn send_stream<S, E>(self, stream: S) -> SendClientRequest
+    where
+        S: Stream<Item = Result<Bytes, E>> + 'static,
+        E: Into<BoxError> + 'static,
+    {
+        if let Some(e) = self.err {
+            return e.into();
+        }
+
+        RequestSender::Rc(self.req.head, Some(self.extra_headers)).send_stream(
+            self.req.addr,
+            self.req.response_decompress,
+            self.req.timeout,
+            &self.req.config,
+            stream,
+        )
+    }
+
+    /// Complete request construction and send an empty body.
+    pub fn send(self) -> SendClientRequest {
+        if let Some(e) = self.err {
+            return e.into();
+        }
+
+        RequestSender::Rc(self.req.head, Some(self.extra_headers)).send(
+            self.req.addr,
+            self.req.response_decompress,
+            self.req.timeout,
+            &self.req.config,
+        )
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/lib.rs.html b/src/awc/lib.rs.html new file mode 100644 index 000000000..a706f2216 --- /dev/null +++ b/src/awc/lib.rs.html @@ -0,0 +1,301 @@ +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
+
//! `awc` is an asynchronous HTTP and WebSocket client library.
+//!
+//! # `GET` Requests
+//! ```no_run
+//! # #[actix_rt::main]
+//! # async fn main() -> Result<(), awc::error::SendRequestError> {
+//! // create client
+//! let mut client = awc::Client::default();
+//!
+//! // construct request
+//! let req = client.get("http://www.rust-lang.org")
+//!     .insert_header(("User-Agent", "awc/3.0"));
+//!
+//! // send request and await response
+//! let res = req.send().await?;
+//! println!("Response: {:?}", res);
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! # `POST` Requests
+//! ## Raw Body
+//! ```no_run
+//! # #[actix_rt::main]
+//! # async fn main() -> Result<(), awc::error::SendRequestError> {
+//! let mut client = awc::Client::default();
+//! let response = client.post("http://httpbin.org/post")
+//!     .send_body("Raw body contents")
+//!     .await?;
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! ## JSON
+//! ```no_run
+//! # #[actix_rt::main]
+//! # async fn main() -> Result<(), awc::error::SendRequestError> {
+//! let request = serde_json::json!({
+//!     "lang": "rust",
+//!     "body": "json"
+//! });
+//!
+//! let mut client = awc::Client::default();
+//! let response = client.post("http://httpbin.org/post")
+//!     .send_json(&request)
+//!     .await?;
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! ## URL Encoded Form
+//! ```no_run
+//! # #[actix_rt::main]
+//! # async fn main() -> Result<(), awc::error::SendRequestError> {
+//! let params = [("foo", "bar"), ("baz", "quux")];
+//!
+//! let mut client = awc::Client::default();
+//! let response = client.post("http://httpbin.org/post")
+//!     .send_form(&params)
+//!     .await?;
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! # Response Compression
+//! All [official][iana-encodings] and common content encoding codecs are supported, optionally.
+//!
+//! The `Accept-Encoding` header will automatically be populated with enabled codecs and added to
+//! outgoing requests, allowing servers to select their `Content-Encoding` accordingly.
+//!
+//! Feature flags enable these codecs according to the table below. By default, all `compress-*`
+//! features are enabled.
+//!
+//! | Feature           | Codecs        |
+//! | ----------------- | ------------- |
+//! | `compress-brotli` | brotli        |
+//! | `compress-gzip`   | gzip, deflate |
+//! | `compress-zstd`   | zstd          |
+//!
+//! [iana-encodings]: https://www.iana.org/assignments/http-parameters/http-parameters.xhtml#content-coding
+//!
+//! # WebSockets
+//! ```no_run
+//! # #[actix_rt::main]
+//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
+//! use futures_util::{SinkExt as _, StreamExt as _};
+//!
+//! let (_resp, mut connection) = awc::Client::new()
+//!     .ws("ws://echo.websocket.org")
+//!     .connect()
+//!     .await?;
+//!
+//! connection
+//!     .send(awc::ws::Message::Text("Echo".into()))
+//!     .await?;
+//!
+//! let response = connection.next().await.unwrap()?;
+//! assert_eq!(response, awc::ws::Frame::Text("Echo".into()));
+//! # Ok(())
+//! # }
+//! ```
+
+#![deny(rust_2018_idioms, nonstandard_style)]
+#![warn(future_incompatible)]
+#![allow(unknown_lints)] // temp: #[allow(non_local_definitions)]
+#![allow(
+    clippy::type_complexity,
+    clippy::borrow_interior_mutable_const,
+    clippy::needless_doctest_main
+)]
+#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
+#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+
+pub use actix_http::body;
+#[cfg(feature = "cookies")]
+pub use cookie;
+
+mod any_body;
+mod builder;
+mod client;
+mod connect;
+pub mod error;
+mod frozen;
+pub mod middleware;
+mod request;
+mod responses;
+mod sender;
+pub mod test;
+pub mod ws;
+
+pub mod http {
+    //! Various HTTP related types.
+
+    // TODO: figure out how best to expose http::Error vs actix_http::Error
+    pub use actix_http::{header, uri, ConnectionType, Error, Method, StatusCode, Uri, Version};
+}
+
+#[allow(deprecated)]
+pub use self::responses::{ClientResponse, JsonBody, MessageBody, ResponseBody};
+pub use self::{
+    builder::ClientBuilder,
+    client::{Client, Connect, Connector},
+    connect::{BoxConnectorService, BoxedSocket, ConnectRequest, ConnectResponse},
+    frozen::{FrozenClientRequest, FrozenSendBuilder},
+    request::ClientRequest,
+    sender::SendClientRequest,
+};
+
+pub(crate) type BoxError = Box<dyn std::error::Error>;
+
\ No newline at end of file diff --git a/src/awc/middleware/mod.rs.html b/src/awc/middleware/mod.rs.html new file mode 100644 index 000000000..2ffd31a7c --- /dev/null +++ b/src/awc/middleware/mod.rs.html @@ -0,0 +1,143 @@ +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
+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
+
mod redirect;
+
+use std::marker::PhantomData;
+
+use actix_service::Service;
+
+pub use self::redirect::Redirect;
+
+/// Trait for transform a type to another one.
+/// Both the input and output type should impl [actix_service::Service] trait.
+pub trait Transform<S, Req> {
+    type Transform: Service<Req>;
+
+    /// Creates and returns a new Transform component.
+    fn new_transform(self, service: S) -> Self::Transform;
+}
+
+#[doc(hidden)]
+/// Helper struct for constructing Nested types that would call `Transform::new_transform`
+/// in a chain.
+///
+/// The child field would be called first and the output `Service` type is
+/// passed to parent as input type.
+pub struct NestTransform<T1, T2, S, Req>
+where
+    T1: Transform<S, Req>,
+    T2: Transform<T1::Transform, Req>,
+{
+    child: T1,
+    parent: T2,
+    _service: PhantomData<(S, Req)>,
+}
+
+impl<T1, T2, S, Req> NestTransform<T1, T2, S, Req>
+where
+    T1: Transform<S, Req>,
+    T2: Transform<T1::Transform, Req>,
+{
+    pub(crate) fn new(child: T1, parent: T2) -> Self {
+        NestTransform {
+            child,
+            parent,
+            _service: PhantomData,
+        }
+    }
+}
+
+impl<T1, T2, S, Req> Transform<S, Req> for NestTransform<T1, T2, S, Req>
+where
+    T1: Transform<S, Req>,
+    T2: Transform<T1::Transform, Req>,
+{
+    type Transform = T2::Transform;
+
+    fn new_transform(self, service: S) -> Self::Transform {
+        let service = self.child.new_transform(service);
+        self.parent.new_transform(service)
+    }
+}
+
+/// Dummy impl for kick start `NestTransform` type in `ClientBuilder` type
+impl<S, Req> Transform<S, Req> for ()
+where
+    S: Service<Req>,
+{
+    type Transform = S;
+
+    fn new_transform(self, service: S) -> Self::Transform {
+        service
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/middleware/redirect.rs.html b/src/awc/middleware/redirect.rs.html new file mode 100644 index 000000000..238e84000 --- /dev/null +++ b/src/awc/middleware/redirect.rs.html @@ -0,0 +1,1361 @@ +redirect.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
+
use std::{
+    future::Future,
+    net::SocketAddr,
+    pin::Pin,
+    rc::Rc,
+    task::{Context, Poll},
+};
+
+use actix_http::{header, Method, RequestHead, RequestHeadType, StatusCode, Uri};
+use actix_service::Service;
+use bytes::Bytes;
+use futures_core::ready;
+
+use super::Transform;
+use crate::{
+    any_body::AnyBody,
+    client::{InvalidUrl, SendRequestError},
+    connect::{ConnectRequest, ConnectResponse},
+    ClientResponse,
+};
+
+pub struct Redirect {
+    max_redirect_times: u8,
+}
+
+impl Default for Redirect {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl Redirect {
+    pub fn new() -> Self {
+        Self {
+            max_redirect_times: 10,
+        }
+    }
+
+    pub fn max_redirect_times(mut self, times: u8) -> Self {
+        self.max_redirect_times = times;
+        self
+    }
+}
+
+impl<S> Transform<S, ConnectRequest> for Redirect
+where
+    S: Service<ConnectRequest, Response = ConnectResponse, Error = SendRequestError> + 'static,
+{
+    type Transform = RedirectService<S>;
+
+    fn new_transform(self, service: S) -> Self::Transform {
+        RedirectService {
+            max_redirect_times: self.max_redirect_times,
+            connector: Rc::new(service),
+        }
+    }
+}
+
+pub struct RedirectService<S> {
+    max_redirect_times: u8,
+    connector: Rc<S>,
+}
+
+impl<S> Service<ConnectRequest> for RedirectService<S>
+where
+    S: Service<ConnectRequest, Response = ConnectResponse, Error = SendRequestError> + 'static,
+{
+    type Response = S::Response;
+    type Error = S::Error;
+    type Future = RedirectServiceFuture<S>;
+
+    actix_service::forward_ready!(connector);
+
+    fn call(&self, req: ConnectRequest) -> Self::Future {
+        match req {
+            ConnectRequest::Tunnel(head, addr) => {
+                let fut = self.connector.call(ConnectRequest::Tunnel(head, addr));
+                RedirectServiceFuture::Tunnel { fut }
+            }
+            ConnectRequest::Client(head, body, addr) => {
+                let connector = self.connector.clone();
+                let max_redirect_times = self.max_redirect_times;
+
+                // backup the uri and method for reuse schema and authority.
+                let (uri, method, headers) = match head {
+                    RequestHeadType::Owned(ref head) => {
+                        (head.uri.clone(), head.method.clone(), head.headers.clone())
+                    }
+                    RequestHeadType::Rc(ref head, ..) => {
+                        (head.uri.clone(), head.method.clone(), head.headers.clone())
+                    }
+                };
+
+                let body_opt = match body {
+                    AnyBody::Bytes { ref body } => Some(body.clone()),
+                    _ => None,
+                };
+
+                let fut = connector.call(ConnectRequest::Client(head, body, addr));
+
+                RedirectServiceFuture::Client {
+                    fut,
+                    max_redirect_times,
+                    uri: Some(uri),
+                    method: Some(method),
+                    headers: Some(headers),
+                    body: body_opt,
+                    addr,
+                    connector: Some(connector),
+                }
+            }
+        }
+    }
+}
+
+pin_project_lite::pin_project! {
+    #[project = RedirectServiceProj]
+    pub enum RedirectServiceFuture<S>
+    where
+        S: Service<ConnectRequest, Response = ConnectResponse, Error = SendRequestError>,
+        S: 'static
+    {
+        Tunnel { #[pin] fut: S::Future },
+        Client {
+            #[pin]
+            fut: S::Future,
+            max_redirect_times: u8,
+            uri: Option<Uri>,
+            method: Option<Method>,
+            headers: Option<header::HeaderMap>,
+            body: Option<Bytes>,
+            addr: Option<SocketAddr>,
+            connector: Option<Rc<S>>,
+        }
+    }
+}
+
+impl<S> Future for RedirectServiceFuture<S>
+where
+    S: Service<ConnectRequest, Response = ConnectResponse, Error = SendRequestError> + 'static,
+{
+    type Output = Result<ConnectResponse, SendRequestError>;
+
+    fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        match self.as_mut().project() {
+            RedirectServiceProj::Tunnel { fut } => fut.poll(cx),
+            RedirectServiceProj::Client {
+                fut,
+                max_redirect_times,
+                uri,
+                method,
+                headers,
+                body,
+                addr,
+                connector,
+            } => match ready!(fut.poll(cx))? {
+                ConnectResponse::Client(res) => match res.head().status {
+                    StatusCode::MOVED_PERMANENTLY
+                    | StatusCode::FOUND
+                    | StatusCode::SEE_OTHER
+                    | StatusCode::TEMPORARY_REDIRECT
+                    | StatusCode::PERMANENT_REDIRECT
+                        if *max_redirect_times > 0
+                            && res.headers().contains_key(header::LOCATION) =>
+                    {
+                        let reuse_body = res.head().status == StatusCode::TEMPORARY_REDIRECT
+                            || res.head().status == StatusCode::PERMANENT_REDIRECT;
+
+                        let prev_uri = uri.take().unwrap();
+
+                        // rebuild uri from the location header value.
+                        let next_uri = build_next_uri(&res, &prev_uri)?;
+
+                        // take ownership of states that could be reused
+                        let addr = addr.take();
+                        let connector = connector.take();
+
+                        // reset method
+                        let method = if reuse_body {
+                            method.take().unwrap()
+                        } else {
+                            let method = method.take().unwrap();
+                            match method {
+                                Method::GET | Method::HEAD => method,
+                                _ => Method::GET,
+                            }
+                        };
+
+                        let mut body = body.take();
+                        let body_new = if reuse_body {
+                            // try to reuse saved body
+                            match body {
+                                Some(ref bytes) => AnyBody::Bytes {
+                                    body: bytes.clone(),
+                                },
+
+                                // body was a non-reusable type so send an empty body instead
+                                _ => AnyBody::empty(),
+                            }
+                        } else {
+                            body = None;
+                            // remove body since we're downgrading to a GET
+                            AnyBody::None
+                        };
+
+                        let mut headers = headers.take().unwrap();
+
+                        remove_sensitive_headers(&mut headers, &prev_uri, &next_uri);
+
+                        // use a new request head.
+                        let mut head = RequestHead::default();
+                        head.uri = next_uri.clone();
+                        head.method = method.clone();
+                        head.headers = headers.clone();
+
+                        let head = RequestHeadType::Owned(head);
+
+                        let mut max_redirect_times = *max_redirect_times;
+                        max_redirect_times -= 1;
+
+                        let fut = connector
+                            .as_ref()
+                            .unwrap()
+                            .call(ConnectRequest::Client(head, body_new, addr));
+
+                        self.set(RedirectServiceFuture::Client {
+                            fut,
+                            max_redirect_times,
+                            uri: Some(next_uri),
+                            method: Some(method),
+                            headers: Some(headers),
+                            body,
+                            addr,
+                            connector,
+                        });
+
+                        self.poll(cx)
+                    }
+                    _ => Poll::Ready(Ok(ConnectResponse::Client(res))),
+                },
+                _ => unreachable!("ConnectRequest::Tunnel is not handled by Redirect"),
+            },
+        }
+    }
+}
+
+fn build_next_uri(res: &ClientResponse, prev_uri: &Uri) -> Result<Uri, SendRequestError> {
+    // responses without this header are not processed
+    let location = res.headers().get(header::LOCATION).unwrap();
+
+    // try to parse the location and resolve to a full URI but fall back to default if it fails
+    let uri = Uri::try_from(location.as_bytes()).unwrap_or_else(|_| Uri::default());
+
+    let uri = if uri.scheme().is_none() || uri.authority().is_none() {
+        let builder = Uri::builder()
+            .scheme(prev_uri.scheme().cloned().unwrap())
+            .authority(prev_uri.authority().cloned().unwrap());
+
+        // scheme-relative address
+        if location.as_bytes().starts_with(b"//") {
+            let scheme = prev_uri.scheme_str().unwrap();
+            let mut full_url: Vec<u8> = scheme.as_bytes().to_vec();
+            full_url.push(b':');
+            full_url.extend(location.as_bytes());
+
+            return Uri::try_from(full_url)
+                .map_err(|_| SendRequestError::Url(InvalidUrl::MissingScheme));
+        }
+        // when scheme or authority is missing treat the location value as path and query
+        // recover error where location does not have leading slash
+        let path = if location.as_bytes().starts_with(b"/") {
+            location.as_bytes().to_owned()
+        } else {
+            [b"/", location.as_bytes()].concat()
+        };
+
+        builder
+            .path_and_query(path)
+            .build()
+            .map_err(|err| SendRequestError::Url(InvalidUrl::HttpError(err)))?
+    } else {
+        uri
+    };
+
+    Ok(uri)
+}
+
+fn remove_sensitive_headers(headers: &mut header::HeaderMap, prev_uri: &Uri, next_uri: &Uri) {
+    if next_uri.host() != prev_uri.host()
+        || next_uri.port() != prev_uri.port()
+        || next_uri.scheme() != prev_uri.scheme()
+    {
+        headers.remove(header::COOKIE);
+        headers.remove(header::AUTHORIZATION);
+        headers.remove(header::PROXY_AUTHORIZATION);
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::str::FromStr;
+
+    use actix_web::{web, App, Error, HttpRequest, HttpResponse};
+
+    use super::*;
+    use crate::{http::header::HeaderValue, ClientBuilder};
+
+    #[actix_rt::test]
+    async fn basic_redirect() {
+        let client = ClientBuilder::new()
+            .disable_redirects()
+            .wrap(Redirect::new().max_redirect_times(10))
+            .finish();
+
+        let srv = actix_test::start(|| {
+            App::new()
+                .service(web::resource("/test").route(web::to(|| async {
+                    Ok::<_, Error>(HttpResponse::BadRequest())
+                })))
+                .service(web::resource("/").route(web::to(|| async {
+                    Ok::<_, Error>(
+                        HttpResponse::Found()
+                            .append_header(("location", "/test"))
+                            .finish(),
+                    )
+                })))
+        });
+
+        let res = client.get(srv.url("/")).send().await.unwrap();
+
+        assert_eq!(res.status().as_u16(), 400);
+    }
+
+    #[actix_rt::test]
+    async fn redirect_relative_without_leading_slash() {
+        let client = ClientBuilder::new().finish();
+
+        let srv = actix_test::start(|| {
+            App::new()
+                .service(web::resource("/").route(web::to(|| async {
+                    HttpResponse::Found()
+                        .insert_header(("location", "abc/"))
+                        .finish()
+                })))
+                .service(
+                    web::resource("/abc/")
+                        .route(web::to(|| async { HttpResponse::Accepted().finish() })),
+                )
+        });
+
+        let res = client.get(srv.url("/")).send().await.unwrap();
+        assert_eq!(res.status(), StatusCode::ACCEPTED);
+    }
+
+    #[actix_rt::test]
+    async fn redirect_without_location() {
+        let client = ClientBuilder::new()
+            .disable_redirects()
+            .wrap(Redirect::new().max_redirect_times(10))
+            .finish();
+
+        let srv = actix_test::start(|| {
+            App::new().service(web::resource("/").route(web::to(|| async {
+                Ok::<_, Error>(HttpResponse::Found().finish())
+            })))
+        });
+
+        let res = client.get(srv.url("/")).send().await.unwrap();
+        assert_eq!(res.status(), StatusCode::FOUND);
+    }
+
+    #[actix_rt::test]
+    async fn test_redirect_limit() {
+        let client = ClientBuilder::new()
+            .disable_redirects()
+            .wrap(Redirect::new().max_redirect_times(1))
+            .connector(crate::Connector::new())
+            .finish();
+
+        let srv = actix_test::start(|| {
+            App::new()
+                .service(web::resource("/").route(web::to(|| async {
+                    Ok::<_, Error>(
+                        HttpResponse::Found()
+                            .insert_header(("location", "/test"))
+                            .finish(),
+                    )
+                })))
+                .service(web::resource("/test").route(web::to(|| async {
+                    Ok::<_, Error>(
+                        HttpResponse::Found()
+                            .insert_header(("location", "/test2"))
+                            .finish(),
+                    )
+                })))
+                .service(web::resource("/test2").route(web::to(|| async {
+                    Ok::<_, Error>(HttpResponse::BadRequest())
+                })))
+        });
+
+        let res = client.get(srv.url("/")).send().await.unwrap();
+        assert_eq!(res.status(), StatusCode::FOUND);
+        assert_eq!(
+            res.headers()
+                .get(header::LOCATION)
+                .unwrap()
+                .to_str()
+                .unwrap(),
+            "/test2"
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_redirect_status_kind_307_308() {
+        let srv = actix_test::start(|| {
+            async fn root() -> HttpResponse {
+                HttpResponse::TemporaryRedirect()
+                    .append_header(("location", "/test"))
+                    .finish()
+            }
+
+            async fn test(req: HttpRequest, body: Bytes) -> HttpResponse {
+                if req.method() == Method::POST && !body.is_empty() {
+                    HttpResponse::Ok().finish()
+                } else {
+                    HttpResponse::InternalServerError().finish()
+                }
+            }
+
+            App::new()
+                .service(web::resource("/").route(web::to(root)))
+                .service(web::resource("/test").route(web::to(test)))
+        });
+
+        let res = srv.post("/").send_body("Hello").await.unwrap();
+        assert_eq!(res.status().as_u16(), 200);
+    }
+
+    #[actix_rt::test]
+    async fn test_redirect_status_kind_301_302_303() {
+        let srv = actix_test::start(|| {
+            async fn root() -> HttpResponse {
+                HttpResponse::Found()
+                    .append_header(("location", "/test"))
+                    .finish()
+            }
+
+            async fn test(req: HttpRequest, body: Bytes) -> HttpResponse {
+                if (req.method() == Method::GET || req.method() == Method::HEAD) && body.is_empty()
+                {
+                    HttpResponse::Ok().finish()
+                } else {
+                    HttpResponse::InternalServerError().finish()
+                }
+            }
+
+            App::new()
+                .service(web::resource("/").route(web::to(root)))
+                .service(web::resource("/test").route(web::to(test)))
+        });
+
+        let res = srv.post("/").send_body("Hello").await.unwrap();
+        assert_eq!(res.status().as_u16(), 200);
+
+        let res = srv.post("/").send().await.unwrap();
+        assert_eq!(res.status().as_u16(), 200);
+    }
+
+    #[actix_rt::test]
+    async fn test_redirect_headers() {
+        let srv = actix_test::start(|| {
+            async fn root(req: HttpRequest) -> HttpResponse {
+                if req
+                    .headers()
+                    .get("custom")
+                    .unwrap_or(&HeaderValue::from_str("").unwrap())
+                    == "value"
+                {
+                    HttpResponse::Found()
+                        .append_header(("location", "/test"))
+                        .finish()
+                } else {
+                    HttpResponse::InternalServerError().finish()
+                }
+            }
+
+            async fn test(req: HttpRequest) -> HttpResponse {
+                if req
+                    .headers()
+                    .get("custom")
+                    .unwrap_or(&HeaderValue::from_str("").unwrap())
+                    == "value"
+                {
+                    HttpResponse::Ok().finish()
+                } else {
+                    HttpResponse::InternalServerError().finish()
+                }
+            }
+
+            App::new()
+                .service(web::resource("/").route(web::to(root)))
+                .service(web::resource("/test").route(web::to(test)))
+        });
+
+        let client = ClientBuilder::new()
+            .add_default_header(("custom", "value"))
+            .disable_redirects()
+            .finish();
+        let res = client.get(srv.url("/")).send().await.unwrap();
+        assert_eq!(res.status().as_u16(), 302);
+
+        let client = ClientBuilder::new()
+            .add_default_header(("custom", "value"))
+            .finish();
+        let res = client.get(srv.url("/")).send().await.unwrap();
+        assert_eq!(res.status().as_u16(), 200);
+
+        let client = ClientBuilder::new().finish();
+        let res = client
+            .get(srv.url("/"))
+            .insert_header(("custom", "value"))
+            .send()
+            .await
+            .unwrap();
+        assert_eq!(res.status().as_u16(), 200);
+    }
+
+    #[actix_rt::test]
+    async fn test_redirect_cross_origin_headers() {
+        // defining two services to have two different origins
+        let srv2 = actix_test::start(|| {
+            async fn root(req: HttpRequest) -> HttpResponse {
+                if req.headers().get(header::AUTHORIZATION).is_none() {
+                    HttpResponse::Ok().finish()
+                } else {
+                    HttpResponse::InternalServerError().finish()
+                }
+            }
+
+            App::new().service(web::resource("/").route(web::to(root)))
+        });
+        let srv2_port: u16 = srv2.addr().port();
+
+        let srv1 = actix_test::start(move || {
+            async fn root(req: HttpRequest) -> HttpResponse {
+                let port = *req.app_data::<u16>().unwrap();
+                if req.headers().get(header::AUTHORIZATION).is_some() {
+                    HttpResponse::Found()
+                        .append_header(("location", format!("http://localhost:{}/", port).as_str()))
+                        .finish()
+                } else {
+                    HttpResponse::InternalServerError().finish()
+                }
+            }
+
+            async fn test1(req: HttpRequest) -> HttpResponse {
+                if req.headers().get(header::AUTHORIZATION).is_some() {
+                    HttpResponse::Found()
+                        .append_header(("location", "/test2"))
+                        .finish()
+                } else {
+                    HttpResponse::InternalServerError().finish()
+                }
+            }
+
+            async fn test2(req: HttpRequest) -> HttpResponse {
+                if req.headers().get(header::AUTHORIZATION).is_some() {
+                    HttpResponse::Ok().finish()
+                } else {
+                    HttpResponse::InternalServerError().finish()
+                }
+            }
+
+            App::new()
+                .app_data(srv2_port)
+                .service(web::resource("/").route(web::to(root)))
+                .service(web::resource("/test1").route(web::to(test1)))
+                .service(web::resource("/test2").route(web::to(test2)))
+        });
+
+        // send a request to different origins, http://srv1/ then http://srv2/. So it should remove the header
+        let client = ClientBuilder::new()
+            .add_default_header((header::AUTHORIZATION, "auth_key_value"))
+            .finish();
+        let res = client.get(srv1.url("/")).send().await.unwrap();
+        assert_eq!(res.status().as_u16(), 200);
+
+        // send a request to same origin, http://srv1/test1 then http://srv1/test2. So it should NOT remove any header
+        let res = client.get(srv1.url("/test1")).send().await.unwrap();
+        assert_eq!(res.status().as_u16(), 200);
+    }
+
+    #[actix_rt::test]
+    async fn test_double_slash_redirect() {
+        let client = ClientBuilder::new()
+            .disable_redirects()
+            .wrap(Redirect::new().max_redirect_times(10))
+            .finish();
+
+        let srv = actix_test::start(|| {
+            App::new()
+                .service(web::resource("/test").route(web::to(|| async {
+                    Ok::<_, Error>(HttpResponse::BadRequest())
+                })))
+                .service(
+                    web::resource("/").route(web::to(|req: HttpRequest| async move {
+                        Ok::<_, Error>(
+                            HttpResponse::Found()
+                                .append_header((
+                                    "location",
+                                    format!(
+                                        "//localhost:{}/test",
+                                        req.app_config().local_addr().port()
+                                    )
+                                    .as_str(),
+                                ))
+                                .finish(),
+                        )
+                    })),
+                )
+        });
+
+        let res = client.get(srv.url("/")).send().await.unwrap();
+
+        assert_eq!(res.status().as_u16(), 400);
+    }
+
+    #[actix_rt::test]
+    async fn test_remove_sensitive_headers() {
+        fn gen_headers() -> header::HeaderMap {
+            let mut headers = header::HeaderMap::new();
+            headers.insert(header::USER_AGENT, HeaderValue::from_str("value").unwrap());
+            headers.insert(
+                header::AUTHORIZATION,
+                HeaderValue::from_str("value").unwrap(),
+            );
+            headers.insert(
+                header::PROXY_AUTHORIZATION,
+                HeaderValue::from_str("value").unwrap(),
+            );
+            headers.insert(header::COOKIE, HeaderValue::from_str("value").unwrap());
+            headers
+        }
+
+        // Same origin
+        let prev_uri = Uri::from_str("https://host/path1").unwrap();
+        let next_uri = Uri::from_str("https://host/path2").unwrap();
+        let mut headers = gen_headers();
+        remove_sensitive_headers(&mut headers, &prev_uri, &next_uri);
+        assert_eq!(headers.len(), 4);
+
+        // different schema
+        let prev_uri = Uri::from_str("http://host/").unwrap();
+        let next_uri = Uri::from_str("https://host/").unwrap();
+        let mut headers = gen_headers();
+        remove_sensitive_headers(&mut headers, &prev_uri, &next_uri);
+        assert_eq!(headers.len(), 1);
+
+        // different host
+        let prev_uri = Uri::from_str("https://host1/").unwrap();
+        let next_uri = Uri::from_str("https://host2/").unwrap();
+        let mut headers = gen_headers();
+        remove_sensitive_headers(&mut headers, &prev_uri, &next_uri);
+        assert_eq!(headers.len(), 1);
+
+        // different port
+        let prev_uri = Uri::from_str("https://host:12/").unwrap();
+        let next_uri = Uri::from_str("https://host:23/").unwrap();
+        let mut headers = gen_headers();
+        remove_sensitive_headers(&mut headers, &prev_uri, &next_uri);
+        assert_eq!(headers.len(), 1);
+
+        // different everything!
+        let prev_uri = Uri::from_str("http://host1:12/path1").unwrap();
+        let next_uri = Uri::from_str("https://host2:23/path2").unwrap();
+        let mut headers = gen_headers();
+        remove_sensitive_headers(&mut headers, &prev_uri, &next_uri);
+        assert_eq!(headers.len(), 1);
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/request.rs.html b/src/awc/request.rs.html new file mode 100644 index 000000000..10643f1a2 --- /dev/null +++ b/src/awc/request.rs.html @@ -0,0 +1,1307 @@ +request.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
+
use std::{fmt, net, rc::Rc, time::Duration};
+
+use actix_http::{
+    body::MessageBody,
+    error::HttpError,
+    header::{self, HeaderMap, HeaderValue, TryIntoHeaderPair},
+    ConnectionType, Method, RequestHead, Uri, Version,
+};
+use base64::prelude::*;
+use bytes::Bytes;
+use futures_core::Stream;
+use serde::Serialize;
+
+#[cfg(feature = "cookies")]
+use crate::cookie::{Cookie, CookieJar};
+use crate::{
+    client::ClientConfig,
+    error::{FreezeRequestError, InvalidUrl},
+    frozen::FrozenClientRequest,
+    sender::{PrepForSendingError, RequestSender, SendClientRequest},
+    BoxError,
+};
+
+/// An HTTP Client request builder
+///
+/// This type can be used to construct an instance of `ClientRequest` through a
+/// builder-like pattern.
+///
+/// ```no_run
+/// # #[actix_rt::main]
+/// # async fn main() {
+/// let response = awc::Client::new()
+///      .get("http://www.rust-lang.org") // <- Create request builder
+///      .insert_header(("User-Agent", "Actix-web"))
+///      .send()                          // <- Send HTTP request
+///      .await;
+///
+/// response.and_then(|response| {   // <- server HTTP response
+///      println!("Response: {:?}", response);
+///      Ok(())
+/// });
+/// # }
+/// ```
+pub struct ClientRequest {
+    pub(crate) head: RequestHead,
+    err: Option<HttpError>,
+    addr: Option<net::SocketAddr>,
+    response_decompress: bool,
+    timeout: Option<Duration>,
+    config: ClientConfig,
+
+    #[cfg(feature = "cookies")]
+    cookies: Option<CookieJar>,
+}
+
+impl ClientRequest {
+    /// Create new client request builder.
+    pub(crate) fn new<U>(method: Method, uri: U, config: ClientConfig) -> Self
+    where
+        Uri: TryFrom<U>,
+        <Uri as TryFrom<U>>::Error: Into<HttpError>,
+    {
+        ClientRequest {
+            config,
+            head: RequestHead::default(),
+            err: None,
+            addr: None,
+            #[cfg(feature = "cookies")]
+            cookies: None,
+            timeout: None,
+            response_decompress: true,
+        }
+        .method(method)
+        .uri(uri)
+    }
+
+    /// Set HTTP URI of request.
+    #[inline]
+    pub fn uri<U>(mut self, uri: U) -> Self
+    where
+        Uri: TryFrom<U>,
+        <Uri as TryFrom<U>>::Error: Into<HttpError>,
+    {
+        match Uri::try_from(uri) {
+            Ok(uri) => self.head.uri = uri,
+            Err(err) => self.err = Some(err.into()),
+        }
+        self
+    }
+
+    /// Get HTTP URI of request.
+    pub fn get_uri(&self) -> &Uri {
+        &self.head.uri
+    }
+
+    /// Set socket address of the server.
+    ///
+    /// This address is used for connection. If address is not
+    /// provided url's host name get resolved.
+    pub fn address(mut self, addr: net::SocketAddr) -> Self {
+        self.addr = Some(addr);
+        self
+    }
+
+    /// Set HTTP method of this request.
+    #[inline]
+    pub fn method(mut self, method: Method) -> Self {
+        self.head.method = method;
+        self
+    }
+
+    /// Get HTTP method of this request
+    pub fn get_method(&self) -> &Method {
+        &self.head.method
+    }
+
+    /// Set HTTP version of this request.
+    ///
+    /// By default requests's HTTP version depends on network stream
+    #[doc(hidden)]
+    #[inline]
+    pub fn version(mut self, version: Version) -> Self {
+        self.head.version = version;
+        self
+    }
+
+    /// Get HTTP version of this request.
+    pub fn get_version(&self) -> &Version {
+        &self.head.version
+    }
+
+    /// Get peer address of this request.
+    pub fn get_peer_addr(&self) -> &Option<net::SocketAddr> {
+        &self.head.peer_addr
+    }
+
+    /// Returns request's headers.
+    #[inline]
+    pub fn headers(&self) -> &HeaderMap {
+        &self.head.headers
+    }
+
+    /// Returns request's mutable headers.
+    #[inline]
+    pub fn headers_mut(&mut self) -> &mut HeaderMap {
+        &mut self.head.headers
+    }
+
+    /// Insert a header, replacing any that were set with an equivalent field name.
+    pub fn insert_header(mut self, header: impl TryIntoHeaderPair) -> Self {
+        match header.try_into_pair() {
+            Ok((key, value)) => {
+                self.head.headers.insert(key, value);
+            }
+            Err(err) => self.err = Some(err.into()),
+        };
+
+        self
+    }
+
+    /// Insert a header only if it is not yet set.
+    pub fn insert_header_if_none(mut self, header: impl TryIntoHeaderPair) -> Self {
+        match header.try_into_pair() {
+            Ok((key, value)) => {
+                if !self.head.headers.contains_key(&key) {
+                    self.head.headers.insert(key, value);
+                }
+            }
+            Err(err) => self.err = Some(err.into()),
+        };
+
+        self
+    }
+
+    /// Append a header, keeping any that were set with an equivalent field name.
+    ///
+    /// ```no_run
+    /// use awc::{http::header, Client};
+    ///
+    /// Client::new()
+    ///     .get("http://www.rust-lang.org")
+    ///     .insert_header(("X-TEST", "value"))
+    ///     .insert_header((header::CONTENT_TYPE, mime::APPLICATION_JSON));
+    /// ```
+    pub fn append_header(mut self, header: impl TryIntoHeaderPair) -> Self {
+        match header.try_into_pair() {
+            Ok((key, value)) => self.head.headers.append(key, value),
+            Err(err) => self.err = Some(err.into()),
+        };
+
+        self
+    }
+
+    /// Send headers in `Camel-Case` form.
+    #[inline]
+    pub fn camel_case(mut self) -> Self {
+        self.head.set_camel_case_headers(true);
+        self
+    }
+
+    /// Force close connection instead of returning it back to connections pool.
+    /// This setting affect only HTTP/1 connections.
+    #[inline]
+    pub fn force_close(mut self) -> Self {
+        self.head.set_connection_type(ConnectionType::Close);
+        self
+    }
+
+    /// Set request's content type
+    #[inline]
+    pub fn content_type<V>(mut self, value: V) -> Self
+    where
+        HeaderValue: TryFrom<V>,
+        <HeaderValue as TryFrom<V>>::Error: Into<HttpError>,
+    {
+        match HeaderValue::try_from(value) {
+            Ok(value) => {
+                self.head.headers.insert(header::CONTENT_TYPE, value);
+            }
+            Err(err) => self.err = Some(err.into()),
+        }
+        self
+    }
+
+    /// Set content length
+    #[inline]
+    pub fn content_length(self, len: u64) -> Self {
+        let mut buf = itoa::Buffer::new();
+        self.insert_header((header::CONTENT_LENGTH, buf.format(len)))
+    }
+
+    /// Set HTTP basic authorization header.
+    ///
+    /// If no password is needed, just provide an empty string.
+    pub fn basic_auth(self, username: impl fmt::Display, password: impl fmt::Display) -> Self {
+        let auth = format!("{}:{}", username, password);
+
+        self.insert_header((
+            header::AUTHORIZATION,
+            format!("Basic {}", BASE64_STANDARD.encode(auth)),
+        ))
+    }
+
+    /// Set HTTP bearer authentication header
+    pub fn bearer_auth(self, token: impl fmt::Display) -> Self {
+        self.insert_header((header::AUTHORIZATION, format!("Bearer {}", token)))
+    }
+
+    /// Set a cookie
+    ///
+    /// ```no_run
+    /// use awc::{cookie::Cookie, Client};
+    ///
+    /// # #[actix_rt::main]
+    /// # async fn main() {
+    /// let res = Client::new().get("https://httpbin.org/cookies")
+    ///     .cookie(Cookie::new("name", "value"))
+    ///     .send()
+    ///     .await;
+    ///
+    /// println!("Response: {:?}", res);
+    /// # }
+    /// ```
+    #[cfg(feature = "cookies")]
+    pub fn cookie(mut self, cookie: Cookie<'_>) -> Self {
+        if self.cookies.is_none() {
+            let mut jar = CookieJar::new();
+            jar.add(cookie.into_owned());
+            self.cookies = Some(jar)
+        } else {
+            self.cookies.as_mut().unwrap().add(cookie.into_owned());
+        }
+        self
+    }
+
+    /// Disable automatic decompress of response's body
+    pub fn no_decompress(mut self) -> Self {
+        self.response_decompress = false;
+        self
+    }
+
+    /// Set request timeout. Overrides client wide timeout setting.
+    ///
+    /// Request timeout is the total time before a response must be received.
+    /// Default value is 5 seconds.
+    pub fn timeout(mut self, timeout: Duration) -> Self {
+        self.timeout = Some(timeout);
+        self
+    }
+
+    /// Sets the query part of the request
+    pub fn query<T: Serialize>(mut self, query: &T) -> Result<Self, serde_urlencoded::ser::Error> {
+        let mut parts = self.head.uri.clone().into_parts();
+
+        if let Some(path_and_query) = parts.path_and_query {
+            let query = serde_urlencoded::to_string(query)?;
+            let path = path_and_query.path();
+            parts.path_and_query = format!("{}?{}", path, query).parse().ok();
+
+            match Uri::from_parts(parts) {
+                Ok(uri) => self.head.uri = uri,
+                Err(err) => self.err = Some(err.into()),
+            }
+        }
+
+        Ok(self)
+    }
+
+    /// Freeze request builder and construct `FrozenClientRequest`,
+    /// which could be used for sending same request multiple times.
+    pub fn freeze(self) -> Result<FrozenClientRequest, FreezeRequestError> {
+        let slf = match self.prep_for_sending() {
+            Ok(slf) => slf,
+            Err(err) => return Err(err.into()),
+        };
+
+        let request = FrozenClientRequest {
+            head: Rc::new(slf.head),
+            addr: slf.addr,
+            response_decompress: slf.response_decompress,
+            timeout: slf.timeout,
+            config: slf.config,
+        };
+
+        Ok(request)
+    }
+
+    /// Complete request construction and send body.
+    pub fn send_body<B>(self, body: B) -> SendClientRequest
+    where
+        B: MessageBody + 'static,
+    {
+        let slf = match self.prep_for_sending() {
+            Ok(slf) => slf,
+            Err(err) => return err.into(),
+        };
+
+        RequestSender::Owned(slf.head).send_body(
+            slf.addr,
+            slf.response_decompress,
+            slf.timeout,
+            &slf.config,
+            body,
+        )
+    }
+
+    /// Set a JSON body and generate `ClientRequest`
+    pub fn send_json<T: Serialize>(self, value: &T) -> SendClientRequest {
+        let slf = match self.prep_for_sending() {
+            Ok(slf) => slf,
+            Err(err) => return err.into(),
+        };
+
+        RequestSender::Owned(slf.head).send_json(
+            slf.addr,
+            slf.response_decompress,
+            slf.timeout,
+            &slf.config,
+            value,
+        )
+    }
+
+    /// Set a urlencoded body and generate `ClientRequest`
+    ///
+    /// `ClientRequestBuilder` can not be used after this call.
+    pub fn send_form<T: Serialize>(self, value: &T) -> SendClientRequest {
+        let slf = match self.prep_for_sending() {
+            Ok(slf) => slf,
+            Err(err) => return err.into(),
+        };
+
+        RequestSender::Owned(slf.head).send_form(
+            slf.addr,
+            slf.response_decompress,
+            slf.timeout,
+            &slf.config,
+            value,
+        )
+    }
+
+    /// Set an streaming body and generate `ClientRequest`.
+    pub fn send_stream<S, E>(self, stream: S) -> SendClientRequest
+    where
+        S: Stream<Item = Result<Bytes, E>> + 'static,
+        E: Into<BoxError> + 'static,
+    {
+        let slf = match self.prep_for_sending() {
+            Ok(slf) => slf,
+            Err(err) => return err.into(),
+        };
+
+        RequestSender::Owned(slf.head).send_stream(
+            slf.addr,
+            slf.response_decompress,
+            slf.timeout,
+            &slf.config,
+            stream,
+        )
+    }
+
+    /// Set an empty body and generate `ClientRequest`.
+    pub fn send(self) -> SendClientRequest {
+        let slf = match self.prep_for_sending() {
+            Ok(slf) => slf,
+            Err(err) => return err.into(),
+        };
+
+        RequestSender::Owned(slf.head).send(
+            slf.addr,
+            slf.response_decompress,
+            slf.timeout,
+            &slf.config,
+        )
+    }
+
+    // allow unused mut when cookies feature is disabled
+    fn prep_for_sending(#[allow(unused_mut)] mut self) -> Result<Self, PrepForSendingError> {
+        if let Some(e) = self.err {
+            return Err(e.into());
+        }
+
+        // validate uri
+        let uri = &self.head.uri;
+        if uri.host().is_none() {
+            return Err(InvalidUrl::MissingHost.into());
+        } else if uri.scheme().is_none() {
+            return Err(InvalidUrl::MissingScheme.into());
+        } else if let Some(scheme) = uri.scheme() {
+            match scheme.as_str() {
+                "http" | "ws" | "https" | "wss" => {}
+                _ => return Err(InvalidUrl::UnknownScheme.into()),
+            }
+        } else {
+            return Err(InvalidUrl::UnknownScheme.into());
+        }
+
+        // set cookies
+        #[cfg(feature = "cookies")]
+        if let Some(ref mut jar) = self.cookies {
+            let cookie: String = jar
+                .delta()
+                // ensure only name=value is written to cookie header
+                .map(|c| c.stripped().encoded().to_string())
+                .collect::<Vec<_>>()
+                .join("; ");
+
+            if !cookie.is_empty() {
+                self.head
+                    .headers
+                    .insert(header::COOKIE, HeaderValue::from_str(&cookie).unwrap());
+            }
+        }
+
+        let mut slf = self;
+
+        // Set Accept-Encoding HTTP header depending on enabled feature.
+        // If decompress is not ask, then we are not able to find which encoding is
+        // supported, so we cannot guess Accept-Encoding HTTP header.
+        if slf.response_decompress {
+            // Set Accept-Encoding with compression algorithm awc is built with.
+            #[allow(clippy::vec_init_then_push)]
+            #[cfg(feature = "__compress")]
+            let accept_encoding = {
+                let mut encoding = vec![];
+
+                #[cfg(feature = "compress-brotli")]
+                {
+                    encoding.push("br");
+                }
+
+                #[cfg(feature = "compress-gzip")]
+                {
+                    encoding.push("gzip");
+                    encoding.push("deflate");
+                }
+
+                #[cfg(feature = "compress-zstd")]
+                encoding.push("zstd");
+
+                assert!(
+                    !encoding.is_empty(),
+                    "encoding can not be empty unless __compress feature has been explicitly enabled"
+                );
+
+                encoding.join(", ")
+            };
+
+            // Otherwise tell the server, we do not support any compression algorithm.
+            // So we clearly indicate that we do want identity encoding.
+            #[cfg(not(feature = "__compress"))]
+            let accept_encoding = "identity";
+
+            slf = slf.insert_header_if_none((header::ACCEPT_ENCODING, accept_encoding));
+        }
+
+        Ok(slf)
+    }
+}
+
+impl fmt::Debug for ClientRequest {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        writeln!(
+            f,
+            "\nClientRequest {:?} {} {}",
+            self.head.version, self.head.method, self.head.uri
+        )?;
+        writeln!(f, "  headers:")?;
+        for (key, val) in self.head.headers.iter() {
+            writeln!(f, "    {:?}: {:?}", key, val)?;
+        }
+        Ok(())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::time::SystemTime;
+
+    use actix_http::header::HttpDate;
+
+    use super::*;
+    use crate::Client;
+
+    #[actix_rt::test]
+    async fn test_debug() {
+        let request = Client::new().get("/").append_header(("x-test", "111"));
+        let repr = format!("{:?}", request);
+        assert!(repr.contains("ClientRequest"));
+        assert!(repr.contains("x-test"));
+    }
+
+    #[actix_rt::test]
+    async fn test_basics() {
+        let req = Client::new()
+            .put("/")
+            .version(Version::HTTP_2)
+            .insert_header((header::DATE, HttpDate::from(SystemTime::now())))
+            .content_type("plain/text")
+            .append_header((header::SERVER, "awc"));
+
+        let req = if let Some(val) = Some("server") {
+            req.append_header((header::USER_AGENT, val))
+        } else {
+            req
+        };
+
+        let req = if let Some(_val) = Option::<&str>::None {
+            req.append_header((header::ALLOW, "1"))
+        } else {
+            req
+        };
+
+        let mut req = req.content_length(100);
+
+        assert!(req.headers().contains_key(header::CONTENT_TYPE));
+        assert!(req.headers().contains_key(header::DATE));
+        assert!(req.headers().contains_key(header::SERVER));
+        assert!(req.headers().contains_key(header::USER_AGENT));
+        assert!(!req.headers().contains_key(header::ALLOW));
+        assert!(!req.headers().contains_key(header::EXPECT));
+        assert_eq!(req.head.version, Version::HTTP_2);
+
+        let _ = req.headers_mut();
+
+        #[allow(clippy::let_underscore_future)]
+        let _ = req.send_body("");
+    }
+
+    #[actix_rt::test]
+    async fn test_client_header() {
+        let req = Client::builder()
+            .add_default_header((header::CONTENT_TYPE, "111"))
+            .finish()
+            .get("/");
+
+        assert_eq!(
+            req.head
+                .headers
+                .get(header::CONTENT_TYPE)
+                .unwrap()
+                .to_str()
+                .unwrap(),
+            "111"
+        );
+    }
+
+    #[actix_rt::test]
+    async fn test_client_header_override() {
+        let req = Client::builder()
+            .add_default_header((header::CONTENT_TYPE, "111"))
+            .finish()
+            .get("/")
+            .insert_header((header::CONTENT_TYPE, "222"));
+
+        assert_eq!(
+            req.head
+                .headers
+                .get(header::CONTENT_TYPE)
+                .unwrap()
+                .to_str()
+                .unwrap(),
+            "222"
+        );
+    }
+
+    #[actix_rt::test]
+    async fn client_basic_auth() {
+        let req = Client::new().get("/").basic_auth("username", "password");
+        assert_eq!(
+            req.head
+                .headers
+                .get(header::AUTHORIZATION)
+                .unwrap()
+                .to_str()
+                .unwrap(),
+            "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
+        );
+
+        let req = Client::new().get("/").basic_auth("username", "");
+        assert_eq!(
+            req.head
+                .headers
+                .get(header::AUTHORIZATION)
+                .unwrap()
+                .to_str()
+                .unwrap(),
+            "Basic dXNlcm5hbWU6"
+        );
+    }
+
+    #[actix_rt::test]
+    async fn client_bearer_auth() {
+        let req = Client::new().get("/").bearer_auth("someS3cr3tAutht0k3n");
+        assert_eq!(
+            req.head
+                .headers
+                .get(header::AUTHORIZATION)
+                .unwrap()
+                .to_str()
+                .unwrap(),
+            "Bearer someS3cr3tAutht0k3n"
+        );
+    }
+
+    #[actix_rt::test]
+    async fn client_query() {
+        let req = Client::new()
+            .get("/")
+            .query(&[("key1", "val1"), ("key2", "val2")])
+            .unwrap();
+        assert_eq!(req.get_uri().query().unwrap(), "key1=val1&key2=val2");
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/responses/json_body.rs.html b/src/awc/responses/json_body.rs.html new file mode 100644 index 000000000..4b075fdc0 --- /dev/null +++ b/src/awc/responses/json_body.rs.html @@ -0,0 +1,385 @@ +json_body.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
+
use std::{
+    future::Future,
+    marker::PhantomData,
+    mem,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use actix_http::{error::PayloadError, header, HttpMessage};
+use bytes::Bytes;
+use futures_core::{ready, Stream};
+use pin_project_lite::pin_project;
+use serde::de::DeserializeOwned;
+
+use super::{read_body::ReadBody, ResponseTimeout, DEFAULT_BODY_LIMIT};
+use crate::{error::JsonPayloadError, ClientResponse};
+
+pin_project! {
+    /// A `Future` that reads a body stream, parses JSON, resolving to a deserialized `T`.
+    ///
+    /// # Errors
+    /// `Future` implementation returns error if:
+    /// - content type is not `application/json`;
+    /// - content length is greater than [limit](JsonBody::limit) (default: 2 MiB).
+    pub struct JsonBody<S, T> {
+        #[pin]
+        body: Option<ReadBody<S>>,
+        length: Option<usize>,
+        timeout: ResponseTimeout,
+        err: Option<JsonPayloadError>,
+        _phantom: PhantomData<T>,
+    }
+}
+
+impl<S, T> JsonBody<S, T>
+where
+    S: Stream<Item = Result<Bytes, PayloadError>>,
+    T: DeserializeOwned,
+{
+    /// Creates a JSON body stream reader from a response by taking its payload.
+    pub fn new(res: &mut ClientResponse<S>) -> Self {
+        // check content-type
+        let json = if let Ok(Some(mime)) = res.mime_type() {
+            mime.subtype() == mime::JSON || mime.suffix() == Some(mime::JSON)
+        } else {
+            false
+        };
+
+        if !json {
+            return JsonBody {
+                length: None,
+                body: None,
+                timeout: ResponseTimeout::default(),
+                err: Some(JsonPayloadError::ContentType),
+                _phantom: PhantomData,
+            };
+        }
+
+        let length = res
+            .headers()
+            .get(&header::CONTENT_LENGTH)
+            .and_then(|len_hdr| len_hdr.to_str().ok())
+            .and_then(|len_str| len_str.parse::<usize>().ok());
+
+        JsonBody {
+            body: Some(ReadBody::new(res.take_payload(), DEFAULT_BODY_LIMIT)),
+            length,
+            timeout: mem::take(&mut res.timeout),
+            err: None,
+            _phantom: PhantomData,
+        }
+    }
+
+    /// Change max size of payload. Default limit is 2 MiB.
+    pub fn limit(mut self, limit: usize) -> Self {
+        if let Some(ref mut fut) = self.body {
+            fut.limit = limit;
+        }
+
+        self
+    }
+}
+
+impl<S, T> Future for JsonBody<S, T>
+where
+    S: Stream<Item = Result<Bytes, PayloadError>>,
+    T: DeserializeOwned,
+{
+    type Output = Result<T, JsonPayloadError>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.project();
+
+        if let Some(err) = this.err.take() {
+            return Poll::Ready(Err(err));
+        }
+
+        if let Some(len) = this.length.take() {
+            let body = Option::as_ref(&this.body).unwrap();
+            if len > body.limit {
+                return Poll::Ready(Err(JsonPayloadError::Payload(PayloadError::Overflow)));
+            }
+        }
+
+        this.timeout
+            .poll_timeout(cx)
+            .map_err(JsonPayloadError::Payload)?;
+
+        let body = ready!(this.body.as_pin_mut().unwrap().poll(cx))?;
+        Poll::Ready(serde_json::from_slice::<T>(&body).map_err(JsonPayloadError::from))
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use actix_http::BoxedPayloadStream;
+    use serde::{Deserialize, Serialize};
+    use static_assertions::assert_impl_all;
+
+    use super::*;
+    use crate::test::TestResponse;
+
+    assert_impl_all!(JsonBody<BoxedPayloadStream, String>: Unpin);
+
+    #[derive(Serialize, Deserialize, PartialEq, Debug)]
+    struct MyObject {
+        name: String,
+    }
+
+    fn json_eq(err: JsonPayloadError, other: JsonPayloadError) -> bool {
+        match err {
+            JsonPayloadError::Payload(PayloadError::Overflow) => {
+                matches!(other, JsonPayloadError::Payload(PayloadError::Overflow))
+            }
+            JsonPayloadError::ContentType => matches!(other, JsonPayloadError::ContentType),
+            _ => false,
+        }
+    }
+
+    #[actix_rt::test]
+    async fn read_json_body() {
+        let mut req = TestResponse::default().finish();
+        let json = JsonBody::<_, MyObject>::new(&mut req).await;
+        assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType));
+
+        let mut req = TestResponse::default()
+            .insert_header((
+                header::CONTENT_TYPE,
+                header::HeaderValue::from_static("application/text"),
+            ))
+            .finish();
+        let json = JsonBody::<_, MyObject>::new(&mut req).await;
+        assert!(json_eq(json.err().unwrap(), JsonPayloadError::ContentType));
+
+        let mut req = TestResponse::default()
+            .insert_header((
+                header::CONTENT_TYPE,
+                header::HeaderValue::from_static("application/json"),
+            ))
+            .insert_header((
+                header::CONTENT_LENGTH,
+                header::HeaderValue::from_static("10000"),
+            ))
+            .finish();
+
+        let json = JsonBody::<_, MyObject>::new(&mut req).limit(100).await;
+        assert!(json_eq(
+            json.err().unwrap(),
+            JsonPayloadError::Payload(PayloadError::Overflow)
+        ));
+
+        let mut req = TestResponse::default()
+            .insert_header((
+                header::CONTENT_TYPE,
+                header::HeaderValue::from_static("application/json"),
+            ))
+            .insert_header((
+                header::CONTENT_LENGTH,
+                header::HeaderValue::from_static("16"),
+            ))
+            .set_payload(Bytes::from_static(b"{\"name\": \"test\"}"))
+            .finish();
+
+        let json = JsonBody::<_, MyObject>::new(&mut req).await;
+        assert_eq!(
+            json.ok().unwrap(),
+            MyObject {
+                name: "test".to_owned()
+            }
+        );
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/responses/mod.rs.html b/src/awc/responses/mod.rs.html new file mode 100644 index 000000000..5149c14bd --- /dev/null +++ b/src/awc/responses/mod.rs.html @@ -0,0 +1,97 @@ +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
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+
use std::{future::Future, io, pin::Pin, task::Context};
+
+use actix_http::error::PayloadError;
+use actix_rt::time::Sleep;
+
+mod json_body;
+mod read_body;
+mod response;
+mod response_body;
+
+#[allow(deprecated)]
+pub use self::response_body::{MessageBody, ResponseBody};
+pub use self::{json_body::JsonBody, response::ClientResponse};
+
+/// Default body size limit: 2 MiB
+const DEFAULT_BODY_LIMIT: usize = 2 * 1024 * 1024;
+
+/// Helper enum with reusable sleep passed from `SendClientResponse`.
+///
+/// See [`ClientResponse::_timeout`] for reason.
+pub(crate) enum ResponseTimeout {
+    Disabled(Option<Pin<Box<Sleep>>>),
+    Enabled(Pin<Box<Sleep>>),
+}
+
+impl Default for ResponseTimeout {
+    fn default() -> Self {
+        Self::Disabled(None)
+    }
+}
+
+impl ResponseTimeout {
+    fn poll_timeout(&mut self, cx: &mut Context<'_>) -> Result<(), PayloadError> {
+        match *self {
+            Self::Enabled(ref mut timeout) => {
+                if timeout.as_mut().poll(cx).is_ready() {
+                    Err(PayloadError::Io(io::Error::new(
+                        io::ErrorKind::TimedOut,
+                        "Response Payload IO timed out",
+                    )))
+                } else {
+                    Ok(())
+                }
+            }
+            Self::Disabled(_) => Ok(()),
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/responses/read_body.rs.html b/src/awc/responses/read_body.rs.html new file mode 100644 index 000000000..52201635d --- /dev/null +++ b/src/awc/responses/read_body.rs.html @@ -0,0 +1,123 @@ +read_body.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
+
use std::{
+    future::Future,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use actix_http::{error::PayloadError, Payload};
+use bytes::{Bytes, BytesMut};
+use futures_core::{ready, Stream};
+use pin_project_lite::pin_project;
+
+pin_project! {
+    pub(crate) struct ReadBody<S> {
+        #[pin]
+        pub(crate) stream: Payload<S>,
+        pub(crate) buf: BytesMut,
+        pub(crate) limit: usize,
+    }
+}
+
+impl<S> ReadBody<S> {
+    pub(crate) fn new(stream: Payload<S>, limit: usize) -> Self {
+        Self {
+            stream,
+            buf: BytesMut::new(),
+            limit,
+        }
+    }
+}
+
+impl<S> Future for ReadBody<S>
+where
+    S: Stream<Item = Result<Bytes, PayloadError>>,
+{
+    type Output = Result<Bytes, PayloadError>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let mut this = self.project();
+
+        while let Some(chunk) = ready!(this.stream.as_mut().poll_next(cx)?) {
+            if (this.buf.len() + chunk.len()) > *this.limit {
+                return Poll::Ready(Err(PayloadError::Overflow));
+            }
+
+            this.buf.extend_from_slice(&chunk);
+        }
+
+        Poll::Ready(Ok(this.buf.split().freeze()))
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use static_assertions::assert_impl_all;
+
+    use super::*;
+    use crate::any_body::AnyBody;
+
+    assert_impl_all!(ReadBody<()>: Unpin);
+    assert_impl_all!(ReadBody<AnyBody>: Unpin);
+}
+
\ No newline at end of file diff --git a/src/awc/responses/response.rs.html b/src/awc/responses/response.rs.html new file mode 100644 index 000000000..e8c1e2b92 --- /dev/null +++ b/src/awc/responses/response.rs.html @@ -0,0 +1,527 @@ +response.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
+
use std::{
+    cell::{Ref, RefCell, RefMut},
+    fmt, mem,
+    pin::Pin,
+    task::{Context, Poll},
+    time::{Duration, Instant},
+};
+
+use actix_http::{
+    error::PayloadError, header::HeaderMap, BoxedPayloadStream, Extensions, HttpMessage, Payload,
+    ResponseHead, StatusCode, Version,
+};
+use actix_rt::time::{sleep, Sleep};
+use bytes::Bytes;
+use futures_core::Stream;
+use pin_project_lite::pin_project;
+use serde::de::DeserializeOwned;
+
+use super::{JsonBody, ResponseBody, ResponseTimeout};
+#[cfg(feature = "cookies")]
+use crate::cookie::{Cookie, ParseError as CookieParseError};
+
+pin_project! {
+    /// Client Response
+    pub struct ClientResponse<S = BoxedPayloadStream> {
+        pub(crate) head: ResponseHead,
+        #[pin]
+        pub(crate) payload: Payload<S>,
+        pub(crate) timeout: ResponseTimeout,
+        pub(crate) extensions: RefCell<Extensions>,
+
+    }
+}
+
+impl<S> ClientResponse<S> {
+    /// Create new Request instance
+    pub(crate) fn new(head: ResponseHead, payload: Payload<S>) -> Self {
+        ClientResponse {
+            head,
+            payload,
+            timeout: ResponseTimeout::default(),
+            extensions: RefCell::new(Extensions::new()),
+        }
+    }
+
+    #[inline]
+    pub(crate) fn head(&self) -> &ResponseHead {
+        &self.head
+    }
+
+    /// Read the Request Version.
+    #[inline]
+    pub fn version(&self) -> Version {
+        self.head().version
+    }
+
+    /// Get the status from the server.
+    #[inline]
+    pub fn status(&self) -> StatusCode {
+        self.head().status
+    }
+
+    #[inline]
+    /// Returns request's headers.
+    pub fn headers(&self) -> &HeaderMap {
+        &self.head().headers
+    }
+
+    /// Map the current body type to another using a closure. Returns a new response.
+    ///
+    /// Closure receives the response head and the current body type.
+    pub fn map_body<F, U>(mut self, f: F) -> ClientResponse<U>
+    where
+        F: FnOnce(&mut ResponseHead, Payload<S>) -> Payload<U>,
+    {
+        let payload = f(&mut self.head, self.payload);
+
+        ClientResponse {
+            payload,
+            head: self.head,
+            timeout: self.timeout,
+            extensions: self.extensions,
+        }
+    }
+
+    /// Set a timeout duration for [`ClientResponse`](self::ClientResponse).
+    ///
+    /// This duration covers the duration of processing the response body stream
+    /// and would end it as timeout error when deadline met.
+    ///
+    /// Disabled by default.
+    pub fn timeout(self, dur: Duration) -> Self {
+        let timeout = match self.timeout {
+            ResponseTimeout::Disabled(Some(mut timeout))
+            | ResponseTimeout::Enabled(mut timeout) => match Instant::now().checked_add(dur) {
+                Some(deadline) => {
+                    timeout.as_mut().reset(deadline.into());
+                    ResponseTimeout::Enabled(timeout)
+                }
+                None => ResponseTimeout::Enabled(Box::pin(sleep(dur))),
+            },
+            _ => ResponseTimeout::Enabled(Box::pin(sleep(dur))),
+        };
+
+        Self {
+            payload: self.payload,
+            head: self.head,
+            timeout,
+            extensions: self.extensions,
+        }
+    }
+
+    /// This method does not enable timeout. It's used to pass the boxed `Sleep` from
+    /// `SendClientRequest` and reuse it's heap allocation together with it's slot in
+    /// timer wheel.
+    pub(crate) fn _timeout(mut self, timeout: Option<Pin<Box<Sleep>>>) -> Self {
+        self.timeout = ResponseTimeout::Disabled(timeout);
+        self
+    }
+
+    /// Load request cookies.
+    #[cfg(feature = "cookies")]
+    pub fn cookies(&self) -> Result<Ref<'_, Vec<Cookie<'static>>>, CookieParseError> {
+        struct Cookies(Vec<Cookie<'static>>);
+
+        if self.extensions().get::<Cookies>().is_none() {
+            let mut cookies = Vec::new();
+            for hdr in self.headers().get_all(&actix_http::header::SET_COOKIE) {
+                let s = std::str::from_utf8(hdr.as_bytes()).map_err(CookieParseError::from)?;
+                cookies.push(Cookie::parse_encoded(s)?.into_owned());
+            }
+            self.extensions_mut().insert(Cookies(cookies));
+        }
+
+        Ok(Ref::map(self.extensions(), |ext| {
+            &ext.get::<Cookies>().unwrap().0
+        }))
+    }
+
+    /// Return request cookie.
+    #[cfg(feature = "cookies")]
+    pub fn cookie(&self, name: &str) -> Option<Cookie<'static>> {
+        if let Ok(cookies) = self.cookies() {
+            for cookie in cookies.iter() {
+                if cookie.name() == name {
+                    return Some(cookie.to_owned());
+                }
+            }
+        }
+        None
+    }
+}
+
+impl<S> ClientResponse<S>
+where
+    S: Stream<Item = Result<Bytes, PayloadError>>,
+{
+    /// Returns a [`Future`] that consumes the body stream and resolves to [`Bytes`].
+    ///
+    /// # Errors
+    /// `Future` implementation returns error if:
+    /// - content length is greater than [limit](ResponseBody::limit) (default: 2 MiB)
+    ///
+    /// # Examples
+    /// ```no_run
+    /// # use awc::Client;
+    /// # use bytes::Bytes;
+    /// # #[actix_rt::main]
+    /// # async fn async_ctx() -> Result<(), Box<dyn std::error::Error>> {
+    /// let client = Client::default();
+    /// let mut res = client.get("https://httpbin.org/robots.txt").send().await?;
+    /// let body: Bytes = res.body().await?;
+    /// # Ok(())
+    /// # }
+    /// ```
+    ///
+    /// [`Future`]: std::future::Future
+    pub fn body(&mut self) -> ResponseBody<S> {
+        ResponseBody::new(self)
+    }
+
+    /// Returns a [`Future`] consumes the body stream, parses JSON, and resolves to a deserialized
+    /// `T` value.
+    ///
+    /// # Errors
+    /// Future returns error if:
+    /// - content type is not `application/json`;
+    /// - content length is greater than [limit](JsonBody::limit) (default: 2 MiB).
+    ///
+    /// # Examples
+    /// ```no_run
+    /// # use awc::Client;
+    /// # #[actix_rt::main]
+    /// # async fn async_ctx() -> Result<(), Box<dyn std::error::Error>> {
+    /// let client = Client::default();
+    /// let mut res = client.get("https://httpbin.org/json").send().await?;
+    /// let val = res.json::<serde_json::Value>().await?;
+    /// assert!(val.is_object());
+    /// # Ok(())
+    /// # }
+    /// ```
+    ///
+    /// [`Future`]: std::future::Future
+    pub fn json<T: DeserializeOwned>(&mut self) -> JsonBody<S, T> {
+        JsonBody::new(self)
+    }
+}
+
+impl<S> fmt::Debug for ClientResponse<S> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        writeln!(f, "\nClientResponse {:?} {}", self.version(), self.status(),)?;
+        writeln!(f, "  headers:")?;
+        for (key, val) in self.headers().iter() {
+            writeln!(f, "    {:?}: {:?}", key, val)?;
+        }
+        Ok(())
+    }
+}
+
+impl<S> HttpMessage for ClientResponse<S> {
+    type Stream = S;
+
+    fn headers(&self) -> &HeaderMap {
+        &self.head.headers
+    }
+
+    fn take_payload(&mut self) -> Payload<S> {
+        mem::replace(&mut self.payload, Payload::None)
+    }
+
+    fn extensions(&self) -> Ref<'_, Extensions> {
+        self.extensions.borrow()
+    }
+
+    fn extensions_mut(&self) -> RefMut<'_, Extensions> {
+        self.extensions.borrow_mut()
+    }
+}
+
+impl<S> Stream for ClientResponse<S>
+where
+    S: Stream<Item = Result<Bytes, PayloadError>> + Unpin,
+{
+    type Item = Result<Bytes, PayloadError>;
+
+    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
+        let this = self.project();
+        this.timeout.poll_timeout(cx)?;
+        this.payload.poll_next(cx)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use static_assertions::assert_impl_all;
+
+    use super::*;
+    use crate::any_body::AnyBody;
+
+    assert_impl_all!(ClientResponse: Unpin);
+    assert_impl_all!(ClientResponse<()>: Unpin);
+    assert_impl_all!(ClientResponse<AnyBody>: Unpin);
+}
+
\ No newline at end of file diff --git a/src/awc/responses/response_body.rs.html b/src/awc/responses/response_body.rs.html new file mode 100644 index 000000000..8fc031e5f --- /dev/null +++ b/src/awc/responses/response_body.rs.html @@ -0,0 +1,289 @@ +response_body.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
+
use std::{
+    future::Future,
+    mem,
+    pin::Pin,
+    task::{Context, Poll},
+};
+
+use actix_http::{error::PayloadError, header, HttpMessage};
+use bytes::Bytes;
+use futures_core::Stream;
+use pin_project_lite::pin_project;
+
+use super::{read_body::ReadBody, ResponseTimeout, DEFAULT_BODY_LIMIT};
+use crate::ClientResponse;
+
+pin_project! {
+    /// A `Future` that reads a body stream, resolving as [`Bytes`].
+    ///
+    /// # Errors
+    /// `Future` implementation returns error if:
+    /// - content type is not `application/json`;
+    /// - content length is greater than [limit](JsonBody::limit) (default: 2 MiB).
+    pub struct ResponseBody<S> {
+        #[pin]
+        body: Option<ReadBody<S>>,
+        length: Option<usize>,
+        timeout: ResponseTimeout,
+        err: Option<PayloadError>,
+    }
+}
+
+#[deprecated(since = "3.0.0", note = "Renamed to `ResponseBody`.")]
+pub type MessageBody<B> = ResponseBody<B>;
+
+impl<S> ResponseBody<S>
+where
+    S: Stream<Item = Result<Bytes, PayloadError>>,
+{
+    /// Creates a body stream reader from a response by taking its payload.
+    pub fn new(res: &mut ClientResponse<S>) -> ResponseBody<S> {
+        let length = match res.headers().get(&header::CONTENT_LENGTH) {
+            Some(value) => {
+                let len = value.to_str().ok().and_then(|s| s.parse::<usize>().ok());
+
+                match len {
+                    None => return Self::err(PayloadError::UnknownLength),
+                    len => len,
+                }
+            }
+            None => None,
+        };
+
+        ResponseBody {
+            body: Some(ReadBody::new(res.take_payload(), DEFAULT_BODY_LIMIT)),
+            length,
+            timeout: mem::take(&mut res.timeout),
+            err: None,
+        }
+    }
+
+    /// Change max size limit of payload.
+    ///
+    /// The default limit is 2 MiB.
+    pub fn limit(mut self, limit: usize) -> Self {
+        if let Some(ref mut body) = self.body {
+            body.limit = limit;
+        }
+
+        self
+    }
+
+    fn err(err: PayloadError) -> Self {
+        ResponseBody {
+            body: None,
+            length: None,
+            timeout: ResponseTimeout::default(),
+            err: Some(err),
+        }
+    }
+}
+
+impl<S> Future for ResponseBody<S>
+where
+    S: Stream<Item = Result<Bytes, PayloadError>>,
+{
+    type Output = Result<Bytes, PayloadError>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.project();
+
+        if let Some(err) = this.err.take() {
+            return Poll::Ready(Err(err));
+        }
+
+        if let Some(len) = this.length.take() {
+            let body = Option::as_ref(&this.body).unwrap();
+            if len > body.limit {
+                return Poll::Ready(Err(PayloadError::Overflow));
+            }
+        }
+
+        this.timeout.poll_timeout(cx)?;
+
+        this.body.as_pin_mut().unwrap().poll(cx)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use static_assertions::assert_impl_all;
+
+    use super::*;
+    use crate::test::TestResponse;
+
+    assert_impl_all!(ResponseBody<()>: Unpin);
+
+    #[actix_rt::test]
+    async fn read_body() {
+        let mut req = TestResponse::with_header((header::CONTENT_LENGTH, "xxxx")).finish();
+        match req.body().await.err().unwrap() {
+            PayloadError::UnknownLength => {}
+            _ => unreachable!("error"),
+        }
+
+        let mut req = TestResponse::with_header((header::CONTENT_LENGTH, "10000000")).finish();
+        match req.body().await.err().unwrap() {
+            PayloadError::Overflow => {}
+            _ => unreachable!("error"),
+        }
+
+        let mut req = TestResponse::default()
+            .set_payload(Bytes::from_static(b"test"))
+            .finish();
+        assert_eq!(req.body().await.ok().unwrap(), Bytes::from_static(b"test"));
+
+        let mut req = TestResponse::default()
+            .set_payload(Bytes::from_static(b"11111111111111"))
+            .finish();
+        match req.body().limit(5).await.err().unwrap() {
+            PayloadError::Overflow => {}
+            _ => unreachable!("error"),
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/sender.rs.html b/src/awc/sender.rs.html new file mode 100644 index 000000000..d7c5d9a48 --- /dev/null +++ b/src/awc/sender.rs.html @@ -0,0 +1,631 @@ +sender.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
+
use std::{
+    future::Future,
+    net,
+    pin::Pin,
+    rc::Rc,
+    task::{Context, Poll},
+    time::Duration,
+};
+
+use actix_http::{
+    body::{BodyStream, MessageBody},
+    error::HttpError,
+    header::{self, HeaderMap, HeaderName, TryIntoHeaderValue},
+    RequestHead, RequestHeadType,
+};
+#[cfg(feature = "__compress")]
+use actix_http::{encoding::Decoder, header::ContentEncoding, Payload};
+use actix_rt::time::{sleep, Sleep};
+use bytes::Bytes;
+use derive_more::From;
+use futures_core::Stream;
+use serde::Serialize;
+
+use crate::{
+    any_body::AnyBody,
+    client::ClientConfig,
+    error::{FreezeRequestError, InvalidUrl, SendRequestError},
+    BoxError, ClientResponse, ConnectRequest, ConnectResponse,
+};
+
+#[derive(Debug, From)]
+pub(crate) enum PrepForSendingError {
+    Url(InvalidUrl),
+    Http(HttpError),
+    Json(serde_json::Error),
+    Form(serde_urlencoded::ser::Error),
+}
+
+impl From<PrepForSendingError> for FreezeRequestError {
+    fn from(err: PrepForSendingError) -> FreezeRequestError {
+        match err {
+            PrepForSendingError::Url(err) => FreezeRequestError::Url(err),
+            PrepForSendingError::Http(err) => FreezeRequestError::Http(err),
+            PrepForSendingError::Json(err) => {
+                FreezeRequestError::Custom(Box::new(err), Box::new("json serialization error"))
+            }
+            PrepForSendingError::Form(err) => {
+                FreezeRequestError::Custom(Box::new(err), Box::new("form serialization error"))
+            }
+        }
+    }
+}
+
+impl From<PrepForSendingError> for SendRequestError {
+    fn from(err: PrepForSendingError) -> SendRequestError {
+        match err {
+            PrepForSendingError::Url(e) => SendRequestError::Url(e),
+            PrepForSendingError::Http(e) => SendRequestError::Http(e),
+            PrepForSendingError::Json(err) => {
+                SendRequestError::Custom(Box::new(err), Box::new("json serialization error"))
+            }
+            PrepForSendingError::Form(err) => {
+                SendRequestError::Custom(Box::new(err), Box::new("form serialization error"))
+            }
+        }
+    }
+}
+
+/// Future that sends request's payload and resolves to a server response.
+#[must_use = "futures do nothing unless polled"]
+pub enum SendClientRequest {
+    Fut(
+        Pin<Box<dyn Future<Output = Result<ConnectResponse, SendRequestError>>>>,
+        // FIXME: use a pinned Sleep instead of box.
+        Option<Pin<Box<Sleep>>>,
+        bool,
+    ),
+    Err(Option<SendRequestError>),
+}
+
+impl SendClientRequest {
+    pub(crate) fn new(
+        send: Pin<Box<dyn Future<Output = Result<ConnectResponse, SendRequestError>>>>,
+        response_decompress: bool,
+        timeout: Option<Duration>,
+    ) -> SendClientRequest {
+        let delay = timeout.map(|d| Box::pin(sleep(d)));
+        SendClientRequest::Fut(send, delay, response_decompress)
+    }
+}
+
+#[cfg(feature = "__compress")]
+impl Future for SendClientRequest {
+    type Output = Result<ClientResponse<Decoder<Payload>>, SendRequestError>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.get_mut();
+
+        match this {
+            SendClientRequest::Fut(send, delay, response_decompress) => {
+                if let Some(delay) = delay {
+                    if delay.as_mut().poll(cx).is_ready() {
+                        return Poll::Ready(Err(SendRequestError::Timeout));
+                    }
+                }
+
+                let res = futures_core::ready!(send.as_mut().poll(cx)).map(|res| {
+                    res.into_client_response()
+                        ._timeout(delay.take())
+                        .map_body(|head, payload| {
+                            if *response_decompress {
+                                Payload::Stream {
+                                    payload: Decoder::from_headers(payload, &head.headers),
+                                }
+                            } else {
+                                Payload::Stream {
+                                    payload: Decoder::new(payload, ContentEncoding::Identity),
+                                }
+                            }
+                        })
+                });
+
+                Poll::Ready(res)
+            }
+            SendClientRequest::Err(ref mut err) => match err.take() {
+                Some(err) => Poll::Ready(Err(err)),
+                None => panic!("Attempting to call completed future"),
+            },
+        }
+    }
+}
+
+#[cfg(not(feature = "__compress"))]
+impl Future for SendClientRequest {
+    type Output = Result<ClientResponse, SendRequestError>;
+
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
+        let this = self.get_mut();
+        match this {
+            SendClientRequest::Fut(send, delay, _) => {
+                if let Some(delay) = delay {
+                    if delay.as_mut().poll(cx).is_ready() {
+                        return Poll::Ready(Err(SendRequestError::Timeout));
+                    }
+                }
+                send.as_mut()
+                    .poll(cx)
+                    .map_ok(|res| res.into_client_response()._timeout(delay.take()))
+            }
+            SendClientRequest::Err(ref mut err) => match err.take() {
+                Some(err) => Poll::Ready(Err(err)),
+                None => panic!("Attempting to call completed future"),
+            },
+        }
+    }
+}
+
+impl From<SendRequestError> for SendClientRequest {
+    fn from(e: SendRequestError) -> Self {
+        SendClientRequest::Err(Some(e))
+    }
+}
+
+impl From<HttpError> for SendClientRequest {
+    fn from(e: HttpError) -> Self {
+        SendClientRequest::Err(Some(e.into()))
+    }
+}
+
+impl From<PrepForSendingError> for SendClientRequest {
+    fn from(e: PrepForSendingError) -> Self {
+        SendClientRequest::Err(Some(e.into()))
+    }
+}
+
+#[derive(Debug)]
+pub(crate) enum RequestSender {
+    Owned(RequestHead),
+    Rc(Rc<RequestHead>, Option<HeaderMap>),
+}
+
+impl RequestSender {
+    pub(crate) fn send_body(
+        self,
+        addr: Option<net::SocketAddr>,
+        response_decompress: bool,
+        timeout: Option<Duration>,
+        config: &ClientConfig,
+        body: impl MessageBody + 'static,
+    ) -> SendClientRequest {
+        let req = match self {
+            RequestSender::Owned(head) => ConnectRequest::Client(
+                RequestHeadType::Owned(head),
+                AnyBody::from_message_body(body).into_boxed(),
+                addr,
+            ),
+            RequestSender::Rc(head, extra_headers) => ConnectRequest::Client(
+                RequestHeadType::Rc(head, extra_headers),
+                AnyBody::from_message_body(body).into_boxed(),
+                addr,
+            ),
+        };
+
+        let fut = config.connector.call(req);
+
+        SendClientRequest::new(fut, response_decompress, timeout.or(config.timeout))
+    }
+
+    pub(crate) fn send_json(
+        mut self,
+        addr: Option<net::SocketAddr>,
+        response_decompress: bool,
+        timeout: Option<Duration>,
+        config: &ClientConfig,
+        value: impl Serialize,
+    ) -> SendClientRequest {
+        let body = match serde_json::to_string(&value) {
+            Ok(body) => body,
+            Err(err) => return PrepForSendingError::Json(err).into(),
+        };
+
+        if let Err(err) = self.set_header_if_none(header::CONTENT_TYPE, "application/json") {
+            return err.into();
+        }
+
+        self.send_body(addr, response_decompress, timeout, config, body)
+    }
+
+    pub(crate) fn send_form(
+        mut self,
+        addr: Option<net::SocketAddr>,
+        response_decompress: bool,
+        timeout: Option<Duration>,
+        config: &ClientConfig,
+        value: impl Serialize,
+    ) -> SendClientRequest {
+        let body = match serde_urlencoded::to_string(value) {
+            Ok(body) => body,
+            Err(err) => return PrepForSendingError::Form(err).into(),
+        };
+
+        // set content-type
+        if let Err(err) =
+            self.set_header_if_none(header::CONTENT_TYPE, "application/x-www-form-urlencoded")
+        {
+            return err.into();
+        }
+
+        self.send_body(addr, response_decompress, timeout, config, body)
+    }
+
+    pub(crate) fn send_stream<S, E>(
+        self,
+        addr: Option<net::SocketAddr>,
+        response_decompress: bool,
+        timeout: Option<Duration>,
+        config: &ClientConfig,
+        stream: S,
+    ) -> SendClientRequest
+    where
+        S: Stream<Item = Result<Bytes, E>> + 'static,
+        E: Into<BoxError> + 'static,
+    {
+        self.send_body(
+            addr,
+            response_decompress,
+            timeout,
+            config,
+            BodyStream::new(stream),
+        )
+    }
+
+    pub(crate) fn send(
+        self,
+        addr: Option<net::SocketAddr>,
+        response_decompress: bool,
+        timeout: Option<Duration>,
+        config: &ClientConfig,
+    ) -> SendClientRequest {
+        self.send_body(addr, response_decompress, timeout, config, ())
+    }
+
+    fn set_header_if_none<V>(&mut self, key: HeaderName, value: V) -> Result<(), HttpError>
+    where
+        V: TryIntoHeaderValue,
+    {
+        match self {
+            RequestSender::Owned(head) => {
+                if !head.headers.contains_key(&key) {
+                    match value.try_into_value() {
+                        Ok(value) => {
+                            head.headers.insert(key, value);
+                        }
+                        Err(err) => return Err(err.into()),
+                    }
+                }
+            }
+            RequestSender::Rc(head, extra_headers) => {
+                if !head.headers.contains_key(&key)
+                    && !extra_headers.iter().any(|h| h.contains_key(&key))
+                {
+                    match value.try_into_value() {
+                        Ok(v) => {
+                            let h = extra_headers.get_or_insert(HeaderMap::new());
+                            h.insert(key, v)
+                        }
+                        Err(err) => return Err(err.into()),
+                    };
+                }
+            }
+        }
+
+        Ok(())
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/test.rs.html b/src/awc/test.rs.html new file mode 100644 index 000000000..501b64574 --- /dev/null +++ b/src/awc/test.rs.html @@ -0,0 +1,239 @@ +test.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
+
//! Test helpers for actix http client to use during testing.
+
+use actix_http::{h1, header::TryIntoHeaderPair, Payload, ResponseHead, StatusCode, Version};
+use bytes::Bytes;
+
+#[cfg(feature = "cookies")]
+use crate::cookie::{Cookie, CookieJar};
+use crate::ClientResponse;
+
+/// Test `ClientResponse` builder
+pub struct TestResponse {
+    head: ResponseHead,
+    #[cfg(feature = "cookies")]
+    cookies: CookieJar,
+    payload: Option<Payload>,
+}
+
+impl Default for TestResponse {
+    fn default() -> TestResponse {
+        TestResponse {
+            head: ResponseHead::new(StatusCode::OK),
+            #[cfg(feature = "cookies")]
+            cookies: CookieJar::new(),
+            payload: None,
+        }
+    }
+}
+
+impl TestResponse {
+    /// Create TestResponse and set header
+    pub fn with_header(header: impl TryIntoHeaderPair) -> Self {
+        Self::default().insert_header(header)
+    }
+
+    /// Set HTTP version of this response
+    pub fn version(mut self, ver: Version) -> Self {
+        self.head.version = ver;
+        self
+    }
+
+    /// Insert a header
+    pub fn insert_header(mut self, header: impl TryIntoHeaderPair) -> Self {
+        if let Ok((key, value)) = header.try_into_pair() {
+            self.head.headers.insert(key, value);
+            return self;
+        }
+        panic!("Can not set header");
+    }
+
+    /// Append a header
+    pub fn append_header(mut self, header: impl TryIntoHeaderPair) -> Self {
+        if let Ok((key, value)) = header.try_into_pair() {
+            self.head.headers.append(key, value);
+            return self;
+        }
+        panic!("Can not create header");
+    }
+
+    /// Set cookie for this response
+    #[cfg(feature = "cookies")]
+    pub fn cookie(mut self, cookie: Cookie<'_>) -> Self {
+        self.cookies.add(cookie.into_owned());
+        self
+    }
+
+    /// Set response's payload
+    pub fn set_payload<B: Into<Bytes>>(mut self, data: B) -> Self {
+        let (_, mut payload) = h1::Payload::create(true);
+        payload.unread_data(data.into());
+        self.payload = Some(payload.into());
+        self
+    }
+
+    /// Complete response creation and generate `ClientResponse` instance
+    pub fn finish(self) -> ClientResponse {
+        // allow unused mut when cookies feature is disabled
+        #[allow(unused_mut)]
+        let mut head = self.head;
+
+        #[cfg(feature = "cookies")]
+        for cookie in self.cookies.delta() {
+            use actix_http::header::{self, HeaderValue};
+
+            head.headers.insert(
+                header::SET_COOKIE,
+                HeaderValue::from_str(&cookie.encoded().to_string()).unwrap(),
+            );
+        }
+
+        if let Some(pl) = self.payload {
+            ClientResponse::new(head, pl)
+        } else {
+            let (_, payload) = h1::Payload::create(true);
+            ClientResponse::new(head, payload.into())
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::time::SystemTime;
+
+    use actix_http::header::HttpDate;
+
+    use super::*;
+    use crate::http::header;
+
+    #[test]
+    fn test_basics() {
+        let res = TestResponse::default()
+            .version(Version::HTTP_2)
+            .insert_header((header::DATE, HttpDate::from(SystemTime::now())))
+            .cookie(cookie::Cookie::build("name", "value").finish())
+            .finish();
+        assert!(res.headers().contains_key(header::SET_COOKIE));
+        assert!(res.headers().contains_key(header::DATE));
+        assert_eq!(res.version(), Version::HTTP_2);
+    }
+}
+
\ No newline at end of file diff --git a/src/awc/ws.rs.html b/src/awc/ws.rs.html new file mode 100644 index 000000000..80fc89139 --- /dev/null +++ b/src/awc/ws.rs.html @@ -0,0 +1,1085 @@ +ws.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
+
//! Websockets client
+//!
+//! Type definitions required to use [`awc::Client`](super::Client) as a WebSocket client.
+//!
+//! # Examples
+//!
+//! ```no_run
+//! use awc::{Client, ws};
+//! use futures_util::{SinkExt as _, StreamExt as _};
+//!
+//! #[actix_rt::main]
+//! async fn main() {
+//!     let (_resp, mut connection) = Client::new()
+//!         .ws("ws://echo.websocket.org")
+//!         .connect()
+//!         .await
+//!         .unwrap();
+//!
+//!     connection
+//!         .send(ws::Message::Text("Echo".into()))
+//!         .await
+//!         .unwrap();
+//!     let response = connection.next().await.unwrap().unwrap();
+//!
+//!     assert_eq!(response, ws::Frame::Text("Echo".as_bytes().into()));
+//! }
+//! ```
+
+use std::{fmt, net::SocketAddr, str};
+
+use actix_codec::Framed;
+pub use actix_http::ws::{CloseCode, CloseReason, Codec, Frame, Message};
+use actix_http::{ws, Payload, RequestHead};
+use actix_rt::time::timeout;
+use actix_service::Service as _;
+use base64::prelude::*;
+
+#[cfg(feature = "cookies")]
+use crate::cookie::{Cookie, CookieJar};
+use crate::{
+    client::ClientConfig,
+    connect::{BoxedSocket, ConnectRequest},
+    error::{HttpError, InvalidUrl, SendRequestError, WsClientError},
+    http::{
+        header::{self, HeaderName, HeaderValue, TryIntoHeaderValue, AUTHORIZATION},
+        ConnectionType, Method, StatusCode, Uri, Version,
+    },
+    ClientResponse,
+};
+
+/// WebSocket connection.
+pub struct WebsocketsRequest {
+    pub(crate) head: RequestHead,
+    err: Option<HttpError>,
+    origin: Option<HeaderValue>,
+    protocols: Option<String>,
+    addr: Option<SocketAddr>,
+    max_size: usize,
+    server_mode: bool,
+    config: ClientConfig,
+
+    #[cfg(feature = "cookies")]
+    cookies: Option<CookieJar>,
+}
+
+impl WebsocketsRequest {
+    /// Create new WebSocket connection.
+    pub(crate) fn new<U>(uri: U, config: ClientConfig) -> Self
+    where
+        Uri: TryFrom<U>,
+        <Uri as TryFrom<U>>::Error: Into<HttpError>,
+    {
+        let mut err = None;
+
+        #[allow(clippy::field_reassign_with_default)]
+        let mut head = {
+            let mut head = RequestHead::default();
+            head.method = Method::GET;
+            head.version = Version::HTTP_11;
+            head
+        };
+
+        match Uri::try_from(uri) {
+            Ok(uri) => head.uri = uri,
+            Err(error) => err = Some(error.into()),
+        }
+
+        WebsocketsRequest {
+            head,
+            err,
+            config,
+            addr: None,
+            origin: None,
+            protocols: None,
+            max_size: 65_536,
+            server_mode: false,
+            #[cfg(feature = "cookies")]
+            cookies: None,
+        }
+    }
+
+    /// Set socket address of the server.
+    ///
+    /// This address is used for connection. If address is not
+    /// provided url's host name get resolved.
+    pub fn address(mut self, addr: SocketAddr) -> Self {
+        self.addr = Some(addr);
+        self
+    }
+
+    /// Set supported WebSocket protocols
+    pub fn protocols<U, V>(mut self, protos: U) -> Self
+    where
+        U: IntoIterator<Item = V>,
+        V: AsRef<str>,
+    {
+        let mut protos = protos
+            .into_iter()
+            .fold(String::new(), |acc, s| acc + s.as_ref() + ",");
+        protos.pop();
+        self.protocols = Some(protos);
+        self
+    }
+
+    /// Set a cookie
+    #[cfg(feature = "cookies")]
+    pub fn cookie(mut self, cookie: Cookie<'_>) -> Self {
+        if self.cookies.is_none() {
+            let mut jar = CookieJar::new();
+            jar.add(cookie.into_owned());
+            self.cookies = Some(jar)
+        } else {
+            self.cookies.as_mut().unwrap().add(cookie.into_owned());
+        }
+        self
+    }
+
+    /// Set request Origin
+    pub fn origin<V, E>(mut self, origin: V) -> Self
+    where
+        HeaderValue: TryFrom<V, Error = E>,
+        HttpError: From<E>,
+    {
+        match HeaderValue::try_from(origin) {
+            Ok(value) => self.origin = Some(value),
+            Err(err) => self.err = Some(err.into()),
+        }
+        self
+    }
+
+    /// Set max frame size
+    ///
+    /// By default max size is set to 64kB
+    pub fn max_frame_size(mut self, size: usize) -> Self {
+        self.max_size = size;
+        self
+    }
+
+    /// Disable payload masking. By default ws client masks frame payload.
+    pub fn server_mode(mut self) -> Self {
+        self.server_mode = true;
+        self
+    }
+
+    /// Append a header.
+    ///
+    /// Header gets appended to existing header.
+    /// To override header use `set_header()` method.
+    pub fn header<K, V>(mut self, key: K, value: V) -> Self
+    where
+        HeaderName: TryFrom<K>,
+        <HeaderName as TryFrom<K>>::Error: Into<HttpError>,
+        V: TryIntoHeaderValue,
+    {
+        match HeaderName::try_from(key) {
+            Ok(key) => match value.try_into_value() {
+                Ok(value) => {
+                    self.head.headers.append(key, value);
+                }
+                Err(err) => self.err = Some(err.into()),
+            },
+            Err(err) => self.err = Some(err.into()),
+        }
+        self
+    }
+
+    /// Insert a header, replaces existing header.
+    pub fn set_header<K, V>(mut self, key: K, value: V) -> Self
+    where
+        HeaderName: TryFrom<K>,
+        <HeaderName as TryFrom<K>>::Error: Into<HttpError>,
+        V: TryIntoHeaderValue,
+    {
+        match HeaderName::try_from(key) {
+            Ok(key) => match value.try_into_value() {
+                Ok(value) => {
+                    self.head.headers.insert(key, value);
+                }
+                Err(err) => self.err = Some(err.into()),
+            },
+            Err(err) => self.err = Some(err.into()),
+        }
+        self
+    }
+
+    /// Insert a header only if it is not yet set.
+    pub fn set_header_if_none<K, V>(mut self, key: K, value: V) -> Self
+    where
+        HeaderName: TryFrom<K>,
+        <HeaderName as TryFrom<K>>::Error: Into<HttpError>,
+        V: TryIntoHeaderValue,
+    {
+        match HeaderName::try_from(key) {
+            Ok(key) => {
+                if !self.head.headers.contains_key(&key) {
+                    match value.try_into_value() {
+                        Ok(value) => {
+                            self.head.headers.insert(key, value);
+                        }
+                        Err(err) => self.err = Some(err.into()),
+                    }
+                }
+            }
+            Err(err) => self.err = Some(err.into()),
+        }
+        self
+    }
+
+    /// Set HTTP basic authorization header
+    pub fn basic_auth<U>(self, username: U, password: Option<&str>) -> Self
+    where
+        U: fmt::Display,
+    {
+        let auth = match password {
+            Some(password) => format!("{}:{}", username, password),
+            None => format!("{}:", username),
+        };
+        self.header(
+            AUTHORIZATION,
+            format!("Basic {}", BASE64_STANDARD.encode(auth)),
+        )
+    }
+
+    /// Set HTTP bearer authentication header
+    pub fn bearer_auth<T>(self, token: T) -> Self
+    where
+        T: fmt::Display,
+    {
+        self.header(AUTHORIZATION, format!("Bearer {}", token))
+    }
+
+    /// Complete request construction and connect to a WebSocket server.
+    pub async fn connect(
+        mut self,
+    ) -> Result<(ClientResponse, Framed<BoxedSocket, Codec>), WsClientError> {
+        if let Some(e) = self.err.take() {
+            return Err(e.into());
+        }
+
+        // validate uri
+        let uri = &self.head.uri;
+        if uri.host().is_none() {
+            return Err(InvalidUrl::MissingHost.into());
+        } else if uri.scheme().is_none() {
+            return Err(InvalidUrl::MissingScheme.into());
+        } else if let Some(scheme) = uri.scheme() {
+            match scheme.as_str() {
+                "http" | "ws" | "https" | "wss" => {}
+                _ => return Err(InvalidUrl::UnknownScheme.into()),
+            }
+        } else {
+            return Err(InvalidUrl::UnknownScheme.into());
+        }
+
+        if !self.head.headers.contains_key(header::HOST) {
+            self.head.headers.insert(
+                header::HOST,
+                HeaderValue::from_str(uri.host().unwrap()).unwrap(),
+            );
+        }
+
+        // set cookies
+        #[cfg(feature = "cookies")]
+        if let Some(ref mut jar) = self.cookies {
+            let cookie: String = jar
+                .delta()
+                // ensure only name=value is written to cookie header
+                .map(|c| c.stripped().encoded().to_string())
+                .collect::<Vec<_>>()
+                .join("; ");
+
+            if !cookie.is_empty() {
+                self.head
+                    .headers
+                    .insert(header::COOKIE, HeaderValue::from_str(&cookie).unwrap());
+            }
+        }
+
+        // origin
+        if let Some(origin) = self.origin.take() {
+            self.head.headers.insert(header::ORIGIN, origin);
+        }
+
+        self.head.set_connection_type(ConnectionType::Upgrade);
+
+        #[allow(clippy::declare_interior_mutable_const)]
+        const HV_WEBSOCKET: HeaderValue = HeaderValue::from_static("websocket");
+        self.head.headers.insert(header::UPGRADE, HV_WEBSOCKET);
+
+        #[allow(clippy::declare_interior_mutable_const)]
+        const HV_THIRTEEN: HeaderValue = HeaderValue::from_static("13");
+        self.head
+            .headers
+            .insert(header::SEC_WEBSOCKET_VERSION, HV_THIRTEEN);
+
+        if let Some(protocols) = self.protocols.take() {
+            self.head.headers.insert(
+                header::SEC_WEBSOCKET_PROTOCOL,
+                HeaderValue::try_from(protocols.as_str()).unwrap(),
+            );
+        }
+
+        // Generate a random key for the `Sec-WebSocket-Key` header which is a base64-encoded
+        // (see RFC 4648 §4) value that, when decoded, is 16 bytes in length (RFC 6455 §1.3).
+        let sec_key: [u8; 16] = rand::random();
+        let key = BASE64_STANDARD.encode(sec_key);
+
+        self.head.headers.insert(
+            header::SEC_WEBSOCKET_KEY,
+            HeaderValue::try_from(key.as_str()).unwrap(),
+        );
+
+        let head = self.head;
+        let max_size = self.max_size;
+        let server_mode = self.server_mode;
+
+        let req = ConnectRequest::Tunnel(head, self.addr);
+
+        let fut = self.config.connector.call(req);
+
+        // set request timeout
+        let res = if let Some(to) = self.config.timeout {
+            timeout(to, fut)
+                .await
+                .map_err(|_| SendRequestError::Timeout)??
+        } else {
+            fut.await?
+        };
+
+        let (head, framed) = res.into_tunnel_response();
+
+        // verify response
+        if head.status != StatusCode::SWITCHING_PROTOCOLS {
+            return Err(WsClientError::InvalidResponseStatus(head.status));
+        }
+
+        // check for "UPGRADE" to WebSocket header
+        let has_hdr = if let Some(hdr) = head.headers.get(&header::UPGRADE) {
+            if let Ok(s) = hdr.to_str() {
+                s.to_ascii_lowercase().contains("websocket")
+            } else {
+                false
+            }
+        } else {
+            false
+        };
+        if !has_hdr {
+            log::trace!("Invalid upgrade header");
+            return Err(WsClientError::InvalidUpgradeHeader);
+        }
+
+        // Check for "CONNECTION" header
+        if let Some(conn) = head.headers.get(&header::CONNECTION) {
+            if let Ok(s) = conn.to_str() {
+                if !s.to_ascii_lowercase().contains("upgrade") {
+                    log::trace!("Invalid connection header: {}", s);
+                    return Err(WsClientError::InvalidConnectionHeader(conn.clone()));
+                }
+            } else {
+                log::trace!("Invalid connection header: {:?}", conn);
+                return Err(WsClientError::InvalidConnectionHeader(conn.clone()));
+            }
+        } else {
+            log::trace!("Missing connection header");
+            return Err(WsClientError::MissingConnectionHeader);
+        }
+
+        if let Some(hdr_key) = head.headers.get(&header::SEC_WEBSOCKET_ACCEPT) {
+            let encoded = ws::hash_key(key.as_ref());
+
+            if hdr_key.as_bytes() != encoded {
+                log::trace!(
+                    "Invalid challenge response: expected: {:?} received: {:?}",
+                    &encoded,
+                    key
+                );
+
+                return Err(WsClientError::InvalidChallengeResponse(
+                    encoded,
+                    hdr_key.clone(),
+                ));
+            }
+        } else {
+            log::trace!("Missing SEC-WEBSOCKET-ACCEPT header");
+            return Err(WsClientError::MissingWebSocketAcceptHeader);
+        };
+
+        // response and ws framed
+        Ok((
+            ClientResponse::new(head, Payload::None),
+            framed.into_map_codec(|_| {
+                if server_mode {
+                    ws::Codec::new().max_size(max_size)
+                } else {
+                    ws::Codec::new().max_size(max_size).client_mode()
+                }
+            }),
+        ))
+    }
+}
+
+impl fmt::Debug for WebsocketsRequest {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        writeln!(
+            f,
+            "\nWebsocketsRequest {}:{}",
+            self.head.method, self.head.uri
+        )?;
+        writeln!(f, "  headers:")?;
+        for (key, val) in self.head.headers.iter() {
+            writeln!(f, "    {:?}: {:?}", key, val)?;
+        }
+        Ok(())
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use crate::Client;
+
+    #[actix_rt::test]
+    async fn test_debug() {
+        let request = Client::new().ws("/").header("x-test", "111");
+        let repr = format!("{:?}", request);
+        assert!(repr.contains("WebsocketsRequest"));
+        assert!(repr.contains("x-test"));
+    }
+
+    #[actix_rt::test]
+    async fn test_header_override() {
+        let req = Client::builder()
+            .add_default_header((header::CONTENT_TYPE, "111"))
+            .finish()
+            .ws("/")
+            .set_header(header::CONTENT_TYPE, "222");
+
+        assert_eq!(
+            req.head
+                .headers
+                .get(header::CONTENT_TYPE)
+                .unwrap()
+                .to_str()
+                .unwrap(),
+            "222"
+        );
+    }
+
+    #[actix_rt::test]
+    async fn basic_auth() {
+        let req = Client::new()
+            .ws("/")
+            .basic_auth("username", Some("password"));
+        assert_eq!(
+            req.head
+                .headers
+                .get(header::AUTHORIZATION)
+                .unwrap()
+                .to_str()
+                .unwrap(),
+            "Basic dXNlcm5hbWU6cGFzc3dvcmQ="
+        );
+
+        let req = Client::new().ws("/").basic_auth("username", None);
+        assert_eq!(
+            req.head
+                .headers
+                .get(header::AUTHORIZATION)
+                .unwrap()
+                .to_str()
+                .unwrap(),
+            "Basic dXNlcm5hbWU6"
+        );
+    }
+
+    #[actix_rt::test]
+    async fn bearer_auth() {
+        let req = Client::new().ws("/").bearer_auth("someS3cr3tAutht0k3n");
+        assert_eq!(
+            req.head
+                .headers
+                .get(header::AUTHORIZATION)
+                .unwrap()
+                .to_str()
+                .unwrap(),
+            "Bearer someS3cr3tAutht0k3n"
+        );
+
+        #[allow(clippy::let_underscore_future)]
+        let _ = req.connect();
+    }
+
+    #[actix_rt::test]
+    async fn basics() {
+        let req = Client::new()
+            .ws("http://localhost/")
+            .origin("test-origin")
+            .max_frame_size(100)
+            .server_mode()
+            .protocols(["v1", "v2"])
+            .set_header_if_none(header::CONTENT_TYPE, "json")
+            .set_header_if_none(header::CONTENT_TYPE, "text")
+            .cookie(Cookie::build("cookie1", "value1").finish());
+        assert_eq!(
+            req.origin.as_ref().unwrap().to_str().unwrap(),
+            "test-origin"
+        );
+        assert_eq!(req.max_size, 100);
+        assert!(req.server_mode);
+        assert_eq!(req.protocols, Some("v1,v2".to_string()));
+        assert_eq!(
+            req.head.headers.get(header::CONTENT_TYPE).unwrap(),
+            header::HeaderValue::from_static("json")
+        );
+
+        let _ = req.connect().await;
+
+        assert!(Client::new().ws("/").connect().await.is_err());
+        assert!(Client::new().ws("http:///test").connect().await.is_err());
+        assert!(Client::new().ws("hmm://test.com/").connect().await.is_err());
+    }
+}
+
\ No newline at end of file diff --git a/static.files/COPYRIGHT-23e9bde6c69aea69.txt b/static.files/COPYRIGHT-23e9bde6c69aea69.txt new file mode 100644 index 000000000..1447df792 --- /dev/null +++ b/static.files/COPYRIGHT-23e9bde6c69aea69.txt @@ -0,0 +1,50 @@ +# REUSE-IgnoreStart + +These documentation pages include resources by third parties. This copyright +file applies only to those resources. The following third party resources are +included, and carry their own copyright notices and license terms: + +* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2): + + Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ + with Reserved Font Name Fira Sans. + + Copyright (c) 2014, Telefonica S.A. + + Licensed under the SIL Open Font License, Version 1.1. + See FiraSans-LICENSE.txt. + +* rustdoc.css, main.js, and playpen.js: + + Copyright 2015 The Rust Developers. + Licensed under the Apache License, Version 2.0 (see LICENSE-APACHE.txt) or + the MIT license (LICENSE-MIT.txt) at your option. + +* normalize.css: + + Copyright (c) Nicolas Gallagher and Jonathan Neal. + Licensed under the MIT license (see LICENSE-MIT.txt). + +* Source Code Pro (SourceCodePro-Regular.ttf.woff2, + SourceCodePro-Semibold.ttf.woff2, SourceCodePro-It.ttf.woff2): + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), + with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark + of Adobe Systems Incorporated in the United States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceCodePro-LICENSE.txt. + +* Source Serif 4 (SourceSerif4-Regular.ttf.woff2, SourceSerif4-Bold.ttf.woff2, + SourceSerif4-It.ttf.woff2): + + Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name + 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United + States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceSerif4-LICENSE.md. + +This copyright file is intended to be distributed with rustdoc output. + +# REUSE-IgnoreEnd diff --git a/static.files/FiraSans-LICENSE-db4b642586e02d97.txt b/static.files/FiraSans-LICENSE-db4b642586e02d97.txt new file mode 100644 index 000000000..d7e9c149b --- /dev/null +++ b/static.files/FiraSans-LICENSE-db4b642586e02d97.txt @@ -0,0 +1,98 @@ +// REUSE-IgnoreStart + +Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. +with Reserved Font Name < Fira >, + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 b/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 new file mode 100644 index 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/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 b/static.files/FiraSans-Regular-018c141bf0843ffd.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;2JO>~QPMdMZ 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

xz5_8aF@(pQs@zgto+ItjS_s2^}<|M=lFQ2 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,qWUc(1+qXDfx7@=bp~~)(TqS z_5BF?f8WUf{W$C@srj@O_I!NmB#!7Q>m6xX4+Kp^uaau+*B^8k-RnraR#b zBF9Oqo~}9c})B7HgVPuHcNUPgcGCCXknwYipUhLC7QNo2D`P?r22X;qyxpg zIebJ#b?Wa7)KrZ4IOq&0N|rP%kAvK)(~KLqGS@+!zsgk#__P{DJk$eg3km9YqlAEm z`x&-5RH}}E%kGw7JF@gy(|=l3b-HTM(TZD|Z8HP!9!ViE2T{ErA4~2lZV6ftt z(6U6w+^CywChK4Ou&BSthY2RLnJXF$)i<0PB}cH6ipV`^TdM_nGf!LtIcmNodH^nB zH5?5j{2#&Ebz$Bx5?)|Dl2{=a9B)Swb8bo&!MX8*>HS0j-*!fvi_RR#PSk7<3~LhM z*jj%yL3}I~cfJE|a51%*R4~p!F%3e&dx+?JF3vtPdn3Mc&K!(&n@N;X-_mu9qleSV zWlmAV64=lX(F{WaB86_SxHeIN%eVc57luaPI-9c!7H}r$`5YC&C_GaMmOv4Kb+7s zjwf0T2F%=^5Wg2VDO=sp#d(DAC23heV9S8a$PxZq z3CW;Tt|6CYPTxcjP+}xdg=B!Jkv|f&&~bxAtRV635T|MrXn@m%fry65I3@4 z8{i|@=N+Shf@lZG`9zLO#SNpuO3VD^2{PcPafNo9F4hRrg{w2=BR2kfi5*$P?xw)t z_)SL^*Gv#OUCMAnwqle4F`ac7)+zkHI=rCuCklZT0T!^S`1O$Y4u|hQCx{h6eIJ4# zH0Z=#7;Su+ItaJt%8fmZhQ8c7q_>%H=_+_C9DmUS1)Xn;)P ze?dWcG4{;Sp~E)=^r(oflRf{-P3uoIXjMuJ!x%pG6&Bay9bOn`RoQPSnYfU6NJdL2 zZk#yG$>GgfZ{6AsDe{L+-ko`Ok&3gZu@6~A1NL2nABvOjX6_A1o|4dZ{f?E_tD|{a zI#{Hc4Ib@@4xK%INAU!tGaAQ+pkWmbdgT&94wVv8kZJBh-1!D?Q4e_q57UKAKE<<4 z^fUWs49l4x+xM_JYt@$>bCkn$FnAwA&S|+;^pH3R>_{5jdeP6UnvB3S4G73F&|K&u zf5J$O$)VAl!UVmgAgB&9?#<=S1_s#}gheGF3(v&m_V1~}5qgzhWM zgj1=D#jIET13>g&}L4L^U? zZ`miWtR>X?s9m$m`Uta#J1%{MQv71iEtunQB9oS5@jO4_7NTW()Dwe3d+j@|KsV{7tGc7F{Ekd`g z6z=WnCfw+30%IKgxjp`*BDch-qz~4)=^lHzSY-|rL!{YUmEydV8x>D8pw}^Jls+K| zC%70QczSM-7S8fHWS}699?eQVm^~J{Rhu*So0<>}t3&exOr%<(f2RGc>(jeWDM6a# z@#$49fG4crPn;uhhi0$-EV{~@0cysG3&*C2g~*P@zgU;nj-4iU2nMnp=f*=*>(Ob# zHx^%ov|ZHOq?mey@m3V#<21owRbNa$ft-GqT)zCr#H$Pq0dv3gSq!5CsMowBcJve- zZ>46}U|3-7nN2bAKk!xd+DE+;fYfSfPcS5`hW@!-;te+OPHN`#AKMtgdt1bwdF5Sv z5Cm)2D*vc6P04rTqEUSH8^Z8Ocf7O#^H^{f1o|Gs`8*eQ?}e0p%s0i{-g&GaX^_PU z{kY|>I{fYYd6`%54SKEw34HemnG=CeFuHUmLIa8C) zb-ElL1#F+kLzJefeRttn**KT+4#UJ_a0)&_KIUYQLP?*>f)FC>=|iTO8Q)JJ*Euvk zJQLBCF~IRNn~&@c0u1!G;as5RUmlwXkOQ&94(?;DW2;kq;EsD3tTS_|-x0ak$gxu{ z0b>@Q2S{&_1N}J%XULN(3cL4ieCoktj~D6aV5fi+|BwWDI`V~IuDnzSPOqt|io|d$ zdCsM5JMls*;e1i?vqjWE*#n?%*CQFeiWf5#giI!fPF=95qu~~FK%FtMHoKEf7k?=( zx<#)IxyXm!fl=fm^A9r_%3QYDk0B|a_Ja>=90X`Qp7yq7-REf~HJ3{qryds|8MN|@0-sfDJ2iFTM4swU_fL+V*zLiwNA-G#ToPgR zsu?c3+VrBR27KSpmmZSY;rOaFWmu}W$|aTNxa6xueTt_0D}-5ZS(3x(dY4S70?wBU zXcIv(+&zm(Fvo_3=jK)@S#g;FJeJlM0d)A`YUjn#Y9h(({aW55+zFy3xEU@e2K{>AK?zFo;yLJ`fY-e)s`t69+y#=8pm- zumy6V6F7K@4A;4v<|DNxYt36*qS$hZNIt{9_Xb+#4)?g&6&~OPRsBRJ9yU6Qjmp;-g>9&|LbS3j`4} zrm)qi`u4R|aH-esA91+ioD`0QZ+Pmz-rAao#MrVLV}rgXZl1PZrMu!`M8HN8cd~N# z&#Wi0tlalA8zSPu;2)_9hp9S39;~8T72Wm!Cxo3Luf|c@(P*MAMN)|zUoRWOY*>2Z zg9XJLa*rVo$bAk+)V@m$wbZ+obV)H3F zkwJptU(0OQ&zYw7?yNYys;IGb1dmS}_n}hSwqS=pDr+43R+c^1VoTb zpqZ=sX1wOkHEv|tv3X+Hkc74z2d`c;(g{)L`Rc`itanYNnsh-sRufx)j~w{7hH1f9EHu-OL!yr| z$uNogsP&>DD#*>D8YR>3ni~*khHz*|_*)nIAN;XaqiZ7J(%QPuw;EmdoSR_%fg=9p zbZscahGAM6w<&Tcec%2iqNAQPj6Xufb4;6uci4=PkFQ6pKP33EGmJTd>zp>oW~iDU z6&oMvut6d!Gpjyc=FNch1WP=P@`}Xxe6=dIYND>c3c}VE82aM9w6koy8lb}uU)TNB zJ>p~m(z+H3V_c`Wi{P8Uruj0drO z^3O@(Ofe5O$|v*K@XilJf|iBWyeS0n5$57aPcC16W4A9`g;ZnK3r8AaTK-{eJdq~T z@kuxNAYt{ueHLABlP$eG2$a^ohIuCJ{@}{%LXYi<0cdmf9lFkmUFJu`Y-Vo*2`Cwu z?k>Ns?+Ea?ew>DHXH{D}Ogx`492#vH1m{zzlhm2&pgRNECZGrzZKTF7c4b?5a+dCS zMCw}AuE5%%_I?Ac-l*Wr*u{9JKPS(dqIa^}%qqHkbP{?4sT5PEh&e#5-G&B41iyeQ z+br}vLPzZtdKk7Z`Q`vWinL1~%dHiRPm8fLo|*sG)il0btamzt1y?(hkLNe$U_`95 zcO9c@8HtxEe5xI!V7i-c*$Dik*v_C$Fzg$Yi}OJt(5Y(d^xoMfw_fB(K5(az zj%75C%1x3PQ$bj{(ErG}e8kNpE(n4qk}y#WJD0y*?>`^VRD$?vS7|OxHQ;Ov+jg?F>abXY#yG>Z1QcrVqtjL#hy7fz zc_AX-FE;lbfuR+_J>4f_)B%Hm8BMMdQ!ziIeLzy4viQV<&Dq@RUkO`vtqA zzqa0*6}0K0j=(Zf80RuBcXkgWXw=ydw=+O)W)jX;J6Ww>UH%GG-1H!XJp76vP_rp{ zay3KhTOW$O(Bu$zMik*bE;itd?$IX0^}a7DgceU*EnAe1J?9kfN2-x?!_480KQa)z z0u^1a(P0@VB8gg_%MoXtsvFf*jQ;+#k?WGhEFKPO(jlX79LwnYLXYjZMjb&~X+Oi7 zh)AY8T4!-gT38I4ITrs$Ds^jkLQ}XQ0l`gV_clh)0ub-)-j4*f@KTQ@h<|Jj_K#<5 zifgZEd$hXR$NT6ertfmm#A+1V0GaM?84$rc+2MNItC3Tpvb&zpYQX7-lsg^B4IBR( zHwf0Vq0oTnmCI6^bRA^)dZ0<$k#4?S`el?q)5UpLOKD%U|-!i*%XKEAtP4^UD z+}K_*2dAP;^_+~8JBjm5@Ltru3v<2Fh;Mo$xH4YEfSZrtx5|(ig$}Xfv|F7cLPIVg z=lXNR_MVcRNA9N!%j+#kgn2wLD@9;eMY{Q0^>{8^ zJ65cV^a&|g_;u~9SDZ1`o_e(ake)D}|_M zV6pB|n!L|Sbc@>V-88hH!J}3sf0N64o6*1dUKh6G`0#ZW$k`tma@2*x2AJ&CF^6jV z(RWHtG?y1_05*Ad{@QJDBjfX30)%#bt1*gp@JKt{{uj?v;ui`<+tGX)mpmub&8BLu zQh|Pje*bs}H|_fy1+lUF1a%h{2dCmo7C4?9*S%nN^7?#|hH;Jrn!!{4eK6UwU;x(R z@mYl}E2oC8rXZT(xNgG0&$L@;{n%lKH@a+~83DHBY1rIz0$LI7wM89Kd!YQ*hBsnH zx6CpDU&Lz>z~@tYYW(+?L;_FvcgNG-Z(DoJ%B+tbeujf#G?5LOE(+)y{?0Ms2I~)5 z8#^kQ7WJ>An8BQcgElU8FcI}ER%?S43aa)z!5H;U6^9&BkC z*8`C|aq~!e5GPAnbr2z)2ACD_T+dWRJ!F|%=4IPv==GfU|K{8}PK^K44trQ&J9E2p z7qy>#3TeGWa1?c-eLS$tuQU<5&Z-4CKNe}zsP!G>I|*|&fWihQiKR4>i3xT4xik6H zl_7G~z*JpMIP{*^#fI;;K({Y&$Q4IxU2hvXfIBpu;9MJaqqIXDC5mP&b z2u}yCe=b$9_-jL%L%7;M-B``ZYVN@S)GTt2Z*`)$;?f1tBC(s^Y-lZN&ETEAnKLfy zz^7(lPgzJTX`d}+4+j-SuvcM~J|||#S{#90Mp9pABL9B33T~DFB_DvVxkhKqt-BR#mDy1Kf*!b6}Y(DiR=ly7^&b%elX=omNf)a)=tm~ZW9(TL z8iqRiQ*Alt3%M^srx?y0lJsK_JneA0&G813F5@kwF@bY;{=NI9` z9S6O#){_$|wtW#A*l@CUy;_4rxB0iX;pI5CH4kuGYI^Y}t$oysoU3D@xlQ7i&31+YHLv(qhp$ETmslTsp;D$iO27J4{a7SrAQ4W32#j! z&KN%J&3$Gx;-wKg&WNRITqXsh#>BW;)q3!oK|K`@SB-k#4z-@(4$nD>Q#p!BV%5}p z4_1Z4j1X9?*Q@SGVu5iYEH@fZsu~ZB&{};Dm(4{DTXDUrW$(3Wr;|LLF>)_&{Cq_! zm-QrAueZHVJC4{ z^$4Ls=p`fg7!QqTl#n%%8gvj@4&%?`Y;JIdY|rEhgaj=IVil=DZND++HrBsIzR;1D zqzFxU!#LiBZ?o&1RYd9Qb7FcSL2%M-4dh>17h=p!GA(D&IOgEs;96;RHO&hlET*`| zL8Ii~#=A@pbOG)1eLVA4%X2if*cIkyNU?d++%b)d6s@J{dW#fM2n3r8g>OR&c?~Jb z?HE4DRr$%6)7Y_R|B-`dP z50H-Jhk;PHyDbG7Y{!1T9T!`b5~T$y*5SHF!QDnKa0Uo(HVAmEV9z1^&|1y1C0QSt zV;N>iXa!y}z?ebG8p4Oz%yjFlHg@L8@Avwhdeerhv377%72yIKEbpTrK(%puG~HQj z^@}Y`x579Zyo=*2H8iW;J!tMOtI#P62Mv5)u$VPHbxPPrMcP>n0W;hM3YA%R+L5Vv zbIW5A*^H~u0R`+xn+*}hwcSpsD$<;8^P5VuXYbmKdHd2_Z%-H` zADR)9v8|!uLx>P?-qqH1BSj~RyY^oHYEduP@oiHtUtALNG+$m|xmctUTcF_TNKh0E zmg9?2K`5lLaN!Rxg5XYLTHroK)d;JCA_PYDO(p)$so1wbH3>WWr*$DmByUvTiq1-m zT7;>63}}WtC782`_&@fxP6YN!pVA%PsDWjyY&q`?bqU}_x6Rr>cdB_u-_z$zT18~g z=0uCI?d3)@Qg=jFgzpN|W&u-s62~DO_bw;AUfbkFha_4>idju^_cDLv%?HJRID-{wfHfrno3&LIA89Y-H)B|w+52)dNW}C1Xsb$C6^|< z^7jTfBkSPr{_svoKRCFS=vLkN`D81XtwmLjepeSW#pBM*A){$O#s}Xe;72BrjP2lh zfwlVAaSikO#;prub5XFk?pW>g&t2SfoLMHvt_-#05azvjGrZTNLd1HYADt5xv>_O} z(-NSmvsi5@wf$4G+AXRe^bE7Tmg4QQOp0g^UIkKHFHcoEU}XMpj;t)#EmFN7ruQ7NIKR_cjc!Q{i!^h-8Tcb?^&z zEs$px*VgZNn1sE1Xn1QLe|M8{+Y!h?p4G+=RNc;*JV5kNy}xV&(sK`=(bW+W!agk5 zT~^#JM~Y1hhy5BFr<2otq0IbJ+f{<`L9I5?3y}#V?cCnyCyiM+U39nIZ^r~FRBtpd z=~TN^iCurFdklHe5>T+01#+}vtTYC35Xt8HWv|z+FuJ-i!L?t~gx4^q`7?SKu9~>c zU9({nVk_w6JiX3lrSE*x+6E68JJghkM!mwmO?>Yi&*Wo+HdxZe)+4}1cvOcZew%y1 z?p6os=RR{gTc{5B7EzFQT^dmLk=J_z=UV1+&wgJ-oPw49jYs<{U6{)>0vc_R# zHIfe^nV(eRygB!3gTyi?t5ZecT%W$%1)K^B4?cq^%s-ojo`zydV+r_2Xr^#)Mj?b) z7+F+>i5aS0xhSw;dp4=yPcFu27r|8M#rM1vw~z7ozl3gW0ZRzxu)D9F}d>_OO5p3H!f=eTHIHDt8?nJtIOOTFlJ?t==;^WA8(=`Qyo1 zY23@R(=o*l-t3N!!wyAl%IVXUPUI1u)A@X~vtg1Dc1MEokCC4Ei`bfrZ<9}9x6&jA zpm{{gWey9ZY~4oI)Eb;OA)~e=GiCMBKLQ@t9N(e0NcPfCYd2yEr06IjHC#gEu~w+2 zbr!|C*Do1#*1SLJgOztC^|7Zv&RS6VTHm&Ca-=K_!@5>j{h&87)r^^As^`Yh- z+w2Vh8MKBo;1wf=iupLMua$<7xW+@TTVP9KeQMkjzsSKs$P^Faw3W$7Nbdspf?Geg zjeD7zR3}*2@N+E6tLA0*&)OZ;_8p1!05427I~#LBOStstB8XNYWoYOqN_Vn4nxvKF z$?a0~N7IjQjy-MEq7TxZCr-0^q>RND+=7yb7AT!{D3@r;)ur25huq;9%@7Q9U}kch zLvJzv5&!VGp4RGrLe#GcZ{{4PYCm;1HY>PfFXE$y4Qsu@x>4W6#)f<51Ku<9IcmS` zzz3;yKpG`P(l03-hlq4kUg({aJAt*CgHfx%c0IX&F8^f@i7^HpMna=>p6hLyjJcDMziM%Kc?>dy9 z)j4`3y?$*@K`cKOTXB68$wp)G*Aw3PH zffwP=aCh!CU%Yzr%q_VszyuJtoTd9A21Xn^Yd;^@wx3kC(V8~OTEE&_0lwNQM;wR) zhJ0Q;TG;ojT90n2`Si*S<$NZ3|JG}RdSV}pOBIR;nNioGdtUr{JRT=ch6$xi7>KT3 zif4GFHitt|WPVFwE{?u~`(EqFv65#vPa zv%&S5(dy~o>RGf{kJ5oe8`++@_XiGhUm)(c=(i9;lH{v$UR4nH0sa zpQFH2*jr|F!I%X8TS~pSp!t2>OZ%d6jhVNG=I%b$Uv*$R=4A&hu-19bd7Tl} z8R2%w8>W*?UW|#UKl{uJ7iEGv8eq`u;F`K8Vg+kt$1+-rFvpigV?ovi&M()bS!5jG zpy6OMV9ch6JN6Li#vb#l19ROHD}j5Xy+JZIDQo%^uw=++fNIPYe~ zhRd6ZovlQrJr<=Rb&4~|0^4#N80-ZxrD}*IV8ovlaZVU7R?Q@LsQt`MycR$4*ZPSX72G{|3t`WFdg(8v#7K}bC--$Eu@QiXqsriKVriO04hqOLzU$Yv4#vtdH z-0UjX8P1vQFsx!@>=!s;(J>FF>yMpJM3wkGCXW6tXi)ukL$HcPu5oHJ0Jlb;(*@Iz z#R>UQDDi??F&b*4;{6x}uf@VOh_8D}Y)SZp!Re>X0u%leBPeI9SVLFEiNkdVtW6+s z+_+rQxxg3ooP(g}*z9i+NVUefK6zpSf9euAD3qf&a{fH>{lS||Mv|whPSSWCJJ9YB zO8LV5Ph$C$7OUmPBxkHEJ~&^C)%Tp|#8#h_X-M-8+?%%05@gCwIAez!yvv|ODvoIV zdkcz^2Rk+`>gR`X095&YZz#v0GIe?07n&ezih0SI0ya5?Frfeo>|^X_D7YFYD_f9m2g&q zjJTpzi%;~35MNTY8UQ07XQ$S5S+#qU6@%IK%$R$`U2eZ3$~o2?cd@E6&KFg%H-Jz zQr5;?&OfriM$EX8C(4BU!L=K2dl6gnf$ihBeY3dB8F0 zpe2Wj0nyD7cnc=K;$7~9P#&iS{*~E~P z(pL_Yj3c&ln~_!OVdr<_qAM~wmDA6g2mCSWulF4~kVpsvc8M-hliE-NtMQsU+@A;o zgOtflH)j;}%0rFd@U%_uH@mUsBVOYH|l76hi|bMR3B%(I<@Mz z>#Eer;<_*WvL*%es6y#=YHP}+AA$~ALA-b;4)59P47Y$g2#+n#6+}JOLUgTX{~K{m0l9z2s+uMCTdKdjDytKK8fuoR9icMkcO{4#yL$p`k^KaHEIC~< z0z7|Sk0wtTnK{M!J@als7K+Q}wx(kt-Rkuf<|zLSNbl1%5;q2(8o7| zyT#{@}N5}%%r~?l8Zo@-#dU_gL(uTcVj%C zF62v;*js;kASr!!-M%EnbX^te^riZ1A*yEmV{6dlID{F|-V!}~GqN_psHm%Iw)2tE zJZkE>!5Q7@Y=hEJjqu}V`{KV|XUp$%Q)4vNSOJoUXP^L48)s1_J}ZM*-LNA-d{%}g zEQw-N&i+N~EVoX*QddZi`}U}1Cak+eKv#hs`m?xlrsKNlq3`97d8t^gp=#^0ub1C! zqq^^zTsdPMqbQpO<8ZlJdq0@kV7jbVgB%-X=CLmHVsn4tG`@7X`a(3Oecb0ZH20)l zf?{JI7uN-1TouFxM&V!TzD654qyF7AdWI$^azx2~^`g8E5J6uhT`h_>FHA5ceRsh( zJA`Ar_U38Qj}{DgHXop49JzD zpxX&t88;E+O767ztWU+x6!PhvE~M>r7(avF^0$BYF5eX_VwH~KwW9`W3^a&-Ouvkl zS(*9mkF=FSqE$dx`K=71s8gm1U&8&=1AgNR#cO6XlKIFaD(|iGm{;F)7P)5;s~i@4 z!ksX+$h2cO4L1!X7Qb66{&};2YYI@M(YDRFzFU))nhdoB2PzV(-f0Z9hBLtG`*Rv< zzntSI?Eb+qPbc}l{3!$<|G#cYkf;bUEqBWs7+$_v(abLrrYJilH4xUtHM$$o>un{=SFO-2q-g0MIfYPlEs81 zpfjb&TJ-3wd4kz11o}F3@#lXxacbDlCvVaT37%yCTN=`_rQ4>V?muJ&aAsVn&L*lU zSm)LEiZ8JW6w^1Plu}C62s=MZgdpGL>JxpQ6Rt%^2H^D;du#<}udp5)ytT+b?$DH^ z&Jk4qBQasYU8V~{Ks^FOEHRi}7!EyL&Aw==kI;v6f9hdKwS#PU?aI)HnkgPn2n$EP zV;U{teIqQ}&C%aR9_f}tW@}KEn+#uDQ79}N=p-!b zBKNmmcGKEUOky0I%=`DN_19f7m%H2&8o>U2HrCHC0O~u|9lG)@ORNc7m@RbIpExQB z4$C?!Zv5tUgVm&rxNYe&+ra7j21Pg2#K-sc?{ZmBTOQlALp5)nU3dNL?>A_(HLP|K ze~(W%bO0pG-j(#OB4`05o_(T*XJWm~V{B+W?Xat4J==b(e{JV&k6jMjrussmIqvw9 z4-4Zso8JnZMLrWX_J^raz2lWk)au8vxJVcFH-McOXn~$p2SA;<>^7;!{0S&OoaxDX zoth!3dt8*QkvS}}^;|bKe`UtS#$bQNIFU3sJ!jwCmC&=|s!3?MW%J<*yn}TTi{fIG zboPj3vj|N;m&zA8H9OR`yi>EXt3e`Avpf*ovfqXV&e(V7b`y&Tjy(C8)}zV-SyleG z@4W4=H%=gd&stza`yjVJiPV#UnnUxxMif3jg4-P`{!7S0-#5YwvzeGCJ-t6Ecl$;8 zPtTz7Dp2W+8(LJ`>BQqpKs$}!H^f9}52JkkT`8A?;7sgwF>ln+7PTJQ0;}Kg8NYj$ zQ;YqgmKXN3unq2?0eyHM=|Z$POwijpE%I%m#7)%MSrpjYC8bE(Tj4WuL-xN1$x*+~ zcrWdNsOBI%Os?*D4|>E#L~E z9JY&75j$168yb5sg!SK5Mj07pB$LcfQ|!rrY5O?elkE#RIFcQ@@0Ak-GFZ^iGBx+l zhoyiTnAx^>%3$a@Q3R9I<29Ax!)`$5WakHizM}Dnr=3;=3A%W8>CfsE)1E_wOD~x~ zkPnXIt{kZtvT*&0oxCV=YCU2t=6o|(vv-hZW(etPq^siQu3c-Tu4v71MdmkLxJ^>n zt2{`e$ZHM2a$~a>Qr5@OG zUERQpxLF*RRs~_CC?hT-g04|_EXBYO445JcjUbB>S;La9xJhFs_RN{b2rNtx78e*6 z%PYrxzg1miXLue~KF13Vkc9!jz3*Gi7{&ZlHn8G!BQO9(f)V#_CrE{K+|u88Fb5h^ zupbME?dc@8W#}U7(R){|))3HQT*MqxA4%5hL(-F9>W1X2WRT_ zaV-o8CFp9SccQBVcH6H-5uPYoL22)VnfIN}Gat6^m)P6b@WlaX@naSk7kK&%N{uFk zjdhkz!(gtfo{8X?2pqlllNO8q3GgCO4X6dF&QN zm|v7b$RgwxTdwB`!0kIR01IN@55MB$7KW7&54v^8%QFWw4E*z)Vi8`CS)tTRJpdEs zH*atnEaIbp;W@bI@>Ox%agevwT6jr3Lz^zw@1l0W&^wx}rhF;gpk3bA_RPUJVezL} zz+n6kJStwnO0%oT^>;0@_4XoE`JVp6&ikX^_@?NjdO9{5O216N!G&)^9*VK=ZV02SRK6H4bi z%Z2Y*2Gwn)@S*i+j;5a~1-MZ1QT{GOB^4zO~uMYp>jzUu59T z`|FGPMjQqht@ZyO%ifEQ-gW*}jB|=1mXCSeU}-<~0fBCiYUuot>pDwOaAvcM^!w4# zT90K*($F=Vv=lL;MxK0Hv!wHvviZodGiP^7Iw(%BdEKbwCR!XMuZ<0DG-%i#?~9f? zclgr(4*L2=9+Lr7OhhMT;CO;}S@@kCzG}G7X z1jrx9*Xbg-{$^x56Dd8%pRI_^n$+qAqSKCm9O^N-==rX}2^{{|VP5Os;XKw{RtfZ) zz6oT-wb7nw&UW?VymoJT@wFS^>Wd+U_Y__4;;~qN&dtR-rX`=UI-@teJ}_U6UyH#` z4an|Rb@jx=^fbNIcaf8iQ$s(Tn`Su~pS=xAS}@sI{nHjju=9}DvN zA<^$Mu(?zTz*Nn>tks7p2B!Ph*ur$55yWFeVGrrBcE2B8pZu!{WZtr)`;3zryQc3M zVXXyS_gzuMwQ6p z!0)S0V5=@F*Xgxu6xXFQ!c37R;)y%#*>Vl4bBO{B#$VoeVKwDby=c!U+tC?admj6( zd7oc`*1RKk*h`zU`zXEnzRsD6??Aza9?)~rFB$%bfDz!3fQuQiwY@@e&!^>{h`n%t zN`H>+mvNY5ksYxu5Wg6LwpM#?x;?>@$0GC3ALPVVu*OC_#I%QojAoaj_K{6u(u^$_ zj$~4h7y$jpa+%oFK1DR;NH4I;1l5-es)M@l&&2by@BdwT62Wxp{w8QI^-v`1O?~o|GUFn?S?8;fUf-sr>iP^E8q4965Nk(}>{L zi%6C?t|Y@7HHU5ZK^Vd1Ut?xzay0zZQH!}CW&@It4?C{~eveL;!;Mg{R%BCd3pNP+qnlE9RZ~-UmCo;bxyppCpXx7SYyjA};4^P5jH35&N144TzHyvCO63+3OimRV0NVn1C-LEJeS`KrfukyW zkk5$tzI(gfv@Rwr45fl(J-%FuLXbWME8lz(-iC_rcU(el{|hnvlNwf9wwxz=zx?7$ z4g4{<7W=1w{Ya*k3e;B{1B`>0UvdZ(AB!d1`GpEl$Tu;!Nl=4}Of)6GY6HB8F(AO0 zM0Ve)HtO6BHk%|is~Vjp2k_)i-j9i#6L(-W*B)COgM&{&LrlIq#D&t^Bk$f`u0TFy z6s=MY#Tq9nKcv^AkOyEE6kMA-%W!Y58CYjkm7@&abig0v<)YMAa*u25ZLZOPs!FF{ z^z;F+JLUo>+COFp`y5a7Tidli+1sMbh{PV9M;|UPY)z12b{(qDB>vv77z$2@1BeW0 z{?6_>bkTWxCgU`-DpSf9gU;en&b!E!-?lvoZBrs2uK9RWq8UToqrDD2`Tj9dDlR!$ zYbU5bT9+WP8pMiR&mcl}XBv#TaI0+wK`7^wl^0omk?5*;9uTIS`i9L;7|6;C(Yrb(+83~JHQTlH%Sju-vH#E2 z0AWC$zhIC8=M?eBs{Y|_bcP{8iD5Cmh&32Bh(zo*bj_Fj7bRskf90I2IceEl5|iEW zmBH8j|D&R^8%HO;U;hlu_sX|C+7DkZJub-zoc!ti@q%3ciDQeYTglubo%`aP-o7_L zVLh%*sG}n+$0+{cymaJ0T|G$iHSESHV$4eg1<{?^;*b#qIOkc{Yi%A1i)|a6`dKB)D5Fy~j<^ z4*wIdzg>Jky&r%&;=vCi=$3*9-&bL$JY8?vK$!QDH0f}}8qC^tJntn&lNgc*XWMH} zv^(?iz%_%5uW_vs?EL3LGh&f)Cs{TFibgG%S;K{;-77Ua$QgtdMT}~{)~&1g$Jh3- zX+1cVdK8VfJ7QVCHx#A(`rkujSaoFoTHU>I7lmfdTAbI@m3m^mNmgGS8Gd}aJ}fCV zElSRptUoWzKX`cMwRQG`Gy{K@&D*eXy}{zHg^KR z0kUGaUD-zFc@WB>lMGduQKgPkp+2#aF2-nB8-}hw>h`5a&TxDfwyNl{fJ?Pome8M^ zK=nAe70wVtkkH=AFJ+X7G}{D7@mOXEBj1;8$gG?#SE+mfn{c-zps396ES<52VbGt@ znjY)C1Uf0DAIn;qU6kAam)5hqb&Rqc;U8t3%;fKRC~O9Fy}6-ou;8<@$AHFck^}XK z6T>XI5=RA}fr4bKJlE}gsHB2N^T#6w_9+NDVwU)1OAgA2SWX>C3^LTcZubSEU9ca$ zt`VTo?q*%Wkb0ogSfcj^rOTt^WAgPb_-+iH-98H>oG~Hk+O=SZePKs@H?I2G8uY?O zf1-|xZg?k{D-}YaUv1=Ii$4Whgc?kRV!{gUD7uofi}yGby|PF4-ri+hydIO0SgG8M zaT~a`p>HyM4Uo39eY-k3CCV8R^K`WwcNsQejff}pO?qU zNA~Yjr3mG4CfvPCq@P!oMgFosX{DRLx8xs{2QGiZ+7P$pXZd-Fh$~J`Omz8by7)ZS zwrEF7ZD1)u$}chOJ>=F%j!!-weom(rW#4?E$#$m%8zY<2WP|q z<4%6&F>FkCf2@5O;B5;yUh0Teg7|2 z35VxQHsTA<-9Ee3DyWU;fmipkk{rF^CwM{f%kYU6GZBrsV0N_#o9N!}q~C=%ZY{&n z1HV$MJoditcisKnfHBbyg50DBOGmuFvu3geTTS|%cA|dWgF&Y&d@Kh=>7Xw{tQ7UO zRQ2d(T30DDp;x%*CBypde&58+tiSh(_Q_D(tdl3*yyJVjF(Iif|MG!tYx2fJ*BYSX zZjX)(z_RalkRvB-o)pkt1D)wCt1_D9?%pk|pqm_?-^q4ys2%IXytH1-C-Vj&cRR)2 z)X>ZBZKaqG>z^{0i?aRYIgQdm`<##2as7rx+(%TO(0wQQtBoTgv?MfE!oew@mrc%c z1hDhKi0syElzcWBy}<78bP{!EeZa9HLHnv7xR-K^u(9iLYlDv;twi15(fzHy6+9M) zIMQ#K5s*mh9_6E=eartet^Lan(8;@|y!^BKRwKotyQk?!(U)(-C;ue>1}f3ENPhXz zXrihjYh$deiFtR9W(f{b)*Q$Oem}}+gRXws-d&?I5FWQIMV{XSZbeIrTlq2E@?(5x z_g>PhXi8rn72`g=ah#;JvTtt?A8#I@r}4dZ(B7}yd+s}D*V6`@qC)2MCkb<@I(T=} z`&XGV(%lB}Rp)sW7Ko5dBQ*dI@9iKY+z_BAiMhNcf26~)(b8-iN8Ajg9ERv7x*HGj ze10WU{exIs9qq{;yw-F8?_!-xv1X4P>E1yRZmBnS5Of?#darSjWS{mhn(vq3X#L}B z;SdAd$f(+OZT;QoNyOIX+cmO9rI{{ws@Xx*+!<)NS_?>$Oo z^oA{UO}))-M#j{1H z0&wSqcXN1T(knX)1!rCxk2_lpqYK0LwB163?u&2Y>rcs8khJhhdng;1i^-#FMYgN( zu#fvY%G%?$Z?*HU8%-W=-Onh>OPcnUd!Nq2(Xb*MfmqrNuGp~s{pPpO_yaxGLg#o4 z3KD)#9kZLkfKNi}1rNoB_1={Xq1STW5waGWNKD_NNps0^Y%-2+o+QqO%&_u1=W#UL zyS%zD#A|3qYS=v)eb~|0SuMOn*g=~1FPHi)eqyPUVrX`@tf*KPo7_aYBX&=sZZLQ1 z41%M#&QWdT zj$OePo6rw=XfvlzA4Tgy83OIODa4|J@%yLJt^Oa;Xr%C4-J}w=nt96WIKcVG^39+_ z@``#lPfh*~=(Nz|m9CEX#wJjpneOeGKFNEnhd(okm;!C~%0wtK%tQuZSp`*G{)c$t zJ$bwF;@<1|2bA|4A&p={ce8P3JcwDKpq-|tSLc5tqKJ!UP7!`WWG?f)$T@&l5^;9~ z6Q;Tr%M|n*Q*(`q($-+(GDDEXiOZQHLa)~uMb*tm?Ji#Rt7` z7~dM!iWKFst?!wb#)|!0!K_EhOp=M9KtF-J(4jfSUd{EM>WT*I3Y=s)L_FZtti_8QTnqaox5)F@%(t ztwM=b;Ar5efq{nipoJ`~by3=AXL54S@}Lnc>O)`ZPYOGeF2img7UD>SeQlIwGmcpI zKS=B1s%Y(f2AXWyH4vlAq8apOwf_6KNV0(*(iMCi!uRgrGXL~!h#CbM-H6~{TWzr2 z(>?>qv3oMMv_wQtjgywn{Z)E2x3BWO$&cMOrJ}zu`<he3Aut{zHkJ+Ix$RW{~a;QtLwqZQ3X#Gh3 zW*V2na&K$@@BFhKA?Iwl;#=`axLUSocap3TDNc-oesVy1pgfk~ZQyTP~ zxf6WaktVO76i&_KruKntMZsrW`wfs?{y?j2ky&vqw^DTuGl=KMnxoRiV*I1mcYd&o zthD{Rs&V)Z%~h0lTVs5QHfU&L)NoWno-t1%8wcCsL&=9L12AlO#QXFExQsn`=$7V% z=6Qdn*8?;E96mGJxY|>QX3PV*Q+TEqFcC#+I|nVHqJtSmRH_fK>ze*t)-OLOLY@h#^`hQ;TGbIZwOJeuilhoO+f z<8n+O(RcvNtPk|PGMHpj`vHY!>-1m#4#9tXA$$wH#ARpZ7NnQA={3Q&98q_IhdRFw z}M>~?>O5^T$)m7wbu}#t|L1~GDD%zbgWC>xG|@_RUD(-4Z)!J zZI?3YIXhxuPINvDklQ(lFzZreYHE! zrNay9&ks(bJs>52DBa%Ut8b>}vw<19SMw8DlpqWdz%r-Gz)7?K(z=%wmDesZKqAmM zfbM>a$!EJh5_CCA2FETk{2?$-LJ@5c3J>$S8$kpm#v{e?ej*(?%C99?aG4}Hgol`t zmV^Rv*9S0d=eIt6pfeRs!%TuWmO*oENr-!hXPH_3#ND56SR#p4@J(Lo+2^M3Sm(FYl;tFE&W?u0#EqRd@wTQKS<& zeYpMh+xhX4Vv&2tW*avKKuqC9DB5Cgo}MFl!69?v`lx`!_S{TrhApQ75)7|g$1hw= zPS9wEZ=mul!bM%9ssiLK6j*sZ{TtevR<~V~FviqVjb^VOUM=mwOGA=et`@Xy4VsuK zdh{$ylLe9cLXG%2b>Usg_lN^}ySX!LC1M)Ot)}tr^Uoz-ke$IPS)>Udd~pFg{SZ!h zEa)sRDo+^OIbXT=Ih>ukFBDwa7}~;S!of-m@B9wI9+sr73WSsWvS|g_4Bp49Y)Wae zEA`!&jCqGn+3D@l>SLh|&o!2co*Q08+x*ZT^v3CL*F54AxpN=N78DgmY?EjD-C(tv zaUnu2rIxg5AiY^2u^6xEZ~D-9>`cnr6LIh=0=hDc1kJ4Qv)lZss~2uP29T+;E!kM<1d zf2=h7tY`oD(`2uuu>7qcOPnTFwk{JE!t#{Ct;YfTaPm8MUx`cXiq57(A~(M*F6~I$ zxaU&ySXblGX}9|!1*~l_(ONp^GYuJq1h%QV7C&tjcdtZvqwuDIIEC7ek`}7XELR&; zv&mfSf5tVI}kJ-Kq6cAQM;Ej#q1`cci)`2fF6GfZ}eXKt_`XE<;eH2VgxfIFB zx;Oc8Dg_mw&z1QrV4`}FfHdkd8H2SZ-C&Xy)>0_%*|nuY>}x2>p2c%G(PHgfd1y#D z^Sl!ytFp5bZP_}0GeNy-YuV+|(E6)}p^(%9J)x;@{r8}^ypXse-Y%%EkEVo(^(rdY zSR6VfMnZCNBqe5rXspFsp493I%kV-mX_`!A@encj*zlndQPF41;cz^32dT-M-w z@d?=bx#{~m%jB|q@G|tx(9WIn8*mGfM`ccpoVY623>me#-kmgQWTuwo^7#V30mt=U z2>zkG|9a(gvGloBO5Q_Mv@BQ@hLWqni!YKr1ep~vmv`JV5sbl`gB6VxtA~q>fV-S+ zWOGv=tK9$TayBllz5IoX`4xadOK0Z4s>m>ax5Fs6#A9(kJg8_nbAo)gkoNCa=9cwU z?LA=7cBK1D9GnexTMT<^OEQ{)Sco#c0{k$ySQ!C&azX!QB!7oY=(RCvuerDE^_quk zOHOSvmu`);#@^R7omGq_n*M>kA!AieWQ>gmA%&XA^D3o;XkHhB3OIoc=N-GazrhA+O35x)>!80A(7yaWKrx$B+b#{t=C=LnS2rZvt8oWI zZcW+Bm3z?V^iF!c+^iY*dpxuBIQ}hbF<(#?gIsUtWdI3pBS^4QWUda@K_D;6$gd${ zn~Gev_Co1^-JU>>;{VgoK5)84Fch>&MdmC>$T?6Z8j0UlvXPh%^JV^Wtt-Vd8d5YN zN6joK6b2vr~TAZ|%lD zTI)aCxJoqIc43q&Rc7m6bb;4*ul)-oKDtwF@$4YOD9&oTd52kisR#*HP>D>0BBN;O zL>3C{wxo5MRlg4)m!0S)`3l6Kc}gM@`t)saad9u-iyktEok^Px((s! zI3dfr_XS+Q=VAYOh`pZ3+OLuRda3rdJ3o)>vk?5oXa1I$FQV;-8&0R^d80?Ufe^s> zZj|{#Zp+pFm-nr?<>s3p5P6}_xj7vqGLv8CKLh2;v1GujOVN)hZ0_n6lsxvmz{rrtQIXuj{=)=WT{er?$_^_PjcQ zj~7qEP4k}HWjQfX{&r(V3j|Rjb!6EYaVx^pENV6`O~p;>em(9=uZRUBHIdx1K;N>jn%MP?|4<*#?uoya?bt<>Y!dmsxT7HW7_=A7V z?w)O#W+Jg|ecl;j8fLeeNdIAmzw+9sACb@KCvdHEpiRqkzSD%fH=79{SK!?Ztrm^{Zm+a!sQ8TP-nW`=vr; zU>0zoh3;Q9WPKo{L!JtqJ5+GxiTF)SvR5|Wr_(L9^up_3+{d}y$BtppAd&O?op9>a zxXn}wq~33wL@^gcGy@gtly5ZY1g4#8UY|IHLXotbxW%M=FP{}_(Z=2p@iq&l%znR@ z@?o2n1gIjYu#~-fWr&-lv=YsZBig&76yF=`CX&YP4F)KKUFc4IlfDsX;la^`Ejzpc zUc1FQHUk8VR>*Mzq5Li_Z_*MaLyc7Cook19N0;i7Ee;0gSon(5viLS*qO~_zrd~te zyl(5~AgOOz>bL8xYh|nc?GI_WVPJXdy3OO`9o?@J;I>}z;jlysXxo0FA=<1BW6F(Q z*oym5w51Q6y4SwAjEksmx7`e43SSh6QRdiQazIwQ5tRKIKA+qiUlDEYwA|PTTd{;H zuQx}ct_w`3|CMFo#8od?B#r~CU)c3>o<3!x;{#0{3C!4d=Ud@-4eT1wwJGSZ#2_lr zn!%-XiB#F{NM56}Fe`|MHsnYhQ^wW+3CmPzkhSs8`#yZ>``Vei%jjKv(k}Td6GDi? zVLtSVX=h<5Z5*Gy{bhn=f-+X29GpT?@^XDQxmh56_7J>V^I;5f_dKnSFyPwBTlIn62C z1>#3vy=wxwd>=A0vVYy$3~pVGQ0+pE$AN{R-dfL(H%a>h$rq(YEKbDo>kP?FNhce& zzhT8zUe~=~8xSUQVm9pITaPC)fxqZ2YffxOOyZC*k- z0|pFcLr{lQ^F3CCez&rM-(%)8-Aok`!5-ZB`6P-6yO4X*sLlisTaoEVBf-LkN8Pa3 zz*a-Pf`e_t{^n~N3f+V-FWS{61K%-h66Nkwx!%*mEe(vQD>w<;(?iXF^oon%xN2>rNeDVUx9_nmDgQfu-J45G6!}+M%XnrkSSH8Go8Rp zb5v!AEDhE|*2YIA66wFXn+&ymo1I`aSr`H%k>)y-yxJiz`&68Q#%cdih*?fo#NCKQ z2%b?-o37@VZ!G`ehMYoAv$lfEs18gk>J(=q9$(BlxB`k~Oa`%Y>t#r6{tn{w{aHaJ z+^@#8=pv3#og-Csg39Z=)+N>{OjhrR3B z&e+>Wjjr%y8C`#9*DcS`?SFb3@77#+^jdrTN^WUAk|BJ9toC(&#K^m$i-7@MU`&ew zq02Chzz9s9iaPVDW}N_*y%C2~Yg;18fggR!ADdXO{|3`eT3R=l2#r1Dy4D z<{WR#L~P^yI%CGLfk#$dewjgWT(Awn*teY-;!Erd%x&j-CBkSf?R7NG=vstfUwn%i zy(Mn0I&}<-;|s-}Nfrw~rKMf8e_Bv)9H;Z?h~;6~_8AnDKodtU@$~&n3p*I)_nS2( zzBL1F&xu#&C13<4(OtiB7+6OwhOTQ{c)Tpw5R?hJF1;18&1e{MNh03X)mfyDD8-nk z3BQ&~01yuH+C45$d`0lJSz$`)GJocQ@`QSa<>>+kj{bh|O}Fpm1U@T&CcEGYB-4bB*mhk0VoHK!B5gF+DPiI}Ww~$$nbL6S3SNDgC zrpGUupR8oku&7+G34pR;EqK;<#w7q7MmB`3jp#23d@re;Z6UvX8Qkcy<#kG%?%Z0Z zaj&iBmc5vPJ&$kf)mUp1_C5zN&`yLz@$SnM-2RFEzC^fQpm1)?25ymGlzZk5S5))k z_YkyERlo+3dnWF4brS3o+fi+FeGPNLx$@?-ixq&$J{lOd8hZ$2PR%P) zdBw^I>=Kgq@=PI8M4LtBQ`kkk5QC`vPgaaRnh`kvkt4{r%y9STf`2Pt{duWCg}1;k z+Ge5xgq{Y$1N26{m&a5)F$a%8Fzid93E|JT^!ysn$AbrtP=~xn{knj&UtaZDnfn>w z%nRJkEum~(h0jgaGWPBEyU!p;HgH>jhU$2z1L3rYoz6c_>~98+Dmh&u^KtgeQ+(x_ zby1_$L2)yJu_!R)Dp*-xwM%hd`wEw2-}cW6#_ zlTgkKU2$TLKC=B0KkoVLJ^N7u77zL3^phiHhx3%p zML})bF4c~Dpm4Axms32oQ7d(ib+Xh^9)59FYk^#}xg-VuOraApmZIu?Tu9q-XI+?ry?yW>1+wQ^XX=op@UbKOL{vQSH^EU(||g86vT0E+9##w2=4suvtFN zmuBOA(qiB(YczulNt3Qy5s)YtUebb>zt06oX<7;_eCasm+A|LR={9%Z&{B(^|A*xt z2VVY~R!{fqhQ{Uscj^Dsg9BoZvvr}^B{4-?Er>BEMQKB*;rQBU@10IC>2&*N53U#hjDV7@O!*y-lbLCtS- zd^B?i08&in@Lg_T?+hf*D`oAacur3r=wmHmPUn-3#Qopf-!vwzBf4A5kf$x?cFeo% zk$>ll3k3K13Lj1c{6Z z6jkIva1^v=s!~}fae9)v#5M@eE zygOdRzj=x&3FCXZ`X{YeYG3Z?b%}?DW25VEOhL^Vt+c0ee=sQbmD_PP`iQVPO*QHD zSE=u6KCdD%@etE;)V9F7vChveDisvaM7pVL<@cwgT!@G{QjkFIx8u074oE{iwb8e5 zh=D}ZE4*O+ojg0Wj~mOc73B7mg>npTJSEL=x?H~73$0y0gq&CyRsp>Ux?0cUO1G?? zPU@6S3EJH8O*n7=vud6p!#SbLzOV8=e5Us)=xz4aQ!WlZip8mY3$6EBcsbhTJfvYM zusq7!BV{c4{N2XFZuq29lCV^lXi~%06+=pMQ*@y$pnhB|f9@R`N8SaH+f#IcU7nZL z@C^8OI;@Rocb!=;^+#sJ6j?kA(zi~d9E#FHln0UFr!&SpySxOhRid}FWfkl;jon_{ z4F&=-vJ>4{5UXe{v7lIO-NhBWU5bNu@i|I4_f=#5CymJ!C(+Oj_|yDPBlr z&ybw3A8CWb{}w@R4pKIsIvPuy{e?o2dM4o~&N~IDMzl}UJ5mq2_x4JVtV)}yvam6{ z3+~bluCH0;7`sjR=6yj>E_<;<0edaIcd;*Wd_MltW) zV$=x#`2xO^5-$1^(4m@8_a>@qM7cO7->iFg69LP9fb&>o=2G(EI|Yzue&lO;hK?KR z--dGE<9<7_f8)+^KZ=_^*tIAH18L_`wgU2_^PV;PmJU|vhblL{R%mieH8zIy(XnGD zv{n8;U`UacCH@qX%)(4Tg=!M;vuJLB2{c(6m$e&V?&#F?vc;gr3I#}2mpKqvkL2Y2c+x&y ziiu^7Nz1qM5%52-EbOSU;Q0mvsl5eBZ!%$jRU;|ISc_s-$K+hIpFjH+6vw`m5!#sJ9?HzCu{Zz zCW4qn^=t;eeviyg`Wql`XTtVqaxhQ$94>VBlIIv-XE~6H{6;Pn{8lpOH^1M60UrKq zlSe}?78y2t#BMhO0ZpA^QV=33tO6v!{#~2M20Ryp=&m2+HLPW-Y9>xK;d#|0-Vd z8%cu=NlayJpM~!2shz9vuY%c=T4|UUM3)}Y#4QXA%sAS-mAJ<28UOLZ>4g_j%n##B zZ`$?9p^dvUfHxh4A0+oeb^)_aXgI6xlvvv{%bV$ySk7`+sGatex2&;pY}*>GO{HSx zR;w)ryC5icU%{5L&D$&x(qhnI*+tEnFW#beaDV$cr9<>qMYL`5U!y8RLr>%Ec)U-WMnwCcd-<8_ zK$3T+N%sS{hnc9U_iEnVN~ssI^Hi~XT>cs(M6Q|@d!qCg(6$D?1n1sKL*S>|ZE3gR z-nW)@dZ^u&3v$zMcT&3{+~h!`p=dHOeMMNYvE)t^4!zsDH8dS{tp|sPx9PSy^}c0a zw%g?G1tGVNg)pB*g9^x@8~XLp%WA9B!AW3gM$g%T`5=vkQ#S3T1k^hJcI*$bW2d5L zYeQ0}iO4r9+-VwZB`XI~H1fanMcLyYB&N5uVqJyoFIBOhR!l@<3H@rycls%a0+Z>D z-cmrz^3RAdNOS$ge8YDyI~bTR5d|YM;5KA@cJv{N^XXq7U-KPvFSPlx1EF#{zay=- z60Tln#COf^*ZnBUq2zpc^^4I^26mW6HmO2OMpkyEU0pvg&FJE>v9&;>zDo`d8{0>g zwn+I)M~$|ufYOz)w5;y6U${JLJww47S+?&wA z4Dp~?;%GHffo&}ZiqKYID%J@>iL15->+(Yur*|Nx#Xw*tMJB#-spw3AnV1|ItU0ot zzINM2%J0Dpu!#uGbO;oIQ55OoQUJHEt&D(Hj9uf1`L0Ed(BY9>; zJ(`T>H-E+0KR%eH#@@K=I%7)9LLgn+LCV8$=<3F5&22Ps=9$tV9=(0VjQYOev!SLP zygV@dfNVJI8&{=NDPkz#Cl(J`<-wD3LHaNs4^$=R?|iYG&r83LpPrFJ9``~iDiC7H z|2)l$-A4(t&7BWS`+*OflZug>P9B+z>>4pQ$KlNrG?FtPu{^vRakTGmegPYpdj#Zy z{6Gwxmy}IiS7c$wt@?v!i)x{N4{fJOpETzVO31JGj80-F_C9kO&6Ezj+jG2 zHVs2_WbfmLP@#44b4!Zc5%b{lN?I0s^18xMsFP9unK;M0tFexDDju z2+kqUE-zbKtnBa%*a)vP&Y+Kvbo%7)SpSo(76*kE|8#9RQBgo*_`q*Dl%bb!|{lI}A$4?1zZQq-7t?q2? zR1%B1b~4R((4lcuY!WC`zD#TK*dfX|bQjtZ#>sFj!!b4_cg|Uv9EYQr{ymM?-mUeN z`Jqk6!3EuLWQR#C`SI;K4G$0#@06)!Gj2>7E@muD0mP&I5r&eAgxc`Fm%l#R{8c_G zM+cpK-Jp16(7~u1Z^0w`af*D+xkc^n#(sFa<-JH*#Fy03_CXxp5SnrMX#ut1SZ&qY z+Kt4akNZyvz>g^nE|RL-8U0W5PjvtULH$?t)OB9*ZVB>c|GCjWx@c4I4C;wf`805W z6z#w2)S}h4WOZU~v!*3vt#;U9yHpw?vt>aRBs8mtW(s+MCNW8>iIe4P2Ce=g~umQp|~(ZU~%Ot4o|Qk|Ne$tRc8 z1ykFJ35U$W79$YX!li;q?x)7o(gO4LqXXGZC#-bH1ep=uO6YhOJv1@dsVs@M*~iA2 zSfMY?)&s~0ToZo_#uBD)I{+jR)ZGNdxd}>vL^aha5TT%4Dy8g5jBX|nR3L71c5Cba zix4BD5+KkbK3~&ZhpY<9Ibtw5 zc<%2VSiubDuIf{Vrvc=+oI*7X8!(u3B1owP*=s-?t!R*hX*+hHXA}am7%>7~n4ws@ zGqs8~L<)iumCO`vi8F-N1#3uQvx)lKI;2*y&n(&AFa{`{0O*K#!ApPuu=(Ul;%n@-!52(Ha>v4y-EMN(5|>=! z@>-YRL(CRgbl_f31H4dFP#~>}z_k>Du!~Dh8Uut>a@fM6!&or^FsjJ6{~H-h%|$8% zikujdQkekN;tDWgO4(GW0kMf4Rx?ReyZXZY-a>7jdiGm(JTQsll|5bp(UWB|UPTo`+wHEkKB=WK&s##LSpnl3GR3T1rM@ z@*g>qu+B_-@da-fPp^oq$=GzK!zMala>*ucQ_VUZqYnc^O~k6n*Lu4ej4 ztO3`a>*SnXkpn$d!0b~Z3vSfAkr}1}Pxz9Hgs*PxCr(|?{keKkz92W2O?Mh_HCN9Z zS2SN*1#|I)9@1UzV4fAe8TSQK4tV&U@eiV;kNW^}i0kHBm@ZM9Dwj+CAWA92V7hQ} zJ5TQj?|$&?Om^@9#22X)6g7zPHMG<*#wj1kmRQgl=D)ZyxmjW@We0DYR@AEL@b@k% zpc^ZQ#3C9a78Dvnnyxah(LY&U5ae0}1!9Q+-Hp(l8--mYvF+sHDT+oDp+^uwl33$^K(#>w zkwCdsRJ1L85Ol^R)M@mwakc0TdG}6FlwWeg3+?t0748MOL2QEbNFi%@umB6CuqYwa zm+z9t>BPh)f+knwrD#A%4?O||q{Vy|F$zHRIfNg+U)qZ;+r9Ws3h3p|=-UU&CEdCG zRtF4F5<)PV#O)Xz+zXO8M5ri|klKWI3zN}=vNsVu!lNx#vCp}rKtu^SXDRKdk_B+a zCRXH7=?s^>6XAplI+-1IG?>IPb?C7RCOJT;*`@*;R-nCmju6h9rsBY*JrE*UA#0RB zs6K+D=MEZ7SFdu_OM$HYA38}2xP=GkO#AMO43HhR$Dp{-LOXu1 z!=^e7=z6;8Il!7w#afI&z*1uejt;qjv%^j9rDFdg7d>7I)qk*Z_J!%(2|Bc52a6AG ze(QTh(AKX!4JjIhQm2#IGO@y`SUU$6P@bYdY04}@VUFuKO68bBjLn&tnpD@tRxq-2 zZL+;1b*~(K%dbjnC*g@)7-k;n{rHwg9^X6~Q zM*H^LIPBtjY<0Fdk(`j_v9}a1Ufle5JWkRF%l@wB(kwrboWX}yd;!voZVJnCx6!(u zl#MD@T9Hb5S{B{PFiS;OLwnIUS4Zl$ze>EYBMUd!SYq3W-ULci(nIF zotG}c>c3^$mG$y_Mo;odSjeqicO={3-?}|=zCLw%LOCb7pgChb^wfX#h_}dCmugia z|99thIp?s9Sm!R`(YmF9LtE(xVg?w-fHi(Ynpo#m@k2i7*;rjjxSqM5muEG(u5>*q zi$>SBdf-yCaw+eWwX3JJuo>4-S{mB_9OyS*C)TDLT161V3^0t5_dAF5%T~oP#(t-8 zz4KmLICZFM1~-UL>4)vZ!Kh~7kf!bjdZL%qM@}f0L*BAKl@Pj_yAA$#SwrW3=5E6Z z*j~^#ne>2aW?JgzR876_+;(UjWRLZ!vAQG7JstnB_D^8&#H6y*dFVPlGtxA3GNu2Y zjIjX;4)*b{cF6Bj9V$88wqbYFu*1VxyE8{mj-uyA!=y5P>^FXU`Q*#s>9PT|cJ|vg zS-n}6&NV$**aA!3bjY3BPVFDD6Wa?bM;ZK$<>O>5(xvW%LBtftkFtJ%FJ@@k?jbT6KmHwiyl?QNPq2l`=3A zFB*@eC&<$#DZw)4H1}X>)CP)<1t+^^Y{$6SvlVpnfGFYA942grGn|#2d|5kcj++l* zrjiNU`mXEi4V)Ct6D8|r1u`}f^t|nnsq|CM|CO26r5YP#11UMx zQX$r90pKQ!RupjBV>+xyYnw@F$_viCqJYx0iV-%IoSr1u5YB}DC>Z-uWXUw;G-3EZ z(F;+Kw}lQpG#C^qSO$kteW8}0NsAJC1}vG`BR5mOmNexKw1ry@bP}r-MhqTWeKF31 zu>;5i-Bd8r2Gx5AN$3K3k)4g%2T<>Lv-q| zGeA{g_{bb5`e9s`%>2-}XKC%HmRF_Fm#qKXFdoAAyQNl6!+5%q<4dQkGLNU{;+YGp zXP5Di=7#0dWPpB@uSyIEx*1>?W67|9=JFM^i$RUhI~J{>IIv_~Lc1E9Mx0pEuS(k+ zSI{GP>1_ZVRc+Xfn2$Zpt)G?_;`c zdg=6))HdBTy{*w?>}F&XpEm#7OY~Vy(YEMj^f-y9i_)SC#exSfRvviU_1usWd1ea0%|m9VWaemQ&vHB91kIUsu&@Bl@eC zz_Wwb3G-GHYD$iYRnnO|>X+Mfj^*2!2YlBtWIz$X8T^J+=l$bn5Y-kfT ziMyaVGDJ*>2{9pkAU32O@|E;86*h%IL0WT*t|{)arHY$Zxni6w@qt&Q1x{1b&O?Vr zC}2{nCJCf+kVH$<^!+7vD7wBTRCI2s^;4>(=vl{9)JIY4qPdScK$QpZn)Jw9ZDnSKsrkwi8l#`@!KWN~wUs%_%0#oLO>@PMRdjBWPI`gkSNJ1agvk9_6uFWQ_9pgC ziC2Rn@#}R_Cq?879*XET_oF4kvCu*^2$tM`R{2uwmeA?qL6jyx%@qJ58?biH-Cfdv zgGnhfo{Ji2-rn~iOoNH{suT_AEsGxB!BWAHhM*~}1xyLL>30r>12?5Mfl1o4^w$}A z%Mva}G(AB#Z9p?}a2h>Dm~J<>5EL0f89X>e%@mO@SXDp?qu2h?lJ^g2Q@?F>*VX7x z4wu}ULR_+Hz~q`CZP3JvjY+eGW>DKSZ8d8(H>9T6BsS3|aUWuvxKuo*yNK%!TH=}B z)Uid!ptg0Cb}aClcZ}@+#(^!~He&Se`l+&-mWr?n(IxdG+*D(#@1x#U->hE}4{=+) zsUATk#xZWvnv8uIZN|1no6%t8$&eT_553M*B_N)y{X<*Z>sO3evA4ieJtrxUvXm<>_!P7=n%9p!U|pP4>#?qT#EI1tGbZ$rTw_a9TH4LFR~`GEvG@@Fo8+^YOo_IQ*C7vn#i#B{CjSc{9=REU$Q= zCtw#2bi!$hE_fyl9-wHBBk~2Saws-3SDy=n=%(n04Y-7+Fp7xaKV=mJ?zx=AW63jt zeDtyp8*mlZT_yz?ANQ|M^54(G z|5$qQXQwk^ug{`){=e73?H`Td9P#G=Yhz*#SUR9KW|HW2lW}c)x3((ic5L5hpPZO! zc5px~Ja*ujTDpmy&LS7)CyVoq-EOjMc7U#Yqp?wj<~?@en1R2Mb>L>9`YxE~_^#hifV1*bcMSM0HDauGPKInrGLJ%b=ExyWS#flg1o!SrS+Q=% zeQ^ojTQhIXnq2JrU}1*RFb3&Wnir&u=~05y`xdg8c<{v+xA6CiC9Kq1zjl_aQ4~@E zxPmu#N3H0>+Qt0iIe5K4)GldqVW$tEn}`sx?8zR@drY~dml2lSlDb4I}R;abg zX-lYeX5cUZKTezJk@IE_s%Nss+hGN1(8u)t;g-kA8xwfICoHl$RauNksntW zx{Df&E)%pTB0N{4SLbA z+Xs3?MXXA8H&7ny%=w`A<7ieyCoLC6y6;xGvMw} zDYKqd?=CCqxqhPFohoNe!Qm^RX*1Nh`u1C^eVT3Y@%^`}x>9@O0ta1*`lgmsZoVce z)-Ta-y=#3R^KDe2ARBs2&HQ}&SyIp@-9$IhP4qtKHhLR63cJvoDqFlsvsU*-u#P|X zB>4)$mcHTsq_#asw$Yh1CbSRK25q!9y$Raz#^RJsq?-eVF-m#2SR2p8E7g4OGwHg5 zAo=NsNE`b9f@~5t<4y4nIm9fFH63^+JQP#}T>u1p|u%HV2W zjB58rR43gvr|9p;F%KPhz*o?19P^2Rp;+l;s+t%_RGi-@AyUVIw;hh;ZU5izd@bid zbSd&byc?9@Yb^Qi=f~5o$R~{dr<;s~%^%GA|I2dD=BM*gZPVhpL zCu`HVjvz}SSDFK{1GL%O%touu)Fe=>`ADMgR+F)9XqT|RGj#I8F*@+T!eOy1J5MpW zcY^DzDKe=Z@`t1WKT6kxf#Boc4hqJqtun z&H#cJ2lY{9(p=Uh$?;JWnL6ax9nR|(EUum0PeZ+;da2~h&6Uhn>P`3T&+Qvclt&=y zt-!c~yw@Gbu0))D%PWcGvV3fJNj1!+<9Hzq*hd0E(Jei1#|MQ)(`k?=?78?hhqnPv z==nwfnUX0PRVr?`0+h*B20M0`=onbA)Sh~6(DkO% z1@X_t4OAeGIff-b5CbM&sne7sOqv?)#il)o2rJiY!Y1$-^bO?bP5o5A@!Ci4J!2S< zVIs%W0!)ok1PV3g39gcZBJU+KH3D(2_v1U>Yf|rwYMEwJ8+|VTJlF@#rS+!4w3)gA zyRrhQ$@1z!7V87#=#h9q2y~qBUpM!+Cet*jS|OAgUy`CRkH>v@!Mp&b>MZ`fm@16l Psah$GwaNdR#Q^{S={DW} literal 0 HcmV?d00001 diff --git a/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt b/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt new file mode 100644 index 000000000..4b3edc29e --- /dev/null +++ b/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt @@ -0,0 +1,103 @@ +// REUSE-IgnoreStart + +Copyright (c) 2010, NAVER Corporation (https://www.navercorp.com/), + +with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic, +NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen, +Naver NanumPen, Naver NanumGothicEco, NanumGothicEco, Naver NanumMyeongjoEco, +NanumMyeongjoEco, Naver NanumGothicLight, NanumGothicLight, NanumBarunGothic, +Naver NanumBarunGothic, NanumSquareRound, NanumBarunPen, MaruBuri + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 b/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..462c34efcd9d6b70b42359ca1a1d9476efe43eeb GIT binary patch literal 44896 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 V7)~)yDZnpu49h_gZvJhn{{a>V-DCg& literal 0 HcmV?d00001 diff --git a/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt b/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt new file mode 100644 index 000000000..0d2941e14 --- /dev/null +++ b/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt @@ -0,0 +1,97 @@ +// REUSE-IgnoreStart + +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 b/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..10b558e0b69a74b8329766fffbd5f64356c7230d GIT binary patch literal 52228 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 z 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 D0=ucW literal 0 HcmV?d00001 diff --git a/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 b/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..181a07f63bef8f18e42a5a57463e0e60cf8e8035 GIT binary patch literal 81540 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 literal 0 HcmV?d00001 diff --git a/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 b/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..2ae08a7bedfed08cdfea76039c1bb1fa1d6cdf67 GIT binary patch literal 59716 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 tC40Gi`Mi4m<9BpxR%m?w=so8}_Gqj!BM1dG + +Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. +Copyright 2014 - 2023 Adobe (http://www.adobe.com/), with Reserved Font Name ‘Source’. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + + diff --git a/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 b/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..0263fc304226d90e224e53053855ad138303b70b GIT binary patch literal 76260 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 G0RRB5qhxRZ literal 0 HcmV?d00001 diff --git a/static.files/favicon-2c020d218678b618.svg b/static.files/favicon-2c020d218678b618.svg new file mode 100644 index 000000000..8b34b5119 --- /dev/null +++ b/static.files/favicon-2c020d218678b618.svg @@ -0,0 +1,24 @@ + + + + + diff --git a/static.files/favicon-32x32-422f7d1d52889060.png b/static.files/favicon-32x32-422f7d1d52889060.png new file mode 100644 index 0000000000000000000000000000000000000000..69b8613ce1506e1c92b864f91cc46df06348c62b GIT binary patch literal 1125 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE0wix1Z>k4UEa{HEjtmSN`?>!lvVtU&J%W50 z7^>757#dm_7=8hT8eT9klo~KFyh>nTu$sZZAYL$MSD+10f+@+{-G$+Qd;gjJKptm- zM`SV3z!DH1*13q>1OJmp-&A)3@J_A;A0V7u0bkfJ)-`Krrb zGey1(YybBo_r#8#3kPrfo#tA4xb3R$F4j$a9H~9huUPE$JQDstTM~O>^@Ps(;>UH<3Fx0=LBZUre@8723HjVToWun1;~KVtGY7SF1E7liM5< zHa%KaZ1y+v;MF5PX0dXM#bh1)zI}?P`JCclPp)GktoyD%Uv%1HzQp-VwViVJr}FN4 zBVAi3pdsabJ2zzio=sD>mtWX++u%m3k>>5t|1&=?+*B*EnLW)#$^O=9J{D1Fvz#4w zCmkrSML-}_v8Imc2?OP1;|%KWmLM+u&^dKy+fI{C57UY0UhRg-3U_ zKl;3k)jRBCi*uZh#-8L8Gwj!FXV37syULEeYD%&1+S-jgUC&wB|>?y4oO5hW>!C8<`)MX5lF!N|bKNY}tn*U&h` z(Adh*+{(a0+rYrez#!Wq{4a`z-29Zxv`X9>q*C7l^C^QQ$cEtjw370~qEv?R@^Zb* zyzJuS#DY}4{G#;P?`))iio&ZxB1(c1%M}WW^3yVNQWZ)n3sMy_3rdn17%JvG{=~yk z7^b0d%K!8k&!<5Q%*xz)$=t%q!rqfbn1vNw8cYtSFe`5kQ8<0$%84Uqj>sHgKi%N5 cz)O$emAGKZCnwXXKr0wLUHx3vIVCg!0EmFw6951J literal 0 HcmV?d00001 diff --git a/static.files/main-20a3ad099b048cf2.js b/static.files/main-20a3ad099b048cf2.js new file mode 100644 index 000000000..133116e4d --- /dev/null +++ b/static.files/main-20a3ad099b048cf2.js @@ -0,0 +1,11 @@ +"use strict";window.RUSTDOC_TOOLTIP_HOVER_MS=300;window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS=450;function resourcePath(basename,extension){return getVar("root-path")+basename+getVar("resource-suffix")+extension}function hideMain(){addClass(document.getElementById(MAIN_ID),"hidden")}function showMain(){removeClass(document.getElementById(MAIN_ID),"hidden")}function blurHandler(event,parentElem,hideCallback){if(!parentElem.contains(document.activeElement)&&!parentElem.contains(event.relatedTarget)){hideCallback()}}window.rootPath=getVar("root-path");window.currentCrate=getVar("current-crate");function setMobileTopbar(){const mobileTopbar=document.querySelector(".mobile-topbar");const locationTitle=document.querySelector(".sidebar h2.location");if(mobileTopbar){const mobileTitle=document.createElement("h2");mobileTitle.className="location";if(hasClass(document.querySelector(".rustdoc"),"crate")){mobileTitle.innerHTML=`Crate ${window.currentCrate}`}else if(locationTitle){mobileTitle.innerHTML=locationTitle.innerHTML}mobileTopbar.appendChild(mobileTitle)}}function getVirtualKey(ev){if("key"in ev&&typeof ev.key!=="undefined"){return ev.key}const c=ev.charCode||ev.keyCode;if(c===27){return"Escape"}return String.fromCharCode(c)}const MAIN_ID="main-content";const SETTINGS_BUTTON_ID="settings-menu";const ALTERNATIVE_DISPLAY_ID="alternative-display";const NOT_DISPLAYED_ID="not-displayed";const HELP_BUTTON_ID="help-button";function getSettingsButton(){return document.getElementById(SETTINGS_BUTTON_ID)}function getHelpButton(){return document.getElementById(HELP_BUTTON_ID)}function getNakedUrl(){return window.location.href.split("?")[0].split("#")[0]}function insertAfter(newNode,referenceNode){referenceNode.parentNode.insertBefore(newNode,referenceNode.nextSibling)}function getOrCreateSection(id,classes){let el=document.getElementById(id);if(!el){el=document.createElement("section");el.id=id;el.className=classes;insertAfter(el,document.getElementById(MAIN_ID))}return el}function getAlternativeDisplayElem(){return getOrCreateSection(ALTERNATIVE_DISPLAY_ID,"content hidden")}function getNotDisplayedElem(){return getOrCreateSection(NOT_DISPLAYED_ID,"hidden")}function switchDisplayedElement(elemToDisplay){const el=getAlternativeDisplayElem();if(el.children.length>0){getNotDisplayedElem().appendChild(el.firstElementChild)}if(elemToDisplay===null){addClass(el,"hidden");showMain();return}el.appendChild(elemToDisplay);hideMain();removeClass(el,"hidden")}function browserSupportsHistoryApi(){return window.history&&typeof window.history.pushState==="function"}function preLoadCss(cssUrl){const link=document.createElement("link");link.href=cssUrl;link.rel="preload";link.as="style";document.getElementsByTagName("head")[0].appendChild(link)}(function(){const isHelpPage=window.location.pathname.endsWith("/help.html");function loadScript(url,errorCallback){const script=document.createElement("script");script.src=url;if(errorCallback!==undefined){script.onerror=errorCallback}document.head.append(script)}getSettingsButton().onclick=event=>{if(event.ctrlKey||event.altKey||event.metaKey){return}window.hideAllModals(false);addClass(getSettingsButton(),"rotate");event.preventDefault();loadScript(getVar("static-root-path")+getVar("settings-js"));setTimeout(()=>{const themes=getVar("themes").split(",");for(const theme of themes){if(theme!==""){preLoadCss(getVar("root-path")+theme+".css")}}},0)};window.searchState={loadingText:"Loading search results...",input:document.getElementsByClassName("search-input")[0],outputElement:()=>{let el=document.getElementById("search");if(!el){el=document.createElement("section");el.id="search";getNotDisplayedElem().appendChild(el)}return el},title:document.title,titleBeforeSearch:document.title,timeout:null,currentTab:0,focusedByTab:[null,null,null],clearInputTimeout:()=>{if(searchState.timeout!==null){clearTimeout(searchState.timeout);searchState.timeout=null}},isDisplayed:()=>searchState.outputElement().parentElement.id===ALTERNATIVE_DISPLAY_ID,focus:()=>{searchState.input.focus()},defocus:()=>{searchState.input.blur()},showResults:search=>{if(search===null||typeof search==="undefined"){search=searchState.outputElement()}switchDisplayedElement(search);searchState.mouseMovedAfterSearch=false;document.title=searchState.title},removeQueryParameters:()=>{document.title=searchState.titleBeforeSearch;if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.hash)}},hideResults:()=>{switchDisplayedElement(null);searchState.removeQueryParameters()},getQueryStringParams:()=>{const params={};window.location.search.substring(1).split("&").map(s=>{const pair=s.split("=").map(x=>x.replace(/\+/g," "));params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1])});return params},setup:()=>{const search_input=searchState.input;if(!searchState.input){return}let searchLoaded=false;function sendSearchForm(){document.getElementsByClassName("search-form")[0].submit()}function loadSearch(){if(!searchLoaded){searchLoaded=true;loadScript(getVar("static-root-path")+getVar("search-js"),sendSearchForm);loadScript(resourcePath("search-index",".js"),sendSearchForm)}}search_input.addEventListener("focus",()=>{search_input.origPlaceholder=search_input.placeholder;search_input.placeholder="Type your search here.";loadSearch()});if(search_input.value!==""){loadSearch()}const params=searchState.getQueryStringParams();if(params.search!==undefined){searchState.setLoadingSearch();loadSearch()}},setLoadingSearch:()=>{const search=searchState.outputElement();search.innerHTML="

"+searchState.loadingText+"

";searchState.showResults(search)},descShards:new Map(),loadDesc:async function({descShard,descIndex}){if(descShard.promise===null){descShard.promise=new Promise((resolve,reject)=>{descShard.resolve=resolve;const ds=descShard;const fname=`${ds.crate}-desc-${ds.shard}-`;const url=resourcePath(`search.desc/${descShard.crate}/${fname}`,".js",);loadScript(url,reject)})}const list=await descShard.promise;return list[descIndex]},loadedDescShard:function(crate,shard,data){this.descShards.get(crate)[shard].resolve(data.split("\n"))},};const toggleAllDocsId="toggle-all-docs";let savedHash="";function handleHashes(ev){if(ev!==null&&searchState.isDisplayed()&&ev.newURL){switchDisplayedElement(null);const hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.search+"#"+hash)}const elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}const pageId=window.location.hash.replace(/^#/,"");if(savedHash!==pageId){savedHash=pageId;if(pageId!==""){expandSection(pageId)}}if(savedHash.startsWith("impl-")){const splitAt=savedHash.indexOf("/");if(splitAt!==-1){const implId=savedHash.slice(0,splitAt);const assocId=savedHash.slice(splitAt+1);const implElem=document.getElementById(implId);if(implElem&&implElem.parentElement.tagName==="SUMMARY"&&implElem.parentElement.parentElement.tagName==="DETAILS"){onEachLazy(implElem.parentElement.parentElement.querySelectorAll(`[id^="${assocId}"]`),item=>{const numbered=/([^-]+)-([0-9]+)/.exec(item.id);if(item.id===assocId||(numbered&&numbered[1]===assocId)){openParentDetails(item);item.scrollIntoView();setTimeout(()=>{window.location.replace("#"+item.id)},0)}},)}}}}function onHashChange(ev){hideSidebar();handleHashes(ev)}function openParentDetails(elem){while(elem){if(elem.tagName==="DETAILS"){elem.open=true}elem=elem.parentNode}}function expandSection(id){openParentDetails(document.getElementById(id))}function handleEscape(ev){searchState.clearInputTimeout();searchState.hideResults();ev.preventDefault();searchState.defocus();window.hideAllModals(true)}function handleShortcut(ev){const disableShortcuts=getSettingValue("disable-shortcuts")==="true";if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts){return}if(document.activeElement.tagName==="INPUT"&&document.activeElement.type!=="checkbox"&&document.activeElement.type!=="radio"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":case"/":ev.preventDefault();searchState.focus();break;case"+":ev.preventDefault();expandAllDocs();break;case"-":ev.preventDefault();collapseAllDocs();break;case"?":showHelp();break;default:break}}}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);function addSidebarItems(){if(!window.SIDEBAR_ITEMS){return}const sidebar=document.getElementsByClassName("sidebar-elems")[0];function block(shortty,id,longty){const filtered=window.SIDEBAR_ITEMS[shortty];if(!filtered){return}const modpath=hasClass(document.querySelector(".rustdoc"),"mod")?"../":"";const h3=document.createElement("h3");h3.innerHTML=`${longty}`;const ul=document.createElement("ul");ul.className="block "+shortty;for(const name of filtered){let path;if(shortty==="mod"){path=`${modpath}${name}/index.html`}else{path=`${modpath}${shortty}.${name}.html`}let current_page=document.location.href.toString();if(current_page.endsWith("/")){current_page+="index.html"}const link=document.createElement("a");link.href=path;if(path===current_page){link.className="current"}link.textContent=name;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebar.appendChild(h3);sidebar.appendChild(ul)}if(sidebar){block("primitive","primitives","Primitive Types");block("mod","modules","Modules");block("macro","macros","Macros");block("struct","structs","Structs");block("enum","enums","Enums");block("constant","constants","Constants");block("static","static","Statics");block("trait","traits","Traits");block("fn","functions","Functions");block("type","types","Type Aliases");block("union","unions","Unions");block("foreigntype","foreign-types","Foreign Types");block("keyword","keywords","Keywords");block("opaque","opaque-types","Opaque Types");block("attr","attributes","Attribute Macros");block("derive","derives","Derive Macros");block("traitalias","trait-aliases","Trait Aliases")}}window.register_implementors=imp=>{const implementors=document.getElementById("implementors-list");const synthetic_implementors=document.getElementById("synthetic-implementors-list");const inlined_types=new Set();const TEXT_IDX=0;const SYNTHETIC_IDX=1;const TYPES_IDX=2;if(synthetic_implementors){onEachLazy(synthetic_implementors.getElementsByClassName("impl"),el=>{const aliases=el.getAttribute("data-aliases");if(!aliases){return}aliases.split(",").forEach(alias=>{inlined_types.add(alias)})})}let currentNbImpls=implementors.getElementsByClassName("impl").length;const traitName=document.querySelector(".main-heading h1 > .trait").textContent;const baseIdName="impl-"+traitName+"-";const libs=Object.getOwnPropertyNames(imp);const script=document.querySelector("script[data-ignore-extern-crates]");const ignoreExternCrates=new Set((script?script.getAttribute("data-ignore-extern-crates"):"").split(","),);for(const lib of libs){if(lib===window.currentCrate||ignoreExternCrates.has(lib)){continue}const structs=imp[lib];struct_loop:for(const struct of structs){const list=struct[SYNTHETIC_IDX]?synthetic_implementors:implementors;if(struct[SYNTHETIC_IDX]){for(const struct_type of struct[TYPES_IDX]){if(inlined_types.has(struct_type)){continue struct_loop}inlined_types.add(struct_type)}}const code=document.createElement("h3");code.innerHTML=struct[TEXT_IDX];addClass(code,"code-header");onEachLazy(code.getElementsByTagName("a"),elem=>{const href=elem.getAttribute("href");if(href&&!href.startsWith("#")&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});const currentId=baseIdName+currentNbImpls;const anchor=document.createElement("a");anchor.href="#"+currentId;addClass(anchor,"anchor");const display=document.createElement("div");display.id=currentId;addClass(display,"impl");display.appendChild(anchor);display.appendChild(code);list.appendChild(display);currentNbImpls+=1}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors)}window.register_type_impls=imp=>{if(!imp||!imp[window.currentCrate]){return}window.pending_type_impls=null;const idMap=new Map();let implementations=document.getElementById("implementations-list");let trait_implementations=document.getElementById("trait-implementations-list");let trait_implementations_header=document.getElementById("trait-implementations");const script=document.querySelector("script[data-self-path]");const selfPath=script?script.getAttribute("data-self-path"):null;const mainContent=document.querySelector("#main-content");const sidebarSection=document.querySelector(".sidebar section");let methods=document.querySelector(".sidebar .block.method");let associatedTypes=document.querySelector(".sidebar .block.associatedtype");let associatedConstants=document.querySelector(".sidebar .block.associatedconstant");let sidebarTraitList=document.querySelector(".sidebar .block.trait-implementation");for(const impList of imp[window.currentCrate]){const types=impList.slice(2);const text=impList[0];const isTrait=impList[1]!==0;const traitName=impList[1];if(types.indexOf(selfPath)===-1){continue}let outputList=isTrait?trait_implementations:implementations;if(outputList===null){const outputListName=isTrait?"Trait Implementations":"Implementations";const outputListId=isTrait?"trait-implementations-list":"implementations-list";const outputListHeaderId=isTrait?"trait-implementations":"implementations";const outputListHeader=document.createElement("h2");outputListHeader.id=outputListHeaderId;outputListHeader.innerText=outputListName;outputList=document.createElement("div");outputList.id=outputListId;if(isTrait){const link=document.createElement("a");link.href=`#${outputListHeaderId}`;link.innerText="Trait Implementations";const h=document.createElement("h3");h.appendChild(link);trait_implementations=outputList;trait_implementations_header=outputListHeader;sidebarSection.appendChild(h);sidebarTraitList=document.createElement("ul");sidebarTraitList.className="block trait-implementation";sidebarSection.appendChild(sidebarTraitList);mainContent.appendChild(outputListHeader);mainContent.appendChild(outputList)}else{implementations=outputList;if(trait_implementations){mainContent.insertBefore(outputListHeader,trait_implementations_header);mainContent.insertBefore(outputList,trait_implementations_header)}else{const mainContent=document.querySelector("#main-content");mainContent.appendChild(outputListHeader);mainContent.appendChild(outputList)}}}const template=document.createElement("template");template.innerHTML=text;onEachLazy(template.content.querySelectorAll("a"),elem=>{const href=elem.getAttribute("href");if(href&&!href.startsWith("#")&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});onEachLazy(template.content.querySelectorAll("[id]"),el=>{let i=0;if(idMap.has(el.id)){i=idMap.get(el.id)}else if(document.getElementById(el.id)){i=1;while(document.getElementById(`${el.id}-${2 * i}`)){i=2*i}while(document.getElementById(`${el.id}-${i}`)){i+=1}}if(i!==0){const oldHref=`#${el.id}`;const newHref=`#${el.id}-${i}`;el.id=`${el.id}-${i}`;onEachLazy(template.content.querySelectorAll("a[href]"),link=>{if(link.getAttribute("href")===oldHref){link.href=newHref}})}idMap.set(el.id,i+1)});const templateAssocItems=template.content.querySelectorAll("section.tymethod, "+"section.method, section.associatedtype, section.associatedconstant");if(isTrait){const li=document.createElement("li");const a=document.createElement("a");a.href=`#${template.content.querySelector(".impl").id}`;a.textContent=traitName;li.appendChild(a);sidebarTraitList.append(li)}else{onEachLazy(templateAssocItems,item=>{let block=hasClass(item,"associatedtype")?associatedTypes:(hasClass(item,"associatedconstant")?associatedConstants:(methods));if(!block){const blockTitle=hasClass(item,"associatedtype")?"Associated Types":(hasClass(item,"associatedconstant")?"Associated Constants":("Methods"));const blockClass=hasClass(item,"associatedtype")?"associatedtype":(hasClass(item,"associatedconstant")?"associatedconstant":("method"));const blockHeader=document.createElement("h3");const blockLink=document.createElement("a");blockLink.href="#implementations";blockLink.innerText=blockTitle;blockHeader.appendChild(blockLink);block=document.createElement("ul");block.className=`block ${blockClass}`;const insertionReference=methods||sidebarTraitList;if(insertionReference){const insertionReferenceH=insertionReference.previousElementSibling;sidebarSection.insertBefore(blockHeader,insertionReferenceH);sidebarSection.insertBefore(block,insertionReferenceH)}else{sidebarSection.appendChild(blockHeader);sidebarSection.appendChild(block)}if(hasClass(item,"associatedtype")){associatedTypes=block}else if(hasClass(item,"associatedconstant")){associatedConstants=block}else{methods=block}}const li=document.createElement("li");const a=document.createElement("a");a.innerText=item.id.split("-")[0].split(".")[1];a.href=`#${item.id}`;li.appendChild(a);block.appendChild(li)})}outputList.appendChild(template.content)}for(const list of[methods,associatedTypes,associatedConstants,sidebarTraitList]){if(!list){continue}const newChildren=Array.prototype.slice.call(list.children);newChildren.sort((a,b)=>{const aI=a.innerText;const bI=b.innerText;return aIbI?1:0});list.replaceChildren(...newChildren)}};if(window.pending_type_impls){window.register_type_impls(window.pending_type_impls)}function addSidebarCrates(){if(!window.ALL_CRATES){return}const sidebarElems=document.getElementsByClassName("sidebar-elems")[0];if(!sidebarElems){return}const h3=document.createElement("h3");h3.innerHTML="Crates";const ul=document.createElement("ul");ul.className="block crate";for(const crate of window.ALL_CRATES){const link=document.createElement("a");link.href=window.rootPath+crate+"/index.html";link.textContent=crate;const li=document.createElement("li");if(window.rootPath!=="./"&&crate===window.currentCrate){li.className="current"}li.appendChild(link);ul.appendChild(li)}sidebarElems.appendChild(h3);sidebarElems.appendChild(ul)}function expandAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);removeClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hasClass(e,"type-contents-toggle")&&!hasClass(e,"more-examples-toggle")){e.open=true}});innerToggle.title="collapse all docs";innerToggle.children[0].innerText="\u2212"}function collapseAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);addClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(e.parentNode.id!=="implementations-list"||(!hasClass(e,"implementors-toggle")&&!hasClass(e,"type-contents-toggle"))){e.open=false}});innerToggle.title="expand all docs";innerToggle.children[0].innerText="+"}function toggleAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);if(!innerToggle){return}if(hasClass(innerToggle,"will-expand")){expandAllDocs()}else{collapseAllDocs()}}(function(){const toggles=document.getElementById(toggleAllDocsId);if(toggles){toggles.onclick=toggleAllDocs}const hideMethodDocs=getSettingValue("auto-hide-method-docs")==="true";const hideImplementations=getSettingValue("auto-hide-trait-implementations")==="true";const hideLargeItemContents=getSettingValue("auto-hide-large-items")!=="false";function setImplementorsTogglesOpen(id,open){const list=document.getElementById(id);if(list!==null){onEachLazy(list.getElementsByClassName("implementors-toggle"),e=>{e.open=open})}}if(hideImplementations){setImplementorsTogglesOpen("trait-implementations-list",false);setImplementorsTogglesOpen("blanket-implementations-list",false)}onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hideLargeItemContents&&hasClass(e,"type-contents-toggle")){e.open=true}if(hideMethodDocs&&hasClass(e,"method-toggle")){e.open=false}})}());window.rustdoc_add_line_numbers_to_examples=()=>{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");if(line_numbers.length>0){return}const count=x.textContent.split("\n").length;const elems=[];for(let i=0;i{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");for(const node of line_numbers){parent.removeChild(node)}})};if(getSettingValue("line-numbers")==="true"){window.rustdoc_add_line_numbers_to_examples()}function showSidebar(){window.hideAllModals(false);const sidebar=document.getElementsByClassName("sidebar")[0];addClass(sidebar,"shown")}function hideSidebar(){const sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"shown")}window.addEventListener("resize",()=>{if(window.CURRENT_TOOLTIP_ELEMENT){const base=window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE;const force_visible=base.TOOLTIP_FORCE_VISIBLE;hideTooltip(false);if(force_visible){showTooltip(base);base.TOOLTIP_FORCE_VISIBLE=true}}});const mainElem=document.getElementById(MAIN_ID);if(mainElem){mainElem.addEventListener("click",hideSidebar)}onEachLazy(document.querySelectorAll("a[href^='#']"),el=>{el.addEventListener("click",()=>{expandSection(el.hash.slice(1));hideSidebar()})});onEachLazy(document.querySelectorAll(".toggle > summary:not(.hideme)"),el=>{el.addEventListener("click",e=>{if(e.target.tagName!=="SUMMARY"&&e.target.tagName!=="A"){e.preventDefault()}})});function showTooltip(e){const notable_ty=e.getAttribute("data-notable-ty");if(!window.NOTABLE_TRAITS&¬able_ty){const data=document.getElementById("notable-traits-data");if(data){window.NOTABLE_TRAITS=JSON.parse(data.innerText)}else{throw new Error("showTooltip() called with notable without any notable traits!")}}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE===e){clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);return}window.hideAllModals(false);const wrapper=document.createElement("div");if(notable_ty){wrapper.innerHTML="
"+window.NOTABLE_TRAITS[notable_ty]+"
"}else{if(e.getAttribute("title")!==null){e.setAttribute("data-title",e.getAttribute("title"));e.removeAttribute("title")}if(e.getAttribute("data-title")!==null){const titleContent=document.createElement("div");titleContent.className="content";titleContent.appendChild(document.createTextNode(e.getAttribute("data-title")));wrapper.appendChild(titleContent)}}wrapper.className="tooltip popover";const focusCatcher=document.createElement("div");focusCatcher.setAttribute("tabindex","0");focusCatcher.onfocus=hideTooltip;wrapper.appendChild(focusCatcher);const pos=e.getBoundingClientRect();wrapper.style.top=(pos.top+window.scrollY+pos.height)+"px";wrapper.style.left=0;wrapper.style.right="auto";wrapper.style.visibility="hidden";const body=document.getElementsByTagName("body")[0];body.appendChild(wrapper);const wrapperPos=wrapper.getBoundingClientRect();const finalPos=pos.left+window.scrollX-wrapperPos.width+24;if(finalPos>0){wrapper.style.left=finalPos+"px"}else{wrapper.style.setProperty("--popover-arrow-offset",(wrapperPos.right-pos.right+4)+"px",)}wrapper.style.visibility="";window.CURRENT_TOOLTIP_ELEMENT=wrapper;window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE=e;clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);wrapper.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}clearTooltipHoverTimeout(e)};wrapper.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&!e.contains(ev.relatedTarget)){setTooltipHoverTimeout(e,false);addClass(wrapper,"fade-out")}}}function setTooltipHoverTimeout(element,show){clearTooltipHoverTimeout(element);if(!show&&!window.CURRENT_TOOLTIP_ELEMENT){return}if(show&&window.CURRENT_TOOLTIP_ELEMENT){return}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE!==element){return}element.TOOLTIP_HOVER_TIMEOUT=setTimeout(()=>{if(show){showTooltip(element)}else if(!element.TOOLTIP_FORCE_VISIBLE){hideTooltip(false)}},show?window.RUSTDOC_TOOLTIP_HOVER_MS:window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS)}function clearTooltipHoverTimeout(element){if(element.TOOLTIP_HOVER_TIMEOUT!==undefined){removeClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out");clearTimeout(element.TOOLTIP_HOVER_TIMEOUT);delete element.TOOLTIP_HOVER_TIMEOUT}}function tooltipBlurHandler(event){if(window.CURRENT_TOOLTIP_ELEMENT&&!window.CURRENT_TOOLTIP_ELEMENT.contains(document.activeElement)&&!window.CURRENT_TOOLTIP_ELEMENT.contains(event.relatedTarget)&&!window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.contains(document.activeElement)&&!window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.contains(event.relatedTarget)){setTimeout(()=>hideTooltip(false),0)}}function hideTooltip(focus){if(window.CURRENT_TOOLTIP_ELEMENT){if(window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE){if(focus){window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.focus()}window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE=false}const body=document.getElementsByTagName("body")[0];body.removeChild(window.CURRENT_TOOLTIP_ELEMENT);clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);window.CURRENT_TOOLTIP_ELEMENT=null}}onEachLazy(document.getElementsByClassName("tooltip"),e=>{e.onclick=()=>{e.TOOLTIP_FORCE_VISIBLE=e.TOOLTIP_FORCE_VISIBLE?false:true;if(window.CURRENT_TOOLTIP_ELEMENT&&!e.TOOLTIP_FORCE_VISIBLE){hideTooltip(true)}else{showTooltip(e);window.CURRENT_TOOLTIP_ELEMENT.setAttribute("tabindex","0");window.CURRENT_TOOLTIP_ELEMENT.focus();window.CURRENT_TOOLTIP_ELEMENT.onblur=tooltipBlurHandler}return false};e.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointermove=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&window.CURRENT_TOOLTIP_ELEMENT&&!window.CURRENT_TOOLTIP_ELEMENT.contains(ev.relatedTarget)){setTooltipHoverTimeout(e,false);addClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out")}}});const sidebar_menu_toggle=document.getElementsByClassName("sidebar-menu-toggle")[0];if(sidebar_menu_toggle){sidebar_menu_toggle.addEventListener("click",()=>{const sidebar=document.getElementsByClassName("sidebar")[0];if(!hasClass(sidebar,"shown")){showSidebar()}else{hideSidebar()}})}function helpBlurHandler(event){blurHandler(event,getHelpButton(),window.hidePopoverMenus)}function buildHelpMenu(){const book_info=document.createElement("span");const channel=getVar("channel");book_info.className="top";book_info.innerHTML=`You can find more information in \ +the rustdoc book.`;const shortcuts=[["?","Show this help dialog"],["S / /","Focus the search field"],["↑","Move up in search results"],["↓","Move down in search results"],["← / →","Switch result tab (when results focused)"],["⏎","Go to active search result"],["+","Expand all sections"],["-","Collapse all sections"],].map(x=>"
"+x[0].split(" ").map((y,index)=>((index&1)===0?""+y+"":" "+y+" ")).join("")+"
"+x[1]+"
").join("");const div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="

Keyboard Shortcuts

"+shortcuts+"
";const infos=[`For a full list of all search features, take a look here.`,"Prefix searches with a type followed by a colon (e.g., fn:) to \ + restrict the search to a given item kind.","Accepted kinds are: fn, mod, struct, \ + enum, trait, type, macro, \ + and const.","Search functions by type signature (e.g., vec -> usize or \ + -> vec or String, enum:Cow -> bool)","You can look for items with an exact name by putting double quotes around \ + your request: \"string\"","Look for functions that accept or return \ + slices and \ + arrays by writing \ + square brackets (e.g., -> [u8] or [] -> Option)","Look for items inside another one by searching for a path: vec::Vec",].map(x=>"

"+x+"

").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="

Search Tricks

"+infos;const rustdoc_version=document.createElement("span");rustdoc_version.className="bottom";const rustdoc_version_code=document.createElement("code");rustdoc_version_code.innerText="rustdoc "+getVar("rustdoc-version");rustdoc_version.appendChild(rustdoc_version_code);const container=document.createElement("div");if(!isHelpPage){container.className="popover"}container.id="help";container.style.display="none";const side_by_side=document.createElement("div");side_by_side.className="side-by-side";side_by_side.appendChild(div_shortcuts);side_by_side.appendChild(div_infos);container.appendChild(book_info);container.appendChild(side_by_side);container.appendChild(rustdoc_version);if(isHelpPage){const help_section=document.createElement("section");help_section.appendChild(container);document.getElementById("main-content").appendChild(help_section);container.style.display="block"}else{const help_button=getHelpButton();help_button.appendChild(container);container.onblur=helpBlurHandler;help_button.onblur=helpBlurHandler;help_button.children[0].onblur=helpBlurHandler}return container}window.hideAllModals=switchFocus=>{hideSidebar();window.hidePopoverMenus();hideTooltip(switchFocus)};window.hidePopoverMenus=()=>{onEachLazy(document.querySelectorAll(".search-form .popover"),elem=>{elem.style.display="none"})};function getHelpMenu(buildNeeded){let menu=getHelpButton().querySelector(".popover");if(!menu&&buildNeeded){menu=buildHelpMenu()}return menu}function showHelp(){getHelpButton().querySelector("a").focus();const menu=getHelpMenu(true);if(menu.style.display==="none"){window.hideAllModals();menu.style.display=""}}if(isHelpPage){showHelp();document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault()})}else{document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault();const menu=getHelpMenu(true);const shouldShowHelp=menu.style.display==="none";if(shouldShowHelp){showHelp()}else{window.hidePopoverMenus()}})}setMobileTopbar();addSidebarItems();addSidebarCrates();onHashChange(null);window.addEventListener("hashchange",onHashChange);searchState.setup()}());(function(){const SIDEBAR_MIN=100;const SIDEBAR_MAX=500;const RUSTDOC_MOBILE_BREAKPOINT=700;const BODY_MIN=400;const SIDEBAR_VANISH_THRESHOLD=SIDEBAR_MIN/2;const sidebarButton=document.getElementById("sidebar-button");if(sidebarButton){sidebarButton.addEventListener("click",e=>{removeClass(document.documentElement,"hide-sidebar");updateLocalStorage("hide-sidebar","false");if(document.querySelector(".rustdoc.src")){window.rustdocToggleSrcSidebar()}e.preventDefault()})}let currentPointerId=null;let desiredSidebarSize=null;let pendingSidebarResizingFrame=false;const resizer=document.querySelector(".sidebar-resizer");const sidebar=document.querySelector(".sidebar");if(!resizer||!sidebar){return}const isSrcPage=hasClass(document.body,"src");function hideSidebar(){if(isSrcPage){window.rustdocCloseSourceSidebar();updateLocalStorage("src-sidebar-width",null);document.documentElement.style.removeProperty("--src-sidebar-width");sidebar.style.removeProperty("--src-sidebar-width");resizer.style.removeProperty("--src-sidebar-width")}else{addClass(document.documentElement,"hide-sidebar");updateLocalStorage("hide-sidebar","true");updateLocalStorage("desktop-sidebar-width",null);document.documentElement.style.removeProperty("--desktop-sidebar-width");sidebar.style.removeProperty("--desktop-sidebar-width");resizer.style.removeProperty("--desktop-sidebar-width")}}function showSidebar(){if(isSrcPage){window.rustdocShowSourceSidebar()}else{removeClass(document.documentElement,"hide-sidebar");updateLocalStorage("hide-sidebar","false")}}function changeSidebarSize(size){if(isSrcPage){updateLocalStorage("src-sidebar-width",size);sidebar.style.setProperty("--src-sidebar-width",size+"px");resizer.style.setProperty("--src-sidebar-width",size+"px")}else{updateLocalStorage("desktop-sidebar-width",size);sidebar.style.setProperty("--desktop-sidebar-width",size+"px");resizer.style.setProperty("--desktop-sidebar-width",size+"px")}}function isSidebarHidden(){return isSrcPage?!hasClass(document.documentElement,"src-sidebar-expanded"):hasClass(document.documentElement,"hide-sidebar")}function resize(e){if(currentPointerId===null||currentPointerId!==e.pointerId){return}e.preventDefault();const pos=e.clientX-3;if(pos=SIDEBAR_MIN){if(isSidebarHidden()){showSidebar()}const constrainedPos=Math.min(pos,window.innerWidth-BODY_MIN,SIDEBAR_MAX);changeSidebarSize(constrainedPos);desiredSidebarSize=constrainedPos;if(pendingSidebarResizingFrame!==false){clearTimeout(pendingSidebarResizingFrame)}pendingSidebarResizingFrame=setTimeout(()=>{if(currentPointerId===null||pendingSidebarResizingFrame===false){return}pendingSidebarResizingFrame=false;document.documentElement.style.setProperty("--resizing-sidebar-width",desiredSidebarSize+"px",)},100)}}window.addEventListener("resize",()=>{if(window.innerWidth=(window.innerWidth-BODY_MIN)){changeSidebarSize(window.innerWidth-BODY_MIN)}else if(desiredSidebarSize!==null&&desiredSidebarSize>SIDEBAR_MIN){changeSidebarSize(desiredSidebarSize)}});function stopResize(e){if(currentPointerId===null){return}if(e){e.preventDefault()}desiredSidebarSize=sidebar.getBoundingClientRect().width;removeClass(resizer,"active");window.removeEventListener("pointermove",resize,false);window.removeEventListener("pointerup",stopResize,false);removeClass(document.documentElement,"sidebar-resizing");document.documentElement.style.removeProperty("--resizing-sidebar-width");if(resizer.releasePointerCapture){resizer.releasePointerCapture(currentPointerId);currentPointerId=null}}function initResize(e){if(currentPointerId!==null||e.altKey||e.ctrlKey||e.metaKey||e.button!==0){return}if(resizer.setPointerCapture){resizer.setPointerCapture(e.pointerId);if(!resizer.hasPointerCapture(e.pointerId)){resizer.releasePointerCapture(e.pointerId);return}currentPointerId=e.pointerId}window.hideAllModals(false);e.preventDefault();window.addEventListener("pointermove",resize,false);window.addEventListener("pointercancel",stopResize,false);window.addEventListener("pointerup",stopResize,false);addClass(resizer,"active");addClass(document.documentElement,"sidebar-resizing");const pos=e.clientX-sidebar.offsetLeft-3;document.documentElement.style.setProperty("--resizing-sidebar-width",pos+"px");desiredSidebarSize=null}resizer.addEventListener("pointerdown",initResize,false)}());(function(){let reset_button_timeout=null;const but=document.getElementById("copy-path");if(!but){return}but.onclick=()=>{const parent=but.parentElement;const path=[];onEach(parent.childNodes,child=>{if(child.tagName==="A"){path.push(child.textContent)}});const el=document.createElement("textarea");el.value=path.join("::");el.setAttribute("readonly","");el.style.position="absolute";el.style.left="-9999px";document.body.appendChild(el);el.select();document.execCommand("copy");document.body.removeChild(el);but.classList.add("clicked");if(reset_button_timeout!==null){window.clearTimeout(reset_button_timeout)}function reset_button(){reset_button_timeout=null;but.classList.remove("clicked")}reset_button_timeout=window.setTimeout(reset_button,1000)}}()) \ No newline at end of file diff --git a/static.files/normalize-76eba96aa4d2e634.css b/static.files/normalize-76eba96aa4d2e634.css new file mode 100644 index 000000000..469959f13 --- /dev/null +++ b/static.files/normalize-76eba96aa4d2e634.css @@ -0,0 +1,2 @@ + /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ +html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type="button"],[type="reset"],[type="submit"],button{-webkit-appearance:button}[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none} \ No newline at end of file diff --git a/static.files/noscript-df360f571f6edeae.css b/static.files/noscript-df360f571f6edeae.css new file mode 100644 index 000000000..4c310ae52 --- /dev/null +++ b/static.files/noscript-df360f571f6edeae.css @@ -0,0 +1 @@ + #main-content .attributes{margin-left:0 !important;}#copy-path,#sidebar-button,.sidebar-resizer{display:none !important;}nav.sub{display:none;}.src .sidebar{display:none;}.notable-traits{display:none;}:root,:root:not([data-theme]){--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#f5f5f5;--sidebar-background-color-hover:#e0e0e0;--code-block-background-color:#f5f5f5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--mobile-sidebar-menu-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#fff;--settings-menu-filter:none;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#f5f5f5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);--sidebar-resizer-hover:hsl(207,90%,66%);--sidebar-resizer-active:hsl(207,90%,54%);}@media (prefers-color-scheme:dark){:root,:root:not([data-theme]){--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--mobile-sidebar-menu-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2a2a2a;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);--sidebar-resizer-hover:hsl(207,30%,54%);--sidebar-resizer-active:hsl(207,90%,54%);}} \ No newline at end of file diff --git a/static.files/rust-logo-151179464ae7ed46.svg b/static.files/rust-logo-151179464ae7ed46.svg new file mode 100644 index 000000000..62424d8ff --- /dev/null +++ b/static.files/rust-logo-151179464ae7ed46.svg @@ -0,0 +1,61 @@ + + + diff --git a/static.files/rustdoc-dd39b87e5fcfba68.css b/static.files/rustdoc-dd39b87e5fcfba68.css new file mode 100644 index 000000000..77f898322 --- /dev/null +++ b/static.files/rustdoc-dd39b87e5fcfba68.css @@ -0,0 +1,46 @@ + :root{--nav-sub-mobile-padding:8px;--search-typename-width:6.75rem;--desktop-sidebar-width:200px;--src-sidebar-width:300px;--desktop-sidebar-z-index:100;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular-018c141bf0843ffd.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium-8f9a781e4970d388.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:400;src:local('Source Serif 4'),url("SourceSerif4-Regular-46f98efaafac5295.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:italic;font-weight:400;src:local('Source Serif 4 Italic'),url("SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:700;src:local('Source Serif 4 Bold'),url("SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:italic;font-weight:400;src:url("SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'NanumBarunGothic';src:url("NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2") format("woff2");font-display:swap;unicode-range:U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF;}*{box-sizing:border-box;}body{font:1rem/1.5 "Source Serif 4",NanumBarunGothic,serif;margin:0;position:relative;overflow-wrap:break-word;overflow-wrap:anywhere;font-feature-settings:"kern","liga";background-color:var(--main-background-color);color:var(--main-color);}h1{font-size:1.5rem;}h2{font-size:1.375rem;}h3{font-size:1.25rem;}h1,h2,h3,h4,h5,h6{font-weight:500;}h1,h2,h3,h4{margin:25px 0 15px 0;padding-bottom:6px;}.docblock h3,.docblock h4,h5,h6{margin:15px 0 5px 0;}.docblock>h2:first-child,.docblock>h3:first-child,.docblock>h4:first-child,.docblock>h5:first-child,.docblock>h6:first-child{margin-top:0;}.main-heading h1{margin:0;padding:0;flex-grow:1;overflow-wrap:break-word;overflow-wrap:anywhere;}.main-heading{display:flex;flex-wrap:wrap;padding-bottom:6px;margin-bottom:15px;}.content h2,.top-doc .docblock>h3,.top-doc .docblock>h4{border-bottom:1px solid var(--headings-border-bottom-color);}h1,h2{line-height:1.25;padding-top:3px;padding-bottom:9px;}h3.code-header{font-size:1.125rem;}h4.code-header{font-size:1rem;}.code-header{font-weight:600;margin:0;padding:0;white-space:pre-wrap;}#crate-search,h1,h2,h3,h4,h5,h6,.sidebar,.mobile-topbar,.search-input,.search-results .result-name,.item-name>a,.out-of-band,span.since,a.src,#help-button>a,summary.hideme,.scraped-example-list,ul.all-items{font-family:"Fira Sans",Arial,NanumBarunGothic,sans-serif;}#toggle-all-docs,a.anchor,.section-header a,#src-sidebar a,.rust a,.sidebar h2 a,.sidebar h3 a,.mobile-topbar h2 a,h1 a,.search-results a,.stab,.result-name i{color:var(--main-color);}span.enum,a.enum,span.struct,a.struct,span.union,a.union,span.primitive,a.primitive,span.type,a.type,span.foreigntype,a.foreigntype{color:var(--type-link-color);}span.trait,a.trait,span.traitalias,a.traitalias{color:var(--trait-link-color);}span.associatedtype,a.associatedtype,span.constant,a.constant,span.static,a.static{color:var(--assoc-item-link-color);}span.fn,a.fn,span.method,a.method,span.tymethod,a.tymethod{color:var(--function-link-color);}span.attr,a.attr,span.derive,a.derive,span.macro,a.macro{color:var(--macro-link-color);}span.mod,a.mod{color:var(--mod-link-color);}span.keyword,a.keyword{color:var(--keyword-link-color);}a{color:var(--link-color);text-decoration:none;}ol,ul{padding-left:24px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.625em;}p,.docblock>.warning{margin:0 0 .75em 0;}p:last-child,.docblock>.warning:last-child{margin:0;}button{padding:1px 6px;cursor:pointer;}button#toggle-all-docs{padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.rustdoc{display:flex;flex-direction:row;flex-wrap:nowrap;}main{position:relative;flex-grow:1;padding:10px 15px 40px 45px;min-width:0;}.src main{padding:15px;}.width-limiter{max-width:960px;margin-right:auto;}details:not(.toggle) summary{margin-bottom:.6em;}code,pre,a.test-arrow,.code-header{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.125em;}.docblock pre code,.docblock-short pre code{padding:0;}pre{padding:14px;line-height:1.5;}pre.item-decl{overflow-x:auto;}.item-decl .type-contents-toggle{contain:initial;}.src .content pre{padding:20px;}.rustdoc.src .example-wrap pre.src-line-numbers{padding:20px 0 20px 4px;}img{max-width:100%;}.logo-container{line-height:0;display:block;}.rust-logo{filter:var(--rust-logo-filter);}.sidebar{font-size:0.875rem;flex:0 0 var(--desktop-sidebar-width);width:var(--desktop-sidebar-width);overflow-y:scroll;overscroll-behavior:contain;position:sticky;height:100vh;top:0;left:0;z-index:var(--desktop-sidebar-z-index);}.rustdoc.src .sidebar{flex-basis:50px;width:50px;border-right:1px solid;overflow-x:hidden;overflow-y:hidden;}.hide-sidebar .sidebar,.hide-sidebar .sidebar-resizer{display:none;}.sidebar-resizer{touch-action:none;width:9px;cursor:col-resize;z-index:calc(var(--desktop-sidebar-z-index) + 1);position:fixed;height:100%;left:calc(var(--desktop-sidebar-width) + 1px);}.rustdoc.src .sidebar-resizer{left:49px;}.src-sidebar-expanded .src .sidebar-resizer{left:var(--src-sidebar-width);}.sidebar-resizing{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;}.sidebar-resizing*{cursor:col-resize !important;}.sidebar-resizing .sidebar{position:fixed;}.sidebar-resizing>body{padding-left:var(--resizing-sidebar-width);}.sidebar-resizer:hover,.sidebar-resizer:active,.sidebar-resizer:focus,.sidebar-resizer.active{width:10px;margin:0;left:var(--desktop-sidebar-width);border-left:solid 1px var(--sidebar-resizer-hover);}.src-sidebar-expanded .rustdoc.src .sidebar-resizer:hover,.src-sidebar-expanded .rustdoc.src .sidebar-resizer:active,.src-sidebar-expanded .rustdoc.src .sidebar-resizer:focus,.src-sidebar-expanded .rustdoc.src .sidebar-resizer.active{left:calc(var(--src-sidebar-width) - 1px);}@media (pointer:coarse){.sidebar-resizer{display:none !important;}}.sidebar-resizer.active{padding:0 140px;width:2px;margin-left:-140px;border-left:none;}.sidebar-resizer.active:before{border-left:solid 2px var(--sidebar-resizer-active);display:block;height:100%;content:"";}.sidebar,.mobile-topbar,.sidebar-menu-toggle,#src-sidebar{background-color:var(--sidebar-background-color);}.src .sidebar>*{visibility:hidden;}.src-sidebar-expanded .src .sidebar{overflow-y:auto;flex-basis:var(--src-sidebar-width);width:var(--src-sidebar-width);}.src-sidebar-expanded .src .sidebar>*{visibility:visible;}#all-types{margin-top:1em;}*{scrollbar-width:initial;scrollbar-color:var(--scrollbar-color);}.sidebar{scrollbar-width:thin;scrollbar-color:var(--scrollbar-color);}::-webkit-scrollbar{width:12px;}.sidebar::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0;background-color:var(--scrollbar-track-background-color);}.sidebar::-webkit-scrollbar-track{background-color:var(--scrollbar-track-background-color);}::-webkit-scrollbar-thumb,.sidebar::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb-background-color);}.hidden{display:none !important;}.logo-container>img{height:48px;width:48px;}ul.block,.block li{padding:0;margin:0;list-style:none;}.sidebar-elems a,.sidebar>h2 a{display:block;padding:0.25rem;margin-left:-0.25rem;margin-right:0.25rem;}.sidebar h2{overflow-wrap:anywhere;padding:0;margin:0.7rem 0;}.sidebar h3{font-size:1.125rem;padding:0;margin:0;}.sidebar-elems,.sidebar>.version,.sidebar>h2{padding-left:24px;}.sidebar a{color:var(--sidebar-link-color);}.sidebar .current,.sidebar .current a,.sidebar-crate a.logo-container:hover+h2 a,.sidebar a:hover:not(.logo-container){background-color:var(--sidebar-current-link-background-color);}.sidebar-elems .block{margin-bottom:2em;}.sidebar-elems .block li a{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}.sidebar-crate{display:flex;align-items:center;justify-content:center;margin:14px 32px 1rem;row-gap:10px;column-gap:32px;flex-wrap:wrap;}.sidebar-crate h2{flex-grow:1;margin:0 -8px;align-self:start;}.sidebar-crate .logo-container{margin:0 -16px 0 -16px;text-align:center;}.sidebar-crate h2 a{display:block;margin:0 calc(-24px + 0.25rem) 0 -0.2rem;padding:calc((16px - 0.57rem ) / 2 ) 0.25rem;padding-left:0.2rem;}.sidebar-crate h2 .version{display:block;font-weight:normal;font-size:1rem;overflow-wrap:break-word;}.sidebar-crate+.version{margin-top:-1rem;margin-bottom:1rem;}.mobile-topbar{display:none;}.rustdoc .example-wrap{display:flex;position:relative;margin-bottom:10px;}.rustdoc .example-wrap:last-child{margin-bottom:0px;}.rustdoc .example-wrap pre{margin:0;flex-grow:1;}.rustdoc:not(.src) .example-wrap pre{overflow:auto hidden;}.rustdoc .example-wrap pre.example-line-numbers,.rustdoc .example-wrap pre.src-line-numbers{flex-grow:0;min-width:fit-content;overflow:initial;text-align:right;-webkit-user-select:none;user-select:none;padding:14px 8px;color:var(--src-line-numbers-span-color);}.rustdoc .example-wrap pre.src-line-numbers{padding:14px 0;}.src-line-numbers a,.src-line-numbers span{color:var(--src-line-numbers-span-color);padding:0 8px;}.src-line-numbers :target{background-color:transparent;border-right:none;padding:0 8px;}.src-line-numbers .line-highlighted{background-color:var(--src-line-number-highlighted-background-color);}.search-loading{text-align:center;}.docblock-short{overflow-wrap:break-word;overflow-wrap:anywhere;}.docblock :not(pre)>code,.docblock-short code{white-space:pre-wrap;}.top-doc .docblock h2{font-size:1.375rem;}.top-doc .docblock h3{font-size:1.25rem;}.top-doc .docblock h4,.top-doc .docblock h5{font-size:1.125rem;}.top-doc .docblock h6{font-size:1rem;}.docblock h5{font-size:1rem;}.docblock h6{font-size:0.875rem;}.docblock{margin-left:24px;position:relative;}.docblock>:not(.more-examples-toggle):not(.example-wrap){max-width:100%;overflow-x:auto;}.out-of-band{flex-grow:0;font-size:1.125rem;}.docblock code,.docblock-short code,pre,.rustdoc.src .example-wrap{background-color:var(--code-block-background-color);}#main-content{position:relative;}.docblock table{margin:.5em 0;border-collapse:collapse;}.docblock table td,.docblock table th{padding:.5em;border:1px solid var(--border-color);}.docblock table tbody tr:nth-child(2n){background:var(--table-alt-row-background-color);}div.where{white-space:pre-wrap;font-size:0.875rem;}.item-info{display:block;margin-left:24px;}.item-info code{font-size:0.875rem;}#main-content>.item-info{margin-left:0;}nav.sub{flex-grow:1;flex-flow:row nowrap;margin:4px 0 25px 0;display:flex;align-items:center;}.search-form{position:relative;display:flex;height:34px;flex-grow:1;}.src nav.sub{margin:0 0 15px 0;}.section-header{display:block;position:relative;}.section-header:hover>.anchor,.impl:hover>.anchor,.trait-impl:hover>.anchor,.variant:hover>.anchor{display:initial;}.anchor{display:none;position:absolute;left:-0.5em;background:none !important;}.anchor.field{left:-5px;}.section-header>.anchor{left:-15px;padding-right:8px;}h2.section-header>.anchor{padding-right:6px;}a.doc-anchor{color:var(--main-color);display:none;position:absolute;left:-17px;padding-right:5px;padding-left:3px;}*:hover>.doc-anchor{display:block;}.top-doc>.docblock>*:first-child>.doc-anchor{display:none !important;}.main-heading a:hover,.example-wrap .rust a:hover,.all-items a:hover,.docblock a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover:not(.doc-anchor),.docblock-short a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.item-info a{text-decoration:underline;}.crate.block li.current a{font-weight:500;}table,.item-table{overflow-wrap:break-word;}.item-table{display:table;padding:0;margin:0;}.item-table>li{display:table-row;}.item-table>li>div{display:table-cell;}.item-table>li>.item-name{padding-right:1.25rem;}.search-results-title{margin-top:0;white-space:nowrap;display:flex;align-items:baseline;}#crate-search-div{position:relative;min-width:5em;}#crate-search{min-width:115px;padding:0 23px 0 4px;max-width:100%;text-overflow:ellipsis;border:1px solid var(--border-color);border-radius:4px;outline:none;cursor:pointer;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;background-color:var(--main-background-color);color:inherit;line-height:1.5;font-weight:500;}#crate-search:hover,#crate-search:focus{border-color:var(--crate-search-hover-border);}#crate-search-div::after{pointer-events:none;width:100%;height:100%;position:absolute;top:0;left:0;content:"";background-repeat:no-repeat;background-size:20px;background-position:calc(100% - 2px) 56%;background-image:url('data:image/svg+xml, \ + ');filter:var(--crate-search-div-filter);}#crate-search-div:hover::after,#crate-search-div:focus-within::after{filter:var(--crate-search-div-hover-filter);}#crate-search>option{font-size:1rem;}.search-input{-webkit-appearance:none;outline:none;border:1px solid var(--border-color);border-radius:2px;padding:8px;font-size:1rem;flex-grow:1;background-color:var(--button-background-color);color:var(--search-color);}.search-input:focus{border-color:var(--search-input-focused-border-color);}.search-results{display:none;}.search-results.active{display:block;}.search-results>a{display:flex;margin-left:2px;margin-right:2px;border-bottom:1px solid var(--search-result-border-color);gap:1em;}.search-results>a>div.desc{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex:2;}.search-results a:hover,.search-results a:focus{background-color:var(--search-result-link-focus-background-color);}.search-results .result-name{display:flex;align-items:center;justify-content:start;flex:3;}.search-results .result-name .alias{color:var(--search-results-alias-color);}.search-results .result-name .grey{color:var(--search-results-grey-color);}.search-results .result-name .typename{color:var(--search-results-grey-color);font-size:0.875rem;width:var(--search-typename-width);}.search-results .result-name .path{word-break:break-all;max-width:calc(100% - var(--search-typename-width));display:inline-block;}.search-results .result-name .path>*{display:inline;}.popover{position:absolute;top:100%;right:0;z-index:calc(var(--desktop-sidebar-z-index) + 1);margin-top:7px;border-radius:3px;border:1px solid var(--border-color);background-color:var(--main-background-color);color:var(--main-color);--popover-arrow-offset:11px;}.popover::before{content:'';position:absolute;right:var(--popover-arrow-offset);border:solid var(--border-color);border-width:1px 1px 0 0;background-color:var(--main-background-color);padding:4px;transform:rotate(-45deg);top:-5px;}.setting-line{margin:1.2em 0.6em;}.setting-radio input,.setting-check input{margin-right:0.3em;height:1.2rem;width:1.2rem;border:2px solid var(--settings-input-border-color);outline:none;-webkit-appearance:none;cursor:pointer;}.setting-radio input{border-radius:50%;}.setting-radio span,.setting-check span{padding-bottom:1px;}.setting-radio{margin-top:0.1em;margin-bottom:0.1em;min-width:3.8em;padding:0.3em;display:inline-flex;align-items:center;cursor:pointer;}.setting-radio+.setting-radio{margin-left:0.5em;}.setting-check{margin-right:20px;display:flex;align-items:center;cursor:pointer;}.setting-radio input:checked{box-shadow:inset 0 0 0 3px var(--main-background-color);background-color:var(--settings-input-color);}.setting-check input:checked{background-color:var(--settings-input-color);border-width:1px;content:url('data:image/svg+xml,\ + \ + ');}.setting-radio input:focus,.setting-check input:focus{box-shadow:0 0 1px 1px var(--settings-input-color);}.setting-radio input:checked:focus{box-shadow:inset 0 0 0 3px var(--main-background-color),0 0 2px 2px var(--settings-input-color);}.setting-radio input:hover,.setting-check input:hover{border-color:var(--settings-input-color) !important;}#help.popover{max-width:600px;--popover-arrow-offset:48px;}#help dt{float:left;clear:left;margin-right:0.5rem;}#help span.top,#help span.bottom{text-align:center;display:block;font-size:1.125rem;}#help span.top{margin:10px 0;border-bottom:1px solid var(--border-color);padding-bottom:4px;margin-bottom:6px;}#help span.bottom{clear:both;border-top:1px solid var(--border-color);}.side-by-side>div{width:50%;float:left;padding:0 20px 20px 17px;}.item-info .stab{display:block;padding:3px;margin-bottom:5px;}.item-name .stab{margin-left:0.3125em;}.stab{padding:0 2px;font-size:0.875rem;font-weight:normal;color:var(--main-color);background-color:var(--stab-background-color);width:fit-content;white-space:pre-wrap;border-radius:3px;display:inline;vertical-align:baseline;}.stab.portability>code{background:none;color:var(--stab-code-color);}.stab .emoji,.item-info .stab::before{font-size:1.25rem;}.stab .emoji{margin-right:0.3rem;}.item-info .stab::before{content:"\0";width:0;display:inline-block;color:transparent;}.emoji{text-shadow:1px 0 0 black,-1px 0 0 black,0 1px 0 black,0 -1px 0 black;}.since{font-weight:normal;font-size:initial;}.rightside{padding-left:12px;float:right;}.rightside:not(a),.out-of-band{color:var(--right-side-color);}pre.rust{tab-size:4;-moz-tab-size:4;}pre.rust .kw{color:var(--code-highlight-kw-color);}pre.rust .kw-2{color:var(--code-highlight-kw-2-color);}pre.rust .lifetime{color:var(--code-highlight-lifetime-color);}pre.rust .prelude-ty{color:var(--code-highlight-prelude-color);}pre.rust .prelude-val{color:var(--code-highlight-prelude-val-color);}pre.rust .string{color:var(--code-highlight-string-color);}pre.rust .number{color:var(--code-highlight-number-color);}pre.rust .bool-val{color:var(--code-highlight-literal-color);}pre.rust .self{color:var(--code-highlight-self-color);}pre.rust .attr{color:var(--code-highlight-attribute-color);}pre.rust .macro,pre.rust .macro-nonterminal{color:var(--code-highlight-macro-color);}pre.rust .question-mark{font-weight:bold;color:var(--code-highlight-question-mark-color);}pre.rust .comment{color:var(--code-highlight-comment-color);}pre.rust .doccomment{color:var(--code-highlight-doc-comment-color);}.rustdoc.src .example-wrap pre.rust a{background:var(--codeblock-link-background);}.example-wrap.compile_fail,.example-wrap.should_panic{border-left:2px solid var(--codeblock-error-color);}.ignore.example-wrap{border-left:2px solid var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover,.example-wrap.should_panic:hover{border-left:2px solid var(--codeblock-error-hover-color);}.example-wrap.ignore:hover{border-left:2px solid var(--codeblock-ignore-hover-color);}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip{color:var(--codeblock-error-color);}.example-wrap.ignore .tooltip{color:var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover .tooltip,.example-wrap.should_panic:hover .tooltip{color:var(--codeblock-error-hover-color);}.example-wrap.ignore:hover .tooltip{color:var(--codeblock-ignore-hover-color);}.example-wrap .tooltip{position:absolute;display:block;left:-25px;top:5px;margin:0;line-height:1;}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip,.example-wrap.ignore .tooltip{font-weight:bold;font-size:1.25rem;}.content .docblock .warning{border-left:2px solid var(--warning-border-color);padding:14px;position:relative;overflow-x:visible !important;}.content .docblock .warning::before{color:var(--warning-border-color);content:"ⓘ";position:absolute;left:-25px;top:5px;font-weight:bold;font-size:1.25rem;}.top-doc>.docblock>.warning:first-child::before{top:20px;}a.test-arrow{visibility:hidden;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:1.375rem;top:5px;right:5px;z-index:1;color:var(--test-arrow-color);background-color:var(--test-arrow-background-color);}a.test-arrow:hover{color:var(--test-arrow-hover-color);background-color:var(--test-arrow-hover-background-color);}.example-wrap:hover .test-arrow{visibility:visible;}.code-attribute{font-weight:300;color:var(--code-attribute-color);}.item-spacer{width:100%;height:12px;display:block;}.out-of-band>span.since{font-size:1.25rem;}.sub-variant h4{font-size:1rem;font-weight:400;margin-top:0;margin-bottom:0;}.sub-variant{margin-left:24px;margin-bottom:40px;}.sub-variant>.sub-variant-field{margin-left:24px;}:target{padding-right:3px;background-color:var(--target-background-color);border-right:3px solid var(--target-border-color);}.code-header a.tooltip{color:inherit;margin-right:15px;position:relative;}.code-header a.tooltip:hover{color:var(--link-color);}a.tooltip:hover::after{position:absolute;top:calc(100% - 10px);left:-15px;right:-15px;height:20px;content:"\00a0";}.fade-out{opacity:0;transition:opacity 0.45s cubic-bezier(0,0,0.1,1.0);}.popover.tooltip .content{margin:0.25em 0.5em;}.popover.tooltip .content pre,.popover.tooltip .content code{background:transparent;margin:0;padding:0;font-size:1.25rem;white-space:pre-wrap;}.popover.tooltip .content>h3:first-child{margin:0 0 5px 0;}.search-failed{text-align:center;margin-top:20px;display:none;}.search-failed.active{display:block;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#search-tabs{display:flex;flex-direction:row;gap:1px;margin-bottom:4px;}#search-tabs button{text-align:center;font-size:1.125rem;border:0;border-top:2px solid;flex:1;line-height:1.5;color:inherit;}#search-tabs button:not(.selected){background-color:var(--search-tab-button-not-selected-background);border-top-color:var(--search-tab-button-not-selected-border-top-color);}#search-tabs button:hover,#search-tabs button.selected{background-color:var(--search-tab-button-selected-background);border-top-color:var(--search-tab-button-selected-border-top-color);}#search-tabs .count{font-size:1rem;font-variant-numeric:tabular-nums;color:var(--search-tab-title-count-color);}#search .error code{border-radius:3px;background-color:var(--search-error-code-background-color);}.search-corrections{font-weight:normal;}#src-sidebar{width:100%;overflow:auto;}#src-sidebar div.files>a:hover,details.dir-entry summary:hover,#src-sidebar div.files>a:focus,details.dir-entry summary:focus{background-color:var(--src-sidebar-background-hover);}#src-sidebar div.files>a.selected{background-color:var(--src-sidebar-background-selected);}.src-sidebar-title{position:sticky;top:0;display:flex;padding:8px 8px 0 48px;margin-bottom:7px;background:var(--sidebar-background-color);border-bottom:1px solid var(--border-color);}#settings-menu,#help-button{margin-left:4px;display:flex;}#sidebar-button{display:none;line-height:0;}.hide-sidebar #sidebar-button,.src #sidebar-button{display:flex;margin-right:4px;position:fixed;left:6px;height:34px;width:34px;background-color:var(--main-background-color);z-index:1;}.src #sidebar-button{left:8px;z-index:calc(var(--desktop-sidebar-z-index) + 1);}.hide-sidebar .src #sidebar-button{position:static;}#settings-menu>a,#help-button>a,#sidebar-button>a{display:flex;align-items:center;justify-content:center;background-color:var(--button-background-color);border:1px solid var(--border-color);border-radius:2px;color:var(--settings-button-color);font-size:20px;width:33px;}#settings-menu>a:hover,#settings-menu>a:focus,#help-button>a:hover,#help-button>a:focus,#sidebar-button>a:hover,#sidebar-button>a:focus{border-color:var(--settings-button-border-focus);}#settings-menu>a{line-height:0;font-size:0;}#settings-menu>a:before{content:url('data:image/svg+xml,\ + ');width:22px;height:22px;filter:var(--settings-menu-filter);}#sidebar-button>a:before{content:url('data:image/svg+xml,\ + \ + \ + ');width:22px;height:22px;}#copy-path{color:var(--copy-path-button-color);background:var(--main-background-color);height:34px;width:33px;margin-left:10px;padding:0;padding-left:2px;border:0;font-size:0;}#copy-path::before{filter:var(--copy-path-img-filter);content:url('data:image/svg+xml,\ +\ +\ +');width:19px;height:18px;}#copy-path:hover::before{filter:var(--copy-path-img-hover-filter);}#copy-path.clicked::before{content:url('data:image/svg+xml,\ + \ + ');}@keyframes rotating{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}#settings-menu.rotate>a img{animation:rotating 2s linear infinite;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px var(--border-color);border-radius:3px;color:var(--kbd-color);background-color:var(--kbd-background);box-shadow:inset 0 -1px 0 var(--kbd-box-shadow-color);}ul.all-items>li{list-style:none;}details.dir-entry{padding-left:4px;}details.dir-entry>summary{margin:0 0 0 -4px;padding:0 0 0 4px;cursor:pointer;}details.dir-entry div.folders,details.dir-entry div.files{padding-left:23px;}details.dir-entry a{display:block;}details.toggle{contain:layout;position:relative;}details.toggle>summary.hideme{cursor:pointer;font-size:1rem;}details.toggle>summary{list-style:none;outline:none;}details.toggle>summary::-webkit-details-marker,details.toggle>summary::marker{display:none;}details.toggle>summary.hideme>span{margin-left:9px;}details.toggle>summary::before{background:url('data:image/svg+xml,') no-repeat top left;content:"";cursor:pointer;width:16px;height:16px;display:inline-block;vertical-align:middle;opacity:.5;filter:var(--toggle-filter);}details.toggle>summary.hideme>span,.more-examples-toggle summary,.more-examples-toggle .hide-more{color:var(--toggles-color);}details.toggle>summary::after{content:"Expand";overflow:hidden;width:0;height:0;position:absolute;}details.toggle>summary.hideme::after{content:"";}details.toggle>summary:focus::before,details.toggle>summary:hover::before{opacity:1;}details.toggle>summary:focus-visible::before{outline:1px dotted #000;outline-offset:1px;}details.non-exhaustive{margin-bottom:8px;}details.toggle>summary.hideme::before{position:relative;}details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;top:4px;}.impl-items>details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;}details.toggle[open] >summary.hideme{position:absolute;}details.toggle[open] >summary.hideme>span{display:none;}details.toggle[open] >summary::before{background:url('data:image/svg+xml,') no-repeat top left;}details.toggle[open] >summary::after{content:"Collapse";}.docblock summary>*{display:inline-block;}.docblock>.example-wrap:first-child .tooltip{margin-top:16px;}.src #sidebar-button>a:before,.sidebar-menu-toggle:before{content:url('data:image/svg+xml,\ + ');opacity:0.75;}.sidebar-menu-toggle:hover:before,.sidebar-menu-toggle:active:before,.sidebar-menu-toggle:focus:before{opacity:1;}.src #sidebar-button>a:before{content:url('data:image/svg+xml,\ + \ + \ + ');opacity:0.75;}@media (max-width:850px){#search-tabs .count{display:block;}}@media (max-width:700px){*[id]{scroll-margin-top:45px;}.rustdoc{display:block;}main{padding-left:15px;padding-top:0px;}.main-heading{flex-direction:column;}.out-of-band{text-align:left;margin-left:initial;padding:initial;}.out-of-band .since::before{content:"Since ";}.sidebar .logo-container,.sidebar .location,.sidebar-resizer{display:none;}.sidebar{position:fixed;top:45px;left:-1000px;z-index:11;height:calc(100vh - 45px);width:200px;}.src main,.rustdoc.src .sidebar{top:0;padding:0;height:100vh;border:0;}.src .search-form{margin-left:40px;}.hide-sidebar .search-form{margin-left:32px;}.hide-sidebar .src .search-form{margin-left:0;}.sidebar.shown,.src-sidebar-expanded .src .sidebar,.rustdoc:not(.src) .sidebar:focus-within{left:0;}.mobile-topbar h2{padding-bottom:0;margin:auto 0.5em auto auto;overflow:hidden;font-size:24px;white-space:nowrap;text-overflow:ellipsis;}.mobile-topbar .logo-container>img{max-width:35px;max-height:35px;margin:5px 0 5px 20px;}.mobile-topbar{display:flex;flex-direction:row;position:sticky;z-index:10;font-size:2rem;height:45px;width:100%;left:0;top:0;}.hide-sidebar .mobile-topbar{display:none;}.sidebar-menu-toggle{width:45px;border:none;line-height:0;}.hide-sidebar .sidebar-menu-toggle{display:none;}.sidebar-elems{margin-top:1em;}.anchor{display:none !important;}#main-content>details.toggle>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}#copy-path,#help-button{display:none;}#sidebar-button>a:before{content:url('data:image/svg+xml,\ + \ + \ + ');width:22px;height:22px;}.sidebar-menu-toggle:before{filter:var(--mobile-sidebar-menu-filter);}.sidebar-menu-toggle:hover{background:var(--main-background-color);}.item-table,.item-row,.item-table>li,.item-table>li>div,.search-results>a,.search-results>a>div{display:block;}.search-results>a{padding:5px 0px;}.search-results>a>div.desc,.item-table>li>div.desc{padding-left:2em;}.search-results .result-name{display:block;}.search-results .result-name .typename{width:initial;margin-right:0;}.search-results .result-name .typename,.search-results .result-name .path{display:inline;}.src-sidebar-expanded .src .sidebar{position:fixed;max-width:100vw;width:100vw;}.src .src-sidebar-title{padding-top:0;}details.toggle:not(.top-doc)>summary{margin-left:10px;}.impl-items>details.toggle>summary:not(.hideme)::before,#main-content>details.toggle:not(.top-doc)>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}.impl-items>.item-info{margin-left:34px;}.src nav.sub{margin:0;padding:var(--nav-sub-mobile-padding);}}@media (min-width:701px){.scraped-example-title{position:absolute;z-index:10;background:var(--main-background-color);bottom:8px;right:5px;padding:2px 4px;box-shadow:0 0 4px var(--main-background-color);}}@media print{nav.sidebar,nav.sub,.out-of-band,a.src,#copy-path,details.toggle[open] >summary::before,details.toggle>summary::before,details.toggle.top-doc>summary{display:none;}.docblock{margin-left:0;}main{padding:10px;}}@media (max-width:464px){.docblock{margin-left:12px;}.docblock code{overflow-wrap:break-word;overflow-wrap:anywhere;}nav.sub{flex-direction:column;}.search-form{align-self:stretch;}}.variant,.implementors-toggle>summary,.impl,#implementors-list>.docblock,.impl-items>section,.impl-items>.toggle>summary,.methods>section,.methods>.toggle>summary{margin-bottom:0.75em;}.variants>.docblock,.implementors-toggle>.docblock,.impl-items>.toggle[open]:not(:last-child),.methods>.toggle[open]:not(:last-child),.implementors-toggle[open]:not(:last-child){margin-bottom:2em;}#trait-implementations-list .impl-items>.toggle:not(:last-child),#synthetic-implementations-list .impl-items>.toggle:not(:last-child),#blanket-implementations-list .impl-items>.toggle:not(:last-child){margin-bottom:1em;}.scraped-example-list .scrape-help{margin-left:10px;padding:0 4px;font-weight:normal;font-size:12px;position:relative;bottom:1px;border:1px solid var(--scrape-example-help-border-color);border-radius:50px;color:var(--scrape-example-help-color);}.scraped-example-list .scrape-help:hover{border-color:var(--scrape-example-help-hover-border-color);color:var(--scrape-example-help-hover-color);}.scraped-example{position:relative;}.scraped-example .code-wrapper{position:relative;display:flex;flex-direction:row;flex-wrap:wrap;width:100%;}.scraped-example:not(.expanded) .code-wrapper{max-height:calc(1.5em * 5 + 10px);}.scraped-example:not(.expanded) .code-wrapper pre{overflow-y:hidden;padding-bottom:0;max-height:calc(1.5em * 5 + 10px);}.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper,.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre{max-height:calc(1.5em * 10 + 10px);}.scraped-example .code-wrapper .next,.scraped-example .code-wrapper .prev,.scraped-example .code-wrapper .expand{color:var(--main-color);position:absolute;top:0.25em;z-index:1;padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.scraped-example .code-wrapper .prev{right:2.25em;}.scraped-example .code-wrapper .next{right:1.25em;}.scraped-example .code-wrapper .expand{right:0.25em;}.scraped-example:not(.expanded) .code-wrapper::before,.scraped-example:not(.expanded) .code-wrapper::after{content:" ";width:100%;height:5px;position:absolute;z-index:1;}.scraped-example:not(.expanded) .code-wrapper::before{top:0;background:linear-gradient(to bottom,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example:not(.expanded) .code-wrapper::after{bottom:0;background:linear-gradient(to top,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example .code-wrapper .example-wrap{width:100%;overflow-y:hidden;margin-bottom:0;}.scraped-example:not(.expanded) .code-wrapper .example-wrap{overflow-x:hidden;}.scraped-example .example-wrap .rust span.highlight{background:var(--scrape-example-code-line-highlight);}.scraped-example .example-wrap .rust span.highlight.focus{background:var(--scrape-example-code-line-highlight-focus);}.more-examples-toggle{max-width:calc(100% + 25px);margin-top:10px;margin-left:-25px;}.more-examples-toggle .hide-more{margin-left:25px;cursor:pointer;}.more-scraped-examples{margin-left:25px;position:relative;}.toggle-line{position:absolute;top:5px;bottom:0;right:calc(100% + 10px);padding:0 4px;cursor:pointer;}.toggle-line-inner{min-width:2px;height:100%;background:var(--scrape-example-toggle-line-background);}.toggle-line:hover .toggle-line-inner{background:var(--scrape-example-toggle-line-hover-background);}.more-scraped-examples .scraped-example,.example-links{margin-top:20px;}.more-scraped-examples .scraped-example:first-child{margin-top:5px;}.example-links ul{margin-bottom:0;}:root[data-theme="light"],:root:not([data-theme]){--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#f5f5f5;--sidebar-background-color-hover:#e0e0e0;--code-block-background-color:#f5f5f5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--mobile-sidebar-menu-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#fff;--settings-menu-filter:none;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#f5f5f5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);--sidebar-resizer-hover:hsl(207,90%,66%);--sidebar-resizer-active:hsl(207,90%,54%);}:root[data-theme="dark"]{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--mobile-sidebar-menu-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--settings-menu-filter:none;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2a2a2a;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);--sidebar-resizer-hover:hsl(207,30%,54%);--sidebar-resizer-active:hsl(207,90%,54%);}:root[data-theme="ayu"]{--main-background-color:#0f1419;--main-color:#c5c5c5;--settings-input-color:#ffb454;--settings-input-border-color:#999;--settings-button-color:#fff;--settings-button-border-focus:#e0e0e0;--sidebar-background-color:#14191f;--sidebar-background-color-hover:rgba(70,70,70,0.33);--code-block-background-color:#191f26;--scrollbar-track-background-color:transparent;--scrollbar-thumb-background-color:#5c6773;--scrollbar-color:#5c6773 #24292f;--headings-border-bottom-color:#5c6773;--border-color:#5c6773;--button-background-color:#141920;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--mobile-sidebar-menu-filter:invert(100%);--search-input-focused-border-color:#5c6773;--copy-path-button-color:#fff;--copy-path-img-filter:invert(70%);--copy-path-img-hover-filter:invert(100%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ffa0a5;--trait-link-color:#39afd7;--assoc-item-link-color:#39afd7;--function-link-color:#fdd687;--macro-link-color:#a37acc;--keyword-link-color:#39afd7;--mod-link-color:#39afd7;--link-color:#39afd7;--sidebar-link-color:#53b1db;--sidebar-current-link-background-color:transparent;--search-result-link-focus-background-color:#3c3c3c;--search-result-border-color:#aaa3;--search-color:#fff;--search-error-code-background-color:#4f4c4c;--search-results-alias-color:#c5c5c5;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:none;--search-tab-button-not-selected-background:transparent !important;--search-tab-button-selected-border-top-color:none;--search-tab-button-selected-background:#141920 !important;--settings-menu-filter:invert(100%);--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ff7733;--code-highlight-kw-2-color:#ff7733;--code-highlight-lifetime-color:#ff7733;--code-highlight-prelude-color:#69f2df;--code-highlight-prelude-val-color:#ff7733;--code-highlight-number-color:#b8cc52;--code-highlight-string-color:#b8cc52;--code-highlight-literal-color:#ff7733;--code-highlight-attribute-color:#e6e1cf;--code-highlight-self-color:#36a3d9;--code-highlight-macro-color:#a37acc;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#788797;--code-highlight-doc-comment-color:#a1ac88;--src-line-numbers-span-color:#5c6773;--src-line-number-highlighted-background-color:rgba(255,236,164,0.06);--test-arrow-color:#788797;--test-arrow-background-color:rgba(57,175,215,0.09);--test-arrow-hover-color:#c5c5c5;--test-arrow-hover-background-color:rgba(57,175,215,0.368);--target-background-color:rgba(255,236,164,0.06);--target-border-color:rgba(255,180,76,0.85);--kbd-color:#c5c5c5;--kbd-background:#314559;--kbd-box-shadow-color:#5c6773;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg) brightness(94%) contrast(94%);--crate-search-div-hover-filter:invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg) brightness(113%) contrast(76%);--crate-search-hover-border:#e0e0e0;--src-sidebar-background-selected:#14191f;--src-sidebar-background-hover:#14191f;--table-alt-row-background-color:#191f26;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(15,20,25,1);--scrape-example-code-wrapper-background-end:rgba(15,20,25,0);--sidebar-resizer-hover:hsl(34,50%,33%);--sidebar-resizer-active:hsl(34,100%,66%);}:root[data-theme="ayu"] h1,:root[data-theme="ayu"] h2,:root[data-theme="ayu"] h3,:root[data-theme="ayu"] h4,:where(:root[data-theme="ayu"]) h1 a,:root[data-theme="ayu"] .sidebar h2 a,:root[data-theme="ayu"] .sidebar h3 a{color:#fff;}:root[data-theme="ayu"] .docblock code{color:#ffb454;}:root[data-theme="ayu"] .docblock a>code{color:#39AFD7 !important;}:root[data-theme="ayu"] .code-header,:root[data-theme="ayu"] .docblock pre>code,:root[data-theme="ayu"] pre,:root[data-theme="ayu"] pre>code,:root[data-theme="ayu"] .item-info code,:root[data-theme="ayu"] .rustdoc.source .example-wrap{color:#e6e1cf;}:root[data-theme="ayu"] .sidebar .current,:root[data-theme="ayu"] .sidebar .current a,:root[data-theme="ayu"] .sidebar a:hover,:root[data-theme="ayu"] #src-sidebar div.files>a:hover,:root[data-theme="ayu"] details.dir-entry summary:hover,:root[data-theme="ayu"] #src-sidebar div.files>a:focus,:root[data-theme="ayu"] details.dir-entry summary:focus,:root[data-theme="ayu"] #src-sidebar div.files>a.selected{color:#ffb44c;}:root[data-theme="ayu"] .sidebar-elems .location{color:#ff7733;}:root[data-theme="ayu"] .src-line-numbers .line-highlighted{color:#708090;padding-right:7px;border-right:1px solid #ffb44c;}:root[data-theme="ayu"] .search-results a:hover,:root[data-theme="ayu"] .search-results a:focus{color:#fff !important;background-color:#3c3c3c;}:root[data-theme="ayu"] .search-results a{color:#0096cf;}:root[data-theme="ayu"] .search-results a div.desc{color:#c5c5c5;}:root[data-theme="ayu"] .result-name .primitive>i,:root[data-theme="ayu"] .result-name .keyword>i{color:#788797;}:root[data-theme="ayu"] #search-tabs>button.selected{border-bottom:1px solid #ffb44c !important;border-top:none;}:root[data-theme="ayu"] #search-tabs>button:not(.selected){border:none;background-color:transparent !important;}:root[data-theme="ayu"] #search-tabs>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}:root[data-theme="ayu"] #settings-menu>a img,:root[data-theme="ayu"] #sidebar-button>a:before{filter:invert(100);} \ No newline at end of file diff --git a/static.files/scrape-examples-ef1e698c1d417c0c.js b/static.files/scrape-examples-ef1e698c1d417c0c.js new file mode 100644 index 000000000..ba830e374 --- /dev/null +++ b/static.files/scrape-examples-ef1e698c1d417c0c.js @@ -0,0 +1 @@ +"use strict";(function(){const DEFAULT_MAX_LINES=5;const HIDDEN_MAX_LINES=10;function scrollToLoc(elt,loc,isHidden){const lines=elt.querySelector(".src-line-numbers");let scrollOffset;const maxLines=isHidden?HIDDEN_MAX_LINES:DEFAULT_MAX_LINES;if(loc[1]-loc[0]>maxLines){const line=Math.max(0,loc[0]-1);scrollOffset=lines.children[line].offsetTop}else{const wrapper=elt.querySelector(".code-wrapper");const halfHeight=wrapper.offsetHeight/2;const offsetTop=lines.children[loc[0]].offsetTop;const lastLine=lines.children[loc[1]];const offsetBot=lastLine.offsetTop+lastLine.offsetHeight;const offsetMid=(offsetTop+offsetBot)/2;scrollOffset=offsetMid-halfHeight}lines.scrollTo(0,scrollOffset);elt.querySelector(".rust").scrollTo(0,scrollOffset)}function updateScrapedExample(example,isHidden){const locs=JSON.parse(example.attributes.getNamedItem("data-locs").textContent);let locIndex=0;const highlights=Array.prototype.slice.call(example.querySelectorAll(".highlight"));const link=example.querySelector(".scraped-example-title a");if(locs.length>1){const onChangeLoc=changeIndex=>{removeClass(highlights[locIndex],"focus");changeIndex();scrollToLoc(example,locs[locIndex][0],isHidden);addClass(highlights[locIndex],"focus");const url=locs[locIndex][1];const title=locs[locIndex][2];link.href=url;link.innerHTML=title};example.querySelector(".prev").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex-1+locs.length)%locs.length})});example.querySelector(".next").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex+1)%locs.length})})}const expandButton=example.querySelector(".expand");if(expandButton){expandButton.addEventListener("click",()=>{if(hasClass(example,"expanded")){removeClass(example,"expanded");scrollToLoc(example,locs[0][0],isHidden)}else{addClass(example,"expanded")}})}scrollToLoc(example,locs[0][0],isHidden)}const firstExamples=document.querySelectorAll(".scraped-example-list > .scraped-example");onEachLazy(firstExamples,el=>updateScrapedExample(el,false));onEachLazy(document.querySelectorAll(".more-examples-toggle"),toggle=>{onEachLazy(toggle.querySelectorAll(".toggle-line, .hide-more"),button=>{button.addEventListener("click",()=>{toggle.open=false})});const moreExamples=toggle.querySelectorAll(".scraped-example");toggle.querySelector("summary").addEventListener("click",()=>{setTimeout(()=>{onEachLazy(moreExamples,el=>updateScrapedExample(el,true))})},{once:true})})})() \ No newline at end of file diff --git a/static.files/search-d52510db62a78183.js b/static.files/search-d52510db62a78183.js new file mode 100644 index 000000000..a2824f297 --- /dev/null +++ b/static.files/search-d52510db62a78183.js @@ -0,0 +1,5 @@ +"use strict";if(!Array.prototype.toSpliced){Array.prototype.toSpliced=function(){const me=this.slice();Array.prototype.splice.apply(me,arguments);return me}}(function(){const itemTypes=["keyword","primitive","mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","associatedtype","constant","associatedconstant","union","foreigntype","existential","attr","derive","traitalias","generic",];const longItemTypes=["keyword","primitive type","module","extern crate","re-export","struct","enum","function","type alias","static","trait","","trait method","method","struct field","enum variant","macro","assoc type","constant","assoc const","union","foreign type","existential type","attribute macro","derive macro","trait alias",];const TY_GENERIC=itemTypes.indexOf("generic");const TY_IMPORT=itemTypes.indexOf("import");const ROOT_PATH=typeof window!=="undefined"?window.rootPath:"../";const UNBOXING_LIMIT=5;function printTab(nb){let iter=0;let foundCurrentTab=false;let foundCurrentResultSet=false;onEachLazy(document.getElementById("search-tabs").childNodes,elem=>{if(nb===iter){addClass(elem,"selected");foundCurrentTab=true}else{removeClass(elem,"selected")}iter+=1});const isTypeSearch=(nb>0||iter===1);iter=0;onEachLazy(document.getElementById("results").childNodes,elem=>{if(nb===iter){addClass(elem,"active");foundCurrentResultSet=true}else{removeClass(elem,"active")}iter+=1});if(foundCurrentTab&&foundCurrentResultSet){searchState.currentTab=nb;const correctionsElem=document.getElementsByClassName("search-corrections");if(isTypeSearch){removeClass(correctionsElem[0],"hidden")}else{addClass(correctionsElem[0],"hidden")}}else if(nb!==0){printTab(0)}}const editDistanceState={current:[],prev:[],prevPrev:[],calculate:function calculate(a,b,limit){if(a.lengthlimit){return limit+1}while(b.length>0&&b[0]===a[0]){a=a.substring(1);b=b.substring(1)}while(b.length>0&&b[b.length-1]===a[a.length-1]){a=a.substring(0,a.length-1);b=b.substring(0,b.length-1)}if(b.length===0){return minDist}const aLength=a.length;const bLength=b.length;for(let i=0;i<=bLength;++i){this.current[i]=0;this.prev[i]=i;this.prevPrev[i]=Number.MAX_VALUE}for(let i=1;i<=aLength;++i){this.current[0]=i;const aIdx=i-1;for(let j=1;j<=bLength;++j){const bIdx=j-1;const substitutionCost=a[aIdx]===b[bIdx]?0:1;this.current[j]=Math.min(this.prev[j]+1,this.current[j-1]+1,this.prev[j-1]+substitutionCost,);if((i>1)&&(j>1)&&(a[aIdx]===b[bIdx-1])&&(a[aIdx-1]===b[bIdx])){this.current[j]=Math.min(this.current[j],this.prevPrev[j-2]+1,)}}const prevPrevTmp=this.prevPrev;this.prevPrev=this.prev;this.prev=this.current;this.current=prevPrevTmp}const distance=this.prev[bLength];return distance<=limit?distance:(limit+1)},};function editDistance(a,b,limit){return editDistanceState.calculate(a,b,limit)}function initSearch(rawSearchIndex){const MAX_RESULTS=200;const NO_TYPE_FILTER=-1;let searchIndex;let searchIndexDeprecated;let searchIndexEmptyDesc;let functionTypeFingerprint;let currentResults;const typeNameIdMap=new Map();const ALIASES=new Map();const typeNameIdOfArray=buildTypeMapIndex("array");const typeNameIdOfSlice=buildTypeMapIndex("slice");const typeNameIdOfArrayOrSlice=buildTypeMapIndex("[]");const typeNameIdOfTuple=buildTypeMapIndex("tuple");const typeNameIdOfUnit=buildTypeMapIndex("unit");const typeNameIdOfTupleOrUnit=buildTypeMapIndex("()");const typeNameIdOfFn=buildTypeMapIndex("fn");const typeNameIdOfFnMut=buildTypeMapIndex("fnmut");const typeNameIdOfFnOnce=buildTypeMapIndex("fnonce");const typeNameIdOfHof=buildTypeMapIndex("->");function buildTypeMapIndex(name,isAssocType){if(name===""||name===null){return null}if(typeNameIdMap.has(name)){const obj=typeNameIdMap.get(name);obj.assocOnly=isAssocType&&obj.assocOnly;return obj.id}else{const id=typeNameIdMap.size;typeNameIdMap.set(name,{id,assocOnly:isAssocType});return id}}function isSpecialStartCharacter(c){return"<\"".indexOf(c)!==-1}function isEndCharacter(c){return"=,>-])".indexOf(c)!==-1}function itemTypeFromName(typename){const index=itemTypes.findIndex(i=>i===typename);if(index<0){throw["Unknown type filter ",typename]}return index}function getStringElem(query,parserState,isInGenerics){if(isInGenerics){throw["Unexpected ","\""," in generics"]}else if(query.literalSearch){throw["Cannot have more than one literal search element"]}else if(parserState.totalElems-parserState.genericsElems>0){throw["Cannot use literal search when there is more than one element"]}parserState.pos+=1;const start=parserState.pos;const end=getIdentEndPosition(parserState);if(parserState.pos>=parserState.length){throw["Unclosed ","\""]}else if(parserState.userQuery[end]!=="\""){throw["Unexpected ",parserState.userQuery[end]," in a string element"]}else if(start===end){throw["Cannot have empty string element"]}parserState.pos+=1;query.literalSearch=true}function isPathStart(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="::"}function isReturnArrow(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="->"}function isIdentCharacter(c){return(c==="_"||(c>="0"&&c<="9")||(c>="a"&&c<="z")||(c>="A"&&c<="Z"))}function isSeparatorCharacter(c){return c===","||c==="="}function isPathSeparator(c){return c===":"||c===" "}function prevIs(parserState,lookingFor){let pos=parserState.pos;while(pos>0){const c=parserState.userQuery[pos-1];if(c===lookingFor){return true}else if(c!==" "){break}pos-=1}return false}function isLastElemGeneric(elems,parserState){return(elems.length>0&&elems[elems.length-1].generics.length>0)||prevIs(parserState,">")}function skipWhitespace(parserState){while(parserState.pos0){throw["Cannot have more than one element if you use quotes"]}const typeFilter=parserState.typeFilter;parserState.typeFilter=null;if(name==="!"){if(typeFilter!==null&&typeFilter!=="primitive"){throw["Invalid search type: primitive never type ","!"," and ",typeFilter," both specified",]}if(generics.length!==0){throw["Never type ","!"," does not accept generic parameters",]}const bindingName=parserState.isInBinding;parserState.isInBinding=null;return makePrimitiveElement("never",{bindingName})}const quadcolon=/::\s*::/.exec(path);if(path.startsWith("::")){throw["Paths cannot start with ","::"]}else if(path.endsWith("::")){throw["Paths cannot end with ","::"]}else if(quadcolon!==null){throw["Unexpected ",quadcolon[0]]}const pathSegments=path.split(/(?:::\s*)|(?:\s+(?:::\s*)?)/);if(pathSegments.length===0||(pathSegments.length===1&&pathSegments[0]==="")){if(generics.length>0||prevIs(parserState,">")){throw["Found generics without a path"]}else{throw["Unexpected ",parserState.userQuery[parserState.pos]]}}for(const[i,pathSegment]of pathSegments.entries()){if(pathSegment==="!"){if(i!==0){throw["Never type ","!"," is not associated item"]}pathSegments[i]="never"}}parserState.totalElems+=1;if(isInGenerics){parserState.genericsElems+=1}const bindingName=parserState.isInBinding;parserState.isInBinding=null;const bindings=new Map();const pathLast=pathSegments[pathSegments.length-1];return{name:name.trim(),id:null,fullPath:pathSegments,pathWithoutLast:pathSegments.slice(0,pathSegments.length-1),pathLast,normalizedPathLast:pathLast.replace(/_/g,""),generics:generics.filter(gen=>{if(gen.bindingName!==null){if(gen.name!==null){gen.bindingName.generics.unshift(gen)}bindings.set(gen.bindingName.name,gen.bindingName.generics);return false}return true}),bindings,typeFilter,bindingName,}}function getIdentEndPosition(parserState){const start=parserState.pos;let end=parserState.pos;let foundExclamation=-1;while(parserState.pos0){throw["Unexpected ",c," after ",parserState.userQuery[parserState.pos-1]]}else{throw["Unexpected ",c]}}parserState.pos+=1;end=parserState.pos}if(foundExclamation!==-1&&foundExclamation!==start&&isIdentCharacter(parserState.userQuery[foundExclamation-1])){if(parserState.typeFilter===null){parserState.typeFilter="macro"}else if(parserState.typeFilter!=="macro"){throw["Invalid search type: macro ","!"," and ",parserState.typeFilter," both specified",]}end=foundExclamation}return end}function getFilteredNextElem(query,parserState,elems,isInGenerics){const start=parserState.pos;if(parserState.userQuery[parserState.pos]===":"&&!isPathStart(parserState)){throw["Expected type filter before ",":"]}getNextElem(query,parserState,elems,isInGenerics);if(parserState.userQuery[parserState.pos]===":"&&!isPathStart(parserState)){if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}if(elems.length===0){throw["Expected type filter before ",":"]}else if(query.literalSearch){throw["Cannot use quotes on type filter"]}const typeFilterElem=elems.pop();checkExtraTypeFilterCharacters(start,parserState);parserState.typeFilter=typeFilterElem.name;parserState.pos+=1;parserState.totalElems-=1;query.literalSearch=false;getNextElem(query,parserState,elems,isInGenerics)}}function getNextElem(query,parserState,elems,isInGenerics){const generics=[];skipWhitespace(parserState);let start=parserState.pos;let end;if("[(".indexOf(parserState.userQuery[parserState.pos])!==-1){let endChar=")";let name="()";let friendlyName="tuple";if(parserState.userQuery[parserState.pos]==="["){endChar="]";name="[]";friendlyName="slice"}parserState.pos+=1;const{foundSeparator}=getItemsBefore(query,parserState,generics,endChar);const typeFilter=parserState.typeFilter;const bindingName=parserState.isInBinding;parserState.typeFilter=null;parserState.isInBinding=null;for(const gen of generics){if(gen.bindingName!==null){throw["Type parameter ","=",` cannot be within ${friendlyName} `,name]}}if(name==="()"&&!foundSeparator&&generics.length===1&&typeFilter===null){elems.push(generics[0])}else if(name==="()"&&generics.length===1&&generics[0].name==="->"){generics[0].typeFilter=typeFilter;elems.push(generics[0])}else{if(typeFilter!==null&&typeFilter!=="primitive"){throw["Invalid search type: primitive ",name," and ",typeFilter," both specified",]}parserState.totalElems+=1;if(isInGenerics){parserState.genericsElems+=1}elems.push(makePrimitiveElement(name,{bindingName,generics}))}}else if(parserState.userQuery[parserState.pos]==="&"){if(parserState.typeFilter!==null&&parserState.typeFilter!=="primitive"){throw["Invalid search type: primitive ","&"," and ",parserState.typeFilter," both specified",]}parserState.typeFilter=null;parserState.pos+=1;let c=parserState.userQuery[parserState.pos];while(c===" "&&parserState.pos=end){throw["Found generics without a path"]}parserState.pos+=1;getItemsBefore(query,parserState,generics,">")}else if(parserState.pos=end){throw["Found generics without a path"]}if(parserState.isInBinding){throw["Unexpected ","("," after ","="]}parserState.pos+=1;const typeFilter=parserState.typeFilter;parserState.typeFilter=null;getItemsBefore(query,parserState,generics,")");skipWhitespace(parserState);if(isReturnArrow(parserState)){parserState.pos+=2;skipWhitespace(parserState);getFilteredNextElem(query,parserState,generics,isInGenerics);generics[generics.length-1].bindingName=makePrimitiveElement("output")}else{generics.push(makePrimitiveElement(null,{bindingName:makePrimitiveElement("output"),typeFilter:null,}))}parserState.typeFilter=typeFilter}if(isStringElem){skipWhitespace(parserState)}if(start>=end&&generics.length===0){return}if(parserState.userQuery[parserState.pos]==="="){if(parserState.isInBinding){throw["Cannot write ","="," twice in a binding"]}if(!isInGenerics){throw["Type parameter ","="," must be within generics list"]}const name=parserState.userQuery.slice(start,end).trim();if(name==="!"){throw["Type parameter ","="," key cannot be ","!"," never type"]}if(name.includes("!")){throw["Type parameter ","="," key cannot be ","!"," macro"]}if(name.includes("::")){throw["Type parameter ","="," key cannot contain ","::"," path"]}if(name.includes(":")){throw["Type parameter ","="," key cannot contain ",":"," type"]}parserState.isInBinding={name,generics}}else{elems.push(createQueryElement(query,parserState,parserState.userQuery.slice(start,end),generics,isInGenerics,),)}}}function getItemsBefore(query,parserState,elems,endChar){let foundStopChar=true;let foundSeparator=false;const oldTypeFilter=parserState.typeFilter;parserState.typeFilter=null;const oldIsInBinding=parserState.isInBinding;parserState.isInBinding=null;let hofParameters=null;let extra="";if(endChar===">"){extra="<"}else if(endChar==="]"){extra="["}else if(endChar===")"){extra="("}else if(endChar===""){extra="->"}else{extra=endChar}while(parserState.pos"," after ","="]}hofParameters=[...elems];elems.length=0;parserState.pos+=2;foundStopChar=true;foundSeparator=false;continue}else if(c===" "){parserState.pos+=1;continue}else if(isSeparatorCharacter(c)){parserState.pos+=1;foundStopChar=true;foundSeparator=true;continue}else if(c===":"&&isPathStart(parserState)){throw["Unexpected ","::",": paths cannot start with ","::"]}else if(isEndCharacter(c)){throw["Unexpected ",c," after ",extra]}if(!foundStopChar){let extra=[];if(isLastElemGeneric(query.elems,parserState)){extra=[" after ",">"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(endChar!==""){throw["Expected ",",",", ","=",", or ",endChar,...extra,", found ",c,]}throw["Expected ",","," or ","=",...extra,", found ",c,]}const posBefore=parserState.pos;getFilteredNextElem(query,parserState,elems,endChar!=="");if(endChar!==""&&parserState.pos>=parserState.length){throw["Unclosed ",extra]}if(posBefore===parserState.pos){parserState.pos+=1}foundStopChar=false}if(parserState.pos>=parserState.length&&endChar!==""){throw["Unclosed ",extra]}parserState.pos+=1;if(hofParameters){foundSeparator=false;if([...elems,...hofParameters].some(x=>x.bindingName)||parserState.isInBinding){throw["Unexpected ","="," within ","->"]}const hofElem=makePrimitiveElement("->",{generics:hofParameters,bindings:new Map([["output",[...elems]]]),typeFilter:null,});elems.length=0;elems[0]=hofElem}parserState.typeFilter=oldTypeFilter;parserState.isInBinding=oldIsInBinding;return{foundSeparator}}function checkExtraTypeFilterCharacters(start,parserState){const query=parserState.userQuery.slice(start,parserState.pos).trim();for(const c in query){if(!isIdentCharacter(query[c])){throw["Unexpected ",query[c]," in type filter (before ",":",")",]}}}function parseInput(query,parserState){let foundStopChar=true;while(parserState.pos"){if(isReturnArrow(parserState)){break}throw["Unexpected ",c," (did you mean ","->","?)"]}else if(parserState.pos>0){throw["Unexpected ",c," after ",parserState.userQuery[parserState.pos-1]]}throw["Unexpected ",c]}else if(c===" "){skipWhitespace(parserState);continue}if(!foundStopChar){let extra="";if(isLastElemGeneric(query.elems,parserState)){extra=[" after ",">"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(parserState.typeFilter!==null){throw["Expected ",","," or ","->",...extra,", found ",c,]}throw["Expected ",",",", ",":"," or ","->",...extra,", found ",c,]}const before=query.elems.length;getFilteredNextElem(query,parserState,query.elems,false);if(query.elems.length===before){parserState.pos+=1}foundStopChar=false}if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}while(parserState.pos"]}break}else{parserState.pos+=1}}}function newParsedQuery(userQuery){return{original:userQuery,userQuery:userQuery.toLowerCase(),elems:[],returned:[],foundElems:0,totalElems:0,literalSearch:false,error:null,correction:null,proposeCorrectionFrom:null,proposeCorrectionTo:null,typeFingerprint:new Uint32Array(4),}}function buildUrl(search,filterCrates){let extra="?search="+encodeURIComponent(search);if(filterCrates!==null){extra+="&filter-crate="+encodeURIComponent(filterCrates)}return getNakedUrl()+extra+window.location.hash}function getFilterCrates(){const elem=document.getElementById("crate-search");if(elem&&elem.value!=="all crates"&&rawSearchIndex.has(elem.value)){return elem.value}return null}function parseQuery(userQuery){function convertTypeFilterOnElem(elem){if(elem.typeFilter!==null){let typeFilter=elem.typeFilter;if(typeFilter==="const"){typeFilter="constant"}elem.typeFilter=itemTypeFromName(typeFilter)}else{elem.typeFilter=NO_TYPE_FILTER}for(const elem2 of elem.generics){convertTypeFilterOnElem(elem2)}for(const constraints of elem.bindings.values()){for(const constraint of constraints){convertTypeFilterOnElem(constraint)}}}userQuery=userQuery.trim().replace(/\r|\n|\t/g," ");const parserState={length:userQuery.length,pos:0,totalElems:0,genericsElems:0,typeFilter:null,isInBinding:null,userQuery:userQuery.toLowerCase(),};let query=newParsedQuery(userQuery);try{parseInput(query,parserState);for(const elem of query.elems){convertTypeFilterOnElem(elem)}for(const elem of query.returned){convertTypeFilterOnElem(elem)}}catch(err){query=newParsedQuery(userQuery);query.error=err;return query}if(!query.literalSearch){query.literalSearch=parserState.totalElems>1}query.foundElems=query.elems.length+query.returned.length;query.totalElems=parserState.totalElems;return query}function createQueryResults(results_in_args,results_returned,results_others,parsedQuery){return{"in_args":results_in_args,"returned":results_returned,"others":results_others,"query":parsedQuery,}}async function execQuery(parsedQuery,filterCrates,currentCrate){const results_others=new Map(),results_in_args=new Map(),results_returned=new Map();function transformResults(results){const duplicates=new Set();const out=[];for(const result of results){if(result.id!==-1){const obj=searchIndex[result.id];obj.dist=result.dist;const res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=res[2]+"|"+obj.ty;if(duplicates.has(obj.fullPath)){continue}if(obj.ty===TY_IMPORT&&duplicates.has(res[2])){continue}if(duplicates.has(res[2]+"|"+TY_IMPORT)){continue}duplicates.add(obj.fullPath);duplicates.add(res[2]);obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}return out}async function sortResults(results,isType,preferredCrate){const userQuery=parsedQuery.userQuery;const result_list=[];for(const result of results.values()){result.item=searchIndex[result.id];result.word=searchIndex[result.id].word;result_list.push(result)}result_list.sort((aaa,bbb)=>{let a,b;a=(aaa.word!==userQuery);b=(bbb.word!==userQuery);if(a!==b){return a-b}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.path_dist;b=bbb.path_dist;if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}a=(aaa.dist);b=(bbb.dist);if(a!==b){return a-b}a=searchIndexDeprecated.get(aaa.item.crate).contains(aaa.item.bitIndex);b=searchIndexDeprecated.get(bbb.item.crate).contains(bbb.item.bitIndex);if(a!==b){return a-b}a=(aaa.item.crate!==preferredCrate);b=(bbb.item.crate!==preferredCrate);if(a!==b){return a-b}a=aaa.word.length;b=bbb.word.length;if(a!==b){return a-b}a=aaa.word;b=bbb.word;if(a!==b){return(a>b?+1:-1)}a=searchIndexEmptyDesc.get(aaa.item.crate).contains(aaa.item.bitIndex);b=searchIndexEmptyDesc.get(bbb.item.crate).contains(bbb.item.bitIndex);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});return transformResults(result_list)}function unifyFunctionTypes(fnTypesIn,queryElems,whereClause,mgensIn,solutionCb,unboxingDepth,){if(unboxingDepth>=UNBOXING_LIMIT){return false}const mgens=mgensIn===null?null:new Map(mgensIn);if(queryElems.length===0){return!solutionCb||solutionCb(mgens)}if(!fnTypesIn||fnTypesIn.length===0){return false}const ql=queryElems.length;const fl=fnTypesIn.length;if(ql===1&&queryElems[0].generics.length===0&&queryElems[0].bindings.size===0){const queryElem=queryElems[0];for(const fnType of fnTypesIn){if(!unifyFunctionTypeIsMatchCandidate(fnType,queryElem,mgens)){continue}if(fnType.id<0&&queryElem.id<0){if(mgens&&mgens.has(fnType.id)&&mgens.get(fnType.id)!==queryElem.id){continue}const mgensScratch=new Map(mgens);mgensScratch.set(fnType.id,queryElem.id);if(!solutionCb||solutionCb(mgensScratch)){return true}}else if(!solutionCb||solutionCb(mgens?new Map(mgens):null)){return true}}for(const fnType of fnTypesIn){if(!unifyFunctionTypeIsUnboxCandidate(fnType,queryElem,whereClause,mgens,unboxingDepth+1,)){continue}if(fnType.id<0){if(mgens&&mgens.has(fnType.id)&&mgens.get(fnType.id)!==0){continue}const mgensScratch=new Map(mgens);mgensScratch.set(fnType.id,0);if(unifyFunctionTypes(whereClause[(-fnType.id)-1],queryElems,whereClause,mgensScratch,solutionCb,unboxingDepth+1,)){return true}}else if(unifyFunctionTypes([...fnType.generics,...Array.from(fnType.bindings.values()).flat()],queryElems,whereClause,mgens?new Map(mgens):null,solutionCb,unboxingDepth+1,)){return true}}return false}const fnTypes=fnTypesIn.slice();const flast=fl-1;const qlast=ql-1;const queryElem=queryElems[qlast];let queryElemsTmp=null;for(let i=flast;i>=0;i-=1){const fnType=fnTypes[i];if(!unifyFunctionTypeIsMatchCandidate(fnType,queryElem,mgens)){continue}let mgensScratch;if(fnType.id<0){mgensScratch=new Map(mgens);if(mgensScratch.has(fnType.id)&&mgensScratch.get(fnType.id)!==queryElem.id){continue}mgensScratch.set(fnType.id,queryElem.id)}else{mgensScratch=mgens}fnTypes[i]=fnTypes[flast];fnTypes.length=flast;if(!queryElemsTmp){queryElemsTmp=queryElems.slice(0,qlast)}const passesUnification=unifyFunctionTypes(fnTypes,queryElemsTmp,whereClause,mgensScratch,mgensScratch=>{if(fnType.generics.length===0&&queryElem.generics.length===0&&fnType.bindings.size===0&&queryElem.bindings.size===0){return!solutionCb||solutionCb(mgensScratch)}const solution=unifyFunctionTypeCheckBindings(fnType,queryElem,whereClause,mgensScratch,unboxingDepth,);if(!solution){return false}const simplifiedGenerics=solution.simplifiedGenerics;for(const simplifiedMgens of solution.mgens){const passesUnification=unifyFunctionTypes(simplifiedGenerics,queryElem.generics,whereClause,simplifiedMgens,solutionCb,unboxingDepth,);if(passesUnification){return true}}return false},unboxingDepth,);if(passesUnification){return true}fnTypes[flast]=fnTypes[i];fnTypes[i]=fnType;fnTypes.length=fl}for(let i=flast;i>=0;i-=1){const fnType=fnTypes[i];if(!unifyFunctionTypeIsUnboxCandidate(fnType,queryElem,whereClause,mgens,unboxingDepth+1,)){continue}let mgensScratch;if(fnType.id<0){mgensScratch=new Map(mgens);if(mgensScratch.has(fnType.id)&&mgensScratch.get(fnType.id)!==0){continue}mgensScratch.set(fnType.id,0)}else{mgensScratch=mgens}const generics=fnType.id<0?whereClause[(-fnType.id)-1]:fnType.generics;const bindings=fnType.bindings?Array.from(fnType.bindings.values()).flat():[];const passesUnification=unifyFunctionTypes(fnTypes.toSpliced(i,1,...generics,...bindings),queryElems,whereClause,mgensScratch,solutionCb,unboxingDepth+1,);if(passesUnification){return true}}return false}function unifyFunctionTypeIsMatchCandidate(fnType,queryElem,mgensIn){if(!typePassesFilter(queryElem.typeFilter,fnType.ty)){return false}if(fnType.id<0&&queryElem.id<0){if(mgensIn){if(mgensIn.has(fnType.id)&&mgensIn.get(fnType.id)!==queryElem.id){return false}for(const[fid,qid]of mgensIn.entries()){if(fnType.id!==fid&&queryElem.id===qid){return false}if(fnType.id===fid&&queryElem.id!==qid){return false}}}return true}else{if(queryElem.id===typeNameIdOfArrayOrSlice&&(fnType.id===typeNameIdOfSlice||fnType.id===typeNameIdOfArray)){}else if(queryElem.id===typeNameIdOfTupleOrUnit&&(fnType.id===typeNameIdOfTuple||fnType.id===typeNameIdOfUnit)){}else if(queryElem.id===typeNameIdOfHof&&(fnType.id===typeNameIdOfFn||fnType.id===typeNameIdOfFnMut||fnType.id===typeNameIdOfFnOnce)){}else if(fnType.id!==queryElem.id||queryElem.id===null){return false}if((fnType.generics.length+fnType.bindings.size)===0&&queryElem.generics.length!==0){return false}if(fnType.bindings.size0){const fnTypePath=fnType.path!==undefined&&fnType.path!==null?fnType.path.split("::"):[];if(queryElemPathLength>fnTypePath.length){return false}let i=0;for(const path of fnTypePath){if(path===queryElem.pathWithoutLast[i]){i+=1;if(i>=queryElemPathLength){break}}}if(i0){let mgensSolutionSet=[mgensIn];for(const[name,constraints]of queryElem.bindings.entries()){if(mgensSolutionSet.length===0){return false}if(!fnType.bindings.has(name)){return false}const fnTypeBindings=fnType.bindings.get(name);mgensSolutionSet=mgensSolutionSet.flatMap(mgens=>{const newSolutions=[];unifyFunctionTypes(fnTypeBindings,constraints,whereClause,mgens,newMgens=>{newSolutions.push(newMgens);return false},unboxingDepth,);return newSolutions})}if(mgensSolutionSet.length===0){return false}const binds=Array.from(fnType.bindings.entries()).flatMap(entry=>{const[name,constraints]=entry;if(queryElem.bindings.has(name)){return[]}else{return constraints}});if(simplifiedGenerics.length>0){simplifiedGenerics=[...simplifiedGenerics,...binds]}else{simplifiedGenerics=binds}return{simplifiedGenerics,mgens:mgensSolutionSet}}return{simplifiedGenerics,mgens:[mgensIn]}}function unifyFunctionTypeIsUnboxCandidate(fnType,queryElem,whereClause,mgens,unboxingDepth,){if(unboxingDepth>=UNBOXING_LIMIT){return false}if(fnType.id<0&&queryElem.id>=0){if(!whereClause){return false}if(mgens&&mgens.has(fnType.id)&&mgens.get(fnType.id)!==0){return false}const mgensTmp=new Map(mgens);mgensTmp.set(fnType.id,null);return checkIfInList(whereClause[(-fnType.id)-1],queryElem,whereClause,mgensTmp,unboxingDepth,)}else if(fnType.generics.length>0||fnType.bindings.size>0){const simplifiedGenerics=[...fnType.generics,...Array.from(fnType.bindings.values()).flat(),];return checkIfInList(simplifiedGenerics,queryElem,whereClause,mgens,unboxingDepth,)}return false}function checkIfInList(list,elem,whereClause,mgens,unboxingDepth){for(const entry of list){if(checkType(entry,elem,whereClause,mgens,unboxingDepth)){return true}}return false}function checkType(row,elem,whereClause,mgens,unboxingDepth){if(unboxingDepth>=UNBOXING_LIMIT){return false}if(row.bindings.size===0&&elem.bindings.size===0){if(elem.id<0&&mgens===null){return row.id<0||checkIfInList(row.generics,elem,whereClause,mgens,unboxingDepth+1,)}if(row.id>0&&elem.id>0&&elem.pathWithoutLast.length===0&&typePassesFilter(elem.typeFilter,row.ty)&&elem.generics.length===0&&elem.id!==typeNameIdOfArrayOrSlice&&elem.id!==typeNameIdOfTupleOrUnit&&elem.id!==typeNameIdOfHof){return row.id===elem.id||checkIfInList(row.generics,elem,whereClause,mgens,unboxingDepth,)}}return unifyFunctionTypes([row],[elem],whereClause,mgens,null,unboxingDepth)}function checkPath(contains,ty){if(contains.length===0){return 0}const maxPathEditDistance=Math.floor(contains.reduce((acc,next)=>acc+next.length,0)/3,);let ret_dist=maxPathEditDistance+1;const path=ty.path.split("::");if(ty.parent&&ty.parent.name){path.push(ty.parent.name.toLowerCase())}const length=path.length;const clength=contains.length;pathiter:for(let i=length-clength;i>=0;i-=1){let dist_total=0;for(let x=0;xmaxPathEditDistance){continue pathiter}dist_total+=dist}}ret_dist=Math.min(ret_dist,Math.round(dist_total/clength))}return ret_dist>maxPathEditDistance?null:ret_dist}function typePassesFilter(filter,type){if(filter<=NO_TYPE_FILTER||filter===type)return true;const name=itemTypes[type];switch(itemTypes[filter]){case"constant":return name==="associatedconstant";case"fn":return name==="method"||name==="tymethod";case"type":return name==="primitive"||name==="associatedtype";case"trait":return name==="traitalias"}return false}function createAliasFromItem(item){return{crate:item.crate,name:item.name,path:item.path,descShard:item.descShard,descIndex:item.descIndex,exactPath:item.exactPath,ty:item.ty,parent:item.parent,type:item.type,is_alias:true,bitIndex:item.bitIndex,implDisambiguator:item.implDisambiguator,}}function handleAliases(ret,query,filterCrates,currentCrate){const lowerQuery=query.toLowerCase();const aliases=[];const crateAliases=[];if(filterCrates!==null){if(ALIASES.has(filterCrates)&&ALIASES.get(filterCrates).has(lowerQuery)){const query_aliases=ALIASES.get(filterCrates).get(lowerQuery);for(const alias of query_aliases){aliases.push(createAliasFromItem(searchIndex[alias]))}}}else{for(const[crate,crateAliasesIndex]of ALIASES){if(crateAliasesIndex.has(lowerQuery)){const pushTo=crate===currentCrate?crateAliases:aliases;const query_aliases=crateAliasesIndex.get(lowerQuery);for(const alias of query_aliases){pushTo.push(createAliasFromItem(searchIndex[alias]))}}}}const sortFunc=(aaa,bbb)=>{if(aaa.path{alias.alias=query;const res=buildHrefAndPath(alias);alias.displayPath=pathSplitter(res[0]);alias.fullPath=alias.displayPath+alias.name;alias.href=res[1];ret.others.unshift(alias);if(ret.others.length>MAX_RESULTS){ret.others.pop()}};aliases.forEach(pushFunc);crateAliases.forEach(pushFunc)}function addIntoResults(results,fullId,id,index,dist,path_dist,maxEditDistance){if(dist<=maxEditDistance||index!==-1){if(results.has(fullId)){const result=results.get(fullId);if(result.dontValidate||result.dist<=dist){return}}results.set(fullId,{id:id,index:index,dontValidate:parsedQuery.literalSearch,dist:dist,path_dist:path_dist,})}}function handleSingleArg(row,pos,elem,results_others,results_in_args,results_returned,maxEditDistance,){if(!row||(filterCrates!==null&&row.crate!==filterCrates)){return}let path_dist=0;const fullId=row.id;const tfpDist=compareTypeFingerprints(fullId,parsedQuery.typeFingerprint,);if(tfpDist!==null){const in_args=row.type&&row.type.inputs&&checkIfInList(row.type.inputs,elem,row.type.where_clause,null,0);const returned=row.type&&row.type.output&&checkIfInList(row.type.output,elem,row.type.where_clause,null,0);if(in_args){results_in_args.max_dist=Math.max(results_in_args.max_dist||0,tfpDist);const maxDist=results_in_args.sizenormalizedIndex&&normalizedIndex!==-1)){index=normalizedIndex}if(elem.fullPath.length>1){path_dist=checkPath(elem.pathWithoutLast,row);if(path_dist===null){return}}if(parsedQuery.literalSearch){if(row.word===elem.pathLast){addIntoResults(results_others,fullId,pos,index,0,path_dist)}return}const dist=editDistance(row.normalizedName,elem.normalizedPathLast,maxEditDistance);if(index===-1&&dist>maxEditDistance){return}addIntoResults(results_others,fullId,pos,index,dist,path_dist,maxEditDistance)}function handleArgs(row,pos,results){if(!row||(filterCrates!==null&&row.crate!==filterCrates)||!row.type){return}const tfpDist=compareTypeFingerprints(row.id,parsedQuery.typeFingerprint,);if(tfpDist===null){return}if(results.size>=MAX_RESULTS&&tfpDist>results.max_dist){return}if(!unifyFunctionTypes(row.type.inputs,parsedQuery.elems,row.type.where_clause,null,mgens=>{return unifyFunctionTypes(row.type.output,parsedQuery.returned,row.type.where_clause,mgens,null,0,)},0,)){return}results.max_dist=Math.max(results.max_dist||0,tfpDist);addIntoResults(results,row.id,pos,0,tfpDist,0,Number.MAX_VALUE)}function innerRunQuery(){const queryLen=parsedQuery.elems.reduce((acc,next)=>acc+next.pathLast.length,0)+parsedQuery.returned.reduce((acc,next)=>acc+next.pathLast.length,0);const maxEditDistance=Math.floor(queryLen/3);const genericSymbols=new Map();function convertNameToId(elem,isAssocType){if(typeNameIdMap.has(elem.normalizedPathLast)&&(isAssocType||!typeNameIdMap.get(elem.normalizedPathLast).assocOnly)){elem.id=typeNameIdMap.get(elem.normalizedPathLast).id}else if(!parsedQuery.literalSearch){let match=null;let matchDist=maxEditDistance+1;let matchName="";for(const[name,{id,assocOnly}]of typeNameIdMap){const dist=editDistance(name,elem.normalizedPathLast,maxEditDistance);if(dist<=matchDist&&dist<=maxEditDistance&&(isAssocType||!assocOnly)){if(dist===matchDist&&matchName>name){continue}match=id;matchDist=dist;matchName=name}}if(match!==null){parsedQuery.correction=matchName}elem.id=match}if((elem.id===null&&parsedQuery.totalElems>1&&elem.typeFilter===-1&&elem.generics.length===0&&elem.bindings.size===0)||elem.typeFilter===TY_GENERIC){if(genericSymbols.has(elem.name)){elem.id=genericSymbols.get(elem.name)}else{elem.id=-(genericSymbols.size+1);genericSymbols.set(elem.name,elem.id)}if(elem.typeFilter===-1&&elem.name.length>=3){const maxPartDistance=Math.floor(elem.name.length/3);let matchDist=maxPartDistance+1;let matchName="";for(const name of typeNameIdMap.keys()){const dist=editDistance(name,elem.name,maxPartDistance);if(dist<=matchDist&&dist<=maxPartDistance){if(dist===matchDist&&matchName>name){continue}matchDist=dist;matchName=name}}if(matchName!==""){parsedQuery.proposeCorrectionFrom=elem.name;parsedQuery.proposeCorrectionTo=matchName}}elem.typeFilter=TY_GENERIC}if(elem.generics.length>0&&elem.typeFilter===TY_GENERIC){parsedQuery.error=["Generic type parameter ",elem.name," does not accept generic parameters",]}for(const elem2 of elem.generics){convertNameToId(elem2)}elem.bindings=new Map(Array.from(elem.bindings.entries()).map(entry=>{const[name,constraints]=entry;if(!typeNameIdMap.has(name)){parsedQuery.error=["Type parameter ",name," does not exist",];return[null,[]]}for(const elem2 of constraints){convertNameToId(elem2)}return[typeNameIdMap.get(name).id,constraints]}),)}const fps=new Set();for(const elem of parsedQuery.elems){convertNameToId(elem);buildFunctionTypeFingerprint(elem,parsedQuery.typeFingerprint,fps)}for(const elem of parsedQuery.returned){convertNameToId(elem);buildFunctionTypeFingerprint(elem,parsedQuery.typeFingerprint,fps)}if(parsedQuery.foundElems===1&&parsedQuery.returned.length===0){if(parsedQuery.elems.length===1){const elem=parsedQuery.elems[0];for(let i=0,nSearchIndex=searchIndex.length;i0){const sortQ=(a,b)=>{const ag=a.generics.length===0&&a.bindings.size===0;const bg=b.generics.length===0&&b.bindings.size===0;if(ag!==bg){return ag-bg}const ai=a.id>0;const bi=b.id>0;return ai-bi};parsedQuery.elems.sort(sortQ);parsedQuery.returned.sort(sortQ);for(let i=0,nSearchIndex=searchIndex.length;i{const descs=await Promise.all(list.map(result=>{return searchIndexEmptyDesc.get(result.crate).contains(result.bitIndex)?"":searchState.loadDesc(result)}));for(const[i,result]of list.entries()){result.desc=descs[i]}}));if(parsedQuery.error!==null&&ret.others.length!==0){ret.query.error=null}return ret}function nextTab(direction){const next=(searchState.currentTab+direction+3)%searchState.focusedByTab.length;searchState.focusedByTab[searchState.currentTab]=document.activeElement;printTab(next);focusSearchResult()}function focusSearchResult(){const target=searchState.focusedByTab[searchState.currentTab]||document.querySelectorAll(".search-results.active a").item(0)||document.querySelectorAll("#search-tabs button").item(searchState.currentTab);searchState.focusedByTab[searchState.currentTab]=null;if(target){target.focus()}}function buildHrefAndPath(item){let displayPath;let href;const type=itemTypes[item.ty];const name=item.name;let path=item.path;let exactPath=item.exactPath;if(type==="mod"){displayPath=path+"::";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+name+"/index.html"}else if(type==="import"){displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/index.html#reexport."+name}else if(type==="primitive"||type==="keyword"){displayPath="";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+type+"."+name+".html"}else if(type==="externcrate"){displayPath="";href=ROOT_PATH+name+"/index.html"}else if(item.parent!==undefined){const myparent=item.parent;let anchor=type+"."+name;const parentType=itemTypes[myparent.ty];let pageType=parentType;let pageName=myparent.name;exactPath=`${myparent.exactPath}::${myparent.name}`;if(parentType==="primitive"){displayPath=myparent.name+"::"}else if(type==="structfield"&&parentType==="variant"){const enumNameIdx=item.path.lastIndexOf("::");const enumName=item.path.substr(enumNameIdx+2);path=item.path.substr(0,enumNameIdx);displayPath=path+"::"+enumName+"::"+myparent.name+"::";anchor="variant."+myparent.name+".field."+name;pageType="enum";pageName=enumName}else{displayPath=path+"::"+myparent.name+"::"}if(item.implDisambiguator!==null){anchor=item.implDisambiguator+"/"+anchor}href=ROOT_PATH+path.replace(/::/g,"/")+"/"+pageType+"."+pageName+".html#"+anchor}else{displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html"}return[displayPath,href,`${exactPath}::${name}`]}function pathSplitter(path){const tmp=""+path.replace(/::/g,"::");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}async function addTab(array,query,display){const extraClass=display?" active":"";const output=document.createElement("div");if(array.length>0){output.className="search-results "+extraClass;for(const item of array){const name=item.name;const type=itemTypes[item.ty];const longType=longItemTypes[item.ty];const typeName=longType.length!==0?`${longType}`:"?";const link=document.createElement("a");link.className="result-"+type;link.href=item.href;const resultName=document.createElement("div");resultName.className="result-name";resultName.insertAdjacentHTML("beforeend",`${typeName}`);link.appendChild(resultName);let alias=" ";if(item.is_alias){alias=`
\ +${item.alias} - see \ +
`}resultName.insertAdjacentHTML("beforeend",`
${alias}\ +${item.displayPath}${name}\ +
`);const description=document.createElement("div");description.className="desc";description.insertAdjacentHTML("beforeend",item.desc);link.appendChild(description);output.appendChild(link)}}else if(query.error===null){output.className="search-failed"+extraClass;output.innerHTML="No results :(
"+"Try on DuckDuckGo?

"+"Or try looking in one of these:"}return[output,array.length]}function makeTabHeader(tabNb,text,nbElems){const fmtNbElems=nbElems<10?`\u{2007}(${nbElems})\u{2007}\u{2007}`:nbElems<100?`\u{2007}(${nbElems})\u{2007}`:`\u{2007}(${nbElems})`;if(searchState.currentTab===tabNb){return""}return""}async function showResults(results,go_to_first,filterCrates){const search=searchState.outputElement();if(go_to_first||(results.others.length===1&&getSettingValue("go-to-only-result")==="true")){window.onunload=()=>{};searchState.removeQueryParameters();const elem=document.createElement("a");elem.href=results.others[0].href;removeClass(elem,"active");document.body.appendChild(elem);elem.click();return}if(results.query===undefined){results.query=parseQuery(searchState.input.value)}currentResults=results.query.userQuery;const[ret_others,ret_in_args,ret_returned]=await Promise.all([addTab(results.others,results.query,true),addTab(results.in_args,results.query,false),addTab(results.returned,results.query,false),]);let currentTab=searchState.currentTab;if((currentTab===0&&ret_others[1]===0)||(currentTab===1&&ret_in_args[1]===0)||(currentTab===2&&ret_returned[1]===0)){if(ret_others[1]!==0){currentTab=0}else if(ret_in_args[1]!==0){currentTab=1}else if(ret_returned[1]!==0){currentTab=2}}let crates="";if(rawSearchIndex.size>1){crates=" in 
"}let output=`

Results${crates}

`;if(results.query.error!==null){const error=results.query.error;error.forEach((value,index)=>{value=value.split("<").join("<").split(">").join(">");if(index%2!==0){error[index]=`${value.replaceAll(" ", " ")}`}else{error[index]=value}});output+=`

Query parser error: "${error.join("")}".

`;output+="
"+makeTabHeader(0,"In Names",ret_others[1])+"
";currentTab=0}else if(results.query.foundElems<=1&&results.query.returned.length===0){output+="
"+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+"
"}else{const signatureTabTitle=results.query.elems.length===0?"In Function Return Types":results.query.returned.length===0?"In Function Parameters":"In Function Signatures";output+="
"+makeTabHeader(0,signatureTabTitle,ret_others[1])+"
";currentTab=0}if(results.query.correction!==null){const orig=results.query.returned.length>0?results.query.returned[0].name:results.query.elems[0].name;output+="

"+`Type "${orig}" not found. `+"Showing results for closest type name "+`"${results.query.correction}" instead.

`}if(results.query.proposeCorrectionFrom!==null){const orig=results.query.proposeCorrectionFrom;const targ=results.query.proposeCorrectionTo;output+="

"+`Type "${orig}" not found and used as generic parameter. `+`Consider searching for "${targ}" instead.

`}const resultsElem=document.createElement("div");resultsElem.id="results";resultsElem.appendChild(ret_others[0]);resultsElem.appendChild(ret_in_args[0]);resultsElem.appendChild(ret_returned[0]);search.innerHTML=output;const crateSearch=document.getElementById("crate-search");if(crateSearch){crateSearch.addEventListener("input",updateCrate)}search.appendChild(resultsElem);searchState.showResults(search);const elems=document.getElementById("search-tabs").childNodes;searchState.focusedByTab=[];let i=0;for(const elem of elems){const j=i;elem.onclick=()=>printTab(j);searchState.focusedByTab.push(null);i+=1}printTab(currentTab)}function updateSearchHistory(url){if(!browserSupportsHistoryApi()){return}const params=searchState.getQueryStringParams();if(!history.state&&!params.search){history.pushState(null,"",url)}else{history.replaceState(null,"",url)}}async function search(forced){const query=parseQuery(searchState.input.value.trim());let filterCrates=getFilterCrates();if(!forced&&query.userQuery===currentResults){if(query.userQuery.length>0){putBackSearch()}return}searchState.setLoadingSearch();const params=searchState.getQueryStringParams();if(filterCrates===null&¶ms["filter-crate"]!==undefined){filterCrates=params["filter-crate"]}searchState.title="Results for "+query.original+" - Rust";updateSearchHistory(buildUrl(query.original,filterCrates));await showResults(await execQuery(query,filterCrates,window.currentCrate),params.go_to_first,filterCrates)}function buildItemSearchTypeAll(types,lowercasePaths){return types.length>0?types.map(type=>buildItemSearchType(type,lowercasePaths)):EMPTY_GENERICS_ARRAY}const EMPTY_BINDINGS_MAP=new Map();const EMPTY_GENERICS_ARRAY=[];let TYPES_POOL=new Map();function buildItemSearchType(type,lowercasePaths,isAssocType){const PATH_INDEX_DATA=0;const GENERICS_DATA=1;const BINDINGS_DATA=2;let pathIndex,generics,bindings;if(typeof type==="number"){pathIndex=type;generics=EMPTY_GENERICS_ARRAY;bindings=EMPTY_BINDINGS_MAP}else{pathIndex=type[PATH_INDEX_DATA];generics=buildItemSearchTypeAll(type[GENERICS_DATA],lowercasePaths,);if(type.length>BINDINGS_DATA&&type[BINDINGS_DATA].length>0){bindings=new Map(type[BINDINGS_DATA].map(binding=>{const[assocType,constraints]=binding;return[buildItemSearchType(assocType,lowercasePaths,true).id,buildItemSearchTypeAll(constraints,lowercasePaths),]}))}else{bindings=EMPTY_BINDINGS_MAP}}let result;if(pathIndex<0){result={id:pathIndex,ty:TY_GENERIC,path:null,exactPath:null,generics,bindings,}}else if(pathIndex===0){result={id:null,ty:null,path:null,exactPath:null,generics,bindings,}}else{const item=lowercasePaths[pathIndex-1];result={id:buildTypeMapIndex(item.name,isAssocType),ty:item.ty,path:item.path,exactPath:item.exactPath,generics,bindings,}}const cr=TYPES_POOL.get(result.id);if(cr){if(cr.generics.length===result.generics.length&&cr.generics!==result.generics&&cr.generics.every((x,i)=>result.generics[i]===x)){result.generics=cr.generics}if(cr.bindings.size===result.bindings.size&&cr.bindings!==result.bindings){let ok=true;for(const[k,v]of cr.bindings.entries()){const v2=result.bindings.get(v);if(!v2){ok=false;break}if(v!==v2&&v.length===v2.length&&v.every((x,i)=>v2[i]===x)){result.bindings.set(k,v)}else if(v!==v2){ok=false;break}}if(ok){result.bindings=cr.bindings}}if(cr.ty===result.ty&&cr.path===result.path&&cr.bindings===result.bindings&&cr.generics===result.generics&&cr.ty===result.ty){return cr}}TYPES_POOL.set(result.id,result);return result}function buildFunctionSearchTypeCallback(lowercasePaths){return functionSearchType=>{if(functionSearchType===0){return null}const INPUTS_DATA=0;const OUTPUT_DATA=1;let inputs,output;if(typeof functionSearchType[INPUTS_DATA]==="number"){inputs=[buildItemSearchType(functionSearchType[INPUTS_DATA],lowercasePaths)]}else{inputs=buildItemSearchTypeAll(functionSearchType[INPUTS_DATA],lowercasePaths,)}if(functionSearchType.length>1){if(typeof functionSearchType[OUTPUT_DATA]==="number"){output=[buildItemSearchType(functionSearchType[OUTPUT_DATA],lowercasePaths)]}else{output=buildItemSearchTypeAll(functionSearchType[OUTPUT_DATA],lowercasePaths,)}}else{output=[]}const where_clause=[];const l=functionSearchType.length;for(let i=2;i{k=(~~k+0x7ed55d16)+(k<<12);k=(k ^ 0xc761c23c)^(k>>>19);k=(~~k+0x165667b1)+(k<<5);k=(~~k+0xd3a2646c)^(k<<9);k=(~~k+0xfd7046c5)+(k<<3);return(k ^ 0xb55a4f09)^(k>>>16)};const hashint2=k=>{k=~k+(k<<15);k ^=k>>>12;k+=k<<2;k ^=k>>>4;k=Math.imul(k,2057);return k ^(k>>16)};if(input!==null){const h0a=hashint1(input);const h0b=hashint2(input);const h1a=~~(h0a+Math.imul(h0b,2));const h1b=~~(h0a+Math.imul(h0b,3));const h2a=~~(h0a+Math.imul(h0b,4));const h2b=~~(h0a+Math.imul(h0b,5));output[0]|=(1<<(h0a%32))|(1<<(h1b%32));output[1]|=(1<<(h1a%32))|(1<<(h2b%32));output[2]|=(1<<(h2a%32))|(1<<(h0b%32));fps.add(input)}for(const g of type.generics){buildFunctionTypeFingerprint(g,output,fps)}const fb={id:null,ty:0,generics:EMPTY_GENERICS_ARRAY,bindings:EMPTY_BINDINGS_MAP,};for(const[k,v]of type.bindings.entries()){fb.id=k;fb.generics=v;buildFunctionTypeFingerprint(fb,output,fps)}output[3]=fps.size}function compareTypeFingerprints(fullId,queryFingerprint){const fh0=functionTypeFingerprint[fullId*4];const fh1=functionTypeFingerprint[(fullId*4)+1];const fh2=functionTypeFingerprint[(fullId*4)+2];const[qh0,qh1,qh2]=queryFingerprint;const[in0,in1,in2]=[fh0&qh0,fh1&qh1,fh2&qh2];if((in0 ^ qh0)||(in1 ^ qh1)||(in2 ^ qh2)){return null}return functionTypeFingerprint[(fullId*4)+3]}class VlqHexDecoder{constructor(string,cons){this.string=string;this.cons=cons;this.offset=0;this.backrefQueue=[]}decodeList(){const cb="}".charCodeAt(0);let c=this.string.charCodeAt(this.offset);const ret=[];while(c!==cb){ret.push(this.decode());c=this.string.charCodeAt(this.offset)}this.offset+=1;return ret}decode(){const[ob,la]=["{","`"].map(c=>c.charCodeAt(0));let n=0;let c=this.string.charCodeAt(this.offset);if(c===ob){this.offset+=1;return this.decodeList()}while(c>1];this.offset+=1;return sign?-value:value}next(){const c=this.string.charCodeAt(this.offset);const[zero,ua,la]=["0","@","`"].map(c=>c.charCodeAt(0));if(c>=zero&&c16){this.backrefQueue.pop()}return result}}class RoaringBitmap{constructor(str){const strdecoded=atob(str);const u8array=new Uint8Array(strdecoded.length);for(let j=0;j=4){offsets=[];for(let j=0;j>3]&(1<<(j&0x7))){const runcount=(u8array[i]|(u8array[i+1]<<8));i+=2;this.containers.push(new RoaringBitmapRun(runcount,u8array.slice(i,i+(runcount*4)),));i+=runcount*4}else if(this.cardinalities[j]>=4096){this.containers.push(new RoaringBitmapBits(u8array.slice(i,i+8192)));i+=8192}else{const end=this.cardinalities[j]*2;this.containers.push(new RoaringBitmapArray(this.cardinalities[j],u8array.slice(i,i+end),));i+=end}}}contains(keyvalue){const key=keyvalue>>16;const value=keyvalue&0xFFFF;for(let i=0;i=start&&value<=(start+lenm1)){return true}}return false}}class RoaringBitmapArray{constructor(cardinality,array){this.cardinality=cardinality;this.array=array}contains(value){const l=this.cardinality*2;for(let i=0;i>3]&(1<<(value&7)))}}function buildIndex(rawSearchIndex){searchIndex=[];searchIndexDeprecated=new Map();searchIndexEmptyDesc=new Map();const charA="A".charCodeAt(0);let currentIndex=0;let id=0;for(const crate of rawSearchIndex.values()){id+=crate.t.length+1}functionTypeFingerprint=new Uint32Array((id+1)*4);id=0;for(const[crate,crateCorpus]of rawSearchIndex){const itemDescShardDecoder=new VlqHexDecoder(crateCorpus.D,noop=>noop);let descShard={crate,shard:0,start:0,len:itemDescShardDecoder.next(),promise:null,resolve:null,};const descShardList=[descShard];searchIndexDeprecated.set(crate,new RoaringBitmap(crateCorpus.c));searchIndexEmptyDesc.set(crate,new RoaringBitmap(crateCorpus.e));let descIndex=0;const crateRow={crate,ty:3,name:crate,path:"",descShard,descIndex,exactPath:"",desc:crateCorpus.doc,parent:undefined,type:null,id,word:crate,normalizedName:crate.indexOf("_")===-1?crate:crate.replace(/_/g,""),bitIndex:0,implDisambiguator:null,};id+=1;searchIndex.push(crateRow);currentIndex+=1;if(!searchIndexEmptyDesc.get(crate).contains(0)){descIndex+=1}const itemTypes=crateCorpus.t;const itemNames=crateCorpus.n;const itemPaths=new Map(crateCorpus.q);const itemReexports=new Map(crateCorpus.r);const itemParentIdxs=crateCorpus.i;const implDisambiguator=new Map(crateCorpus.b);const paths=crateCorpus.p;const aliases=crateCorpus.a;const lowercasePaths=[];const itemFunctionDecoder=new VlqHexDecoder(crateCorpus.f,buildFunctionSearchTypeCallback(lowercasePaths),);let len=paths.length;let lastPath=itemPaths.get(0);for(let i=0;i2){path=itemPaths.has(elem[2])?itemPaths.get(elem[2]):lastPath;lastPath=path}const exactPath=elem.length>3?itemPaths.get(elem[3]):path;lowercasePaths.push({ty,name:name.toLowerCase(),path,exactPath});paths[i]={ty,name,path,exactPath}}lastPath="";len=itemTypes.length;for(let i=0;i=descShard.len&&!searchIndexEmptyDesc.get(crate).contains(bitIndex)){descShard={crate,shard:descShard.shard+1,start:descShard.start+descShard.len,len:itemDescShardDecoder.next(),promise:null,resolve:null,};descIndex=0;descShardList.push(descShard)}let word="";if(typeof itemNames[i]==="string"){word=itemNames[i].toLowerCase()}const path=itemPaths.has(i)?itemPaths.get(i):lastPath;const type=itemFunctionDecoder.next();if(type!==null){if(type){const fp=functionTypeFingerprint.subarray(id*4,(id+1)*4);const fps=new Set();for(const t of type.inputs){buildFunctionTypeFingerprint(t,fp,fps)}for(const t of type.output){buildFunctionTypeFingerprint(t,fp,fps)}for(const w of type.where_clause){for(const t of w){buildFunctionTypeFingerprint(t,fp,fps)}}}}const row={crate,ty:itemTypes.charCodeAt(i)-charA,name:itemNames[i],path,descShard,descIndex,exactPath:itemReexports.has(i)?itemPaths.get(itemReexports.get(i)):path,parent:itemParentIdxs[i]>0?paths[itemParentIdxs[i]-1]:undefined,type,id,word,normalizedName:word.indexOf("_")===-1?word:word.replace(/_/g,""),bitIndex,implDisambiguator:implDisambiguator.has(i)?implDisambiguator.get(i):null,};id+=1;searchIndex.push(row);lastPath=row.path;if(!searchIndexEmptyDesc.get(crate).contains(bitIndex)){descIndex+=1}}if(aliases){const currentCrateAliases=new Map();ALIASES.set(crate,currentCrateAliases);for(const alias_name in aliases){if(!Object.prototype.hasOwnProperty.call(aliases,alias_name)){continue}let currentNameAliases;if(currentCrateAliases.has(alias_name)){currentNameAliases=currentCrateAliases.get(alias_name)}else{currentNameAliases=[];currentCrateAliases.set(alias_name,currentNameAliases)}for(const local_alias of aliases[alias_name]){currentNameAliases.push(local_alias+currentIndex)}}}currentIndex+=itemTypes.length;searchState.descShards.set(crate,descShardList)}TYPES_POOL=new Map()}function onSearchSubmit(e){e.preventDefault();searchState.clearInputTimeout();search()}function putBackSearch(){const search_input=searchState.input;if(!searchState.input){return}if(search_input.value!==""&&!searchState.isDisplayed()){searchState.showResults();if(browserSupportsHistoryApi()){history.replaceState(null,"",buildUrl(search_input.value,getFilterCrates()))}document.title=searchState.title}}function registerSearchEvents(){const params=searchState.getQueryStringParams();if(searchState.input.value===""){searchState.input.value=params.search||""}const searchAfter500ms=()=>{searchState.clearInputTimeout();if(searchState.input.value.length===0){searchState.hideResults()}else{searchState.timeout=setTimeout(search,500)}};searchState.input.onkeyup=searchAfter500ms;searchState.input.oninput=searchAfter500ms;document.getElementsByClassName("search-form")[0].onsubmit=onSearchSubmit;searchState.input.onchange=e=>{if(e.target!==document.activeElement){return}searchState.clearInputTimeout();setTimeout(search,0)};searchState.input.onpaste=searchState.input.onchange;searchState.outputElement().addEventListener("keydown",e=>{if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey){return}if(e.which===38){const previous=document.activeElement.previousElementSibling;if(previous){previous.focus()}else{searchState.focus()}e.preventDefault()}else if(e.which===40){const next=document.activeElement.nextElementSibling;if(next){next.focus()}const rect=document.activeElement.getBoundingClientRect();if(window.innerHeight-rect.bottom{if(e.which===40){focusSearchResult();e.preventDefault()}});searchState.input.addEventListener("focus",()=>{putBackSearch()});searchState.input.addEventListener("blur",()=>{searchState.input.placeholder=searchState.input.origPlaceholder});if(browserSupportsHistoryApi()){const previousTitle=document.title;window.addEventListener("popstate",e=>{const params=searchState.getQueryStringParams();document.title=previousTitle;currentResults=null;if(params.search&¶ms.search.length>0){searchState.input.value=params.search;e.preventDefault();search()}else{searchState.input.value="";searchState.hideResults()}})}window.onpageshow=()=>{const qSearch=searchState.getQueryStringParams().search;if(searchState.input.value===""&&qSearch){searchState.input.value=qSearch}search()}}function updateCrate(ev){if(ev.target.value==="all crates"){const query=searchState.input.value.trim();updateSearchHistory(buildUrl(query,null))}currentResults=null;search(true)}buildIndex(rawSearchIndex);if(typeof window!=="undefined"){registerSearchEvents();if(window.searchState.getQueryStringParams().search){search()}}if(typeof exports!=="undefined"){exports.initSearch=initSearch;exports.execQuery=execQuery;exports.parseQuery=parseQuery}}if(typeof window!=="undefined"){window.initSearch=initSearch;if(window.searchIndex!==undefined){initSearch(window.searchIndex)}}else{initSearch(new Map())}})() \ No newline at end of file diff --git a/static.files/settings-4313503d2e1961c2.js b/static.files/settings-4313503d2e1961c2.js new file mode 100644 index 000000000..ab425fe49 --- /dev/null +++ b/static.files/settings-4313503d2e1961c2.js @@ -0,0 +1,17 @@ +"use strict";(function(){const isSettingsPage=window.location.pathname.endsWith("/settings.html");function changeSetting(settingName,value){if(settingName==="theme"){const useSystem=value==="system preference"?"true":"false";updateLocalStorage("use-system-theme",useSystem)}updateLocalStorage(settingName,value);switch(settingName){case"theme":case"preferred-dark-theme":case"preferred-light-theme":updateTheme();updateLightAndDark();break;case"line-numbers":if(value===true){window.rustdoc_add_line_numbers_to_examples()}else{window.rustdoc_remove_line_numbers_from_examples()}break;case"hide-sidebar":if(value===true){addClass(document.documentElement,"hide-sidebar")}else{removeClass(document.documentElement,"hide-sidebar")}break}}function showLightAndDark(){removeClass(document.getElementById("preferred-light-theme"),"hidden");removeClass(document.getElementById("preferred-dark-theme"),"hidden")}function hideLightAndDark(){addClass(document.getElementById("preferred-light-theme"),"hidden");addClass(document.getElementById("preferred-dark-theme"),"hidden")}function updateLightAndDark(){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||(useSystem===null&&getSettingValue("theme")===null)){showLightAndDark()}else{hideLightAndDark()}}function setEvents(settingsElement){updateLightAndDark();onEachLazy(settingsElement.querySelectorAll("input[type=\"checkbox\"]"),toggle=>{const settingId=toggle.id;const settingValue=getSettingValue(settingId);if(settingValue!==null){toggle.checked=settingValue==="true"}toggle.onchange=()=>{changeSetting(toggle.id,toggle.checked)}});onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"),elem=>{const settingId=elem.name;let settingValue=getSettingValue(settingId);if(settingId==="theme"){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||settingValue===null){settingValue=useSystem==="false"?"light":"system preference"}}if(settingValue!==null&&settingValue!=="null"){elem.checked=settingValue===elem.value}elem.addEventListener("change",ev=>{changeSetting(ev.target.name,ev.target.value)})})}function buildSettingsPageSections(settings){let output="";for(const setting of settings){const js_data_name=setting["js_name"];const setting_name=setting["name"];if(setting["options"]!==undefined){output+=`\ +
+
${setting_name}
+
`;onEach(setting["options"],option=>{const checked=option===setting["default"]?" checked":"";const full=`${js_data_name}-${option.replace(/ /g,"-")}`;output+=`\ + `});output+=`\ +
+
`}else{const checked=setting["default"]===true?" checked":"";output+=`\ +
\ + \ +
`}}return output}function buildSettingsPage(){const theme_names=getVar("themes").split(",").filter(t=>t);theme_names.push("light","dark","ayu");const settings=[{"name":"Theme","js_name":"theme","default":"system preference","options":theme_names.concat("system preference"),},{"name":"Preferred light theme","js_name":"preferred-light-theme","default":"light","options":theme_names,},{"name":"Preferred dark theme","js_name":"preferred-dark-theme","default":"dark","options":theme_names,},{"name":"Auto-hide item contents for large items","js_name":"auto-hide-large-items","default":true,},{"name":"Auto-hide item methods' documentation","js_name":"auto-hide-method-docs","default":false,},{"name":"Auto-hide trait implementation documentation","js_name":"auto-hide-trait-implementations","default":false,},{"name":"Directly go to item in search if there is only one result","js_name":"go-to-only-result","default":false,},{"name":"Show line numbers on code examples","js_name":"line-numbers","default":false,},{"name":"Hide persistent navigation bar","js_name":"hide-sidebar","default":false,},{"name":"Disable keyboard shortcuts","js_name":"disable-shortcuts","default":false,},];const elementKind=isSettingsPage?"section":"div";const innerHTML=`
${buildSettingsPageSections(settings)}
`;const el=document.createElement(elementKind);el.id="settings";if(!isSettingsPage){el.className="popover"}el.innerHTML=innerHTML;if(isSettingsPage){document.getElementById(MAIN_ID).appendChild(el)}else{el.setAttribute("tabindex","-1");getSettingsButton().appendChild(el)}return el}const settingsMenu=buildSettingsPage();function displaySettings(){settingsMenu.style.display="";onEachLazy(settingsMenu.querySelectorAll("input[type='checkbox']"),el=>{const val=getSettingValue(el.id);const checked=val==="true";if(checked!==el.checked&&val!==null){el.checked=checked}})}function settingsBlurHandler(event){blurHandler(event,getSettingsButton(),window.hidePopoverMenus)}if(isSettingsPage){getSettingsButton().onclick=event=>{event.preventDefault()}}else{const settingsButton=getSettingsButton();const settingsMenu=document.getElementById("settings");settingsButton.onclick=event=>{if(settingsMenu.contains(event.target)){return}event.preventDefault();const shouldDisplaySettings=settingsMenu.style.display==="none";window.hideAllModals();if(shouldDisplaySettings){displaySettings()}};settingsButton.onblur=settingsBlurHandler;settingsButton.querySelector("a").onblur=settingsBlurHandler;onEachLazy(settingsMenu.querySelectorAll("input"),el=>{el.onblur=settingsBlurHandler});settingsMenu.onblur=settingsBlurHandler}setTimeout(()=>{setEvents(settingsMenu);if(!isSettingsPage){displaySettings()}removeClass(getSettingsButton(),"rotate")},0)})() \ No newline at end of file diff --git a/static.files/src-script-e66d777a5a92e9b2.js b/static.files/src-script-e66d777a5a92e9b2.js new file mode 100644 index 000000000..d0aebb851 --- /dev/null +++ b/static.files/src-script-e66d777a5a92e9b2.js @@ -0,0 +1 @@ +"use strict";(function(){const rootPath=getVar("root-path");const NAME_OFFSET=0;const DIRS_OFFSET=1;const FILES_OFFSET=2;const RUSTDOC_MOBILE_BREAKPOINT=700;function closeSidebarIfMobile(){if(window.innerWidth{removeClass(document.documentElement,"src-sidebar-expanded");updateLocalStorage("source-sidebar-show","false")};window.rustdocShowSourceSidebar=()=>{addClass(document.documentElement,"src-sidebar-expanded");updateLocalStorage("source-sidebar-show","true")};window.rustdocToggleSrcSidebar=()=>{if(document.documentElement.classList.contains("src-sidebar-expanded")){window.rustdocCloseSourceSidebar()}else{window.rustdocShowSourceSidebar()}};function createSrcSidebar(){const container=document.querySelector("nav.sidebar");const sidebar=document.createElement("div");sidebar.id="src-sidebar";let hasFoundFile=false;for(const[key,source]of srcIndex){source[NAME_OFFSET]=key;hasFoundFile=createDirEntry(source,sidebar,"",hasFoundFile)}container.appendChild(sidebar);const selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}}function highlightSrcLines(){const match=window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);if(!match){return}let from=parseInt(match[1],10);let to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to{onEachLazy(e.getElementsByTagName("a"),i_e=>{removeClass(i_e,"line-highlighted")})});for(let i=from;i<=to;++i){elem=document.getElementById(i);if(!elem){break}addClass(elem,"line-highlighted")}}const handleSrcHighlight=(function(){let prev_line_id=0;const set_fragment=name=>{const x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSrcLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return ev=>{let cur_line_id=parseInt(ev.target.id,10);if(isNaN(cur_line_id)||ev.ctrlKey||ev.altKey||ev.metaKey){return}ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){const tmp=prev_line_id;prev_line_id=cur_line_id;cur_line_id=tmp}set_fragment(prev_line_id+"-"+cur_line_id)}else{prev_line_id=cur_line_id;set_fragment(cur_line_id)}}}());window.addEventListener("hashchange",highlightSrcLines);onEachLazy(document.getElementsByClassName("src-line-numbers"),el=>{el.addEventListener("click",handleSrcHighlight)});highlightSrcLines();window.createSrcSidebar=createSrcSidebar})() \ No newline at end of file diff --git a/static.files/storage-118b08c4c78b968e.js b/static.files/storage-118b08c4c78b968e.js new file mode 100644 index 000000000..981894677 --- /dev/null +++ b/static.files/storage-118b08c4c78b968e.js @@ -0,0 +1,24 @@ +"use strict";const builtinThemes=["light","dark","ayu"];const darkThemes=["dark","ayu"];window.currentTheme=document.getElementById("themeStyle");const settingsDataset=(function(){const settingsElement=document.getElementById("default-settings");return settingsElement&&settingsElement.dataset?settingsElement.dataset:null})();function getSettingValue(settingName){const current=getCurrentValue(settingName);if(current===null&&settingsDataset!==null){const def=settingsDataset[settingName.replace(/-/g,"_")];if(def!==undefined){return def}}return current}const localStoredTheme=getSettingValue("theme");function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(elem&&elem.classList){elem.classList.add(className)}}function removeClass(elem,className){if(elem&&elem.classList){elem.classList.remove(className)}}function onEach(arr,func){for(const elem of arr){if(func(elem)){return true}}return false}function onEachLazy(lazyArray,func){return onEach(Array.prototype.slice.call(lazyArray),func)}function updateLocalStorage(name,value){try{window.localStorage.setItem("rustdoc-"+name,value)}catch(e){}}function getCurrentValue(name){try{return window.localStorage.getItem("rustdoc-"+name)}catch(e){return null}}const getVar=(function getVar(name){const el=document.querySelector("head > meta[name='rustdoc-vars']");return el?el.attributes["data-"+name].value:null});function switchTheme(newThemeName,saveTheme){const themeNames=getVar("themes").split(",").filter(t=>t);themeNames.push(...builtinThemes);if(themeNames.indexOf(newThemeName)===-1){return}if(saveTheme){updateLocalStorage("theme",newThemeName)}document.documentElement.setAttribute("data-theme",newThemeName);if(builtinThemes.indexOf(newThemeName)!==-1){if(window.currentTheme){window.currentTheme.parentNode.removeChild(window.currentTheme);window.currentTheme=null}}else{const newHref=getVar("root-path")+encodeURIComponent(newThemeName)+getVar("resource-suffix")+".css";if(!window.currentTheme){if(document.readyState==="loading"){document.write(``);window.currentTheme=document.getElementById("themeStyle")}else{window.currentTheme=document.createElement("link");window.currentTheme.rel="stylesheet";window.currentTheme.id="themeStyle";window.currentTheme.href=newHref;document.documentElement.appendChild(window.currentTheme)}}else if(newHref!==window.currentTheme.href){window.currentTheme.href=newHref}}}const updateTheme=(function(){const mql=window.matchMedia("(prefers-color-scheme: dark)");function updateTheme(){if(getSettingValue("use-system-theme")!=="false"){const lightTheme=getSettingValue("preferred-light-theme")||"light";const darkTheme=getSettingValue("preferred-dark-theme")||"dark";updateLocalStorage("use-system-theme","true");switchTheme(mql.matches?darkTheme:lightTheme,true)}else{switchTheme(getSettingValue("theme"),false)}}mql.addEventListener("change",updateTheme);return updateTheme})();if(getSettingValue("use-system-theme")!=="false"&&window.matchMedia){if(getSettingValue("use-system-theme")===null&&getSettingValue("preferred-dark-theme")===null&&darkThemes.indexOf(localStoredTheme)>=0){updateLocalStorage("preferred-dark-theme",localStoredTheme)}}updateTheme();if(getSettingValue("source-sidebar-show")==="true"){addClass(document.documentElement,"src-sidebar-expanded")}if(getSettingValue("hide-sidebar")==="true"){addClass(document.documentElement,"hide-sidebar")}function updateSidebarWidth(){const desktopSidebarWidth=getSettingValue("desktop-sidebar-width");if(desktopSidebarWidth&&desktopSidebarWidth!=="null"){document.documentElement.style.setProperty("--desktop-sidebar-width",desktopSidebarWidth+"px",)}const srcSidebarWidth=getSettingValue("src-sidebar-width");if(srcSidebarWidth&&srcSidebarWidth!=="null"){document.documentElement.style.setProperty("--src-sidebar-width",srcSidebarWidth+"px",)}}updateSidebarWidth();window.addEventListener("pageshow",ev=>{if(ev.persisted){setTimeout(updateTheme,0);setTimeout(updateSidebarWidth,0)}});class RustdocSearchElement extends HTMLElement{constructor(){super()}connectedCallback(){const rootPath=getVar("root-path");const currentCrate=getVar("current-crate");this.innerHTML=``}}window.customElements.define("rustdoc-search",RustdocSearchElement) \ No newline at end of file diff --git a/trait.impl/actix/actor/trait.ActorContext.js b/trait.impl/actix/actor/trait.ActorContext.js new file mode 100644 index 000000000..b09404328 --- /dev/null +++ b/trait.impl/actix/actor/trait.ActorContext.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_web_actors":[["impl<A> ActorContext for HttpContext<A>
where\n A: Actor<Context = Self>,
"],["impl<A> ActorContext for WebsocketContext<A>
where\n A: Actor<Context = Self>,
"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix/actor/trait.AsyncContext.js b/trait.impl/actix/actor/trait.AsyncContext.js new file mode 100644 index 000000000..6da2b9bbb --- /dev/null +++ b/trait.impl/actix/actor/trait.AsyncContext.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_web_actors":[["impl<A> AsyncContext<A> for HttpContext<A>
where\n A: Actor<Context = Self>,
"],["impl<A> AsyncContext<A> for WebsocketContext<A>
where\n A: Actor<Context = Self>,
"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix/address/envelope/trait.ToEnvelope.js b/trait.impl/actix/address/envelope/trait.ToEnvelope.js new file mode 100644 index 000000000..54d680a62 --- /dev/null +++ b/trait.impl/actix/address/envelope/trait.ToEnvelope.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_web_actors":[["impl<A, M> ToEnvelope<A, M> for HttpContext<A>
where\n A: Actor<Context = HttpContext<A>> + Handler<M>,\n M: Message + Send + 'static,\n M::Result: Send,
"],["impl<A, M> ToEnvelope<A, M> for WebsocketContext<A>
where\n A: Actor<Context = WebsocketContext<A>> + Handler<M>,\n M: ActixMessage + Send + 'static,\n M::Result: Send,
"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix/context_impl/trait.AsyncContextParts.js b/trait.impl/actix/context_impl/trait.AsyncContextParts.js new file mode 100644 index 000000000..affbd998e --- /dev/null +++ b/trait.impl/actix/context_impl/trait.AsyncContextParts.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_web_actors":[["impl<A> AsyncContextParts<A> for HttpContext<A>
where\n A: Actor<Context = Self>,
"],["impl<A> AsyncContextParts<A> for WebsocketContext<A>
where\n A: Actor<Context = Self>,
"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_http/body/message_body/trait.MessageBody.js b/trait.impl/actix_http/body/message_body/trait.MessageBody.js new file mode 100644 index 000000000..3771fce74 --- /dev/null +++ b/trait.impl/actix_http/body/message_body/trait.MessageBody.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"actix_http":[], +"actix_web":[], +"awc":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_http/header/as_name/trait.AsHeaderName.js b/trait.impl/actix_http/header/as_name/trait.AsHeaderName.js new file mode 100644 index 000000000..3771fce74 --- /dev/null +++ b/trait.impl/actix_http/header/as_name/trait.AsHeaderName.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"actix_http":[], +"actix_web":[], +"awc":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_http/header/into_pair/trait.TryIntoHeaderPair.js b/trait.impl/actix_http/header/into_pair/trait.TryIntoHeaderPair.js new file mode 100644 index 000000000..3771fce74 --- /dev/null +++ b/trait.impl/actix_http/header/into_pair/trait.TryIntoHeaderPair.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"actix_http":[], +"actix_web":[], +"awc":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_http/header/into_value/trait.TryIntoHeaderValue.js b/trait.impl/actix_http/header/into_value/trait.TryIntoHeaderValue.js new file mode 100644 index 000000000..3d5cfb7c0 --- /dev/null +++ b/trait.impl/actix_http/header/into_value/trait.TryIntoHeaderValue.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"actix_http":[], +"actix_web":[["impl TryIntoHeaderValue for ContentRangeSpec"],["impl TryIntoHeaderValue for IfMatch"],["impl TryIntoHeaderValue for IfNoneMatch"],["impl TryIntoHeaderValue for IfRange"],["impl TryIntoHeaderValue for Range"],["impl TryIntoHeaderValue for Accept"],["impl TryIntoHeaderValue for AcceptCharset"],["impl TryIntoHeaderValue for AcceptEncoding"],["impl TryIntoHeaderValue for AcceptLanguage"],["impl TryIntoHeaderValue for Allow"],["impl TryIntoHeaderValue for CacheControl"],["impl TryIntoHeaderValue for ContentDisposition"],["impl TryIntoHeaderValue for ContentLanguage"],["impl TryIntoHeaderValue for ContentLength"],["impl TryIntoHeaderValue for ContentRange"],["impl TryIntoHeaderValue for ContentType"],["impl TryIntoHeaderValue for Date"],["impl TryIntoHeaderValue for ETag"],["impl TryIntoHeaderValue for EntityTag"],["impl TryIntoHeaderValue for Expires"],["impl TryIntoHeaderValue for IfModifiedSince"],["impl TryIntoHeaderValue for IfUnmodifiedSince"],["impl TryIntoHeaderValue for LastModified"]], +"awc":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_http/header/trait.Header.js b/trait.impl/actix_http/header/trait.Header.js new file mode 100644 index 000000000..2d677199b --- /dev/null +++ b/trait.impl/actix_http/header/trait.Header.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"actix_http":[], +"actix_web":[["impl Header for IfMatch"],["impl Header for IfNoneMatch"],["impl Header for IfRange"],["impl Header for Range"],["impl Header for Accept"],["impl Header for AcceptCharset"],["impl Header for AcceptEncoding"],["impl Header for AcceptLanguage"],["impl Header for Allow"],["impl Header for CacheControl"],["impl Header for ContentDisposition"],["impl Header for ContentLanguage"],["impl Header for ContentLength"],["impl Header for ContentRange"],["impl Header for ContentType"],["impl Header for Date"],["impl Header for ETag"],["impl Header for Expires"],["impl Header for IfModifiedSince"],["impl Header for IfUnmodifiedSince"],["impl Header for LastModified"]], +"awc":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_http/http_message/trait.HttpMessage.js b/trait.impl/actix_http/http_message/trait.HttpMessage.js new file mode 100644 index 000000000..5121fcc36 --- /dev/null +++ b/trait.impl/actix_http/http_message/trait.HttpMessage.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"actix_http":[], +"actix_web":[["impl HttpMessage for ServiceRequest"],["impl HttpMessage for HttpRequest"]], +"awc":[["impl<S> HttpMessage for ClientResponse<S>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_multipart/form/trait.FieldReader.js b/trait.impl/actix_multipart/form/trait.FieldReader.js new file mode 100644 index 000000000..4b5aba49d --- /dev/null +++ b/trait.impl/actix_multipart/form/trait.FieldReader.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_multipart":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_router/pattern/trait.IntoPatterns.js b/trait.impl/actix_router/pattern/trait.IntoPatterns.js new file mode 100644 index 000000000..2c3eaef9f --- /dev/null +++ b/trait.impl/actix_router/pattern/trait.IntoPatterns.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_router":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_router/resource_path/trait.Resource.js b/trait.impl/actix_router/resource_path/trait.Resource.js new file mode 100644 index 000000000..9b28367c4 --- /dev/null +++ b/trait.impl/actix_router/resource_path/trait.Resource.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"actix_router":[], +"actix_web":[["impl Resource for ServiceRequest"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_router/resource_path/trait.ResourcePath.js b/trait.impl/actix_router/resource_path/trait.ResourcePath.js new file mode 100644 index 000000000..50a2851e3 --- /dev/null +++ b/trait.impl/actix_router/resource_path/trait.ResourcePath.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"actix_router":[], +"actix_web":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_service/trait.Service.js b/trait.impl/actix_service/trait.Service.js new file mode 100644 index 000000000..2ba8d5520 --- /dev/null +++ b/trait.impl/actix_service/trait.Service.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"actix_files":[["impl Service<ServiceRequest> for FilesService"]], +"actix_http":[["impl Service<Request> for ExpectHandler"],["impl<T> Service<(Request, Framed<T, Codec>)> for UpgradeHandler"]], +"actix_web":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_service/trait.ServiceFactory.js b/trait.impl/actix_service/trait.ServiceFactory.js new file mode 100644 index 000000000..aa7b1ac26 --- /dev/null +++ b/trait.impl/actix_service/trait.ServiceFactory.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"actix_files":[["impl ServiceFactory<ServiceRequest> for Files"],["impl ServiceFactory<ServiceRequest> for NamedFile"]], +"actix_http":[["impl ServiceFactory<Request> for ExpectHandler"],["impl<T> ServiceFactory<(Request, Framed<T, Codec>)> for UpgradeHandler"],["impl<T, S, B> ServiceFactory<(T, Option<SocketAddr>)> for H2Service<T, S, B>
where\n T: AsyncRead + AsyncWrite + Unpin + 'static,\n S: ServiceFactory<Request, Config = ()>,\n S::Future: 'static,\n S::Error: Into<Response<BoxBody>> + 'static,\n S::Response: Into<Response<B>> + 'static,\n <S::Service as Service<Request>>::Future: 'static,\n B: MessageBody + 'static,
"],["impl<T, S, B, X, U> ServiceFactory<(T, Protocol, Option<SocketAddr>)> for HttpService<T, S, B, X, U>
where\n T: AsyncRead + AsyncWrite + Unpin + 'static,\n S: ServiceFactory<Request, Config = ()>,\n S::Future: 'static,\n S::Error: Into<Response<BoxBody>> + 'static,\n S::InitError: Debug,\n S::Response: Into<Response<B>> + 'static,\n <S::Service as Service<Request>>::Future: 'static,\n B: MessageBody + 'static,\n X: ServiceFactory<Request, Config = (), Response = Request>,\n X::Future: 'static,\n X::Error: Into<Response<BoxBody>>,\n X::InitError: Debug,\n U: ServiceFactory<(Request, Framed<T, Codec>), Config = (), Response = ()>,\n U::Future: 'static,\n U::Error: Display + Into<Response<BoxBody>>,\n U::InitError: Debug,
"],["impl<T, S, B, X, U> ServiceFactory<(T, Option<SocketAddr>)> for H1Service<T, S, B, X, U>
where\n T: AsyncRead + AsyncWrite + Unpin + 'static,\n S: ServiceFactory<Request, Config = ()>,\n S::Future: 'static,\n S::Error: Into<Response<BoxBody>>,\n S::Response: Into<Response<B>>,\n S::InitError: Debug,\n B: MessageBody,\n X: ServiceFactory<Request, Config = (), Response = Request>,\n X::Future: 'static,\n X::Error: Into<Response<BoxBody>>,\n X::InitError: Debug,\n U: ServiceFactory<(Request, Framed<T, Codec>), Config = (), Response = ()>,\n U::Future: 'static,\n U::Error: Display + Into<Response<BoxBody>>,\n U::InitError: Debug,
"]], +"actix_web":[["impl ServiceFactory<ServiceRequest> for Route"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_service/transform/trait.Transform.js b/trait.impl/actix_service/transform/trait.Transform.js new file mode 100644 index 000000000..f550920bd --- /dev/null +++ b/trait.impl/actix_service/transform/trait.Transform.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_web":[["impl<S, B> Transform<S, ServiceRequest> for Compress
where\n B: MessageBody,\n S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
"],["impl<S, B> Transform<S, ServiceRequest> for DefaultHeaders
where\n S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,\n S::Future: 'static,
"],["impl<S, B> Transform<S, ServiceRequest> for ErrorHandlers<B>
where\n S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,\n S::Future: 'static,\n B: 'static,
"],["impl<S, B> Transform<S, ServiceRequest> for Logger
where\n S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,\n B: MessageBody,
"],["impl<S, B> Transform<S, ServiceRequest> for NormalizePath
where\n S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,\n S::Future: 'static,
"],["impl<S, T, Req> Transform<S, Req> for Compat<T>
where\n S: Service<Req>,\n T: Transform<S, Req>,\n T::Future: 'static,\n T::Response: MapServiceResponseBody,\n T::Error: Into<Error>,
"],["impl<S, T, Req, BE, BD, Err> Transform<S, Req> for Condition<T>
where\n S: Service<Req, Response = ServiceResponse<BD>, Error = Err> + 'static,\n T: Transform<S, Req, Response = ServiceResponse<BE>, Error = Err>,\n T::Future: 'static,\n T::InitError: 'static,\n T::Transform: 'static,
"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_web/error/response_error/trait.ResponseError.js b/trait.impl/actix_web/error/response_error/trait.ResponseError.js new file mode 100644 index 000000000..4aa469953 --- /dev/null +++ b/trait.impl/actix_web/error/response_error/trait.ResponseError.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"actix_multipart":[["impl ResponseError for MultipartError"],["impl ResponseError for JsonFieldError"],["impl ResponseError for TempFileError"],["impl ResponseError for TextError"]], +"actix_web":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_web/extract/trait.FromRequest.js b/trait.impl/actix_web/extract/trait.FromRequest.js new file mode 100644 index 000000000..8e09667cb --- /dev/null +++ b/trait.impl/actix_web/extract/trait.FromRequest.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"actix_multipart":[["impl FromRequest for Multipart"],["impl<T> FromRequest for MultipartForm<T>
where\n T: MultipartCollect,
"]], +"actix_web":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_web/guard/trait.Guard.js b/trait.impl/actix_web/guard/trait.Guard.js new file mode 100644 index 000000000..20e2e1061 --- /dev/null +++ b/trait.impl/actix_web/guard/trait.Guard.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_web":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_web/handler/trait.Handler.js b/trait.impl/actix_web/handler/trait.Handler.js new file mode 100644 index 000000000..20e2e1061 --- /dev/null +++ b/trait.impl/actix_web/handler/trait.Handler.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_web":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_web/response/responder/trait.Responder.js b/trait.impl/actix_web/response/responder/trait.Responder.js new file mode 100644 index 000000000..81edd1978 --- /dev/null +++ b/trait.impl/actix_web/response/responder/trait.Responder.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"actix_files":[["impl Responder for NamedFile"]], +"actix_web":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/actix_web/service/trait.HttpServiceFactory.js b/trait.impl/actix_web/service/trait.HttpServiceFactory.js new file mode 100644 index 000000000..8764853da --- /dev/null +++ b/trait.impl/actix_web/service/trait.HttpServiceFactory.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"actix_files":[["impl HttpServiceFactory for Files"],["impl HttpServiceFactory for NamedFile"]], +"actix_web":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/awc/middleware/trait.Transform.js b/trait.impl/awc/middleware/trait.Transform.js new file mode 100644 index 000000000..76849e002 --- /dev/null +++ b/trait.impl/awc/middleware/trait.Transform.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"awc":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/bytes/buf/buf_impl/trait.Buf.js b/trait.impl/bytes/buf/buf_impl/trait.Buf.js new file mode 100644 index 000000000..20e2e1061 --- /dev/null +++ b/trait.impl/bytes/buf/buf_impl/trait.Buf.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_web":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/bytes/buf/buf_mut/trait.BufMut.js b/trait.impl/bytes/buf/buf_mut/trait.BufMut.js new file mode 100644 index 000000000..20e2e1061 --- /dev/null +++ b/trait.impl/bytes/buf/buf_mut/trait.BufMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_web":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/clone/trait.Clone.js b/trait.impl/core/clone/trait.Clone.js new file mode 100644 index 000000000..834f11772 --- /dev/null +++ b/trait.impl/core/clone/trait.Clone.js @@ -0,0 +1,9 @@ +(function() {var implementors = { +"actix_files":[["impl Clone for Files"],["impl Clone for FilesService"],["impl Clone for HttpRange"]], +"actix_http":[["impl Clone for BodySize"],["impl Clone for ConnectionType"],["impl Clone for KeepAlive"],["impl Clone for Protocol"],["impl Clone for MessageType"],["impl Clone for Charset"],["impl Clone for ContentEncoding"],["impl Clone for CloseCode"],["impl Clone for HandshakeError"],["impl Clone for OpCode"],["impl Clone for None"],["impl Clone for HeaderMap"],["impl Clone for ExtendedValue"],["impl Clone for HttpDate"],["impl Clone for Quality"],["impl Clone for RequestHead"],["impl Clone for ResponseHead"],["impl Clone for ServiceConfig"],["impl Clone for TestSeqBuffer"],["impl Clone for CloseReason"],["impl Clone for Codec"],["impl<L: Clone, R: Clone> Clone for EitherBody<L, R>"],["impl<T: Clone> Clone for QualityItem<T>"]], +"actix_multipart":[["impl Clone for JsonConfig"],["impl Clone for MultipartFormConfig"],["impl Clone for TempFileConfig"],["impl Clone for TextConfig"]], +"actix_router":[["impl Clone for Patterns"],["impl Clone for ResourceDef"],["impl Clone for ResourceId"],["impl Clone for Url"],["impl<T: Clone> Clone for Path<T>"]], +"actix_test":[["impl Clone for TestServerConfig"]], +"actix_web":[["impl Clone for ByteRangeSpec"],["impl Clone for CacheDirective"],["impl Clone for ContentRangeSpec"],["impl Clone for DispositionParam"],["impl Clone for DispositionType"],["impl Clone for Encoding"],["impl Clone for IfMatch"],["impl Clone for IfNoneMatch"],["impl Clone for IfRange"],["impl Clone for Range"],["impl Clone for TrailingSlash"],["impl Clone for AppConfig"],["impl Clone for ConnectionInfo"],["impl Clone for PeerAddr"],["impl Clone for ResourceMap"],["impl Clone for Acceptable"],["impl Clone for Accept"],["impl Clone for AcceptCharset"],["impl Clone for AcceptEncoding"],["impl Clone for AcceptLanguage"],["impl Clone for Allow"],["impl Clone for CacheControl"],["impl Clone for ContentDisposition"],["impl Clone for ContentLanguage"],["impl Clone for ContentLength"],["impl Clone for ContentRange"],["impl Clone for ContentType"],["impl Clone for Date"],["impl Clone for ETag"],["impl Clone for EntityTag"],["impl Clone for Expires"],["impl Clone for IfModifiedSince"],["impl Clone for IfUnmodifiedSince"],["impl Clone for LastModified"],["impl Clone for Compress"],["impl Clone for DefaultHeaders"],["impl Clone for NormalizePath"],["impl Clone for HttpRequest"],["impl Clone for FormConfig"],["impl Clone for JsonConfig"],["impl Clone for PathConfig"],["impl Clone for PayloadConfig"],["impl Clone for QueryConfig"],["impl Clone for Redirect"],["impl<T: Clone + Clone + 'static> Clone for ReqData<T>"],["impl<T: Clone> Clone for Preference<T>"],["impl<T: Clone> Clone for Header<T>"],["impl<T: Clone> Clone for Query<T>"],["impl<T: ?Sized> Clone for Data<T>"]], +"awc":[["impl Clone for Client"],["impl Clone for Connect"],["impl Clone for FrozenClientRequest"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.Eq.js b/trait.impl/core/cmp/trait.Eq.js new file mode 100644 index 000000000..28c58000d --- /dev/null +++ b/trait.impl/core/cmp/trait.Eq.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"actix_http":[["impl Eq for BodySize"],["impl Eq for ConnectionType"],["impl Eq for KeepAlive"],["impl Eq for Protocol"],["impl Eq for MessageType"],["impl Eq for Charset"],["impl Eq for ContentEncoding"],["impl Eq for CloseCode"],["impl Eq for Frame"],["impl Eq for HandshakeError"],["impl Eq for Item"],["impl Eq for Message"],["impl Eq for OpCode"],["impl Eq for ExtendedValue"],["impl Eq for HttpDate"],["impl Eq for Quality"],["impl Eq for CloseReason"],["impl<T: Eq> Eq for QualityItem<T>"]], +"actix_router":[["impl Eq for Patterns"],["impl Eq for ResourceDef"],["impl Eq for ResourceId"]], +"actix_web":[["impl Eq for UrlGenerationError"],["impl Eq for ByteRangeSpec"],["impl Eq for CacheDirective"],["impl Eq for ContentRangeSpec"],["impl Eq for DispositionParam"],["impl Eq for DispositionType"],["impl Eq for Encoding"],["impl Eq for IfMatch"],["impl Eq for IfNoneMatch"],["impl Eq for IfRange"],["impl Eq for Range"],["impl Eq for PeerAddr"],["impl Eq for Accept"],["impl Eq for AcceptCharset"],["impl Eq for AcceptEncoding"],["impl Eq for AcceptLanguage"],["impl Eq for Allow"],["impl Eq for CacheControl"],["impl Eq for ContentDisposition"],["impl Eq for ContentLanguage"],["impl Eq for ContentLength"],["impl Eq for ContentRange"],["impl Eq for ContentType"],["impl Eq for Date"],["impl Eq for ETag"],["impl Eq for EntityTag"],["impl Eq for Expires"],["impl Eq for IfModifiedSince"],["impl Eq for IfUnmodifiedSince"],["impl Eq for LastModified"],["impl<L: Eq, R: Eq> Eq for Either<L, R>"],["impl<T: Eq> Eq for Preference<T>"],["impl<T: Eq> Eq for Form<T>"],["impl<T: Eq> Eq for Header<T>"],["impl<T: Eq> Eq for Path<T>"],["impl<T: Eq> Eq for Query<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.Ord.js b/trait.impl/core/cmp/trait.Ord.js new file mode 100644 index 000000000..40633c280 --- /dev/null +++ b/trait.impl/core/cmp/trait.Ord.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"actix_http":[["impl Ord for HttpDate"],["impl Ord for Quality"]], +"actix_web":[["impl Ord for PeerAddr"],["impl Ord for ContentLength"],["impl<T: Ord> Ord for Form<T>"],["impl<T: Ord> Ord for Header<T>"],["impl<T: Ord> Ord for Path<T>"],["impl<T: Ord> Ord for Query<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.PartialEq.js b/trait.impl/core/cmp/trait.PartialEq.js new file mode 100644 index 000000000..a18043039 --- /dev/null +++ b/trait.impl/core/cmp/trait.PartialEq.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"actix_http":[["impl PartialEq for BodySize"],["impl PartialEq for ConnectionType"],["impl PartialEq for KeepAlive"],["impl PartialEq for Protocol"],["impl PartialEq for MessageType"],["impl PartialEq for Charset"],["impl PartialEq for ContentEncoding"],["impl PartialEq for CloseCode"],["impl PartialEq for Frame"],["impl PartialEq for HandshakeError"],["impl PartialEq for Item"],["impl PartialEq for Message"],["impl PartialEq for OpCode"],["impl PartialEq for ExtendedValue"],["impl PartialEq for HttpDate"],["impl PartialEq for Quality"],["impl PartialEq for CloseReason"],["impl<T: PartialEq> PartialEq for QualityItem<T>"]], +"actix_router":[["impl PartialEq for Patterns"],["impl PartialEq for ResourceDef"],["impl PartialEq for ResourceId"]], +"actix_web":[["impl PartialEq for UrlGenerationError"],["impl PartialEq for ByteRangeSpec"],["impl PartialEq for CacheDirective"],["impl PartialEq for ContentRangeSpec"],["impl PartialEq for DispositionParam"],["impl PartialEq for DispositionType"],["impl PartialEq for Encoding"],["impl PartialEq for IfMatch"],["impl PartialEq for IfNoneMatch"],["impl PartialEq for IfRange"],["impl PartialEq for Range"],["impl PartialEq for PeerAddr"],["impl PartialEq for Accept"],["impl PartialEq for AcceptCharset"],["impl PartialEq for AcceptEncoding"],["impl PartialEq for AcceptLanguage"],["impl PartialEq for Allow"],["impl PartialEq for CacheControl"],["impl PartialEq for ContentDisposition"],["impl PartialEq for ContentLanguage"],["impl PartialEq for ContentLength"],["impl PartialEq for ContentRange"],["impl PartialEq for ContentType"],["impl PartialEq for Date"],["impl PartialEq for ETag"],["impl PartialEq for EntityTag"],["impl PartialEq for Expires"],["impl PartialEq for IfModifiedSince"],["impl PartialEq for IfUnmodifiedSince"],["impl PartialEq for LastModified"],["impl PartialEq<usize> for ContentLength"],["impl PartialEq<ContentLength> for usize"],["impl<L: PartialEq, R: PartialEq> PartialEq for Either<L, R>"],["impl<T: PartialEq> PartialEq for Preference<T>"],["impl<T: PartialEq> PartialEq for Form<T>"],["impl<T: PartialEq> PartialEq for Header<T>"],["impl<T: PartialEq> PartialEq for Path<T>"],["impl<T: PartialEq> PartialEq for Query<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.PartialOrd.js b/trait.impl/core/cmp/trait.PartialOrd.js new file mode 100644 index 000000000..24d5c5e20 --- /dev/null +++ b/trait.impl/core/cmp/trait.PartialOrd.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"actix_http":[["impl PartialOrd for HttpDate"],["impl PartialOrd for Quality"],["impl<T: PartialEq> PartialOrd for QualityItem<T>"]], +"actix_web":[["impl PartialOrd for PeerAddr"],["impl PartialOrd for ContentLength"],["impl PartialOrd<usize> for ContentLength"],["impl PartialOrd<ContentLength> for usize"],["impl<T: PartialOrd> PartialOrd for Preference<T>"],["impl<T: PartialOrd> PartialOrd for Form<T>"],["impl<T: PartialOrd> PartialOrd for Header<T>"],["impl<T: PartialOrd> PartialOrd for Path<T>"],["impl<T: PartialOrd> PartialOrd for Query<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/convert/trait.AsRef.js b/trait.impl/core/convert/trait.AsRef.js new file mode 100644 index 000000000..6a802538f --- /dev/null +++ b/trait.impl/core/convert/trait.AsRef.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"actix_http":[["impl AsRef<RequestHead> for RequestHeadType"]], +"actix_web":[["impl<T> AsRef<T> for Path<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/convert/trait.From.js b/trait.impl/core/convert/trait.From.js new file mode 100644 index 000000000..e6fe98807 --- /dev/null +++ b/trait.impl/core/convert/trait.From.js @@ -0,0 +1,7 @@ +(function() {var implementors = { +"actix_http":[["impl From<&'static str> for Response<&'static str>"],["impl From<&'static [u8]> for Response<&'static [u8]>"],["impl From<&HandshakeError> for Response<BoxBody>"],["impl From<&HeaderMap> for HeaderMap"],["impl From<&String> for Response<String>"],["impl From<&Vec<u8>> for Response<Vec<u8>>"],["impl From<ParseError> for DispatchError"],["impl From<ParseError> for Error"],["impl From<ParseError> for Response<BoxBody>"],["impl From<PayloadError> for Error"],["impl From<CloseCode> for u16"],["impl From<CloseCode> for CloseReason"],["impl From<HandshakeError> for Error"],["impl From<HandshakeError> for Response<BoxBody>"],["impl From<OpCode> for ProtocolError"],["impl From<OpCode> for u8"],["impl From<ProtocolError> for Error"],["impl From<Infallible> for Error"],["impl From<Infallible> for Response<BoxBody>"],["impl From<Option<Duration>> for KeepAlive"],["impl From<Option<Error>> for PayloadError"],["impl From<u16> for CloseCode"],["impl From<u8> for OpCode"],["impl From<u8> for ProtocolError"],["impl From<usize> for ProtocolError"],["impl From<Error> for Response<BoxBody>"],["impl From<Error> for Error"],["impl From<HeaderMap> for HeaderMap"],["impl From<HttpDate> for SystemTime"],["impl From<Message<RequestHead>> for Request<BoxedPayloadStream>"],["impl From<RequestHead> for RequestHeadType"],["impl From<Response<BoxBody>> for DispatchError"],["impl From<ResponseBuilder> for Response<EitherBody<()>>"],["impl From<InvalidUri> for ParseError"],["impl From<Box<dyn Error>> for DispatchError"],["impl From<FromUtf8Error> for ParseError"],["impl From<String> for Response<String>"],["impl From<Vec<u8>> for Response<Vec<u8>>"],["impl From<Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> for Payload"],["impl From<Utf8Error> for ParseError"],["impl From<Duration> for KeepAlive"],["impl From<Error> for DispatchError"],["impl From<Error> for ParseError"],["impl From<Error> for PayloadError"],["impl From<Error> for ProtocolError"],["impl From<SystemTime> for HttpDate"],["impl From<HeaderMap> for HeaderMap"],["impl From<ByteString> for Response<ByteString>"],["impl From<Bytes> for Response<Bytes>"],["impl From<BytesMut> for Response<BytesMut>"],["impl From<Error> for DispatchError"],["impl From<Error> for ParseError"],["impl From<Error> for PayloadError"],["impl<'a> From<&'a ResponseHead> for ResponseBuilder"],["impl<B> From<Response<B>> for ResponseBuilder"],["impl<I: Into<Response<BoxBody>>, E: Into<Error>> From<Result<I, E>> for Response<BoxBody>"],["impl<S> From<Payload> for Payload<S>"],["impl<S> From<Payload> for Payload<S>"],["impl<S> From<RecvStream> for Payload<S>"],["impl<T> From<T> for Message<T>"],["impl<T: Into<String>> From<(CloseCode, T)> for CloseReason"]], +"actix_multipart":[["impl From<(String, Error)> for MultipartError"],["impl From<ParseError> for MultipartError"],["impl From<PayloadError> for MultipartError"]], +"actix_router":[["impl From<String> for ResourceDef"],["impl<'a> From<&'a str> for ResourceDef"]], +"actix_web":[["impl From<(usize, usize)> for UrlencodedError"],["impl From<ContentTypeError> for ReadlinesError"],["impl From<PayloadError> for JsonPayloadError"],["impl From<PayloadError> for ReadlinesError"],["impl From<PayloadError> for UrlencodedError"],["impl From<ParseError> for UrlGenerationError"],["impl From<usize> for ContentLength"],["impl From<Error> for Response<BoxBody>"],["impl From<Error> for HttpResponse"],["impl From<ContentLength> for usize"],["impl From<HttpResponseBuilder> for Response<BoxBody>"],["impl From<HttpResponseBuilder> for HttpResponse"],["impl From<Error> for QueryPayloadError"],["impl From<Error> for UrlencodedError"],["impl From<Error> for UrlencodedError"],["impl<'a> From<&'a str> for DispositionType"],["impl<B> From<Response<B>> for HttpResponse<B>"],["impl<B> From<ServiceResponse<B>> for Response<B>"],["impl<B> From<ServiceResponse<B>> for HttpResponse<B>"],["impl<B> From<HttpResponse<B>> for Response<B>"],["impl<T> From<T> for Path<T>"],["impl<T: ResponseError + 'static> From<T> for Error"],["impl<T: ?Sized> From<Arc<T>> for Data<T>"]], +"awc":[["impl From<(Box<dyn Error>, Box<dyn Debug>)> for FreezeRequestError"],["impl From<(Box<dyn Error>, Box<dyn Debug>)> for SendRequestError"],["impl From<([u8; 28], HeaderValue)> for WsClientError"],["impl From<ConnectError> for SendRequestError"],["impl From<FreezeRequestError> for SendRequestError"],["impl From<InvalidUrl> for FreezeRequestError"],["impl From<InvalidUrl> for SendRequestError"],["impl From<InvalidUrl> for WsClientError"],["impl From<PayloadError> for JsonPayloadError"],["impl From<SendRequestError> for SendClientRequest"],["impl From<SendRequestError> for WsClientError"],["impl From<ProtocolError> for WsClientError"],["impl From<()> for JsonPayloadError"],["impl From<Error> for SendClientRequest"],["impl From<Error> for FreezeRequestError"],["impl From<Error> for InvalidUrl"],["impl From<Error> for SendRequestError"],["impl From<Error> for WsClientError"],["impl From<HeaderValue> for WsClientError"],["impl From<StatusCode> for WsClientError"],["impl From<Box<dyn Error>> for ConnectError"],["impl From<Box<dyn Error>> for SendRequestError"],["impl From<Error> for ConnectError"],["impl From<Error> for SendRequestError"],["impl From<Error> for ConnectError"],["impl From<Error> for JsonPayloadError"],["impl From<ConnectError> for ConnectError"],["impl From<Error> for ConnectError"],["impl From<Error> for SendRequestError"],["impl From<ParseError> for SendRequestError"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/convert/trait.TryFrom.js b/trait.impl/core/convert/trait.TryFrom.js new file mode 100644 index 000000000..14e522bb3 --- /dev/null +++ b/trait.impl/core/convert/trait.TryFrom.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_http":[["impl TryFrom<&str> for ContentEncoding"],["impl TryFrom<f32> for Quality"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/default/trait.Default.js b/trait.impl/core/default/trait.Default.js new file mode 100644 index 000000000..5b45fcfc2 --- /dev/null +++ b/trait.impl/core/default/trait.Default.js @@ -0,0 +1,8 @@ +(function() {var implementors = { +"actix_http":[["impl Default for KeepAlive"],["impl Default for ContentEncoding"],["impl Default for None"],["impl Default for ClientCodec"],["impl Default for Codec"],["impl Default for HeaderMap"],["impl Default for Quality"],["impl Default for Extensions"],["impl Default for RequestHead"],["impl Default for ResponseBuilder"],["impl Default for ServiceConfig"],["impl Default for TlsAcceptorConfig"],["impl Default for TestRequest"],["impl Default for Codec"],["impl<B: Default> Default for Response<B>"],["impl<T, S> Default for HttpServiceBuilder<T, S, ExpectHandler, UpgradeHandler>
where\n S: ServiceFactory<Request, Config = ()>,\n S::Error: Into<Response<BoxBody>> + 'static,\n S::InitError: Debug,\n <S::Service as Service<Request>>::Future: 'static,
"]], +"actix_multipart":[["impl Default for JsonConfig"],["impl Default for MultipartFormConfig"],["impl Default for TempFileConfig"],["impl Default for TextConfig"]], +"actix_router":[["impl Default for Url"],["impl<T: Default> Default for Path<T>"]], +"actix_test":[["impl Default for TestServerConfig"]], +"actix_web":[["impl Default for TrailingSlash"],["impl Default for AppConfig"],["impl Default for ConnectionInfo"],["impl Default for Compress"],["impl Default for DefaultHeaders"],["impl Default for Logger"],["impl Default for NormalizePath"],["impl Default for TestRequest"],["impl Default for FormConfig"],["impl Default for JsonConfig"],["impl Default for PathConfig"],["impl Default for PayloadConfig"],["impl Default for QueryConfig"],["impl<B> Default for ErrorHandlers<B>"],["impl<T: Default> Default for Data<T>"]], +"awc":[["impl Default for Redirect"],["impl Default for Client"],["impl Default for TestResponse"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/error/trait.Error.js b/trait.impl/core/error/trait.Error.js new file mode 100644 index 000000000..4275a080e --- /dev/null +++ b/trait.impl/core/error/trait.Error.js @@ -0,0 +1,6 @@ +(function() {var implementors = { +"actix_http":[["impl Error for ContentTypeError"],["impl Error for DispatchError"],["impl Error for ParseError"],["impl Error for PayloadError"],["impl Error for HandshakeError"],["impl Error for ProtocolError"],["impl Error for BodyLimitExceeded"],["impl Error for Error"]], +"actix_multipart":[["impl Error for MultipartError"],["impl Error for JsonFieldError"],["impl Error for TempFileError"],["impl Error for TextError"]], +"actix_web":[["impl Error for JsonPayloadError"],["impl Error for PathError"],["impl Error for QueryPayloadError"],["impl Error for ReadlinesError"],["impl Error for UrlGenerationError"],["impl Error for UrlencodedError"],["impl Error for BlockingError"],["impl Error for Error"]], +"awc":[["impl Error for ConnectError"],["impl Error for FreezeRequestError"],["impl Error for InvalidUrl"],["impl Error for JsonPayloadError"],["impl Error for SendRequestError"],["impl Error for WsClientError"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/fmt/trait.Debug.js b/trait.impl/core/fmt/trait.Debug.js new file mode 100644 index 000000000..e2aa546a4 --- /dev/null +++ b/trait.impl/core/fmt/trait.Debug.js @@ -0,0 +1,8 @@ +(function() {var implementors = { +"actix_files":[["impl Debug for Directory"],["impl Debug for Files"],["impl Debug for FilesService"],["impl Debug for HttpRange"],["impl Debug for NamedFile"]], +"actix_http":[["impl Debug for BodySize"],["impl Debug for ConnectionType"],["impl Debug for KeepAlive"],["impl Debug for Protocol"],["impl Debug for RequestHeadType"],["impl Debug for ContentTypeError"],["impl Debug for DispatchError"],["impl Debug for ParseError"],["impl Debug for PayloadError"],["impl Debug for MessageType"],["impl Debug for Charset"],["impl Debug for ContentEncoding"],["impl Debug for CloseCode"],["impl Debug for Frame"],["impl Debug for HandshakeError"],["impl Debug for Item"],["impl Debug for Message"],["impl Debug for OpCode"],["impl Debug for ProtocolError"],["impl Debug for BodyLimitExceeded"],["impl Debug for BoxBody"],["impl Debug for None"],["impl Debug for Error"],["impl Debug for ClientCodec"],["impl Debug for Codec"],["impl Debug for Payload"],["impl Debug for HeaderMap"],["impl Debug for IntoIter"],["impl Debug for Removed"],["impl Debug for ExtendedValue"],["impl Debug for HttpDate"],["impl Debug for Quality"],["impl Debug for Extensions"],["impl Debug for RequestHead"],["impl Debug for ResponseBuilder"],["impl Debug for ResponseHead"],["impl Debug for ServiceConfig"],["impl Debug for TlsAcceptorConfig"],["impl Debug for TestBuffer"],["impl Debug for CloseReason"],["impl Debug for Codec"],["impl Debug for Parser"],["impl<'a> Debug for Drain<'a>"],["impl<'a> Debug for Iter<'a>"],["impl<'a> Debug for Keys<'a>"],["impl<B> Debug for Response<B>
where\n B: MessageBody,
"],["impl<L: Debug, R: Debug> Debug for EitherBody<L, R>"],["impl<P> Debug for Request<P>"],["impl<T: Debug> Debug for Message<T>"],["impl<T: Debug> Debug for QualityItem<T>"]], +"actix_multipart":[["impl Debug for MultipartError"],["impl Debug for JsonFieldError"],["impl Debug for TempFileError"],["impl Debug for TextError"],["impl Debug for Bytes"],["impl Debug for TempFile"],["impl Debug for Field"],["impl<T: Debug + DeserializeOwned> Debug for Json<T>"],["impl<T: Debug + DeserializeOwned> Debug for Text<T>"]], +"actix_router":[["impl Debug for Patterns"],["impl Debug for ResourceDef"],["impl Debug for ResourceId"],["impl Debug for Url"],["impl<T: Debug> Debug for Path<T>"]], +"actix_web":[["impl Debug for JsonPayloadError"],["impl Debug for PathError"],["impl Debug for QueryPayloadError"],["impl Debug for ReadlinesError"],["impl Debug for UrlGenerationError"],["impl Debug for UrlencodedError"],["impl Debug for ByteRangeSpec"],["impl Debug for CacheDirective"],["impl Debug for ContentRangeSpec"],["impl Debug for DispositionParam"],["impl Debug for DispositionType"],["impl Debug for Encoding"],["impl Debug for IfMatch"],["impl Debug for IfNoneMatch"],["impl Debug for IfRange"],["impl Debug for Range"],["impl Debug for TrailingSlash"],["impl Debug for AppConfig"],["impl Debug for ConnectionInfo"],["impl Debug for PeerAddr"],["impl Debug for ResourceMap"],["impl Debug for ServiceRequest"],["impl Debug for BlockingError"],["impl Debug for Error"],["impl Debug for Acceptable"],["impl Debug for Accept"],["impl Debug for AcceptCharset"],["impl Debug for AcceptEncoding"],["impl Debug for AcceptLanguage"],["impl Debug for Allow"],["impl Debug for CacheControl"],["impl Debug for ContentDisposition"],["impl Debug for ContentLanguage"],["impl Debug for ContentLength"],["impl Debug for ContentRange"],["impl Debug for ContentType"],["impl Debug for Date"],["impl Debug for ETag"],["impl Debug for EntityTag"],["impl Debug for Expires"],["impl Debug for IfModifiedSince"],["impl Debug for IfUnmodifiedSince"],["impl Debug for LastModified"],["impl Debug for Compress"],["impl Debug for DefaultHeaders"],["impl Debug for Logger"],["impl Debug for NormalizePath"],["impl Debug for HttpRequest"],["impl Debug for Redirect"],["impl<'a> Debug for GuardContext<'a>"],["impl<B> Debug for ServiceResponse<B>
where\n B: MessageBody,\n B::Error: Into<Error>,
"],["impl<B> Debug for HttpResponse<B>
where\n B: MessageBody,
"],["impl<L: Debug, R: Debug> Debug for Either<L, R>"],["impl<T: Debug + Clone + 'static> Debug for ReqData<T>"],["impl<T: Debug + ?Sized> Debug for Data<T>"],["impl<T: Debug> Debug for Preference<T>"],["impl<T: Debug> Debug for InternalError<T>"],["impl<T: Debug> Debug for Form<T>"],["impl<T: Debug> Debug for Header<T>"],["impl<T: Debug> Debug for Json<T>"],["impl<T: Debug> Debug for Path<T>"],["impl<T: Debug> Debug for Query<T>"]], +"awc":[["impl Debug for ConnectError"],["impl Debug for FreezeRequestError"],["impl Debug for InvalidUrl"],["impl Debug for JsonPayloadError"],["impl Debug for SendRequestError"],["impl Debug for WsClientError"],["impl Debug for ClientRequest"],["impl Debug for WebsocketsRequest"],["impl<S> Debug for ClientResponse<S>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/fmt/trait.Display.js b/trait.impl/core/fmt/trait.Display.js new file mode 100644 index 000000000..f9090f0dd --- /dev/null +++ b/trait.impl/core/fmt/trait.Display.js @@ -0,0 +1,6 @@ +(function() {var implementors = { +"actix_http":[["impl Display for ContentTypeError"],["impl Display for DispatchError"],["impl Display for ParseError"],["impl Display for PayloadError"],["impl Display for Charset"],["impl Display for HandshakeError"],["impl Display for OpCode"],["impl Display for ProtocolError"],["impl Display for BodyLimitExceeded"],["impl Display for Error"],["impl Display for ExtendedValue"],["impl Display for HttpDate"],["impl Display for Quality"],["impl<T: Display> Display for QualityItem<T>"]], +"actix_multipart":[["impl Display for MultipartError"],["impl Display for JsonFieldError"],["impl Display for TempFileError"],["impl Display for TextError"]], +"actix_web":[["impl Display for JsonPayloadError"],["impl Display for PathError"],["impl Display for QueryPayloadError"],["impl Display for ReadlinesError"],["impl Display for UrlGenerationError"],["impl Display for UrlencodedError"],["impl Display for ByteRangeSpec"],["impl Display for CacheDirective"],["impl Display for ContentRangeSpec"],["impl Display for DispositionParam"],["impl Display for DispositionType"],["impl Display for Encoding"],["impl Display for IfMatch"],["impl Display for IfNoneMatch"],["impl Display for IfRange"],["impl Display for Range"],["impl Display for PeerAddr"],["impl Display for BlockingError"],["impl Display for Error"],["impl Display for Accept"],["impl Display for AcceptCharset"],["impl Display for AcceptEncoding"],["impl Display for AcceptLanguage"],["impl Display for Allow"],["impl Display for CacheControl"],["impl Display for ContentDisposition"],["impl Display for ContentLanguage"],["impl Display for ContentRange"],["impl Display for ContentType"],["impl Display for Date"],["impl Display for ETag"],["impl Display for EntityTag"],["impl Display for Expires"],["impl Display for IfModifiedSince"],["impl Display for IfUnmodifiedSince"],["impl Display for LastModified"],["impl<T> Display for Header<T>
where\n T: Display,
"],["impl<T> Display for Path<T>
where\n T: Display,
"],["impl<T: Display> Display for Preference<T>"],["impl<T: Display> Display for InternalError<T>"],["impl<T: Display> Display for Form<T>"],["impl<T: Display> Display for Json<T>"],["impl<T: Display> Display for Query<T>"]], +"awc":[["impl Display for ConnectError"],["impl Display for FreezeRequestError"],["impl Display for InvalidUrl"],["impl Display for JsonPayloadError"],["impl Display for SendRequestError"],["impl Display for WsClientError"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/future/future/trait.Future.js b/trait.impl/core/future/future/trait.Future.js new file mode 100644 index 000000000..3b046d764 --- /dev/null +++ b/trait.impl/core/future/future/trait.Future.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"actix_http":[["impl<S, T> Future for Dispatcher<S, T>
where\n T: AsyncRead + AsyncWrite,\n S: Service<Frame, Response = Message>,\n S::Future: 'static,\n S::Error: 'static,
"],["impl<T, B> Future for SendResponse<T, B>
where\n T: AsyncRead + AsyncWrite + Unpin,\n B: MessageBody,\n B::Error: Into<Error>,
"],["impl<T, S, B, X, U> Future for Dispatcher<T, S, B, X, U>
where\n T: AsyncRead + AsyncWrite + Unpin,\n S: Service<Request>,\n S::Error: Into<Response<BoxBody>>,\n S::Response: Into<Response<B>>,\n B: MessageBody,\n X: Service<Request, Response = Request>,\n X::Error: Into<Response<BoxBody>>,\n U: Service<(Request, Framed<T, Codec>), Response = ()>,\n U::Error: Display,
"],["impl<T, S, B, X, U> Future for Dispatcher<T, S, B, X, U>
where\n T: AsyncRead + AsyncWrite + Unpin,\n S: Service<Request>,\n S::Error: Into<Response<BoxBody>>,\n S::Future: 'static,\n S::Response: Into<Response<B>>,\n B: MessageBody,
"]], +"actix_web":[["impl Future for HttpResponseBuilder"],["impl<T> Future for UrlEncoded<T>
where\n T: DeserializeOwned + 'static,
"],["impl<T: DeserializeOwned> Future for JsonBody<T>"]], +"awc":[["impl Future for SendClientRequest"],["impl<S> Future for ResponseBody<S>
where\n S: Stream<Item = Result<Bytes, PayloadError>>,
"],["impl<S, T> Future for JsonBody<S, T>
where\n S: Stream<Item = Result<Bytes, PayloadError>>,\n T: DeserializeOwned,
"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/hash/trait.Hash.js b/trait.impl/core/hash/trait.Hash.js new file mode 100644 index 000000000..21456e164 --- /dev/null +++ b/trait.impl/core/hash/trait.Hash.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"actix_http":[["impl Hash for Protocol"],["impl Hash for ContentEncoding"]], +"actix_router":[["impl Hash for Patterns"],["impl Hash for ResourceDef"]], +"actix_web":[["impl Hash for Encoding"],["impl Hash for PeerAddr"],["impl<T: Hash> Hash for Preference<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/iter/traits/collect/trait.IntoIterator.js b/trait.impl/core/iter/traits/collect/trait.IntoIterator.js new file mode 100644 index 000000000..fb67b2fcd --- /dev/null +++ b/trait.impl/core/iter/traits/collect/trait.IntoIterator.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_http":[["impl IntoIterator for HeaderMap"],["impl<'a> IntoIterator for &'a HeaderMap"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/iter/traits/exact_size/trait.ExactSizeIterator.js b/trait.impl/core/iter/traits/exact_size/trait.ExactSizeIterator.js new file mode 100644 index 000000000..e20f2f904 --- /dev/null +++ b/trait.impl/core/iter/traits/exact_size/trait.ExactSizeIterator.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_http":[["impl ExactSizeIterator for Drain<'_>"],["impl ExactSizeIterator for IntoIter"],["impl ExactSizeIterator for Iter<'_>"],["impl ExactSizeIterator for Keys<'_>"],["impl ExactSizeIterator for Removed"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/iter/traits/iterator/trait.Iterator.js b/trait.impl/core/iter/traits/iterator/trait.Iterator.js new file mode 100644 index 000000000..90c993c5e --- /dev/null +++ b/trait.impl/core/iter/traits/iterator/trait.Iterator.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_http":[["impl Iterator for IntoIter"],["impl Iterator for Removed"],["impl<'a> Iterator for Drain<'a>"],["impl<'a> Iterator for Iter<'a>"],["impl<'a> Iterator for Keys<'a>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/iter/traits/marker/trait.FusedIterator.js b/trait.impl/core/iter/traits/marker/trait.FusedIterator.js new file mode 100644 index 000000000..ba847c65f --- /dev/null +++ b/trait.impl/core/iter/traits/marker/trait.FusedIterator.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_http":[["impl FusedIterator for Drain<'_>"],["impl FusedIterator for IntoIter"],["impl FusedIterator for Iter<'_>"],["impl FusedIterator for Keys<'_>"],["impl FusedIterator for Removed"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Copy.js b/trait.impl/core/marker/trait.Copy.js new file mode 100644 index 000000000..cad45a68f --- /dev/null +++ b/trait.impl/core/marker/trait.Copy.js @@ -0,0 +1,6 @@ +(function() {var implementors = { +"actix_files":[["impl Copy for HttpRange"]], +"actix_http":[["impl Copy for BodySize"],["impl Copy for ConnectionType"],["impl Copy for KeepAlive"],["impl Copy for Protocol"],["impl Copy for MessageType"],["impl Copy for ContentEncoding"],["impl Copy for CloseCode"],["impl Copy for HandshakeError"],["impl Copy for OpCode"],["impl Copy for None"],["impl Copy for HttpDate"],["impl Copy for Quality"],["impl<T: Copy> Copy for QualityItem<T>"]], +"actix_router":[["impl Copy for ResourceId"]], +"actix_web":[["impl Copy for TrailingSlash"],["impl Copy for PeerAddr"],["impl Copy for NormalizePath"],["impl<T: Copy> Copy for Preference<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Freeze.js b/trait.impl/core/marker/trait.Freeze.js new file mode 100644 index 000000000..f1475d35e --- /dev/null +++ b/trait.impl/core/marker/trait.Freeze.js @@ -0,0 +1,11 @@ +(function() {var implementors = { +"actix_files":[["impl Freeze for Directory",1,["actix_files::directory::Directory"]],["impl Freeze for Files",1,["actix_files::files::Files"]],["impl Freeze for FilesService",1,["actix_files::service::FilesService"]],["impl Freeze for HttpRange",1,["actix_files::range::HttpRange"]],["impl Freeze for NamedFile",1,["actix_files::named::NamedFile"]]], +"actix_http":[["impl !Freeze for RequestHeadType",1,["actix_http::requests::head::RequestHeadType"]],["impl !Freeze for DispatchError",1,["actix_http::error::DispatchError"]],["impl !Freeze for PayloadError",1,["actix_http::error::PayloadError"]],["impl !Freeze for Frame",1,["actix_http::ws::codec::Frame"]],["impl !Freeze for Item",1,["actix_http::ws::codec::Item"]],["impl !Freeze for Message",1,["actix_http::ws::codec::Message"]],["impl !Freeze for BoxBody",1,["actix_http::body::boxed::BoxBody"]],["impl !Freeze for IntoIter",1,["actix_http::header::map::IntoIter"]],["impl !Freeze for Removed",1,["actix_http::header::map::Removed"]],["impl !Freeze for RequestHead",1,["actix_http::requests::head::RequestHead"]],["impl !Freeze for TestRequest",1,["actix_http::test::TestRequest"]],["impl Freeze for BodySize",1,["actix_http::body::size::BodySize"]],["impl Freeze for ConnectionType",1,["actix_http::message::ConnectionType"]],["impl Freeze for KeepAlive",1,["actix_http::keep_alive::KeepAlive"]],["impl Freeze for Protocol",1,["actix_http::Protocol"]],["impl Freeze for ContentTypeError",1,["actix_http::error::ContentTypeError"]],["impl Freeze for ParseError",1,["actix_http::error::ParseError"]],["impl Freeze for MessageType",1,["actix_http::h1::MessageType"]],["impl Freeze for Charset",1,["actix_http::header::shared::charset::Charset"]],["impl Freeze for ContentEncoding",1,["actix_http::header::shared::content_encoding::ContentEncoding"]],["impl Freeze for CloseCode",1,["actix_http::ws::proto::CloseCode"]],["impl Freeze for HandshakeError",1,["actix_http::ws::HandshakeError"]],["impl Freeze for OpCode",1,["actix_http::ws::proto::OpCode"]],["impl Freeze for ProtocolError",1,["actix_http::ws::ProtocolError"]],["impl Freeze for BodyLimitExceeded",1,["actix_http::body::utils::BodyLimitExceeded"]],["impl Freeze for None",1,["actix_http::body::none::None"]],["impl Freeze for Error",1,["actix_http::error::Error"]],["impl Freeze for ClientCodec",1,["actix_http::h1::client::ClientCodec"]],["impl Freeze for ClientPayloadCodec",1,["actix_http::h1::client::ClientPayloadCodec"]],["impl Freeze for Codec",1,["actix_http::h1::codec::Codec"]],["impl Freeze for ExpectHandler",1,["actix_http::h1::expect::ExpectHandler"]],["impl Freeze for Payload",1,["actix_http::h1::payload::Payload"]],["impl Freeze for UpgradeHandler",1,["actix_http::h1::upgrade::UpgradeHandler"]],["impl Freeze for Payload",1,["actix_http::h2::Payload"]],["impl Freeze for HeaderMap",1,["actix_http::header::map::HeaderMap"]],["impl Freeze for ExtendedValue",1,["actix_http::header::shared::extended::ExtendedValue"]],["impl Freeze for HttpDate",1,["actix_http::header::shared::http_date::HttpDate"]],["impl Freeze for Quality",1,["actix_http::header::shared::quality::Quality"]],["impl Freeze for Extensions",1,["actix_http::extensions::Extensions"]],["impl Freeze for ResponseBuilder",1,["actix_http::responses::builder::ResponseBuilder"]],["impl Freeze for ResponseHead",1,["actix_http::responses::head::ResponseHead"]],["impl Freeze for ServiceConfig",1,["actix_http::config::ServiceConfig"]],["impl Freeze for TlsAcceptorConfig",1,["actix_http::service::TlsAcceptorConfig"]],["impl Freeze for TestBuffer",1,["actix_http::test::TestBuffer"]],["impl Freeze for TestSeqBuffer",1,["actix_http::test::TestSeqBuffer"]],["impl Freeze for TestSeqInner",1,["actix_http::test::TestSeqInner"]],["impl Freeze for CloseReason",1,["actix_http::ws::proto::CloseReason"]],["impl Freeze for Codec",1,["actix_http::ws::codec::Codec"]],["impl Freeze for Parser",1,["actix_http::ws::frame::Parser"]],["impl<'a> !Freeze for Drain<'a>",1,["actix_http::header::map::Drain"]],["impl<'a> Freeze for Iter<'a>",1,["actix_http::header::map::Iter"]],["impl<'a> Freeze for Keys<'a>",1,["actix_http::header::map::Keys"]],["impl<B> !Freeze for Encoder<B>",1,["actix_http::encoding::encoder::Encoder"]],["impl<B> !Freeze for Response<B>",1,["actix_http::responses::response::Response"]],["impl<L, R> Freeze for EitherBody<L, R>
where\n L: Freeze,\n R: Freeze,
",1,["actix_http::body::either::EitherBody"]],["impl<P = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Freeze for Request<P>",1,["actix_http::requests::request::Request"]],["impl<S> Freeze for Payload<S>
where\n S: Freeze,
",1,["actix_http::payload::Payload"]],["impl<S> Freeze for BodyStream<S>
where\n S: Freeze,
",1,["actix_http::body::body_stream::BodyStream"]],["impl<S> Freeze for SizedStream<S>
where\n S: Freeze,
",1,["actix_http::body::sized_stream::SizedStream"]],["impl<S> Freeze for Decoder<S>
where\n S: Freeze,
",1,["actix_http::encoding::decoder::Decoder"]],["impl<S, T> Freeze for Dispatcher<S, T>
where\n S: Freeze,\n T: Freeze,\n <S as Service<Frame>>::Error: Freeze,
",1,["actix_http::ws::dispatcher::Dispatcher"]],["impl<T> !Freeze for Message<T>",1,["actix_http::h1::Message"]],["impl<T> Freeze for QualityItem<T>
where\n T: Freeze,
",1,["actix_http::header::shared::quality_item::QualityItem"]],["impl<T> Freeze for Message<T>",1,["actix_http::message::Message"]],["impl<T, B> !Freeze for SendResponse<T, B>",1,["actix_http::h1::utils::SendResponse"]],["impl<T, S, B> Freeze for H2Service<T, S, B>
where\n S: Freeze,
",1,["actix_http::h2::service::H2Service"]],["impl<T, S, B, X, U> !Freeze for Dispatcher<T, S, B, X, U>",1,["actix_http::h1::dispatcher::Dispatcher"]],["impl<T, S, B, X, U> !Freeze for Dispatcher<T, S, B, X, U>",1,["actix_http::h2::dispatcher::Dispatcher"]],["impl<T, S, B, X, U> Freeze for H1Service<T, S, B, X, U>
where\n S: Freeze,\n X: Freeze,\n U: Freeze,
",1,["actix_http::h1::service::H1Service"]],["impl<T, S, B, X, U> Freeze for HttpService<T, S, B, X, U>
where\n S: Freeze,\n X: Freeze,\n U: Freeze,
",1,["actix_http::service::HttpService"]],["impl<T, S, X, U> Freeze for HttpServiceBuilder<T, S, X, U>
where\n X: Freeze,\n U: Freeze,
",1,["actix_http::builder::HttpServiceBuilder"]]], +"actix_http_test":[["impl Freeze for TestServer",1,["actix_http_test::TestServer"]]], +"actix_multipart":[["impl !Freeze for MultipartError",1,["actix_multipart::error::MultipartError"]],["impl !Freeze for Bytes",1,["actix_multipart::form::bytes::Bytes"]],["impl !Freeze for Field",1,["actix_multipart::server::Field"]],["impl !Freeze for Multipart",1,["actix_multipart::server::Multipart"]],["impl Freeze for JsonFieldError",1,["actix_multipart::form::json::JsonFieldError"]],["impl Freeze for TempFileError",1,["actix_multipart::form::tempfile::TempFileError"]],["impl Freeze for TextError",1,["actix_multipart::form::text::TextError"]],["impl Freeze for JsonConfig",1,["actix_multipart::form::json::JsonConfig"]],["impl Freeze for Limits",1,["actix_multipart::form::Limits"]],["impl Freeze for MultipartFormConfig",1,["actix_multipart::form::MultipartFormConfig"]],["impl Freeze for TempFile",1,["actix_multipart::form::tempfile::TempFile"]],["impl Freeze for TempFileConfig",1,["actix_multipart::form::tempfile::TempFileConfig"]],["impl Freeze for TextConfig",1,["actix_multipart::form::text::TextConfig"]],["impl<T> Freeze for Json<T>
where\n T: Freeze,
",1,["actix_multipart::form::json::Json"]],["impl<T> Freeze for MultipartForm<T>
where\n T: Freeze,
",1,["actix_multipart::form::MultipartForm"]],["impl<T> Freeze for Text<T>
where\n T: Freeze,
",1,["actix_multipart::form::text::Text"]]], +"actix_router":[["impl !Freeze for Url",1,["actix_router::url::Url"]],["impl Freeze for Patterns",1,["actix_router::pattern::Patterns"]],["impl Freeze for Quoter",1,["actix_router::quoter::Quoter"]],["impl Freeze for ResourceDef",1,["actix_router::resource::ResourceDef"]],["impl Freeze for ResourceId",1,["actix_router::router::ResourceId"]],["impl<'de, T> Freeze for PathDeserializer<'de, T>",1,["actix_router::de::PathDeserializer"]],["impl<T> Freeze for Path<T>
where\n T: Freeze,
",1,["actix_router::path::Path"]],["impl<T, U> Freeze for Router<T, U>",1,["actix_router::router::Router"]],["impl<T, U> Freeze for RouterBuilder<T, U>",1,["actix_router::router::RouterBuilder"]]], +"actix_test":[["impl Freeze for TestServer",1,["actix_test::TestServer"]],["impl Freeze for TestServerConfig",1,["actix_test::TestServerConfig"]]], +"actix_web":[["impl !Freeze for JsonPayloadError",1,["actix_web::error::JsonPayloadError"]],["impl !Freeze for ReadlinesError",1,["actix_web::error::ReadlinesError"]],["impl !Freeze for UrlencodedError",1,["actix_web::error::UrlencodedError"]],["impl !Freeze for ResourceMap",1,["actix_web::rmap::ResourceMap"]],["impl !Freeze for HttpResponseBuilder",1,["actix_web::response::builder::HttpResponseBuilder"]],["impl !Freeze for TestRequest",1,["actix_web::test::test_request::TestRequest"]],["impl Freeze for PathError",1,["actix_web::error::PathError"]],["impl Freeze for QueryPayloadError",1,["actix_web::error::QueryPayloadError"]],["impl Freeze for UrlGenerationError",1,["actix_web::error::UrlGenerationError"]],["impl Freeze for ByteRangeSpec",1,["actix_web::http::header::range::ByteRangeSpec"]],["impl Freeze for CacheDirective",1,["actix_web::http::header::cache_control::CacheDirective"]],["impl Freeze for ContentRangeSpec",1,["actix_web::http::header::content_range::ContentRangeSpec"]],["impl Freeze for DispositionParam",1,["actix_web::http::header::content_disposition::DispositionParam"]],["impl Freeze for DispositionType",1,["actix_web::http::header::content_disposition::DispositionType"]],["impl Freeze for Encoding",1,["actix_web::http::header::encoding::Encoding"]],["impl Freeze for IfMatch",1,["actix_web::http::header::if_match::IfMatch"]],["impl Freeze for IfNoneMatch",1,["actix_web::http::header::if_none_match::IfNoneMatch"]],["impl Freeze for IfRange",1,["actix_web::http::header::if_range::IfRange"]],["impl Freeze for Range",1,["actix_web::http::header::range::Range"]],["impl Freeze for TrailingSlash",1,["actix_web::middleware::normalize::TrailingSlash"]],["impl Freeze for AppConfig",1,["actix_web::config::AppConfig"]],["impl Freeze for AppService",1,["actix_web::config::AppService"]],["impl Freeze for ConnectionInfo",1,["actix_web::info::ConnectionInfo"]],["impl Freeze for PeerAddr",1,["actix_web::info::PeerAddr"]],["impl Freeze for ServiceRequest",1,["actix_web::service::ServiceRequest"]],["impl Freeze for WebService",1,["actix_web::service::WebService"]],["impl Freeze for BlockingError",1,["actix_web::error::BlockingError"]],["impl Freeze for Error",1,["actix_web::error::error::Error"]],["impl Freeze for Acceptable",1,["actix_web::guard::acceptable::Acceptable"]],["impl Freeze for AllGuard",1,["actix_web::guard::AllGuard"]],["impl Freeze for AnyGuard",1,["actix_web::guard::AnyGuard"]],["impl Freeze for Accept",1,["actix_web::http::header::accept::Accept"]],["impl Freeze for AcceptCharset",1,["actix_web::http::header::accept_charset::AcceptCharset"]],["impl Freeze for AcceptEncoding",1,["actix_web::http::header::accept_encoding::AcceptEncoding"]],["impl Freeze for AcceptLanguage",1,["actix_web::http::header::accept_language::AcceptLanguage"]],["impl Freeze for Allow",1,["actix_web::http::header::allow::Allow"]],["impl Freeze for CacheControl",1,["actix_web::http::header::cache_control::CacheControl"]],["impl Freeze for ContentDisposition",1,["actix_web::http::header::content_disposition::ContentDisposition"]],["impl Freeze for ContentLanguage",1,["actix_web::http::header::content_language::ContentLanguage"]],["impl Freeze for ContentLength",1,["actix_web::http::header::content_length::ContentLength"]],["impl Freeze for ContentRange",1,["actix_web::http::header::content_range::ContentRange"]],["impl Freeze for ContentType",1,["actix_web::http::header::content_type::ContentType"]],["impl Freeze for Date",1,["actix_web::http::header::date::Date"]],["impl Freeze for ETag",1,["actix_web::http::header::etag::ETag"]],["impl Freeze for EntityTag",1,["actix_web::http::header::entity::EntityTag"]],["impl Freeze for Expires",1,["actix_web::http::header::expires::Expires"]],["impl Freeze for IfModifiedSince",1,["actix_web::http::header::if_modified_since::IfModifiedSince"]],["impl Freeze for IfUnmodifiedSince",1,["actix_web::http::header::if_unmodified_since::IfUnmodifiedSince"]],["impl Freeze for LastModified",1,["actix_web::http::header::last_modified::LastModified"]],["impl Freeze for Compress",1,["actix_web::middleware::compress::Compress"]],["impl Freeze for DefaultHeaders",1,["actix_web::middleware::default_headers::DefaultHeaders"]],["impl Freeze for Logger",1,["actix_web::middleware::logger::Logger"]],["impl Freeze for NormalizePath",1,["actix_web::middleware::normalize::NormalizePath"]],["impl Freeze for HttpRequest",1,["actix_web::request::HttpRequest"]],["impl Freeze for Route",1,["actix_web::route::Route"]],["impl Freeze for FormConfig",1,["actix_web::types::form::FormConfig"]],["impl Freeze for JsonConfig",1,["actix_web::types::json::JsonConfig"]],["impl Freeze for PathConfig",1,["actix_web::types::path::PathConfig"]],["impl Freeze for Payload",1,["actix_web::types::payload::Payload"]],["impl Freeze for PayloadConfig",1,["actix_web::types::payload::PayloadConfig"]],["impl Freeze for QueryConfig",1,["actix_web::types::query::QueryConfig"]],["impl Freeze for Redirect",1,["actix_web::redirect::Redirect"]],["impl Freeze for ServiceConfig",1,["actix_web::config::ServiceConfig"]],["impl<'a> Freeze for GuardContext<'a>",1,["actix_web::guard::GuardContext"]],["impl<B = BoxBody> !Freeze for ServiceResponse<B>",1,["actix_web::service::ServiceResponse"]],["impl<B = BoxBody> !Freeze for HttpResponse<B>",1,["actix_web::response::response::HttpResponse"]],["impl<B> !Freeze for ErrorHandlerResponse<B>",1,["actix_web::middleware::err_handlers::ErrorHandlerResponse"]],["impl<B> Freeze for ErrorHandlers<B>",1,["actix_web::middleware::err_handlers::ErrorHandlers"]],["impl<F, I, S, B> Freeze for HttpServer<F, I, S, B>",1,["actix_web::server::HttpServer"]],["impl<G> Freeze for Not<G>
where\n G: Freeze,
",1,["actix_web::guard::Not"]],["impl<L, R> Freeze for Either<L, R>
where\n L: Freeze,\n R: Freeze,
",1,["actix_web::types::either::Either"]],["impl<R> Freeze for CustomizeResponder<R>
where\n R: Freeze,
",1,["actix_web::response::customize_responder::CustomizeResponder"]],["impl<T> !Freeze for JsonBody<T>",1,["actix_web::types::json::JsonBody"]],["impl<T> !Freeze for Readlines<T>",1,["actix_web::types::readlines::Readlines"]],["impl<T> !Freeze for UrlEncoded<T>",1,["actix_web::types::form::UrlEncoded"]],["impl<T> !Freeze for InternalError<T>",1,["actix_web::error::internal::InternalError"]],["impl<T> Freeze for Preference<T>
where\n T: Freeze,
",1,["actix_web::http::header::preference::Preference"]],["impl<T> Freeze for Compat<T>
where\n T: Freeze,
",1,["actix_web::middleware::compat::Compat"]],["impl<T> Freeze for Condition<T>
where\n T: Freeze,
",1,["actix_web::middleware::condition::Condition"]],["impl<T> Freeze for App<T>
where\n T: Freeze,
",1,["actix_web::app::App"]],["impl<T> Freeze for Resource<T>
where\n T: Freeze,
",1,["actix_web::resource::Resource"]],["impl<T> Freeze for Scope<T>
where\n T: Freeze,
",1,["actix_web::scope::Scope"]],["impl<T> Freeze for Data<T>
where\n T: ?Sized,
",1,["actix_web::data::Data"]],["impl<T> Freeze for Form<T>
where\n T: Freeze,
",1,["actix_web::types::form::Form"]],["impl<T> Freeze for Header<T>
where\n T: Freeze,
",1,["actix_web::types::header::Header"]],["impl<T> Freeze for Json<T>
where\n T: Freeze,
",1,["actix_web::types::json::Json"]],["impl<T> Freeze for Path<T>
where\n T: Freeze,
",1,["actix_web::types::path::Path"]],["impl<T> Freeze for Query<T>
where\n T: Freeze,
",1,["actix_web::types::query::Query"]],["impl<T> Freeze for ReqData<T>
where\n T: Freeze,
",1,["actix_web::request_data::ReqData"]]], +"actix_web_actors":[["impl<'a, A, T> Freeze for WsResponseBuilder<'a, A, T>
where\n A: Freeze,\n T: Freeze,
",1,["actix_web_actors::ws::WsResponseBuilder"]],["impl<A> Freeze for HttpContext<A>",1,["actix_web_actors::context::HttpContext"]],["impl<A> Freeze for WebsocketContext<A>",1,["actix_web_actors::ws::WebsocketContext"]]], +"awc":[["impl !Freeze for ConnectRequest",1,["awc::connect::ConnectRequest"]],["impl !Freeze for ConnectResponse",1,["awc::connect::ConnectResponse"]],["impl !Freeze for SendClientRequest",1,["awc::sender::SendClientRequest"]],["impl !Freeze for ConnectError",1,["awc::client::error::ConnectError"]],["impl !Freeze for JsonPayloadError",1,["awc::error::JsonPayloadError"]],["impl !Freeze for SendRequestError",1,["awc::client::error::SendRequestError"]],["impl !Freeze for WsClientError",1,["awc::error::WsClientError"]],["impl !Freeze for ClientRequest",1,["awc::request::ClientRequest"]],["impl !Freeze for Connect",1,["awc::client::Connect"]],["impl !Freeze for WebsocketsRequest",1,["awc::ws::WebsocketsRequest"]],["impl Freeze for FreezeRequestError",1,["awc::client::error::FreezeRequestError"]],["impl Freeze for InvalidUrl",1,["awc::client::error::InvalidUrl"]],["impl Freeze for Redirect",1,["awc::middleware::redirect::Redirect"]],["impl Freeze for Client",1,["awc::client::Client"]],["impl Freeze for FrozenClientRequest",1,["awc::frozen::FrozenClientRequest"]],["impl Freeze for FrozenSendBuilder",1,["awc::frozen::FrozenSendBuilder"]],["impl Freeze for TestResponse",1,["awc::test::TestResponse"]],["impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Freeze for ClientResponse<S>",1,["awc::responses::response::ClientResponse"]],["impl<S> !Freeze for ResponseBody<S>",1,["awc::responses::response_body::ResponseBody"]],["impl<S, M> Freeze for ClientBuilder<S, M>
where\n M: Freeze,\n S: Freeze,
",1,["awc::builder::ClientBuilder"]],["impl<S, T> !Freeze for JsonBody<S, T>",1,["awc::responses::json_body::JsonBody"]],["impl<T> Freeze for Connector<T>
where\n T: Freeze,
",1,["awc::client::connector::Connector"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Send.js b/trait.impl/core/marker/trait.Send.js new file mode 100644 index 000000000..3cb14634a --- /dev/null +++ b/trait.impl/core/marker/trait.Send.js @@ -0,0 +1,11 @@ +(function() {var implementors = { +"actix_files":[["impl !Send for Files",1,["actix_files::files::Files"]],["impl !Send for FilesService",1,["actix_files::service::FilesService"]],["impl !Send for NamedFile",1,["actix_files::named::NamedFile"]],["impl Send for Directory",1,["actix_files::directory::Directory"]],["impl Send for HttpRange",1,["actix_files::range::HttpRange"]]], +"actix_http":[["impl !Send for RequestHeadType",1,["actix_http::requests::head::RequestHeadType"]],["impl !Send for DispatchError",1,["actix_http::error::DispatchError"]],["impl !Send for BoxBody",1,["actix_http::body::boxed::BoxBody"]],["impl !Send for Error",1,["actix_http::error::Error"]],["impl !Send for ClientCodec",1,["actix_http::h1::client::ClientCodec"]],["impl !Send for ClientPayloadCodec",1,["actix_http::h1::client::ClientPayloadCodec"]],["impl !Send for Codec",1,["actix_http::h1::codec::Codec"]],["impl !Send for Payload",1,["actix_http::h1::payload::Payload"]],["impl !Send for Extensions",1,["actix_http::extensions::Extensions"]],["impl !Send for ServiceConfig",1,["actix_http::config::ServiceConfig"]],["impl !Send for TestBuffer",1,["actix_http::test::TestBuffer"]],["impl !Send for TestRequest",1,["actix_http::test::TestRequest"]],["impl !Send for TestSeqBuffer",1,["actix_http::test::TestSeqBuffer"]],["impl Send for BodySize",1,["actix_http::body::size::BodySize"]],["impl Send for ConnectionType",1,["actix_http::message::ConnectionType"]],["impl Send for KeepAlive",1,["actix_http::keep_alive::KeepAlive"]],["impl Send for Protocol",1,["actix_http::Protocol"]],["impl Send for ContentTypeError",1,["actix_http::error::ContentTypeError"]],["impl Send for ParseError",1,["actix_http::error::ParseError"]],["impl Send for PayloadError",1,["actix_http::error::PayloadError"]],["impl Send for MessageType",1,["actix_http::h1::MessageType"]],["impl Send for Charset",1,["actix_http::header::shared::charset::Charset"]],["impl Send for ContentEncoding",1,["actix_http::header::shared::content_encoding::ContentEncoding"]],["impl Send for CloseCode",1,["actix_http::ws::proto::CloseCode"]],["impl Send for Frame",1,["actix_http::ws::codec::Frame"]],["impl Send for HandshakeError",1,["actix_http::ws::HandshakeError"]],["impl Send for Item",1,["actix_http::ws::codec::Item"]],["impl Send for Message",1,["actix_http::ws::codec::Message"]],["impl Send for OpCode",1,["actix_http::ws::proto::OpCode"]],["impl Send for ProtocolError",1,["actix_http::ws::ProtocolError"]],["impl Send for BodyLimitExceeded",1,["actix_http::body::utils::BodyLimitExceeded"]],["impl Send for None",1,["actix_http::body::none::None"]],["impl Send for ExpectHandler",1,["actix_http::h1::expect::ExpectHandler"]],["impl Send for UpgradeHandler",1,["actix_http::h1::upgrade::UpgradeHandler"]],["impl Send for Payload",1,["actix_http::h2::Payload"]],["impl Send for HeaderMap",1,["actix_http::header::map::HeaderMap"]],["impl Send for IntoIter",1,["actix_http::header::map::IntoIter"]],["impl Send for Removed",1,["actix_http::header::map::Removed"]],["impl Send for ExtendedValue",1,["actix_http::header::shared::extended::ExtendedValue"]],["impl Send for HttpDate",1,["actix_http::header::shared::http_date::HttpDate"]],["impl Send for Quality",1,["actix_http::header::shared::quality::Quality"]],["impl Send for RequestHead",1,["actix_http::requests::head::RequestHead"]],["impl Send for ResponseBuilder",1,["actix_http::responses::builder::ResponseBuilder"]],["impl Send for ResponseHead",1,["actix_http::responses::head::ResponseHead"]],["impl Send for TlsAcceptorConfig",1,["actix_http::service::TlsAcceptorConfig"]],["impl Send for TestSeqInner",1,["actix_http::test::TestSeqInner"]],["impl Send for CloseReason",1,["actix_http::ws::proto::CloseReason"]],["impl Send for Codec",1,["actix_http::ws::codec::Codec"]],["impl Send for Parser",1,["actix_http::ws::frame::Parser"]],["impl<'a> Send for Drain<'a>",1,["actix_http::header::map::Drain"]],["impl<'a> Send for Iter<'a>",1,["actix_http::header::map::Iter"]],["impl<'a> Send for Keys<'a>",1,["actix_http::header::map::Keys"]],["impl<B> !Send for Response<B>",1,["actix_http::responses::response::Response"]],["impl<B> Send for Encoder<B>
where\n B: Send,
",1,["actix_http::encoding::encoder::Encoder"]],["impl<L, R> Send for EitherBody<L, R>
where\n L: Send,\n R: Send,
",1,["actix_http::body::either::EitherBody"]],["impl<P = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Send for Request<P>",1,["actix_http::requests::request::Request"]],["impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Send for Payload<S>",1,["actix_http::payload::Payload"]],["impl<S> Send for BodyStream<S>
where\n S: Send,
",1,["actix_http::body::body_stream::BodyStream"]],["impl<S> Send for SizedStream<S>
where\n S: Send,
",1,["actix_http::body::sized_stream::SizedStream"]],["impl<S> Send for Decoder<S>
where\n S: Send,
",1,["actix_http::encoding::decoder::Decoder"]],["impl<S, T> !Send for Dispatcher<S, T>",1,["actix_http::ws::dispatcher::Dispatcher"]],["impl<T> !Send for Message<T>",1,["actix_http::message::Message"]],["impl<T> Send for Message<T>
where\n T: Send,
",1,["actix_http::h1::Message"]],["impl<T> Send for QualityItem<T>
where\n T: Send,
",1,["actix_http::header::shared::quality_item::QualityItem"]],["impl<T, B> !Send for SendResponse<T, B>",1,["actix_http::h1::utils::SendResponse"]],["impl<T, S, B> !Send for H2Service<T, S, B>",1,["actix_http::h2::service::H2Service"]],["impl<T, S, B, X = ExpectHandler, U = UpgradeHandler> !Send for H1Service<T, S, B, X, U>",1,["actix_http::h1::service::H1Service"]],["impl<T, S, B, X = ExpectHandler, U = UpgradeHandler> !Send for HttpService<T, S, B, X, U>",1,["actix_http::service::HttpService"]],["impl<T, S, B, X, U> !Send for Dispatcher<T, S, B, X, U>",1,["actix_http::h1::dispatcher::Dispatcher"]],["impl<T, S, B, X, U> !Send for Dispatcher<T, S, B, X, U>",1,["actix_http::h2::dispatcher::Dispatcher"]],["impl<T, S, X = ExpectHandler, U = UpgradeHandler> !Send for HttpServiceBuilder<T, S, X, U>",1,["actix_http::builder::HttpServiceBuilder"]]], +"actix_http_test":[["impl !Send for TestServer",1,["actix_http_test::TestServer"]]], +"actix_multipart":[["impl !Send for MultipartError",1,["actix_multipart::error::MultipartError"]],["impl !Send for Field",1,["actix_multipart::server::Field"]],["impl !Send for Multipart",1,["actix_multipart::server::Multipart"]],["impl Send for JsonFieldError",1,["actix_multipart::form::json::JsonFieldError"]],["impl Send for TempFileError",1,["actix_multipart::form::tempfile::TempFileError"]],["impl Send for TextError",1,["actix_multipart::form::text::TextError"]],["impl Send for Bytes",1,["actix_multipart::form::bytes::Bytes"]],["impl Send for JsonConfig",1,["actix_multipart::form::json::JsonConfig"]],["impl Send for Limits",1,["actix_multipart::form::Limits"]],["impl Send for MultipartFormConfig",1,["actix_multipart::form::MultipartFormConfig"]],["impl Send for TempFile",1,["actix_multipart::form::tempfile::TempFile"]],["impl Send for TempFileConfig",1,["actix_multipart::form::tempfile::TempFileConfig"]],["impl Send for TextConfig",1,["actix_multipart::form::text::TextConfig"]],["impl<T> Send for Json<T>
where\n T: Send,
",1,["actix_multipart::form::json::Json"]],["impl<T> Send for MultipartForm<T>
where\n T: Send,
",1,["actix_multipart::form::MultipartForm"]],["impl<T> Send for Text<T>
where\n T: Send,
",1,["actix_multipart::form::text::Text"]]], +"actix_router":[["impl Send for Patterns",1,["actix_router::pattern::Patterns"]],["impl Send for Quoter",1,["actix_router::quoter::Quoter"]],["impl Send for ResourceDef",1,["actix_router::resource::ResourceDef"]],["impl Send for ResourceId",1,["actix_router::router::ResourceId"]],["impl Send for Url",1,["actix_router::url::Url"]],["impl<'de, T> Send for PathDeserializer<'de, T>
where\n T: Sync,
",1,["actix_router::de::PathDeserializer"]],["impl<T> Send for Path<T>
where\n T: Send,
",1,["actix_router::path::Path"]],["impl<T, U> Send for Router<T, U>
where\n T: Send,\n U: Send,
",1,["actix_router::router::Router"]],["impl<T, U> Send for RouterBuilder<T, U>
where\n T: Send,\n U: Send,
",1,["actix_router::router::RouterBuilder"]]], +"actix_test":[["impl !Send for TestServer",1,["actix_test::TestServer"]],["impl Send for TestServerConfig",1,["actix_test::TestServerConfig"]]], +"actix_web":[["impl !Send for AppService",1,["actix_web::config::AppService"]],["impl !Send for ResourceMap",1,["actix_web::rmap::ResourceMap"]],["impl !Send for ServiceRequest",1,["actix_web::service::ServiceRequest"]],["impl !Send for WebService",1,["actix_web::service::WebService"]],["impl !Send for Error",1,["actix_web::error::error::Error"]],["impl !Send for AllGuard",1,["actix_web::guard::AllGuard"]],["impl !Send for AnyGuard",1,["actix_web::guard::AnyGuard"]],["impl !Send for DefaultHeaders",1,["actix_web::middleware::default_headers::DefaultHeaders"]],["impl !Send for Logger",1,["actix_web::middleware::logger::Logger"]],["impl !Send for HttpRequest",1,["actix_web::request::HttpRequest"]],["impl !Send for HttpResponseBuilder",1,["actix_web::response::builder::HttpResponseBuilder"]],["impl !Send for Route",1,["actix_web::route::Route"]],["impl !Send for TestRequest",1,["actix_web::test::test_request::TestRequest"]],["impl !Send for FormConfig",1,["actix_web::types::form::FormConfig"]],["impl !Send for Payload",1,["actix_web::types::payload::Payload"]],["impl !Send for ServiceConfig",1,["actix_web::config::ServiceConfig"]],["impl Send for JsonPayloadError",1,["actix_web::error::JsonPayloadError"]],["impl Send for PathError",1,["actix_web::error::PathError"]],["impl Send for QueryPayloadError",1,["actix_web::error::QueryPayloadError"]],["impl Send for ReadlinesError",1,["actix_web::error::ReadlinesError"]],["impl Send for UrlGenerationError",1,["actix_web::error::UrlGenerationError"]],["impl Send for UrlencodedError",1,["actix_web::error::UrlencodedError"]],["impl Send for ByteRangeSpec",1,["actix_web::http::header::range::ByteRangeSpec"]],["impl Send for CacheDirective",1,["actix_web::http::header::cache_control::CacheDirective"]],["impl Send for ContentRangeSpec",1,["actix_web::http::header::content_range::ContentRangeSpec"]],["impl Send for DispositionParam",1,["actix_web::http::header::content_disposition::DispositionParam"]],["impl Send for DispositionType",1,["actix_web::http::header::content_disposition::DispositionType"]],["impl Send for Encoding",1,["actix_web::http::header::encoding::Encoding"]],["impl Send for IfMatch",1,["actix_web::http::header::if_match::IfMatch"]],["impl Send for IfNoneMatch",1,["actix_web::http::header::if_none_match::IfNoneMatch"]],["impl Send for IfRange",1,["actix_web::http::header::if_range::IfRange"]],["impl Send for Range",1,["actix_web::http::header::range::Range"]],["impl Send for TrailingSlash",1,["actix_web::middleware::normalize::TrailingSlash"]],["impl Send for AppConfig",1,["actix_web::config::AppConfig"]],["impl Send for ConnectionInfo",1,["actix_web::info::ConnectionInfo"]],["impl Send for PeerAddr",1,["actix_web::info::PeerAddr"]],["impl Send for BlockingError",1,["actix_web::error::BlockingError"]],["impl Send for Acceptable",1,["actix_web::guard::acceptable::Acceptable"]],["impl Send for Accept",1,["actix_web::http::header::accept::Accept"]],["impl Send for AcceptCharset",1,["actix_web::http::header::accept_charset::AcceptCharset"]],["impl Send for AcceptEncoding",1,["actix_web::http::header::accept_encoding::AcceptEncoding"]],["impl Send for AcceptLanguage",1,["actix_web::http::header::accept_language::AcceptLanguage"]],["impl Send for Allow",1,["actix_web::http::header::allow::Allow"]],["impl Send for CacheControl",1,["actix_web::http::header::cache_control::CacheControl"]],["impl Send for ContentDisposition",1,["actix_web::http::header::content_disposition::ContentDisposition"]],["impl Send for ContentLanguage",1,["actix_web::http::header::content_language::ContentLanguage"]],["impl Send for ContentLength",1,["actix_web::http::header::content_length::ContentLength"]],["impl Send for ContentRange",1,["actix_web::http::header::content_range::ContentRange"]],["impl Send for ContentType",1,["actix_web::http::header::content_type::ContentType"]],["impl Send for Date",1,["actix_web::http::header::date::Date"]],["impl Send for ETag",1,["actix_web::http::header::etag::ETag"]],["impl Send for EntityTag",1,["actix_web::http::header::entity::EntityTag"]],["impl Send for Expires",1,["actix_web::http::header::expires::Expires"]],["impl Send for IfModifiedSince",1,["actix_web::http::header::if_modified_since::IfModifiedSince"]],["impl Send for IfUnmodifiedSince",1,["actix_web::http::header::if_unmodified_since::IfUnmodifiedSince"]],["impl Send for LastModified",1,["actix_web::http::header::last_modified::LastModified"]],["impl Send for Compress",1,["actix_web::middleware::compress::Compress"]],["impl Send for NormalizePath",1,["actix_web::middleware::normalize::NormalizePath"]],["impl Send for JsonConfig",1,["actix_web::types::json::JsonConfig"]],["impl Send for PathConfig",1,["actix_web::types::path::PathConfig"]],["impl Send for PayloadConfig",1,["actix_web::types::payload::PayloadConfig"]],["impl Send for QueryConfig",1,["actix_web::types::query::QueryConfig"]],["impl Send for Redirect",1,["actix_web::redirect::Redirect"]],["impl<'a> !Send for GuardContext<'a>",1,["actix_web::guard::GuardContext"]],["impl<B = BoxBody> !Send for ServiceResponse<B>",1,["actix_web::service::ServiceResponse"]],["impl<B = BoxBody> !Send for HttpResponse<B>",1,["actix_web::response::response::HttpResponse"]],["impl<B> !Send for ErrorHandlerResponse<B>",1,["actix_web::middleware::err_handlers::ErrorHandlerResponse"]],["impl<B> !Send for ErrorHandlers<B>",1,["actix_web::middleware::err_handlers::ErrorHandlers"]],["impl<F, I, S, B> Send for HttpServer<F, I, S, B>
where\n <S as ServiceFactory<Request>>::Response: Sized,\n <S as ServiceFactory<Request>>::Error: Sized,\n S: Send,\n B: Send,
",1,["actix_web::server::HttpServer"]],["impl<G> Send for Not<G>
where\n G: Send,
",1,["actix_web::guard::Not"]],["impl<L, R> Send for Either<L, R>
where\n L: Send,\n R: Send,
",1,["actix_web::types::either::Either"]],["impl<R> Send for CustomizeResponder<R>
where\n R: Send,
",1,["actix_web::response::customize_responder::CustomizeResponder"]],["impl<T = ResourceEndpoint> !Send for Resource<T>",1,["actix_web::resource::Resource"]],["impl<T = ScopeEndpoint> !Send for Scope<T>",1,["actix_web::scope::Scope"]],["impl<T> !Send for JsonBody<T>",1,["actix_web::types::json::JsonBody"]],["impl<T> !Send for Readlines<T>",1,["actix_web::types::readlines::Readlines"]],["impl<T> !Send for UrlEncoded<T>",1,["actix_web::types::form::UrlEncoded"]],["impl<T> !Send for InternalError<T>",1,["actix_web::error::internal::InternalError"]],["impl<T> !Send for App<T>",1,["actix_web::app::App"]],["impl<T> Send for Preference<T>
where\n T: Send,
",1,["actix_web::http::header::preference::Preference"]],["impl<T> Send for Compat<T>
where\n T: Send,
",1,["actix_web::middleware::compat::Compat"]],["impl<T> Send for Condition<T>
where\n T: Send,
",1,["actix_web::middleware::condition::Condition"]],["impl<T> Send for Data<T>
where\n T: Sync + Send + ?Sized,
",1,["actix_web::data::Data"]],["impl<T> Send for Form<T>
where\n T: Send,
",1,["actix_web::types::form::Form"]],["impl<T> Send for Header<T>
where\n T: Send,
",1,["actix_web::types::header::Header"]],["impl<T> Send for Json<T>
where\n T: Send,
",1,["actix_web::types::json::Json"]],["impl<T> Send for Path<T>
where\n T: Send,
",1,["actix_web::types::path::Path"]],["impl<T> Send for Query<T>
where\n T: Send,
",1,["actix_web::types::query::Query"]],["impl<T> Send for ReqData<T>
where\n T: Send,
",1,["actix_web::request_data::ReqData"]]], +"actix_web_actors":[["impl<'a, A, T> !Send for WsResponseBuilder<'a, A, T>",1,["actix_web_actors::ws::WsResponseBuilder"]],["impl<A> !Send for HttpContext<A>",1,["actix_web_actors::context::HttpContext"]],["impl<A> !Send for WebsocketContext<A>",1,["actix_web_actors::ws::WebsocketContext"]]], +"awc":[["impl !Send for ConnectRequest",1,["awc::connect::ConnectRequest"]],["impl !Send for ConnectResponse",1,["awc::connect::ConnectResponse"]],["impl !Send for SendClientRequest",1,["awc::sender::SendClientRequest"]],["impl !Send for ConnectError",1,["awc::client::error::ConnectError"]],["impl !Send for FreezeRequestError",1,["awc::client::error::FreezeRequestError"]],["impl !Send for SendRequestError",1,["awc::client::error::SendRequestError"]],["impl !Send for WsClientError",1,["awc::error::WsClientError"]],["impl !Send for Client",1,["awc::client::Client"]],["impl !Send for ClientRequest",1,["awc::request::ClientRequest"]],["impl !Send for FrozenClientRequest",1,["awc::frozen::FrozenClientRequest"]],["impl !Send for FrozenSendBuilder",1,["awc::frozen::FrozenSendBuilder"]],["impl !Send for TestResponse",1,["awc::test::TestResponse"]],["impl !Send for WebsocketsRequest",1,["awc::ws::WebsocketsRequest"]],["impl Send for InvalidUrl",1,["awc::client::error::InvalidUrl"]],["impl Send for JsonPayloadError",1,["awc::error::JsonPayloadError"]],["impl Send for Redirect",1,["awc::middleware::redirect::Redirect"]],["impl Send for Connect",1,["awc::client::Connect"]],["impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Send for ClientResponse<S>",1,["awc::responses::response::ClientResponse"]],["impl<S> !Send for ResponseBody<S>",1,["awc::responses::response_body::ResponseBody"]],["impl<S, M> Send for ClientBuilder<S, M>
where\n M: Send,\n S: Send,
",1,["awc::builder::ClientBuilder"]],["impl<S, T> !Send for JsonBody<S, T>",1,["awc::responses::json_body::JsonBody"]],["impl<T> Send for Connector<T>
where\n T: Send,
",1,["awc::client::connector::Connector"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.StructuralPartialEq.js b/trait.impl/core/marker/trait.StructuralPartialEq.js new file mode 100644 index 000000000..aa69fa2aa --- /dev/null +++ b/trait.impl/core/marker/trait.StructuralPartialEq.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"actix_http":[["impl StructuralPartialEq for BodySize"],["impl StructuralPartialEq for ConnectionType"],["impl StructuralPartialEq for KeepAlive"],["impl StructuralPartialEq for Protocol"],["impl StructuralPartialEq for MessageType"],["impl StructuralPartialEq for Charset"],["impl StructuralPartialEq for ContentEncoding"],["impl StructuralPartialEq for CloseCode"],["impl StructuralPartialEq for Frame"],["impl StructuralPartialEq for HandshakeError"],["impl StructuralPartialEq for Item"],["impl StructuralPartialEq for Message"],["impl StructuralPartialEq for OpCode"],["impl StructuralPartialEq for ExtendedValue"],["impl StructuralPartialEq for HttpDate"],["impl StructuralPartialEq for Quality"],["impl StructuralPartialEq for CloseReason"],["impl<T> StructuralPartialEq for QualityItem<T>"]], +"actix_router":[["impl StructuralPartialEq for Patterns"],["impl StructuralPartialEq for ResourceId"]], +"actix_web":[["impl StructuralPartialEq for UrlGenerationError"],["impl StructuralPartialEq for ByteRangeSpec"],["impl StructuralPartialEq for CacheDirective"],["impl StructuralPartialEq for ContentRangeSpec"],["impl StructuralPartialEq for DispositionParam"],["impl StructuralPartialEq for DispositionType"],["impl StructuralPartialEq for Encoding"],["impl StructuralPartialEq for IfMatch"],["impl StructuralPartialEq for IfNoneMatch"],["impl StructuralPartialEq for IfRange"],["impl StructuralPartialEq for Range"],["impl StructuralPartialEq for PeerAddr"],["impl StructuralPartialEq for Accept"],["impl StructuralPartialEq for AcceptCharset"],["impl StructuralPartialEq for AcceptEncoding"],["impl StructuralPartialEq for AcceptLanguage"],["impl StructuralPartialEq for Allow"],["impl StructuralPartialEq for CacheControl"],["impl StructuralPartialEq for ContentDisposition"],["impl StructuralPartialEq for ContentLanguage"],["impl StructuralPartialEq for ContentLength"],["impl StructuralPartialEq for ContentRange"],["impl StructuralPartialEq for ContentType"],["impl StructuralPartialEq for Date"],["impl StructuralPartialEq for ETag"],["impl StructuralPartialEq for EntityTag"],["impl StructuralPartialEq for Expires"],["impl StructuralPartialEq for IfModifiedSince"],["impl StructuralPartialEq for IfUnmodifiedSince"],["impl StructuralPartialEq for LastModified"],["impl<L, R> StructuralPartialEq for Either<L, R>"],["impl<T> StructuralPartialEq for Preference<T>"],["impl<T> StructuralPartialEq for Form<T>"],["impl<T> StructuralPartialEq for Header<T>"],["impl<T> StructuralPartialEq for Path<T>"],["impl<T> StructuralPartialEq for Query<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Sync.js b/trait.impl/core/marker/trait.Sync.js new file mode 100644 index 000000000..311e37ef1 --- /dev/null +++ b/trait.impl/core/marker/trait.Sync.js @@ -0,0 +1,11 @@ +(function() {var implementors = { +"actix_files":[["impl !Sync for Files",1,["actix_files::files::Files"]],["impl !Sync for FilesService",1,["actix_files::service::FilesService"]],["impl !Sync for NamedFile",1,["actix_files::named::NamedFile"]],["impl Sync for Directory",1,["actix_files::directory::Directory"]],["impl Sync for HttpRange",1,["actix_files::range::HttpRange"]]], +"actix_http":[["impl !Sync for RequestHeadType",1,["actix_http::requests::head::RequestHeadType"]],["impl !Sync for DispatchError",1,["actix_http::error::DispatchError"]],["impl !Sync for BoxBody",1,["actix_http::body::boxed::BoxBody"]],["impl !Sync for Error",1,["actix_http::error::Error"]],["impl !Sync for ClientCodec",1,["actix_http::h1::client::ClientCodec"]],["impl !Sync for ClientPayloadCodec",1,["actix_http::h1::client::ClientPayloadCodec"]],["impl !Sync for Codec",1,["actix_http::h1::codec::Codec"]],["impl !Sync for Payload",1,["actix_http::h1::payload::Payload"]],["impl !Sync for Extensions",1,["actix_http::extensions::Extensions"]],["impl !Sync for ServiceConfig",1,["actix_http::config::ServiceConfig"]],["impl !Sync for TestBuffer",1,["actix_http::test::TestBuffer"]],["impl !Sync for TestRequest",1,["actix_http::test::TestRequest"]],["impl !Sync for TestSeqBuffer",1,["actix_http::test::TestSeqBuffer"]],["impl Sync for BodySize",1,["actix_http::body::size::BodySize"]],["impl Sync for ConnectionType",1,["actix_http::message::ConnectionType"]],["impl Sync for KeepAlive",1,["actix_http::keep_alive::KeepAlive"]],["impl Sync for Protocol",1,["actix_http::Protocol"]],["impl Sync for ContentTypeError",1,["actix_http::error::ContentTypeError"]],["impl Sync for ParseError",1,["actix_http::error::ParseError"]],["impl Sync for PayloadError",1,["actix_http::error::PayloadError"]],["impl Sync for MessageType",1,["actix_http::h1::MessageType"]],["impl Sync for Charset",1,["actix_http::header::shared::charset::Charset"]],["impl Sync for ContentEncoding",1,["actix_http::header::shared::content_encoding::ContentEncoding"]],["impl Sync for CloseCode",1,["actix_http::ws::proto::CloseCode"]],["impl Sync for Frame",1,["actix_http::ws::codec::Frame"]],["impl Sync for HandshakeError",1,["actix_http::ws::HandshakeError"]],["impl Sync for Item",1,["actix_http::ws::codec::Item"]],["impl Sync for Message",1,["actix_http::ws::codec::Message"]],["impl Sync for OpCode",1,["actix_http::ws::proto::OpCode"]],["impl Sync for ProtocolError",1,["actix_http::ws::ProtocolError"]],["impl Sync for BodyLimitExceeded",1,["actix_http::body::utils::BodyLimitExceeded"]],["impl Sync for None",1,["actix_http::body::none::None"]],["impl Sync for ExpectHandler",1,["actix_http::h1::expect::ExpectHandler"]],["impl Sync for UpgradeHandler",1,["actix_http::h1::upgrade::UpgradeHandler"]],["impl Sync for Payload",1,["actix_http::h2::Payload"]],["impl Sync for HeaderMap",1,["actix_http::header::map::HeaderMap"]],["impl Sync for IntoIter",1,["actix_http::header::map::IntoIter"]],["impl Sync for Removed",1,["actix_http::header::map::Removed"]],["impl Sync for ExtendedValue",1,["actix_http::header::shared::extended::ExtendedValue"]],["impl Sync for HttpDate",1,["actix_http::header::shared::http_date::HttpDate"]],["impl Sync for Quality",1,["actix_http::header::shared::quality::Quality"]],["impl Sync for RequestHead",1,["actix_http::requests::head::RequestHead"]],["impl Sync for ResponseBuilder",1,["actix_http::responses::builder::ResponseBuilder"]],["impl Sync for ResponseHead",1,["actix_http::responses::head::ResponseHead"]],["impl Sync for TlsAcceptorConfig",1,["actix_http::service::TlsAcceptorConfig"]],["impl Sync for TestSeqInner",1,["actix_http::test::TestSeqInner"]],["impl Sync for CloseReason",1,["actix_http::ws::proto::CloseReason"]],["impl Sync for Codec",1,["actix_http::ws::codec::Codec"]],["impl Sync for Parser",1,["actix_http::ws::frame::Parser"]],["impl<'a> Sync for Drain<'a>",1,["actix_http::header::map::Drain"]],["impl<'a> Sync for Iter<'a>",1,["actix_http::header::map::Iter"]],["impl<'a> Sync for Keys<'a>",1,["actix_http::header::map::Keys"]],["impl<B> !Sync for Response<B>",1,["actix_http::responses::response::Response"]],["impl<B> Sync for Encoder<B>
where\n B: Sync,
",1,["actix_http::encoding::encoder::Encoder"]],["impl<L, R> Sync for EitherBody<L, R>
where\n L: Sync,\n R: Sync,
",1,["actix_http::body::either::EitherBody"]],["impl<P = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Sync for Request<P>",1,["actix_http::requests::request::Request"]],["impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Sync for Payload<S>",1,["actix_http::payload::Payload"]],["impl<S> Sync for BodyStream<S>
where\n S: Sync,
",1,["actix_http::body::body_stream::BodyStream"]],["impl<S> Sync for SizedStream<S>
where\n S: Sync,
",1,["actix_http::body::sized_stream::SizedStream"]],["impl<S> Sync for Decoder<S>
where\n S: Sync,
",1,["actix_http::encoding::decoder::Decoder"]],["impl<S, T> !Sync for Dispatcher<S, T>",1,["actix_http::ws::dispatcher::Dispatcher"]],["impl<T> !Sync for Message<T>",1,["actix_http::message::Message"]],["impl<T> Sync for Message<T>
where\n T: Sync,
",1,["actix_http::h1::Message"]],["impl<T> Sync for QualityItem<T>
where\n T: Sync,
",1,["actix_http::header::shared::quality_item::QualityItem"]],["impl<T, B> !Sync for SendResponse<T, B>",1,["actix_http::h1::utils::SendResponse"]],["impl<T, S, B> !Sync for H2Service<T, S, B>",1,["actix_http::h2::service::H2Service"]],["impl<T, S, B, X = ExpectHandler, U = UpgradeHandler> !Sync for H1Service<T, S, B, X, U>",1,["actix_http::h1::service::H1Service"]],["impl<T, S, B, X = ExpectHandler, U = UpgradeHandler> !Sync for HttpService<T, S, B, X, U>",1,["actix_http::service::HttpService"]],["impl<T, S, B, X, U> !Sync for Dispatcher<T, S, B, X, U>",1,["actix_http::h1::dispatcher::Dispatcher"]],["impl<T, S, B, X, U> !Sync for Dispatcher<T, S, B, X, U>",1,["actix_http::h2::dispatcher::Dispatcher"]],["impl<T, S, X = ExpectHandler, U = UpgradeHandler> !Sync for HttpServiceBuilder<T, S, X, U>",1,["actix_http::builder::HttpServiceBuilder"]]], +"actix_http_test":[["impl !Sync for TestServer",1,["actix_http_test::TestServer"]]], +"actix_multipart":[["impl !Sync for MultipartError",1,["actix_multipart::error::MultipartError"]],["impl !Sync for Field",1,["actix_multipart::server::Field"]],["impl !Sync for Multipart",1,["actix_multipart::server::Multipart"]],["impl Sync for JsonFieldError",1,["actix_multipart::form::json::JsonFieldError"]],["impl Sync for TempFileError",1,["actix_multipart::form::tempfile::TempFileError"]],["impl Sync for TextError",1,["actix_multipart::form::text::TextError"]],["impl Sync for Bytes",1,["actix_multipart::form::bytes::Bytes"]],["impl Sync for JsonConfig",1,["actix_multipart::form::json::JsonConfig"]],["impl Sync for Limits",1,["actix_multipart::form::Limits"]],["impl Sync for MultipartFormConfig",1,["actix_multipart::form::MultipartFormConfig"]],["impl Sync for TempFile",1,["actix_multipart::form::tempfile::TempFile"]],["impl Sync for TempFileConfig",1,["actix_multipart::form::tempfile::TempFileConfig"]],["impl Sync for TextConfig",1,["actix_multipart::form::text::TextConfig"]],["impl<T> Sync for Json<T>
where\n T: Sync,
",1,["actix_multipart::form::json::Json"]],["impl<T> Sync for MultipartForm<T>
where\n T: Sync,
",1,["actix_multipart::form::MultipartForm"]],["impl<T> Sync for Text<T>
where\n T: Sync,
",1,["actix_multipart::form::text::Text"]]], +"actix_router":[["impl Sync for Patterns",1,["actix_router::pattern::Patterns"]],["impl Sync for Quoter",1,["actix_router::quoter::Quoter"]],["impl Sync for ResourceDef",1,["actix_router::resource::ResourceDef"]],["impl Sync for ResourceId",1,["actix_router::router::ResourceId"]],["impl Sync for Url",1,["actix_router::url::Url"]],["impl<'de, T> Sync for PathDeserializer<'de, T>
where\n T: Sync,
",1,["actix_router::de::PathDeserializer"]],["impl<T> Sync for Path<T>
where\n T: Sync,
",1,["actix_router::path::Path"]],["impl<T, U> Sync for Router<T, U>
where\n T: Sync,\n U: Sync,
",1,["actix_router::router::Router"]],["impl<T, U> Sync for RouterBuilder<T, U>
where\n T: Sync,\n U: Sync,
",1,["actix_router::router::RouterBuilder"]]], +"actix_test":[["impl !Sync for TestServer",1,["actix_test::TestServer"]],["impl Sync for TestServerConfig",1,["actix_test::TestServerConfig"]]], +"actix_web":[["impl !Sync for AppService",1,["actix_web::config::AppService"]],["impl !Sync for ResourceMap",1,["actix_web::rmap::ResourceMap"]],["impl !Sync for ServiceRequest",1,["actix_web::service::ServiceRequest"]],["impl !Sync for WebService",1,["actix_web::service::WebService"]],["impl !Sync for Error",1,["actix_web::error::error::Error"]],["impl !Sync for AllGuard",1,["actix_web::guard::AllGuard"]],["impl !Sync for AnyGuard",1,["actix_web::guard::AnyGuard"]],["impl !Sync for DefaultHeaders",1,["actix_web::middleware::default_headers::DefaultHeaders"]],["impl !Sync for Logger",1,["actix_web::middleware::logger::Logger"]],["impl !Sync for HttpRequest",1,["actix_web::request::HttpRequest"]],["impl !Sync for HttpResponseBuilder",1,["actix_web::response::builder::HttpResponseBuilder"]],["impl !Sync for Route",1,["actix_web::route::Route"]],["impl !Sync for TestRequest",1,["actix_web::test::test_request::TestRequest"]],["impl !Sync for FormConfig",1,["actix_web::types::form::FormConfig"]],["impl !Sync for Payload",1,["actix_web::types::payload::Payload"]],["impl !Sync for ServiceConfig",1,["actix_web::config::ServiceConfig"]],["impl Sync for JsonPayloadError",1,["actix_web::error::JsonPayloadError"]],["impl Sync for PathError",1,["actix_web::error::PathError"]],["impl Sync for QueryPayloadError",1,["actix_web::error::QueryPayloadError"]],["impl Sync for ReadlinesError",1,["actix_web::error::ReadlinesError"]],["impl Sync for UrlGenerationError",1,["actix_web::error::UrlGenerationError"]],["impl Sync for UrlencodedError",1,["actix_web::error::UrlencodedError"]],["impl Sync for ByteRangeSpec",1,["actix_web::http::header::range::ByteRangeSpec"]],["impl Sync for CacheDirective",1,["actix_web::http::header::cache_control::CacheDirective"]],["impl Sync for ContentRangeSpec",1,["actix_web::http::header::content_range::ContentRangeSpec"]],["impl Sync for DispositionParam",1,["actix_web::http::header::content_disposition::DispositionParam"]],["impl Sync for DispositionType",1,["actix_web::http::header::content_disposition::DispositionType"]],["impl Sync for Encoding",1,["actix_web::http::header::encoding::Encoding"]],["impl Sync for IfMatch",1,["actix_web::http::header::if_match::IfMatch"]],["impl Sync for IfNoneMatch",1,["actix_web::http::header::if_none_match::IfNoneMatch"]],["impl Sync for IfRange",1,["actix_web::http::header::if_range::IfRange"]],["impl Sync for Range",1,["actix_web::http::header::range::Range"]],["impl Sync for TrailingSlash",1,["actix_web::middleware::normalize::TrailingSlash"]],["impl Sync for AppConfig",1,["actix_web::config::AppConfig"]],["impl Sync for ConnectionInfo",1,["actix_web::info::ConnectionInfo"]],["impl Sync for PeerAddr",1,["actix_web::info::PeerAddr"]],["impl Sync for BlockingError",1,["actix_web::error::BlockingError"]],["impl Sync for Acceptable",1,["actix_web::guard::acceptable::Acceptable"]],["impl Sync for Accept",1,["actix_web::http::header::accept::Accept"]],["impl Sync for AcceptCharset",1,["actix_web::http::header::accept_charset::AcceptCharset"]],["impl Sync for AcceptEncoding",1,["actix_web::http::header::accept_encoding::AcceptEncoding"]],["impl Sync for AcceptLanguage",1,["actix_web::http::header::accept_language::AcceptLanguage"]],["impl Sync for Allow",1,["actix_web::http::header::allow::Allow"]],["impl Sync for CacheControl",1,["actix_web::http::header::cache_control::CacheControl"]],["impl Sync for ContentDisposition",1,["actix_web::http::header::content_disposition::ContentDisposition"]],["impl Sync for ContentLanguage",1,["actix_web::http::header::content_language::ContentLanguage"]],["impl Sync for ContentLength",1,["actix_web::http::header::content_length::ContentLength"]],["impl Sync for ContentRange",1,["actix_web::http::header::content_range::ContentRange"]],["impl Sync for ContentType",1,["actix_web::http::header::content_type::ContentType"]],["impl Sync for Date",1,["actix_web::http::header::date::Date"]],["impl Sync for ETag",1,["actix_web::http::header::etag::ETag"]],["impl Sync for EntityTag",1,["actix_web::http::header::entity::EntityTag"]],["impl Sync for Expires",1,["actix_web::http::header::expires::Expires"]],["impl Sync for IfModifiedSince",1,["actix_web::http::header::if_modified_since::IfModifiedSince"]],["impl Sync for IfUnmodifiedSince",1,["actix_web::http::header::if_unmodified_since::IfUnmodifiedSince"]],["impl Sync for LastModified",1,["actix_web::http::header::last_modified::LastModified"]],["impl Sync for Compress",1,["actix_web::middleware::compress::Compress"]],["impl Sync for NormalizePath",1,["actix_web::middleware::normalize::NormalizePath"]],["impl Sync for JsonConfig",1,["actix_web::types::json::JsonConfig"]],["impl Sync for PathConfig",1,["actix_web::types::path::PathConfig"]],["impl Sync for PayloadConfig",1,["actix_web::types::payload::PayloadConfig"]],["impl Sync for QueryConfig",1,["actix_web::types::query::QueryConfig"]],["impl Sync for Redirect",1,["actix_web::redirect::Redirect"]],["impl<'a> !Sync for GuardContext<'a>",1,["actix_web::guard::GuardContext"]],["impl<B = BoxBody> !Sync for ServiceResponse<B>",1,["actix_web::service::ServiceResponse"]],["impl<B = BoxBody> !Sync for HttpResponse<B>",1,["actix_web::response::response::HttpResponse"]],["impl<B> !Sync for ErrorHandlerResponse<B>",1,["actix_web::middleware::err_handlers::ErrorHandlerResponse"]],["impl<B> !Sync for ErrorHandlers<B>",1,["actix_web::middleware::err_handlers::ErrorHandlers"]],["impl<F, I, S, B> !Sync for HttpServer<F, I, S, B>",1,["actix_web::server::HttpServer"]],["impl<G> Sync for Not<G>
where\n G: Sync,
",1,["actix_web::guard::Not"]],["impl<L, R> Sync for Either<L, R>
where\n L: Sync,\n R: Sync,
",1,["actix_web::types::either::Either"]],["impl<R> Sync for CustomizeResponder<R>
where\n R: Sync,
",1,["actix_web::response::customize_responder::CustomizeResponder"]],["impl<T = ResourceEndpoint> !Sync for Resource<T>",1,["actix_web::resource::Resource"]],["impl<T = ScopeEndpoint> !Sync for Scope<T>",1,["actix_web::scope::Scope"]],["impl<T> !Sync for JsonBody<T>",1,["actix_web::types::json::JsonBody"]],["impl<T> !Sync for Readlines<T>",1,["actix_web::types::readlines::Readlines"]],["impl<T> !Sync for UrlEncoded<T>",1,["actix_web::types::form::UrlEncoded"]],["impl<T> !Sync for InternalError<T>",1,["actix_web::error::internal::InternalError"]],["impl<T> !Sync for App<T>",1,["actix_web::app::App"]],["impl<T> Sync for Preference<T>
where\n T: Sync,
",1,["actix_web::http::header::preference::Preference"]],["impl<T> Sync for Compat<T>
where\n T: Sync,
",1,["actix_web::middleware::compat::Compat"]],["impl<T> Sync for Condition<T>
where\n T: Sync,
",1,["actix_web::middleware::condition::Condition"]],["impl<T> Sync for Data<T>
where\n T: Sync + Send + ?Sized,
",1,["actix_web::data::Data"]],["impl<T> Sync for Form<T>
where\n T: Sync,
",1,["actix_web::types::form::Form"]],["impl<T> Sync for Header<T>
where\n T: Sync,
",1,["actix_web::types::header::Header"]],["impl<T> Sync for Json<T>
where\n T: Sync,
",1,["actix_web::types::json::Json"]],["impl<T> Sync for Path<T>
where\n T: Sync,
",1,["actix_web::types::path::Path"]],["impl<T> Sync for Query<T>
where\n T: Sync,
",1,["actix_web::types::query::Query"]],["impl<T> Sync for ReqData<T>
where\n T: Sync,
",1,["actix_web::request_data::ReqData"]]], +"actix_web_actors":[["impl<'a, A, T> !Sync for WsResponseBuilder<'a, A, T>",1,["actix_web_actors::ws::WsResponseBuilder"]],["impl<A> !Sync for HttpContext<A>",1,["actix_web_actors::context::HttpContext"]],["impl<A> !Sync for WebsocketContext<A>",1,["actix_web_actors::ws::WebsocketContext"]]], +"awc":[["impl !Sync for ConnectRequest",1,["awc::connect::ConnectRequest"]],["impl !Sync for ConnectResponse",1,["awc::connect::ConnectResponse"]],["impl !Sync for SendClientRequest",1,["awc::sender::SendClientRequest"]],["impl !Sync for ConnectError",1,["awc::client::error::ConnectError"]],["impl !Sync for FreezeRequestError",1,["awc::client::error::FreezeRequestError"]],["impl !Sync for SendRequestError",1,["awc::client::error::SendRequestError"]],["impl !Sync for WsClientError",1,["awc::error::WsClientError"]],["impl !Sync for Client",1,["awc::client::Client"]],["impl !Sync for ClientRequest",1,["awc::request::ClientRequest"]],["impl !Sync for FrozenClientRequest",1,["awc::frozen::FrozenClientRequest"]],["impl !Sync for FrozenSendBuilder",1,["awc::frozen::FrozenSendBuilder"]],["impl !Sync for TestResponse",1,["awc::test::TestResponse"]],["impl !Sync for WebsocketsRequest",1,["awc::ws::WebsocketsRequest"]],["impl Sync for InvalidUrl",1,["awc::client::error::InvalidUrl"]],["impl Sync for JsonPayloadError",1,["awc::error::JsonPayloadError"]],["impl Sync for Redirect",1,["awc::middleware::redirect::Redirect"]],["impl Sync for Connect",1,["awc::client::Connect"]],["impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !Sync for ClientResponse<S>",1,["awc::responses::response::ClientResponse"]],["impl<S> !Sync for ResponseBody<S>",1,["awc::responses::response_body::ResponseBody"]],["impl<S, M> Sync for ClientBuilder<S, M>
where\n M: Sync,\n S: Sync,
",1,["awc::builder::ClientBuilder"]],["impl<S, T> !Sync for JsonBody<S, T>",1,["awc::responses::json_body::JsonBody"]],["impl<T> Sync for Connector<T>
where\n T: Sync,
",1,["awc::client::connector::Connector"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Unpin.js b/trait.impl/core/marker/trait.Unpin.js new file mode 100644 index 000000000..e5277fa37 --- /dev/null +++ b/trait.impl/core/marker/trait.Unpin.js @@ -0,0 +1,11 @@ +(function() {var implementors = { +"actix_files":[["impl Unpin for Directory",1,["actix_files::directory::Directory"]],["impl Unpin for Files",1,["actix_files::files::Files"]],["impl Unpin for FilesService",1,["actix_files::service::FilesService"]],["impl Unpin for HttpRange",1,["actix_files::range::HttpRange"]],["impl Unpin for NamedFile",1,["actix_files::named::NamedFile"]]], +"actix_http":[["impl Unpin for BodySize",1,["actix_http::body::size::BodySize"]],["impl Unpin for ConnectionType",1,["actix_http::message::ConnectionType"]],["impl Unpin for KeepAlive",1,["actix_http::keep_alive::KeepAlive"]],["impl Unpin for Protocol",1,["actix_http::Protocol"]],["impl Unpin for RequestHeadType",1,["actix_http::requests::head::RequestHeadType"]],["impl Unpin for ContentTypeError",1,["actix_http::error::ContentTypeError"]],["impl Unpin for DispatchError",1,["actix_http::error::DispatchError"]],["impl Unpin for ParseError",1,["actix_http::error::ParseError"]],["impl Unpin for PayloadError",1,["actix_http::error::PayloadError"]],["impl Unpin for MessageType",1,["actix_http::h1::MessageType"]],["impl Unpin for Charset",1,["actix_http::header::shared::charset::Charset"]],["impl Unpin for ContentEncoding",1,["actix_http::header::shared::content_encoding::ContentEncoding"]],["impl Unpin for CloseCode",1,["actix_http::ws::proto::CloseCode"]],["impl Unpin for Frame",1,["actix_http::ws::codec::Frame"]],["impl Unpin for HandshakeError",1,["actix_http::ws::HandshakeError"]],["impl Unpin for Item",1,["actix_http::ws::codec::Item"]],["impl Unpin for Message",1,["actix_http::ws::codec::Message"]],["impl Unpin for OpCode",1,["actix_http::ws::proto::OpCode"]],["impl Unpin for ProtocolError",1,["actix_http::ws::ProtocolError"]],["impl Unpin for BodyLimitExceeded",1,["actix_http::body::utils::BodyLimitExceeded"]],["impl Unpin for BoxBody",1,["actix_http::body::boxed::BoxBody"]],["impl Unpin for None",1,["actix_http::body::none::None"]],["impl Unpin for Error",1,["actix_http::error::Error"]],["impl Unpin for ClientCodec",1,["actix_http::h1::client::ClientCodec"]],["impl Unpin for ClientPayloadCodec",1,["actix_http::h1::client::ClientPayloadCodec"]],["impl Unpin for Codec",1,["actix_http::h1::codec::Codec"]],["impl Unpin for ExpectHandler",1,["actix_http::h1::expect::ExpectHandler"]],["impl Unpin for Payload",1,["actix_http::h1::payload::Payload"]],["impl Unpin for UpgradeHandler",1,["actix_http::h1::upgrade::UpgradeHandler"]],["impl Unpin for Payload",1,["actix_http::h2::Payload"]],["impl Unpin for HeaderMap",1,["actix_http::header::map::HeaderMap"]],["impl Unpin for IntoIter",1,["actix_http::header::map::IntoIter"]],["impl Unpin for Removed",1,["actix_http::header::map::Removed"]],["impl Unpin for ExtendedValue",1,["actix_http::header::shared::extended::ExtendedValue"]],["impl Unpin for HttpDate",1,["actix_http::header::shared::http_date::HttpDate"]],["impl Unpin for Quality",1,["actix_http::header::shared::quality::Quality"]],["impl Unpin for Extensions",1,["actix_http::extensions::Extensions"]],["impl Unpin for RequestHead",1,["actix_http::requests::head::RequestHead"]],["impl Unpin for ResponseBuilder",1,["actix_http::responses::builder::ResponseBuilder"]],["impl Unpin for ResponseHead",1,["actix_http::responses::head::ResponseHead"]],["impl Unpin for ServiceConfig",1,["actix_http::config::ServiceConfig"]],["impl Unpin for TlsAcceptorConfig",1,["actix_http::service::TlsAcceptorConfig"]],["impl Unpin for TestBuffer",1,["actix_http::test::TestBuffer"]],["impl Unpin for TestRequest",1,["actix_http::test::TestRequest"]],["impl Unpin for TestSeqBuffer",1,["actix_http::test::TestSeqBuffer"]],["impl Unpin for TestSeqInner",1,["actix_http::test::TestSeqInner"]],["impl Unpin for CloseReason",1,["actix_http::ws::proto::CloseReason"]],["impl Unpin for Codec",1,["actix_http::ws::codec::Codec"]],["impl Unpin for Parser",1,["actix_http::ws::frame::Parser"]],["impl<'__pin, B> Unpin for Encoder<B>
where\n __Origin<'__pin, B>: Unpin,
"],["impl<'__pin, L, R> Unpin for EitherBody<L, R>
where\n __Origin<'__pin, L, R>: Unpin,
"],["impl<'__pin, S> Unpin for Payload<S>
where\n __Origin<'__pin, S>: Unpin,
"],["impl<'__pin, S> Unpin for BodyStream<S>
where\n __Origin<'__pin, S>: Unpin,
"],["impl<'__pin, S> Unpin for SizedStream<S>
where\n __Origin<'__pin, S>: Unpin,
"],["impl<'__pin, S> Unpin for Decoder<S>
where\n __Origin<'__pin, S>: Unpin,
"],["impl<'__pin, S, T> Unpin for Dispatcher<S, T>
where\n __Origin<'__pin, S, T>: Unpin,\n S: Service<Frame, Response = Message> + 'static,\n T: AsyncRead + AsyncWrite,
"],["impl<'__pin, T, B> Unpin for SendResponse<T, B>
where\n __Origin<'__pin, T, B>: Unpin,
"],["impl<'__pin, T, S, B, X, U> Unpin for Dispatcher<T, S, B, X, U>
where\n __Origin<'__pin, T, S, B, X, U>: Unpin,\n S: Service<Request>,\n S::Error: Into<Response<BoxBody>>,\n B: MessageBody,\n X: Service<Request, Response = Request>,\n X::Error: Into<Response<BoxBody>>,\n U: Service<(Request, Framed<T, Codec>), Response = ()>,\n U::Error: Display,
"],["impl<'__pin, T, S, B, X, U> Unpin for Dispatcher<T, S, B, X, U>
where\n __Origin<'__pin, T, S, B, X, U>: Unpin,
"],["impl<'a> Unpin for Drain<'a>",1,["actix_http::header::map::Drain"]],["impl<'a> Unpin for Iter<'a>",1,["actix_http::header::map::Iter"]],["impl<'a> Unpin for Keys<'a>",1,["actix_http::header::map::Keys"]],["impl<B> Unpin for Response<B>
where\n B: Unpin,
",1,["actix_http::responses::response::Response"]],["impl<P> Unpin for Request<P>
where\n P: Unpin,
",1,["actix_http::requests::request::Request"]],["impl<T> Unpin for Message<T>
where\n T: Unpin,
",1,["actix_http::h1::Message"]],["impl<T> Unpin for QualityItem<T>
where\n T: Unpin,
",1,["actix_http::header::shared::quality_item::QualityItem"]],["impl<T> Unpin for Message<T>",1,["actix_http::message::Message"]],["impl<T, S, B> Unpin for H2Service<T, S, B>
where\n S: Unpin,\n T: Unpin,\n B: Unpin,
",1,["actix_http::h2::service::H2Service"]],["impl<T, S, B, X, U> Unpin for H1Service<T, S, B, X, U>
where\n S: Unpin,\n X: Unpin,\n U: Unpin,\n B: Unpin,
",1,["actix_http::h1::service::H1Service"]],["impl<T, S, B, X, U> Unpin for HttpService<T, S, B, X, U>
where\n S: Unpin,\n X: Unpin,\n U: Unpin,\n B: Unpin,
",1,["actix_http::service::HttpService"]],["impl<T, S, X, U> Unpin for HttpServiceBuilder<T, S, X, U>
where\n X: Unpin,\n U: Unpin,\n S: Unpin,
",1,["actix_http::builder::HttpServiceBuilder"]]], +"actix_http_test":[["impl Unpin for TestServer",1,["actix_http_test::TestServer"]]], +"actix_multipart":[["impl Unpin for MultipartError",1,["actix_multipart::error::MultipartError"]],["impl Unpin for JsonFieldError",1,["actix_multipart::form::json::JsonFieldError"]],["impl Unpin for TempFileError",1,["actix_multipart::form::tempfile::TempFileError"]],["impl Unpin for TextError",1,["actix_multipart::form::text::TextError"]],["impl Unpin for Bytes",1,["actix_multipart::form::bytes::Bytes"]],["impl Unpin for JsonConfig",1,["actix_multipart::form::json::JsonConfig"]],["impl Unpin for Limits",1,["actix_multipart::form::Limits"]],["impl Unpin for MultipartFormConfig",1,["actix_multipart::form::MultipartFormConfig"]],["impl Unpin for TempFile",1,["actix_multipart::form::tempfile::TempFile"]],["impl Unpin for TempFileConfig",1,["actix_multipart::form::tempfile::TempFileConfig"]],["impl Unpin for TextConfig",1,["actix_multipart::form::text::TextConfig"]],["impl Unpin for Field",1,["actix_multipart::server::Field"]],["impl Unpin for Multipart",1,["actix_multipart::server::Multipart"]],["impl<T> Unpin for Json<T>
where\n T: Unpin,
",1,["actix_multipart::form::json::Json"]],["impl<T> Unpin for MultipartForm<T>
where\n T: Unpin,
",1,["actix_multipart::form::MultipartForm"]],["impl<T> Unpin for Text<T>
where\n T: Unpin,
",1,["actix_multipart::form::text::Text"]]], +"actix_router":[["impl Unpin for Patterns",1,["actix_router::pattern::Patterns"]],["impl Unpin for Quoter",1,["actix_router::quoter::Quoter"]],["impl Unpin for ResourceDef",1,["actix_router::resource::ResourceDef"]],["impl Unpin for ResourceId",1,["actix_router::router::ResourceId"]],["impl Unpin for Url",1,["actix_router::url::Url"]],["impl<'de, T> Unpin for PathDeserializer<'de, T>",1,["actix_router::de::PathDeserializer"]],["impl<T> Unpin for Path<T>
where\n T: Unpin,
",1,["actix_router::path::Path"]],["impl<T, U> Unpin for Router<T, U>
where\n T: Unpin,\n U: Unpin,
",1,["actix_router::router::Router"]],["impl<T, U> Unpin for RouterBuilder<T, U>
where\n T: Unpin,\n U: Unpin,
",1,["actix_router::router::RouterBuilder"]]], +"actix_test":[["impl Unpin for TestServer",1,["actix_test::TestServer"]],["impl Unpin for TestServerConfig",1,["actix_test::TestServerConfig"]]], +"actix_web":[["impl Unpin for JsonPayloadError",1,["actix_web::error::JsonPayloadError"]],["impl Unpin for PathError",1,["actix_web::error::PathError"]],["impl Unpin for QueryPayloadError",1,["actix_web::error::QueryPayloadError"]],["impl Unpin for ReadlinesError",1,["actix_web::error::ReadlinesError"]],["impl Unpin for UrlGenerationError",1,["actix_web::error::UrlGenerationError"]],["impl Unpin for UrlencodedError",1,["actix_web::error::UrlencodedError"]],["impl Unpin for ByteRangeSpec",1,["actix_web::http::header::range::ByteRangeSpec"]],["impl Unpin for CacheDirective",1,["actix_web::http::header::cache_control::CacheDirective"]],["impl Unpin for ContentRangeSpec",1,["actix_web::http::header::content_range::ContentRangeSpec"]],["impl Unpin for DispositionParam",1,["actix_web::http::header::content_disposition::DispositionParam"]],["impl Unpin for DispositionType",1,["actix_web::http::header::content_disposition::DispositionType"]],["impl Unpin for Encoding",1,["actix_web::http::header::encoding::Encoding"]],["impl Unpin for IfMatch",1,["actix_web::http::header::if_match::IfMatch"]],["impl Unpin for IfNoneMatch",1,["actix_web::http::header::if_none_match::IfNoneMatch"]],["impl Unpin for IfRange",1,["actix_web::http::header::if_range::IfRange"]],["impl Unpin for Range",1,["actix_web::http::header::range::Range"]],["impl Unpin for TrailingSlash",1,["actix_web::middleware::normalize::TrailingSlash"]],["impl Unpin for AppConfig",1,["actix_web::config::AppConfig"]],["impl Unpin for AppService",1,["actix_web::config::AppService"]],["impl Unpin for ConnectionInfo",1,["actix_web::info::ConnectionInfo"]],["impl Unpin for PeerAddr",1,["actix_web::info::PeerAddr"]],["impl Unpin for ResourceMap",1,["actix_web::rmap::ResourceMap"]],["impl Unpin for ServiceRequest",1,["actix_web::service::ServiceRequest"]],["impl Unpin for WebService",1,["actix_web::service::WebService"]],["impl Unpin for BlockingError",1,["actix_web::error::BlockingError"]],["impl Unpin for Error",1,["actix_web::error::error::Error"]],["impl Unpin for Acceptable",1,["actix_web::guard::acceptable::Acceptable"]],["impl Unpin for AllGuard",1,["actix_web::guard::AllGuard"]],["impl Unpin for AnyGuard",1,["actix_web::guard::AnyGuard"]],["impl Unpin for Accept",1,["actix_web::http::header::accept::Accept"]],["impl Unpin for AcceptCharset",1,["actix_web::http::header::accept_charset::AcceptCharset"]],["impl Unpin for AcceptEncoding",1,["actix_web::http::header::accept_encoding::AcceptEncoding"]],["impl Unpin for AcceptLanguage",1,["actix_web::http::header::accept_language::AcceptLanguage"]],["impl Unpin for Allow",1,["actix_web::http::header::allow::Allow"]],["impl Unpin for CacheControl",1,["actix_web::http::header::cache_control::CacheControl"]],["impl Unpin for ContentDisposition",1,["actix_web::http::header::content_disposition::ContentDisposition"]],["impl Unpin for ContentLanguage",1,["actix_web::http::header::content_language::ContentLanguage"]],["impl Unpin for ContentLength",1,["actix_web::http::header::content_length::ContentLength"]],["impl Unpin for ContentRange",1,["actix_web::http::header::content_range::ContentRange"]],["impl Unpin for ContentType",1,["actix_web::http::header::content_type::ContentType"]],["impl Unpin for Date",1,["actix_web::http::header::date::Date"]],["impl Unpin for ETag",1,["actix_web::http::header::etag::ETag"]],["impl Unpin for EntityTag",1,["actix_web::http::header::entity::EntityTag"]],["impl Unpin for Expires",1,["actix_web::http::header::expires::Expires"]],["impl Unpin for IfModifiedSince",1,["actix_web::http::header::if_modified_since::IfModifiedSince"]],["impl Unpin for IfUnmodifiedSince",1,["actix_web::http::header::if_unmodified_since::IfUnmodifiedSince"]],["impl Unpin for LastModified",1,["actix_web::http::header::last_modified::LastModified"]],["impl Unpin for Compress",1,["actix_web::middleware::compress::Compress"]],["impl Unpin for DefaultHeaders",1,["actix_web::middleware::default_headers::DefaultHeaders"]],["impl Unpin for Logger",1,["actix_web::middleware::logger::Logger"]],["impl Unpin for NormalizePath",1,["actix_web::middleware::normalize::NormalizePath"]],["impl Unpin for HttpRequest",1,["actix_web::request::HttpRequest"]],["impl Unpin for HttpResponseBuilder",1,["actix_web::response::builder::HttpResponseBuilder"]],["impl Unpin for Route",1,["actix_web::route::Route"]],["impl Unpin for TestRequest",1,["actix_web::test::test_request::TestRequest"]],["impl Unpin for FormConfig",1,["actix_web::types::form::FormConfig"]],["impl Unpin for JsonConfig",1,["actix_web::types::json::JsonConfig"]],["impl Unpin for PathConfig",1,["actix_web::types::path::PathConfig"]],["impl Unpin for Payload",1,["actix_web::types::payload::Payload"]],["impl Unpin for PayloadConfig",1,["actix_web::types::payload::PayloadConfig"]],["impl Unpin for QueryConfig",1,["actix_web::types::query::QueryConfig"]],["impl Unpin for Redirect",1,["actix_web::redirect::Redirect"]],["impl Unpin for ServiceConfig",1,["actix_web::config::ServiceConfig"]],["impl<'a> Unpin for GuardContext<'a>",1,["actix_web::guard::GuardContext"]],["impl<B> Unpin for ErrorHandlerResponse<B>
where\n B: Unpin,
",1,["actix_web::middleware::err_handlers::ErrorHandlerResponse"]],["impl<B> Unpin for ServiceResponse<B>
where\n B: Unpin,
",1,["actix_web::service::ServiceResponse"]],["impl<B> Unpin for ErrorHandlers<B>",1,["actix_web::middleware::err_handlers::ErrorHandlers"]],["impl<B> Unpin for HttpResponse<B>
where\n B: Unpin,
",1,["actix_web::response::response::HttpResponse"]],["impl<F, I, S, B> Unpin for HttpServer<F, I, S, B>
where\n <S as ServiceFactory<Request>>::Response: Sized,\n <S as ServiceFactory<Request>>::Error: Sized,\n F: Unpin,\n S: Unpin,\n B: Unpin,
",1,["actix_web::server::HttpServer"]],["impl<G> Unpin for Not<G>
where\n G: Unpin,
",1,["actix_web::guard::Not"]],["impl<L, R> Unpin for Either<L, R>
where\n L: Unpin,\n R: Unpin,
",1,["actix_web::types::either::Either"]],["impl<R> Unpin for CustomizeResponder<R>
where\n R: Unpin,
",1,["actix_web::response::customize_responder::CustomizeResponder"]],["impl<T> Unpin for JsonBody<T>"],["impl<T> Unpin for Preference<T>
where\n T: Unpin,
",1,["actix_web::http::header::preference::Preference"]],["impl<T> Unpin for Readlines<T>
where\n <T as HttpMessage>::Stream: Unpin,
",1,["actix_web::types::readlines::Readlines"]],["impl<T> Unpin for UrlEncoded<T>",1,["actix_web::types::form::UrlEncoded"]],["impl<T> Unpin for InternalError<T>
where\n T: Unpin,
",1,["actix_web::error::internal::InternalError"]],["impl<T> Unpin for Compat<T>
where\n T: Unpin,
",1,["actix_web::middleware::compat::Compat"]],["impl<T> Unpin for Condition<T>
where\n T: Unpin,
",1,["actix_web::middleware::condition::Condition"]],["impl<T> Unpin for App<T>
where\n T: Unpin,
",1,["actix_web::app::App"]],["impl<T> Unpin for Resource<T>
where\n T: Unpin,
",1,["actix_web::resource::Resource"]],["impl<T> Unpin for Scope<T>
where\n T: Unpin,
",1,["actix_web::scope::Scope"]],["impl<T> Unpin for Data<T>
where\n T: ?Sized,
",1,["actix_web::data::Data"]],["impl<T> Unpin for Form<T>
where\n T: Unpin,
",1,["actix_web::types::form::Form"]],["impl<T> Unpin for Header<T>
where\n T: Unpin,
",1,["actix_web::types::header::Header"]],["impl<T> Unpin for Json<T>
where\n T: Unpin,
",1,["actix_web::types::json::Json"]],["impl<T> Unpin for Path<T>
where\n T: Unpin,
",1,["actix_web::types::path::Path"]],["impl<T> Unpin for Query<T>
where\n T: Unpin,
",1,["actix_web::types::query::Query"]],["impl<T> Unpin for ReqData<T>
where\n T: Unpin,
",1,["actix_web::request_data::ReqData"]]], +"actix_web_actors":[["impl<'a, A, T> Unpin for WsResponseBuilder<'a, A, T>
where\n T: Unpin,
",1,["actix_web_actors::ws::WsResponseBuilder"]],["impl<A> Unpin for HttpContext<A>",1,["actix_web_actors::context::HttpContext"]],["impl<A> Unpin for WebsocketContext<A>",1,["actix_web_actors::ws::WebsocketContext"]]], +"awc":[["impl Unpin for ConnectRequest",1,["awc::connect::ConnectRequest"]],["impl Unpin for ConnectResponse",1,["awc::connect::ConnectResponse"]],["impl Unpin for SendClientRequest",1,["awc::sender::SendClientRequest"]],["impl Unpin for ConnectError",1,["awc::client::error::ConnectError"]],["impl Unpin for FreezeRequestError",1,["awc::client::error::FreezeRequestError"]],["impl Unpin for InvalidUrl",1,["awc::client::error::InvalidUrl"]],["impl Unpin for JsonPayloadError",1,["awc::error::JsonPayloadError"]],["impl Unpin for SendRequestError",1,["awc::client::error::SendRequestError"]],["impl Unpin for WsClientError",1,["awc::error::WsClientError"]],["impl Unpin for Redirect",1,["awc::middleware::redirect::Redirect"]],["impl Unpin for Client",1,["awc::client::Client"]],["impl Unpin for ClientRequest",1,["awc::request::ClientRequest"]],["impl Unpin for Connect",1,["awc::client::Connect"]],["impl Unpin for FrozenClientRequest",1,["awc::frozen::FrozenClientRequest"]],["impl Unpin for FrozenSendBuilder",1,["awc::frozen::FrozenSendBuilder"]],["impl Unpin for TestResponse",1,["awc::test::TestResponse"]],["impl Unpin for WebsocketsRequest",1,["awc::ws::WebsocketsRequest"]],["impl<'__pin, S> Unpin for ClientResponse<S>
where\n __Origin<'__pin, S>: Unpin,
"],["impl<'__pin, S> Unpin for ResponseBody<S>
where\n __Origin<'__pin, S>: Unpin,
"],["impl<'__pin, S, T> Unpin for JsonBody<S, T>
where\n __Origin<'__pin, S, T>: Unpin,
"],["impl<S, M> Unpin for ClientBuilder<S, M>
where\n M: Unpin,\n S: Unpin,
",1,["awc::builder::ClientBuilder"]],["impl<T> Unpin for Connector<T>
where\n T: Unpin,
",1,["awc::client::connector::Connector"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/deref/trait.Deref.js b/trait.impl/core/ops/deref/trait.Deref.js new file mode 100644 index 000000000..2938397f8 --- /dev/null +++ b/trait.impl/core/ops/deref/trait.Deref.js @@ -0,0 +1,6 @@ +(function() {var implementors = { +"actix_files":[["impl Deref for FilesService"],["impl Deref for NamedFile"]], +"actix_http":[["impl<T: Head> Deref for Message<T>"]], +"actix_multipart":[["impl<T: MultipartCollect> Deref for MultipartForm<T>"],["impl<T: DeserializeOwned> Deref for Json<T>"],["impl<T: DeserializeOwned> Deref for Text<T>"]], +"actix_web":[["impl Deref for Accept"],["impl Deref for AcceptCharset"],["impl Deref for AcceptEncoding"],["impl Deref for AcceptLanguage"],["impl Deref for Allow"],["impl Deref for CacheControl"],["impl Deref for ContentLanguage"],["impl Deref for ContentLength"],["impl Deref for ContentRange"],["impl Deref for ContentType"],["impl Deref for Date"],["impl Deref for ETag"],["impl Deref for Expires"],["impl Deref for IfModifiedSince"],["impl Deref for IfUnmodifiedSince"],["impl Deref for LastModified"],["impl<T> Deref for Form<T>"],["impl<T> Deref for Header<T>"],["impl<T> Deref for Json<T>"],["impl<T> Deref for Path<T>"],["impl<T> Deref for Query<T>"],["impl<T: Clone + 'static> Deref for ReqData<T>"],["impl<T: ?Sized> Deref for Data<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/deref/trait.DerefMut.js b/trait.impl/core/ops/deref/trait.DerefMut.js new file mode 100644 index 000000000..2bf119e99 --- /dev/null +++ b/trait.impl/core/ops/deref/trait.DerefMut.js @@ -0,0 +1,6 @@ +(function() {var implementors = { +"actix_files":[["impl DerefMut for NamedFile"]], +"actix_http":[["impl<T: Head> DerefMut for Message<T>"]], +"actix_multipart":[["impl<T: MultipartCollect> DerefMut for MultipartForm<T>"],["impl<T: DeserializeOwned> DerefMut for Json<T>"],["impl<T: DeserializeOwned> DerefMut for Text<T>"]], +"actix_web":[["impl DerefMut for Accept"],["impl DerefMut for AcceptCharset"],["impl DerefMut for AcceptEncoding"],["impl DerefMut for AcceptLanguage"],["impl DerefMut for Allow"],["impl DerefMut for CacheControl"],["impl DerefMut for ContentLanguage"],["impl DerefMut for ContentLength"],["impl DerefMut for ContentRange"],["impl DerefMut for ContentType"],["impl DerefMut for Date"],["impl DerefMut for ETag"],["impl DerefMut for Expires"],["impl DerefMut for IfModifiedSince"],["impl DerefMut for IfUnmodifiedSince"],["impl DerefMut for LastModified"],["impl<T> DerefMut for Form<T>"],["impl<T> DerefMut for Header<T>"],["impl<T> DerefMut for Json<T>"],["impl<T> DerefMut for Path<T>"],["impl<T> DerefMut for Query<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/drop/trait.Drop.js b/trait.impl/core/ops/drop/trait.Drop.js new file mode 100644 index 000000000..5fc608fea --- /dev/null +++ b/trait.impl/core/ops/drop/trait.Drop.js @@ -0,0 +1,6 @@ +(function() {var implementors = { +"actix_http":[["impl<T: Head> Drop for Message<T>"]], +"actix_http_test":[["impl Drop for TestServer"]], +"actix_test":[["impl Drop for TestServer"]], +"actix_web":[["impl Drop for HttpRequest"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/ops/index/trait.Index.js b/trait.impl/core/ops/index/trait.Index.js new file mode 100644 index 000000000..1dac74b79 --- /dev/null +++ b/trait.impl/core/ops/index/trait.Index.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_router":[["impl<'a, T: ResourcePath> Index<&'a str> for Path<T>"],["impl<T: ResourcePath> Index<usize> for Path<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js b/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js new file mode 100644 index 000000000..9118d14c4 --- /dev/null +++ b/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js @@ -0,0 +1,11 @@ +(function() {var implementors = { +"actix_files":[["impl !RefUnwindSafe for Files",1,["actix_files::files::Files"]],["impl !RefUnwindSafe for FilesService",1,["actix_files::service::FilesService"]],["impl !RefUnwindSafe for NamedFile",1,["actix_files::named::NamedFile"]],["impl RefUnwindSafe for Directory",1,["actix_files::directory::Directory"]],["impl RefUnwindSafe for HttpRange",1,["actix_files::range::HttpRange"]]], +"actix_http":[["impl !RefUnwindSafe for DispatchError",1,["actix_http::error::DispatchError"]],["impl !RefUnwindSafe for ParseError",1,["actix_http::error::ParseError"]],["impl !RefUnwindSafe for PayloadError",1,["actix_http::error::PayloadError"]],["impl !RefUnwindSafe for ProtocolError",1,["actix_http::ws::ProtocolError"]],["impl !RefUnwindSafe for BoxBody",1,["actix_http::body::boxed::BoxBody"]],["impl !RefUnwindSafe for Error",1,["actix_http::error::Error"]],["impl !RefUnwindSafe for ClientCodec",1,["actix_http::h1::client::ClientCodec"]],["impl !RefUnwindSafe for ClientPayloadCodec",1,["actix_http::h1::client::ClientPayloadCodec"]],["impl !RefUnwindSafe for Codec",1,["actix_http::h1::codec::Codec"]],["impl !RefUnwindSafe for Payload",1,["actix_http::h1::payload::Payload"]],["impl !RefUnwindSafe for Extensions",1,["actix_http::extensions::Extensions"]],["impl !RefUnwindSafe for ServiceConfig",1,["actix_http::config::ServiceConfig"]],["impl !RefUnwindSafe for TestBuffer",1,["actix_http::test::TestBuffer"]],["impl !RefUnwindSafe for TestRequest",1,["actix_http::test::TestRequest"]],["impl !RefUnwindSafe for TestSeqBuffer",1,["actix_http::test::TestSeqBuffer"]],["impl !RefUnwindSafe for TestSeqInner",1,["actix_http::test::TestSeqInner"]],["impl RefUnwindSafe for BodySize",1,["actix_http::body::size::BodySize"]],["impl RefUnwindSafe for ConnectionType",1,["actix_http::message::ConnectionType"]],["impl RefUnwindSafe for KeepAlive",1,["actix_http::keep_alive::KeepAlive"]],["impl RefUnwindSafe for Protocol",1,["actix_http::Protocol"]],["impl RefUnwindSafe for RequestHeadType",1,["actix_http::requests::head::RequestHeadType"]],["impl RefUnwindSafe for ContentTypeError",1,["actix_http::error::ContentTypeError"]],["impl RefUnwindSafe for MessageType",1,["actix_http::h1::MessageType"]],["impl RefUnwindSafe for Charset",1,["actix_http::header::shared::charset::Charset"]],["impl RefUnwindSafe for ContentEncoding",1,["actix_http::header::shared::content_encoding::ContentEncoding"]],["impl RefUnwindSafe for CloseCode",1,["actix_http::ws::proto::CloseCode"]],["impl RefUnwindSafe for Frame",1,["actix_http::ws::codec::Frame"]],["impl RefUnwindSafe for HandshakeError",1,["actix_http::ws::HandshakeError"]],["impl RefUnwindSafe for Item",1,["actix_http::ws::codec::Item"]],["impl RefUnwindSafe for Message",1,["actix_http::ws::codec::Message"]],["impl RefUnwindSafe for OpCode",1,["actix_http::ws::proto::OpCode"]],["impl RefUnwindSafe for BodyLimitExceeded",1,["actix_http::body::utils::BodyLimitExceeded"]],["impl RefUnwindSafe for None",1,["actix_http::body::none::None"]],["impl RefUnwindSafe for ExpectHandler",1,["actix_http::h1::expect::ExpectHandler"]],["impl RefUnwindSafe for UpgradeHandler",1,["actix_http::h1::upgrade::UpgradeHandler"]],["impl RefUnwindSafe for Payload",1,["actix_http::h2::Payload"]],["impl RefUnwindSafe for HeaderMap",1,["actix_http::header::map::HeaderMap"]],["impl RefUnwindSafe for IntoIter",1,["actix_http::header::map::IntoIter"]],["impl RefUnwindSafe for Removed",1,["actix_http::header::map::Removed"]],["impl RefUnwindSafe for ExtendedValue",1,["actix_http::header::shared::extended::ExtendedValue"]],["impl RefUnwindSafe for HttpDate",1,["actix_http::header::shared::http_date::HttpDate"]],["impl RefUnwindSafe for Quality",1,["actix_http::header::shared::quality::Quality"]],["impl RefUnwindSafe for RequestHead",1,["actix_http::requests::head::RequestHead"]],["impl RefUnwindSafe for ResponseBuilder",1,["actix_http::responses::builder::ResponseBuilder"]],["impl RefUnwindSafe for ResponseHead",1,["actix_http::responses::head::ResponseHead"]],["impl RefUnwindSafe for TlsAcceptorConfig",1,["actix_http::service::TlsAcceptorConfig"]],["impl RefUnwindSafe for CloseReason",1,["actix_http::ws::proto::CloseReason"]],["impl RefUnwindSafe for Codec",1,["actix_http::ws::codec::Codec"]],["impl RefUnwindSafe for Parser",1,["actix_http::ws::frame::Parser"]],["impl<'a> RefUnwindSafe for Drain<'a>",1,["actix_http::header::map::Drain"]],["impl<'a> RefUnwindSafe for Iter<'a>",1,["actix_http::header::map::Iter"]],["impl<'a> RefUnwindSafe for Keys<'a>",1,["actix_http::header::map::Keys"]],["impl<B> !RefUnwindSafe for Encoder<B>",1,["actix_http::encoding::encoder::Encoder"]],["impl<B> !RefUnwindSafe for Response<B>",1,["actix_http::responses::response::Response"]],["impl<L, R> RefUnwindSafe for EitherBody<L, R>
where\n L: RefUnwindSafe,\n R: RefUnwindSafe,
",1,["actix_http::body::either::EitherBody"]],["impl<P = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !RefUnwindSafe for Request<P>",1,["actix_http::requests::request::Request"]],["impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !RefUnwindSafe for Payload<S>",1,["actix_http::payload::Payload"]],["impl<S> !RefUnwindSafe for Decoder<S>",1,["actix_http::encoding::decoder::Decoder"]],["impl<S> RefUnwindSafe for BodyStream<S>
where\n S: RefUnwindSafe,
",1,["actix_http::body::body_stream::BodyStream"]],["impl<S> RefUnwindSafe for SizedStream<S>
where\n S: RefUnwindSafe,
",1,["actix_http::body::sized_stream::SizedStream"]],["impl<S, T> !RefUnwindSafe for Dispatcher<S, T>",1,["actix_http::ws::dispatcher::Dispatcher"]],["impl<T> RefUnwindSafe for Message<T>
where\n T: RefUnwindSafe,
",1,["actix_http::h1::Message"]],["impl<T> RefUnwindSafe for QualityItem<T>
where\n T: RefUnwindSafe,
",1,["actix_http::header::shared::quality_item::QualityItem"]],["impl<T> RefUnwindSafe for Message<T>
where\n T: RefUnwindSafe,
",1,["actix_http::message::Message"]],["impl<T, B> !RefUnwindSafe for SendResponse<T, B>",1,["actix_http::h1::utils::SendResponse"]],["impl<T, S, B> !RefUnwindSafe for H2Service<T, S, B>",1,["actix_http::h2::service::H2Service"]],["impl<T, S, B, X = ExpectHandler, U = UpgradeHandler> !RefUnwindSafe for H1Service<T, S, B, X, U>",1,["actix_http::h1::service::H1Service"]],["impl<T, S, B, X = ExpectHandler, U = UpgradeHandler> !RefUnwindSafe for HttpService<T, S, B, X, U>",1,["actix_http::service::HttpService"]],["impl<T, S, B, X, U> !RefUnwindSafe for Dispatcher<T, S, B, X, U>",1,["actix_http::h1::dispatcher::Dispatcher"]],["impl<T, S, B, X, U> !RefUnwindSafe for Dispatcher<T, S, B, X, U>",1,["actix_http::h2::dispatcher::Dispatcher"]],["impl<T, S, X = ExpectHandler, U = UpgradeHandler> !RefUnwindSafe for HttpServiceBuilder<T, S, X, U>",1,["actix_http::builder::HttpServiceBuilder"]]], +"actix_http_test":[["impl !RefUnwindSafe for TestServer",1,["actix_http_test::TestServer"]]], +"actix_multipart":[["impl !RefUnwindSafe for MultipartError",1,["actix_multipart::error::MultipartError"]],["impl !RefUnwindSafe for JsonFieldError",1,["actix_multipart::form::json::JsonFieldError"]],["impl !RefUnwindSafe for TempFileError",1,["actix_multipart::form::tempfile::TempFileError"]],["impl !RefUnwindSafe for JsonConfig",1,["actix_multipart::form::json::JsonConfig"]],["impl !RefUnwindSafe for MultipartFormConfig",1,["actix_multipart::form::MultipartFormConfig"]],["impl !RefUnwindSafe for TempFileConfig",1,["actix_multipart::form::tempfile::TempFileConfig"]],["impl !RefUnwindSafe for TextConfig",1,["actix_multipart::form::text::TextConfig"]],["impl !RefUnwindSafe for Field",1,["actix_multipart::server::Field"]],["impl !RefUnwindSafe for Multipart",1,["actix_multipart::server::Multipart"]],["impl RefUnwindSafe for TextError",1,["actix_multipart::form::text::TextError"]],["impl RefUnwindSafe for Bytes",1,["actix_multipart::form::bytes::Bytes"]],["impl RefUnwindSafe for Limits",1,["actix_multipart::form::Limits"]],["impl RefUnwindSafe for TempFile",1,["actix_multipart::form::tempfile::TempFile"]],["impl<T> RefUnwindSafe for Json<T>
where\n T: RefUnwindSafe,
",1,["actix_multipart::form::json::Json"]],["impl<T> RefUnwindSafe for MultipartForm<T>
where\n T: RefUnwindSafe,
",1,["actix_multipart::form::MultipartForm"]],["impl<T> RefUnwindSafe for Text<T>
where\n T: RefUnwindSafe,
",1,["actix_multipart::form::text::Text"]]], +"actix_router":[["impl RefUnwindSafe for Patterns",1,["actix_router::pattern::Patterns"]],["impl RefUnwindSafe for Quoter",1,["actix_router::quoter::Quoter"]],["impl RefUnwindSafe for ResourceDef",1,["actix_router::resource::ResourceDef"]],["impl RefUnwindSafe for ResourceId",1,["actix_router::router::ResourceId"]],["impl RefUnwindSafe for Url",1,["actix_router::url::Url"]],["impl<'de, T> RefUnwindSafe for PathDeserializer<'de, T>
where\n T: RefUnwindSafe,
",1,["actix_router::de::PathDeserializer"]],["impl<T> RefUnwindSafe for Path<T>
where\n T: RefUnwindSafe,
",1,["actix_router::path::Path"]],["impl<T, U> RefUnwindSafe for Router<T, U>
where\n T: RefUnwindSafe,\n U: RefUnwindSafe,
",1,["actix_router::router::Router"]],["impl<T, U> RefUnwindSafe for RouterBuilder<T, U>
where\n T: RefUnwindSafe,\n U: RefUnwindSafe,
",1,["actix_router::router::RouterBuilder"]]], +"actix_test":[["impl !RefUnwindSafe for TestServer",1,["actix_test::TestServer"]],["impl !RefUnwindSafe for TestServerConfig",1,["actix_test::TestServerConfig"]]], +"actix_web":[["impl !RefUnwindSafe for JsonPayloadError",1,["actix_web::error::JsonPayloadError"]],["impl !RefUnwindSafe for ReadlinesError",1,["actix_web::error::ReadlinesError"]],["impl !RefUnwindSafe for UrlencodedError",1,["actix_web::error::UrlencodedError"]],["impl !RefUnwindSafe for AppService",1,["actix_web::config::AppService"]],["impl !RefUnwindSafe for ResourceMap",1,["actix_web::rmap::ResourceMap"]],["impl !RefUnwindSafe for ServiceRequest",1,["actix_web::service::ServiceRequest"]],["impl !RefUnwindSafe for WebService",1,["actix_web::service::WebService"]],["impl !RefUnwindSafe for Error",1,["actix_web::error::error::Error"]],["impl !RefUnwindSafe for AllGuard",1,["actix_web::guard::AllGuard"]],["impl !RefUnwindSafe for AnyGuard",1,["actix_web::guard::AnyGuard"]],["impl !RefUnwindSafe for Logger",1,["actix_web::middleware::logger::Logger"]],["impl !RefUnwindSafe for HttpRequest",1,["actix_web::request::HttpRequest"]],["impl !RefUnwindSafe for HttpResponseBuilder",1,["actix_web::response::builder::HttpResponseBuilder"]],["impl !RefUnwindSafe for Route",1,["actix_web::route::Route"]],["impl !RefUnwindSafe for TestRequest",1,["actix_web::test::test_request::TestRequest"]],["impl !RefUnwindSafe for FormConfig",1,["actix_web::types::form::FormConfig"]],["impl !RefUnwindSafe for JsonConfig",1,["actix_web::types::json::JsonConfig"]],["impl !RefUnwindSafe for PathConfig",1,["actix_web::types::path::PathConfig"]],["impl !RefUnwindSafe for Payload",1,["actix_web::types::payload::Payload"]],["impl !RefUnwindSafe for QueryConfig",1,["actix_web::types::query::QueryConfig"]],["impl !RefUnwindSafe for ServiceConfig",1,["actix_web::config::ServiceConfig"]],["impl RefUnwindSafe for PathError",1,["actix_web::error::PathError"]],["impl RefUnwindSafe for QueryPayloadError",1,["actix_web::error::QueryPayloadError"]],["impl RefUnwindSafe for UrlGenerationError",1,["actix_web::error::UrlGenerationError"]],["impl RefUnwindSafe for ByteRangeSpec",1,["actix_web::http::header::range::ByteRangeSpec"]],["impl RefUnwindSafe for CacheDirective",1,["actix_web::http::header::cache_control::CacheDirective"]],["impl RefUnwindSafe for ContentRangeSpec",1,["actix_web::http::header::content_range::ContentRangeSpec"]],["impl RefUnwindSafe for DispositionParam",1,["actix_web::http::header::content_disposition::DispositionParam"]],["impl RefUnwindSafe for DispositionType",1,["actix_web::http::header::content_disposition::DispositionType"]],["impl RefUnwindSafe for Encoding",1,["actix_web::http::header::encoding::Encoding"]],["impl RefUnwindSafe for IfMatch",1,["actix_web::http::header::if_match::IfMatch"]],["impl RefUnwindSafe for IfNoneMatch",1,["actix_web::http::header::if_none_match::IfNoneMatch"]],["impl RefUnwindSafe for IfRange",1,["actix_web::http::header::if_range::IfRange"]],["impl RefUnwindSafe for Range",1,["actix_web::http::header::range::Range"]],["impl RefUnwindSafe for TrailingSlash",1,["actix_web::middleware::normalize::TrailingSlash"]],["impl RefUnwindSafe for AppConfig",1,["actix_web::config::AppConfig"]],["impl RefUnwindSafe for ConnectionInfo",1,["actix_web::info::ConnectionInfo"]],["impl RefUnwindSafe for PeerAddr",1,["actix_web::info::PeerAddr"]],["impl RefUnwindSafe for BlockingError",1,["actix_web::error::BlockingError"]],["impl RefUnwindSafe for Acceptable",1,["actix_web::guard::acceptable::Acceptable"]],["impl RefUnwindSafe for Accept",1,["actix_web::http::header::accept::Accept"]],["impl RefUnwindSafe for AcceptCharset",1,["actix_web::http::header::accept_charset::AcceptCharset"]],["impl RefUnwindSafe for AcceptEncoding",1,["actix_web::http::header::accept_encoding::AcceptEncoding"]],["impl RefUnwindSafe for AcceptLanguage",1,["actix_web::http::header::accept_language::AcceptLanguage"]],["impl RefUnwindSafe for Allow",1,["actix_web::http::header::allow::Allow"]],["impl RefUnwindSafe for CacheControl",1,["actix_web::http::header::cache_control::CacheControl"]],["impl RefUnwindSafe for ContentDisposition",1,["actix_web::http::header::content_disposition::ContentDisposition"]],["impl RefUnwindSafe for ContentLanguage",1,["actix_web::http::header::content_language::ContentLanguage"]],["impl RefUnwindSafe for ContentLength",1,["actix_web::http::header::content_length::ContentLength"]],["impl RefUnwindSafe for ContentRange",1,["actix_web::http::header::content_range::ContentRange"]],["impl RefUnwindSafe for ContentType",1,["actix_web::http::header::content_type::ContentType"]],["impl RefUnwindSafe for Date",1,["actix_web::http::header::date::Date"]],["impl RefUnwindSafe for ETag",1,["actix_web::http::header::etag::ETag"]],["impl RefUnwindSafe for EntityTag",1,["actix_web::http::header::entity::EntityTag"]],["impl RefUnwindSafe for Expires",1,["actix_web::http::header::expires::Expires"]],["impl RefUnwindSafe for IfModifiedSince",1,["actix_web::http::header::if_modified_since::IfModifiedSince"]],["impl RefUnwindSafe for IfUnmodifiedSince",1,["actix_web::http::header::if_unmodified_since::IfUnmodifiedSince"]],["impl RefUnwindSafe for LastModified",1,["actix_web::http::header::last_modified::LastModified"]],["impl RefUnwindSafe for Compress",1,["actix_web::middleware::compress::Compress"]],["impl RefUnwindSafe for DefaultHeaders",1,["actix_web::middleware::default_headers::DefaultHeaders"]],["impl RefUnwindSafe for NormalizePath",1,["actix_web::middleware::normalize::NormalizePath"]],["impl RefUnwindSafe for PayloadConfig",1,["actix_web::types::payload::PayloadConfig"]],["impl RefUnwindSafe for Redirect",1,["actix_web::redirect::Redirect"]],["impl<'a> !RefUnwindSafe for GuardContext<'a>",1,["actix_web::guard::GuardContext"]],["impl<B = BoxBody> !RefUnwindSafe for ServiceResponse<B>",1,["actix_web::service::ServiceResponse"]],["impl<B = BoxBody> !RefUnwindSafe for HttpResponse<B>",1,["actix_web::response::response::HttpResponse"]],["impl<B> !RefUnwindSafe for ErrorHandlerResponse<B>",1,["actix_web::middleware::err_handlers::ErrorHandlerResponse"]],["impl<B> !RefUnwindSafe for ErrorHandlers<B>",1,["actix_web::middleware::err_handlers::ErrorHandlers"]],["impl<F, I, S, B> !RefUnwindSafe for HttpServer<F, I, S, B>",1,["actix_web::server::HttpServer"]],["impl<G> RefUnwindSafe for Not<G>
where\n G: RefUnwindSafe,
",1,["actix_web::guard::Not"]],["impl<L, R> RefUnwindSafe for Either<L, R>
where\n L: RefUnwindSafe,\n R: RefUnwindSafe,
",1,["actix_web::types::either::Either"]],["impl<R> RefUnwindSafe for CustomizeResponder<R>
where\n R: RefUnwindSafe,
",1,["actix_web::response::customize_responder::CustomizeResponder"]],["impl<T = ResourceEndpoint> !RefUnwindSafe for Resource<T>",1,["actix_web::resource::Resource"]],["impl<T = ScopeEndpoint> !RefUnwindSafe for Scope<T>",1,["actix_web::scope::Scope"]],["impl<T> !RefUnwindSafe for JsonBody<T>",1,["actix_web::types::json::JsonBody"]],["impl<T> !RefUnwindSafe for Readlines<T>",1,["actix_web::types::readlines::Readlines"]],["impl<T> !RefUnwindSafe for UrlEncoded<T>",1,["actix_web::types::form::UrlEncoded"]],["impl<T> !RefUnwindSafe for InternalError<T>",1,["actix_web::error::internal::InternalError"]],["impl<T> !RefUnwindSafe for App<T>",1,["actix_web::app::App"]],["impl<T> RefUnwindSafe for Preference<T>
where\n T: RefUnwindSafe,
",1,["actix_web::http::header::preference::Preference"]],["impl<T> RefUnwindSafe for Compat<T>
where\n T: RefUnwindSafe,
",1,["actix_web::middleware::compat::Compat"]],["impl<T> RefUnwindSafe for Condition<T>
where\n T: RefUnwindSafe,
",1,["actix_web::middleware::condition::Condition"]],["impl<T> RefUnwindSafe for Data<T>
where\n T: RefUnwindSafe + ?Sized,
",1,["actix_web::data::Data"]],["impl<T> RefUnwindSafe for Form<T>
where\n T: RefUnwindSafe,
",1,["actix_web::types::form::Form"]],["impl<T> RefUnwindSafe for Header<T>
where\n T: RefUnwindSafe,
",1,["actix_web::types::header::Header"]],["impl<T> RefUnwindSafe for Json<T>
where\n T: RefUnwindSafe,
",1,["actix_web::types::json::Json"]],["impl<T> RefUnwindSafe for Path<T>
where\n T: RefUnwindSafe,
",1,["actix_web::types::path::Path"]],["impl<T> RefUnwindSafe for Query<T>
where\n T: RefUnwindSafe,
",1,["actix_web::types::query::Query"]],["impl<T> RefUnwindSafe for ReqData<T>
where\n T: RefUnwindSafe,
",1,["actix_web::request_data::ReqData"]]], +"actix_web_actors":[["impl<'a, A, T> !RefUnwindSafe for WsResponseBuilder<'a, A, T>",1,["actix_web_actors::ws::WsResponseBuilder"]],["impl<A> !RefUnwindSafe for HttpContext<A>",1,["actix_web_actors::context::HttpContext"]],["impl<A> !RefUnwindSafe for WebsocketContext<A>",1,["actix_web_actors::ws::WebsocketContext"]]], +"awc":[["impl !RefUnwindSafe for ConnectRequest",1,["awc::connect::ConnectRequest"]],["impl !RefUnwindSafe for ConnectResponse",1,["awc::connect::ConnectResponse"]],["impl !RefUnwindSafe for SendClientRequest",1,["awc::sender::SendClientRequest"]],["impl !RefUnwindSafe for ConnectError",1,["awc::client::error::ConnectError"]],["impl !RefUnwindSafe for FreezeRequestError",1,["awc::client::error::FreezeRequestError"]],["impl !RefUnwindSafe for JsonPayloadError",1,["awc::error::JsonPayloadError"]],["impl !RefUnwindSafe for SendRequestError",1,["awc::client::error::SendRequestError"]],["impl !RefUnwindSafe for WsClientError",1,["awc::error::WsClientError"]],["impl !RefUnwindSafe for Client",1,["awc::client::Client"]],["impl !RefUnwindSafe for ClientRequest",1,["awc::request::ClientRequest"]],["impl !RefUnwindSafe for FrozenClientRequest",1,["awc::frozen::FrozenClientRequest"]],["impl !RefUnwindSafe for FrozenSendBuilder",1,["awc::frozen::FrozenSendBuilder"]],["impl !RefUnwindSafe for TestResponse",1,["awc::test::TestResponse"]],["impl !RefUnwindSafe for WebsocketsRequest",1,["awc::ws::WebsocketsRequest"]],["impl RefUnwindSafe for InvalidUrl",1,["awc::client::error::InvalidUrl"]],["impl RefUnwindSafe for Redirect",1,["awc::middleware::redirect::Redirect"]],["impl RefUnwindSafe for Connect",1,["awc::client::Connect"]],["impl<S = (), M = ()> !RefUnwindSafe for ClientBuilder<S, M>",1,["awc::builder::ClientBuilder"]],["impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !RefUnwindSafe for ClientResponse<S>",1,["awc::responses::response::ClientResponse"]],["impl<S> !RefUnwindSafe for ResponseBody<S>",1,["awc::responses::response_body::ResponseBody"]],["impl<S, T> !RefUnwindSafe for JsonBody<S, T>",1,["awc::responses::json_body::JsonBody"]],["impl<T> !RefUnwindSafe for Connector<T>",1,["awc::client::connector::Connector"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js b/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js new file mode 100644 index 000000000..8306e4f10 --- /dev/null +++ b/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js @@ -0,0 +1,11 @@ +(function() {var implementors = { +"actix_files":[["impl !UnwindSafe for Files",1,["actix_files::files::Files"]],["impl !UnwindSafe for FilesService",1,["actix_files::service::FilesService"]],["impl !UnwindSafe for NamedFile",1,["actix_files::named::NamedFile"]],["impl UnwindSafe for Directory",1,["actix_files::directory::Directory"]],["impl UnwindSafe for HttpRange",1,["actix_files::range::HttpRange"]]], +"actix_http":[["impl !UnwindSafe for DispatchError",1,["actix_http::error::DispatchError"]],["impl !UnwindSafe for ParseError",1,["actix_http::error::ParseError"]],["impl !UnwindSafe for PayloadError",1,["actix_http::error::PayloadError"]],["impl !UnwindSafe for ProtocolError",1,["actix_http::ws::ProtocolError"]],["impl !UnwindSafe for BoxBody",1,["actix_http::body::boxed::BoxBody"]],["impl !UnwindSafe for Error",1,["actix_http::error::Error"]],["impl !UnwindSafe for ClientCodec",1,["actix_http::h1::client::ClientCodec"]],["impl !UnwindSafe for ClientPayloadCodec",1,["actix_http::h1::client::ClientPayloadCodec"]],["impl !UnwindSafe for Codec",1,["actix_http::h1::codec::Codec"]],["impl !UnwindSafe for Payload",1,["actix_http::h1::payload::Payload"]],["impl !UnwindSafe for Extensions",1,["actix_http::extensions::Extensions"]],["impl !UnwindSafe for ServiceConfig",1,["actix_http::config::ServiceConfig"]],["impl !UnwindSafe for TestBuffer",1,["actix_http::test::TestBuffer"]],["impl !UnwindSafe for TestRequest",1,["actix_http::test::TestRequest"]],["impl !UnwindSafe for TestSeqBuffer",1,["actix_http::test::TestSeqBuffer"]],["impl !UnwindSafe for TestSeqInner",1,["actix_http::test::TestSeqInner"]],["impl UnwindSafe for BodySize",1,["actix_http::body::size::BodySize"]],["impl UnwindSafe for ConnectionType",1,["actix_http::message::ConnectionType"]],["impl UnwindSafe for KeepAlive",1,["actix_http::keep_alive::KeepAlive"]],["impl UnwindSafe for Protocol",1,["actix_http::Protocol"]],["impl UnwindSafe for RequestHeadType",1,["actix_http::requests::head::RequestHeadType"]],["impl UnwindSafe for ContentTypeError",1,["actix_http::error::ContentTypeError"]],["impl UnwindSafe for MessageType",1,["actix_http::h1::MessageType"]],["impl UnwindSafe for Charset",1,["actix_http::header::shared::charset::Charset"]],["impl UnwindSafe for ContentEncoding",1,["actix_http::header::shared::content_encoding::ContentEncoding"]],["impl UnwindSafe for CloseCode",1,["actix_http::ws::proto::CloseCode"]],["impl UnwindSafe for Frame",1,["actix_http::ws::codec::Frame"]],["impl UnwindSafe for HandshakeError",1,["actix_http::ws::HandshakeError"]],["impl UnwindSafe for Item",1,["actix_http::ws::codec::Item"]],["impl UnwindSafe for Message",1,["actix_http::ws::codec::Message"]],["impl UnwindSafe for OpCode",1,["actix_http::ws::proto::OpCode"]],["impl UnwindSafe for BodyLimitExceeded",1,["actix_http::body::utils::BodyLimitExceeded"]],["impl UnwindSafe for None",1,["actix_http::body::none::None"]],["impl UnwindSafe for ExpectHandler",1,["actix_http::h1::expect::ExpectHandler"]],["impl UnwindSafe for UpgradeHandler",1,["actix_http::h1::upgrade::UpgradeHandler"]],["impl UnwindSafe for Payload",1,["actix_http::h2::Payload"]],["impl UnwindSafe for HeaderMap",1,["actix_http::header::map::HeaderMap"]],["impl UnwindSafe for IntoIter",1,["actix_http::header::map::IntoIter"]],["impl UnwindSafe for Removed",1,["actix_http::header::map::Removed"]],["impl UnwindSafe for ExtendedValue",1,["actix_http::header::shared::extended::ExtendedValue"]],["impl UnwindSafe for HttpDate",1,["actix_http::header::shared::http_date::HttpDate"]],["impl UnwindSafe for Quality",1,["actix_http::header::shared::quality::Quality"]],["impl UnwindSafe for RequestHead",1,["actix_http::requests::head::RequestHead"]],["impl UnwindSafe for ResponseBuilder",1,["actix_http::responses::builder::ResponseBuilder"]],["impl UnwindSafe for ResponseHead",1,["actix_http::responses::head::ResponseHead"]],["impl UnwindSafe for TlsAcceptorConfig",1,["actix_http::service::TlsAcceptorConfig"]],["impl UnwindSafe for CloseReason",1,["actix_http::ws::proto::CloseReason"]],["impl UnwindSafe for Codec",1,["actix_http::ws::codec::Codec"]],["impl UnwindSafe for Parser",1,["actix_http::ws::frame::Parser"]],["impl<'a> UnwindSafe for Drain<'a>",1,["actix_http::header::map::Drain"]],["impl<'a> UnwindSafe for Iter<'a>",1,["actix_http::header::map::Iter"]],["impl<'a> UnwindSafe for Keys<'a>",1,["actix_http::header::map::Keys"]],["impl<B> !UnwindSafe for Encoder<B>",1,["actix_http::encoding::encoder::Encoder"]],["impl<B> !UnwindSafe for Response<B>",1,["actix_http::responses::response::Response"]],["impl<L, R> UnwindSafe for EitherBody<L, R>
where\n L: UnwindSafe,\n R: UnwindSafe,
",1,["actix_http::body::either::EitherBody"]],["impl<P = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !UnwindSafe for Request<P>",1,["actix_http::requests::request::Request"]],["impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !UnwindSafe for Payload<S>",1,["actix_http::payload::Payload"]],["impl<S> !UnwindSafe for Decoder<S>",1,["actix_http::encoding::decoder::Decoder"]],["impl<S> UnwindSafe for BodyStream<S>
where\n S: UnwindSafe,
",1,["actix_http::body::body_stream::BodyStream"]],["impl<S> UnwindSafe for SizedStream<S>
where\n S: UnwindSafe,
",1,["actix_http::body::sized_stream::SizedStream"]],["impl<S, T> !UnwindSafe for Dispatcher<S, T>",1,["actix_http::ws::dispatcher::Dispatcher"]],["impl<T> UnwindSafe for Message<T>
where\n T: UnwindSafe,
",1,["actix_http::h1::Message"]],["impl<T> UnwindSafe for QualityItem<T>
where\n T: UnwindSafe,
",1,["actix_http::header::shared::quality_item::QualityItem"]],["impl<T> UnwindSafe for Message<T>
where\n T: RefUnwindSafe,
",1,["actix_http::message::Message"]],["impl<T, B> !UnwindSafe for SendResponse<T, B>",1,["actix_http::h1::utils::SendResponse"]],["impl<T, S, B> !UnwindSafe for H2Service<T, S, B>",1,["actix_http::h2::service::H2Service"]],["impl<T, S, B, X = ExpectHandler, U = UpgradeHandler> !UnwindSafe for H1Service<T, S, B, X, U>",1,["actix_http::h1::service::H1Service"]],["impl<T, S, B, X = ExpectHandler, U = UpgradeHandler> !UnwindSafe for HttpService<T, S, B, X, U>",1,["actix_http::service::HttpService"]],["impl<T, S, B, X, U> !UnwindSafe for Dispatcher<T, S, B, X, U>",1,["actix_http::h1::dispatcher::Dispatcher"]],["impl<T, S, B, X, U> !UnwindSafe for Dispatcher<T, S, B, X, U>",1,["actix_http::h2::dispatcher::Dispatcher"]],["impl<T, S, X = ExpectHandler, U = UpgradeHandler> !UnwindSafe for HttpServiceBuilder<T, S, X, U>",1,["actix_http::builder::HttpServiceBuilder"]]], +"actix_http_test":[["impl !UnwindSafe for TestServer",1,["actix_http_test::TestServer"]]], +"actix_multipart":[["impl !UnwindSafe for MultipartError",1,["actix_multipart::error::MultipartError"]],["impl !UnwindSafe for JsonFieldError",1,["actix_multipart::form::json::JsonFieldError"]],["impl !UnwindSafe for TempFileError",1,["actix_multipart::form::tempfile::TempFileError"]],["impl !UnwindSafe for JsonConfig",1,["actix_multipart::form::json::JsonConfig"]],["impl !UnwindSafe for MultipartFormConfig",1,["actix_multipart::form::MultipartFormConfig"]],["impl !UnwindSafe for TempFileConfig",1,["actix_multipart::form::tempfile::TempFileConfig"]],["impl !UnwindSafe for TextConfig",1,["actix_multipart::form::text::TextConfig"]],["impl !UnwindSafe for Field",1,["actix_multipart::server::Field"]],["impl !UnwindSafe for Multipart",1,["actix_multipart::server::Multipart"]],["impl UnwindSafe for TextError",1,["actix_multipart::form::text::TextError"]],["impl UnwindSafe for Bytes",1,["actix_multipart::form::bytes::Bytes"]],["impl UnwindSafe for Limits",1,["actix_multipart::form::Limits"]],["impl UnwindSafe for TempFile",1,["actix_multipart::form::tempfile::TempFile"]],["impl<T> UnwindSafe for Json<T>
where\n T: UnwindSafe,
",1,["actix_multipart::form::json::Json"]],["impl<T> UnwindSafe for MultipartForm<T>
where\n T: UnwindSafe,
",1,["actix_multipart::form::MultipartForm"]],["impl<T> UnwindSafe for Text<T>
where\n T: UnwindSafe,
",1,["actix_multipart::form::text::Text"]]], +"actix_router":[["impl UnwindSafe for Patterns",1,["actix_router::pattern::Patterns"]],["impl UnwindSafe for Quoter",1,["actix_router::quoter::Quoter"]],["impl UnwindSafe for ResourceDef",1,["actix_router::resource::ResourceDef"]],["impl UnwindSafe for ResourceId",1,["actix_router::router::ResourceId"]],["impl UnwindSafe for Url",1,["actix_router::url::Url"]],["impl<'de, T> UnwindSafe for PathDeserializer<'de, T>
where\n T: RefUnwindSafe,
",1,["actix_router::de::PathDeserializer"]],["impl<T> UnwindSafe for Path<T>
where\n T: UnwindSafe,
",1,["actix_router::path::Path"]],["impl<T, U> UnwindSafe for Router<T, U>
where\n T: UnwindSafe,\n U: UnwindSafe,
",1,["actix_router::router::Router"]],["impl<T, U> UnwindSafe for RouterBuilder<T, U>
where\n T: UnwindSafe,\n U: UnwindSafe,
",1,["actix_router::router::RouterBuilder"]]], +"actix_test":[["impl !UnwindSafe for TestServer",1,["actix_test::TestServer"]],["impl !UnwindSafe for TestServerConfig",1,["actix_test::TestServerConfig"]]], +"actix_web":[["impl !UnwindSafe for JsonPayloadError",1,["actix_web::error::JsonPayloadError"]],["impl !UnwindSafe for ReadlinesError",1,["actix_web::error::ReadlinesError"]],["impl !UnwindSafe for UrlencodedError",1,["actix_web::error::UrlencodedError"]],["impl !UnwindSafe for AppService",1,["actix_web::config::AppService"]],["impl !UnwindSafe for ResourceMap",1,["actix_web::rmap::ResourceMap"]],["impl !UnwindSafe for ServiceRequest",1,["actix_web::service::ServiceRequest"]],["impl !UnwindSafe for WebService",1,["actix_web::service::WebService"]],["impl !UnwindSafe for Error",1,["actix_web::error::error::Error"]],["impl !UnwindSafe for AllGuard",1,["actix_web::guard::AllGuard"]],["impl !UnwindSafe for AnyGuard",1,["actix_web::guard::AnyGuard"]],["impl !UnwindSafe for Logger",1,["actix_web::middleware::logger::Logger"]],["impl !UnwindSafe for HttpRequest",1,["actix_web::request::HttpRequest"]],["impl !UnwindSafe for HttpResponseBuilder",1,["actix_web::response::builder::HttpResponseBuilder"]],["impl !UnwindSafe for Route",1,["actix_web::route::Route"]],["impl !UnwindSafe for TestRequest",1,["actix_web::test::test_request::TestRequest"]],["impl !UnwindSafe for FormConfig",1,["actix_web::types::form::FormConfig"]],["impl !UnwindSafe for JsonConfig",1,["actix_web::types::json::JsonConfig"]],["impl !UnwindSafe for PathConfig",1,["actix_web::types::path::PathConfig"]],["impl !UnwindSafe for Payload",1,["actix_web::types::payload::Payload"]],["impl !UnwindSafe for QueryConfig",1,["actix_web::types::query::QueryConfig"]],["impl !UnwindSafe for ServiceConfig",1,["actix_web::config::ServiceConfig"]],["impl UnwindSafe for PathError",1,["actix_web::error::PathError"]],["impl UnwindSafe for QueryPayloadError",1,["actix_web::error::QueryPayloadError"]],["impl UnwindSafe for UrlGenerationError",1,["actix_web::error::UrlGenerationError"]],["impl UnwindSafe for ByteRangeSpec",1,["actix_web::http::header::range::ByteRangeSpec"]],["impl UnwindSafe for CacheDirective",1,["actix_web::http::header::cache_control::CacheDirective"]],["impl UnwindSafe for ContentRangeSpec",1,["actix_web::http::header::content_range::ContentRangeSpec"]],["impl UnwindSafe for DispositionParam",1,["actix_web::http::header::content_disposition::DispositionParam"]],["impl UnwindSafe for DispositionType",1,["actix_web::http::header::content_disposition::DispositionType"]],["impl UnwindSafe for Encoding",1,["actix_web::http::header::encoding::Encoding"]],["impl UnwindSafe for IfMatch",1,["actix_web::http::header::if_match::IfMatch"]],["impl UnwindSafe for IfNoneMatch",1,["actix_web::http::header::if_none_match::IfNoneMatch"]],["impl UnwindSafe for IfRange",1,["actix_web::http::header::if_range::IfRange"]],["impl UnwindSafe for Range",1,["actix_web::http::header::range::Range"]],["impl UnwindSafe for TrailingSlash",1,["actix_web::middleware::normalize::TrailingSlash"]],["impl UnwindSafe for AppConfig",1,["actix_web::config::AppConfig"]],["impl UnwindSafe for ConnectionInfo",1,["actix_web::info::ConnectionInfo"]],["impl UnwindSafe for PeerAddr",1,["actix_web::info::PeerAddr"]],["impl UnwindSafe for BlockingError",1,["actix_web::error::BlockingError"]],["impl UnwindSafe for Acceptable",1,["actix_web::guard::acceptable::Acceptable"]],["impl UnwindSafe for Accept",1,["actix_web::http::header::accept::Accept"]],["impl UnwindSafe for AcceptCharset",1,["actix_web::http::header::accept_charset::AcceptCharset"]],["impl UnwindSafe for AcceptEncoding",1,["actix_web::http::header::accept_encoding::AcceptEncoding"]],["impl UnwindSafe for AcceptLanguage",1,["actix_web::http::header::accept_language::AcceptLanguage"]],["impl UnwindSafe for Allow",1,["actix_web::http::header::allow::Allow"]],["impl UnwindSafe for CacheControl",1,["actix_web::http::header::cache_control::CacheControl"]],["impl UnwindSafe for ContentDisposition",1,["actix_web::http::header::content_disposition::ContentDisposition"]],["impl UnwindSafe for ContentLanguage",1,["actix_web::http::header::content_language::ContentLanguage"]],["impl UnwindSafe for ContentLength",1,["actix_web::http::header::content_length::ContentLength"]],["impl UnwindSafe for ContentRange",1,["actix_web::http::header::content_range::ContentRange"]],["impl UnwindSafe for ContentType",1,["actix_web::http::header::content_type::ContentType"]],["impl UnwindSafe for Date",1,["actix_web::http::header::date::Date"]],["impl UnwindSafe for ETag",1,["actix_web::http::header::etag::ETag"]],["impl UnwindSafe for EntityTag",1,["actix_web::http::header::entity::EntityTag"]],["impl UnwindSafe for Expires",1,["actix_web::http::header::expires::Expires"]],["impl UnwindSafe for IfModifiedSince",1,["actix_web::http::header::if_modified_since::IfModifiedSince"]],["impl UnwindSafe for IfUnmodifiedSince",1,["actix_web::http::header::if_unmodified_since::IfUnmodifiedSince"]],["impl UnwindSafe for LastModified",1,["actix_web::http::header::last_modified::LastModified"]],["impl UnwindSafe for Compress",1,["actix_web::middleware::compress::Compress"]],["impl UnwindSafe for DefaultHeaders",1,["actix_web::middleware::default_headers::DefaultHeaders"]],["impl UnwindSafe for NormalizePath",1,["actix_web::middleware::normalize::NormalizePath"]],["impl UnwindSafe for PayloadConfig",1,["actix_web::types::payload::PayloadConfig"]],["impl UnwindSafe for Redirect",1,["actix_web::redirect::Redirect"]],["impl<'a> !UnwindSafe for GuardContext<'a>",1,["actix_web::guard::GuardContext"]],["impl<B = BoxBody> !UnwindSafe for ServiceResponse<B>",1,["actix_web::service::ServiceResponse"]],["impl<B = BoxBody> !UnwindSafe for HttpResponse<B>",1,["actix_web::response::response::HttpResponse"]],["impl<B> !UnwindSafe for ErrorHandlerResponse<B>",1,["actix_web::middleware::err_handlers::ErrorHandlerResponse"]],["impl<B> !UnwindSafe for ErrorHandlers<B>",1,["actix_web::middleware::err_handlers::ErrorHandlers"]],["impl<F, I, S, B> !UnwindSafe for HttpServer<F, I, S, B>",1,["actix_web::server::HttpServer"]],["impl<G> UnwindSafe for Not<G>
where\n G: UnwindSafe,
",1,["actix_web::guard::Not"]],["impl<L, R> UnwindSafe for Either<L, R>
where\n L: UnwindSafe,\n R: UnwindSafe,
",1,["actix_web::types::either::Either"]],["impl<R> UnwindSafe for CustomizeResponder<R>
where\n R: UnwindSafe,
",1,["actix_web::response::customize_responder::CustomizeResponder"]],["impl<T = ResourceEndpoint> !UnwindSafe for Resource<T>",1,["actix_web::resource::Resource"]],["impl<T = ScopeEndpoint> !UnwindSafe for Scope<T>",1,["actix_web::scope::Scope"]],["impl<T> !UnwindSafe for JsonBody<T>",1,["actix_web::types::json::JsonBody"]],["impl<T> !UnwindSafe for Readlines<T>",1,["actix_web::types::readlines::Readlines"]],["impl<T> !UnwindSafe for UrlEncoded<T>",1,["actix_web::types::form::UrlEncoded"]],["impl<T> !UnwindSafe for InternalError<T>",1,["actix_web::error::internal::InternalError"]],["impl<T> !UnwindSafe for App<T>",1,["actix_web::app::App"]],["impl<T> UnwindSafe for Preference<T>
where\n T: UnwindSafe,
",1,["actix_web::http::header::preference::Preference"]],["impl<T> UnwindSafe for Compat<T>
where\n T: UnwindSafe,
",1,["actix_web::middleware::compat::Compat"]],["impl<T> UnwindSafe for Condition<T>
where\n T: UnwindSafe,
",1,["actix_web::middleware::condition::Condition"]],["impl<T> UnwindSafe for Data<T>
where\n T: RefUnwindSafe + ?Sized,
",1,["actix_web::data::Data"]],["impl<T> UnwindSafe for Form<T>
where\n T: UnwindSafe,
",1,["actix_web::types::form::Form"]],["impl<T> UnwindSafe for Header<T>
where\n T: UnwindSafe,
",1,["actix_web::types::header::Header"]],["impl<T> UnwindSafe for Json<T>
where\n T: UnwindSafe,
",1,["actix_web::types::json::Json"]],["impl<T> UnwindSafe for Path<T>
where\n T: UnwindSafe,
",1,["actix_web::types::path::Path"]],["impl<T> UnwindSafe for Query<T>
where\n T: UnwindSafe,
",1,["actix_web::types::query::Query"]],["impl<T> UnwindSafe for ReqData<T>
where\n T: UnwindSafe,
",1,["actix_web::request_data::ReqData"]]], +"actix_web_actors":[["impl<'a, A, T> !UnwindSafe for WsResponseBuilder<'a, A, T>",1,["actix_web_actors::ws::WsResponseBuilder"]],["impl<A> !UnwindSafe for HttpContext<A>",1,["actix_web_actors::context::HttpContext"]],["impl<A> !UnwindSafe for WebsocketContext<A>",1,["actix_web_actors::ws::WebsocketContext"]]], +"awc":[["impl !UnwindSafe for ConnectRequest",1,["awc::connect::ConnectRequest"]],["impl !UnwindSafe for ConnectResponse",1,["awc::connect::ConnectResponse"]],["impl !UnwindSafe for SendClientRequest",1,["awc::sender::SendClientRequest"]],["impl !UnwindSafe for ConnectError",1,["awc::client::error::ConnectError"]],["impl !UnwindSafe for FreezeRequestError",1,["awc::client::error::FreezeRequestError"]],["impl !UnwindSafe for JsonPayloadError",1,["awc::error::JsonPayloadError"]],["impl !UnwindSafe for SendRequestError",1,["awc::client::error::SendRequestError"]],["impl !UnwindSafe for WsClientError",1,["awc::error::WsClientError"]],["impl !UnwindSafe for Client",1,["awc::client::Client"]],["impl !UnwindSafe for ClientRequest",1,["awc::request::ClientRequest"]],["impl !UnwindSafe for FrozenClientRequest",1,["awc::frozen::FrozenClientRequest"]],["impl !UnwindSafe for FrozenSendBuilder",1,["awc::frozen::FrozenSendBuilder"]],["impl !UnwindSafe for TestResponse",1,["awc::test::TestResponse"]],["impl !UnwindSafe for WebsocketsRequest",1,["awc::ws::WebsocketsRequest"]],["impl UnwindSafe for InvalidUrl",1,["awc::client::error::InvalidUrl"]],["impl UnwindSafe for Redirect",1,["awc::middleware::redirect::Redirect"]],["impl UnwindSafe for Connect",1,["awc::client::Connect"]],["impl<S = (), M = ()> !UnwindSafe for ClientBuilder<S, M>",1,["awc::builder::ClientBuilder"]],["impl<S = Pin<Box<dyn Stream<Item = Result<Bytes, PayloadError>>>>> !UnwindSafe for ClientResponse<S>",1,["awc::responses::response::ClientResponse"]],["impl<S> !UnwindSafe for ResponseBody<S>",1,["awc::responses::response_body::ResponseBody"]],["impl<S, T> !UnwindSafe for JsonBody<S, T>",1,["awc::responses::json_body::JsonBody"]],["impl<T> !UnwindSafe for Connector<T>",1,["awc::client::connector::Connector"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/str/traits/trait.FromStr.js b/trait.impl/core/str/traits/trait.FromStr.js new file mode 100644 index 000000000..65e7c74f6 --- /dev/null +++ b/trait.impl/core/str/traits/trait.FromStr.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"actix_http":[["impl FromStr for Charset"],["impl FromStr for ContentEncoding"],["impl FromStr for HttpDate"],["impl<T: FromStr> FromStr for QualityItem<T>"]], +"actix_web":[["impl FromStr for ByteRangeSpec"],["impl FromStr for CacheDirective"],["impl FromStr for ContentRangeSpec"],["impl FromStr for Encoding"],["impl FromStr for Range"],["impl FromStr for ContentLength"],["impl FromStr for EntityTag"],["impl<T: FromStr> FromStr for Preference<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/futures_core/stream/trait.Stream.js b/trait.impl/futures_core/stream/trait.Stream.js new file mode 100644 index 000000000..518191c82 --- /dev/null +++ b/trait.impl/futures_core/stream/trait.Stream.js @@ -0,0 +1,6 @@ +(function() {var implementors = { +"actix_http":[["impl Stream for Payload"],["impl Stream for Payload"],["impl<S> Stream for Payload<S>
where\n S: Stream<Item = Result<Bytes, PayloadError>>,
"],["impl<S> Stream for Decoder<S>
where\n S: Stream<Item = Result<Bytes, PayloadError>>,
"]], +"actix_multipart":[["impl Stream for Field"],["impl Stream for Multipart"]], +"actix_web":[["impl Stream for Payload"],["impl<T> Stream for Readlines<T>
where\n T: HttpMessage,\n T::Stream: Stream<Item = Result<Bytes, PayloadError>> + Unpin,
"]], +"awc":[["impl<S> Stream for ClientResponse<S>
where\n S: Stream<Item = Result<Bytes, PayloadError>> + Unpin,
"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/serde/de/trait.Deserialize.js b/trait.impl/serde/de/trait.Deserialize.js new file mode 100644 index 000000000..83915b4d8 --- /dev/null +++ b/trait.impl/serde/de/trait.Deserialize.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_web":[["impl<'de, T> Deserialize<'de> for Data<T>
where\n T: Deserialize<'de>,
"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/serde/de/trait.Deserializer.js b/trait.impl/serde/de/trait.Deserializer.js new file mode 100644 index 000000000..92e57752d --- /dev/null +++ b/trait.impl/serde/de/trait.Deserializer.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_router":[["impl<'de, T: ResourcePath + 'de> Deserializer<'de> for PathDeserializer<'de, T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/serde/ser/trait.Serialize.js b/trait.impl/serde/ser/trait.Serialize.js new file mode 100644 index 000000000..6f828f59b --- /dev/null +++ b/trait.impl/serde/ser/trait.Serialize.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_web":[["impl<T> Serialize for Data<T>
where\n T: Serialize,
"],["impl<T> Serialize for Form<T>
where\n T: Serialize,
"],["impl<T: Serialize> Serialize for Json<T>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/std/io/trait.Read.js b/trait.impl/std/io/trait.Read.js new file mode 100644 index 000000000..ccaeb5b97 --- /dev/null +++ b/trait.impl/std/io/trait.Read.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_http":[["impl Read for TestBuffer"],["impl Read for TestSeqBuffer"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/std/io/trait.Write.js b/trait.impl/std/io/trait.Write.js new file mode 100644 index 000000000..60780b93c --- /dev/null +++ b/trait.impl/std/io/trait.Write.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_http":[["impl Write for TestBuffer"],["impl Write for TestSeqBuffer"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/time/ext/instant/trait.InstantExt.js b/trait.impl/time/ext/instant/trait.InstantExt.js new file mode 100644 index 000000000..20e2e1061 --- /dev/null +++ b/trait.impl/time/ext/instant/trait.InstantExt.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_web":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/time/ext/numerical_duration/trait.NumericalDuration.js b/trait.impl/time/ext/numerical_duration/trait.NumericalDuration.js new file mode 100644 index 000000000..20e2e1061 --- /dev/null +++ b/trait.impl/time/ext/numerical_duration/trait.NumericalDuration.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_web":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/time/ext/numerical_std_duration/trait.NumericalStdDuration.js b/trait.impl/time/ext/numerical_std_duration/trait.NumericalStdDuration.js new file mode 100644 index 000000000..20e2e1061 --- /dev/null +++ b/trait.impl/time/ext/numerical_std_duration/trait.NumericalStdDuration.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_web":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/time/formatting/formattable/trait.Formattable.js b/trait.impl/time/formatting/formattable/trait.Formattable.js new file mode 100644 index 000000000..20e2e1061 --- /dev/null +++ b/trait.impl/time/formatting/formattable/trait.Formattable.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_web":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/time/parsing/parsable/trait.Parsable.js b/trait.impl/time/parsing/parsable/trait.Parsable.js new file mode 100644 index 000000000..20e2e1061 --- /dev/null +++ b/trait.impl/time/parsing/parsable/trait.Parsable.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_web":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/tokio/io/async_read/trait.AsyncRead.js b/trait.impl/tokio/io/async_read/trait.AsyncRead.js new file mode 100644 index 000000000..7d34f4f43 --- /dev/null +++ b/trait.impl/tokio/io/async_read/trait.AsyncRead.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_http":[["impl AsyncRead for TestBuffer"],["impl AsyncRead for TestSeqBuffer"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/tokio/io/async_write/trait.AsyncWrite.js b/trait.impl/tokio/io/async_write/trait.AsyncWrite.js new file mode 100644 index 000000000..b91d366cd --- /dev/null +++ b/trait.impl/tokio/io/async_write/trait.AsyncWrite.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_http":[["impl AsyncWrite for TestBuffer"],["impl AsyncWrite for TestSeqBuffer"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/tokio_util/codec/decoder/trait.Decoder.js b/trait.impl/tokio_util/codec/decoder/trait.Decoder.js new file mode 100644 index 000000000..962eeaef4 --- /dev/null +++ b/trait.impl/tokio_util/codec/decoder/trait.Decoder.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_http":[["impl Decoder for ClientCodec"],["impl Decoder for ClientPayloadCodec"],["impl Decoder for Codec"],["impl Decoder for Codec"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/tokio_util/codec/encoder/trait.Encoder.js b/trait.impl/tokio_util/codec/encoder/trait.Encoder.js new file mode 100644 index 000000000..d04545ac2 --- /dev/null +++ b/trait.impl/tokio_util/codec/encoder/trait.Encoder.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"actix_http":[["impl Encoder<Message<(RequestHeadType, BodySize)>> for ClientCodec"],["impl Encoder<Message<(Response<()>, BodySize)>> for Codec"],["impl Encoder<Message> for Codec"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/type.impl/alloc/boxed/struct.Box.js b/type.impl/alloc/boxed/struct.Box.js new file mode 100644 index 000000000..d19c0751b --- /dev/null +++ b/type.impl/alloc/boxed/struct.Box.js @@ -0,0 +1,3 @@ +(function() {var type_impls = { +"awc":[["
1.64.0 · source§

impl<T> AsFd for Box<T>
where\n T: AsFd + ?Sized,

source§

fn as_fd(&self) -> BorrowedFd<'_>

Borrows the file descriptor. Read more
","AsFd","awc::connect::BoxedSocket"],["
1.5.0 · source§

impl<T, A> AsMut<T> for Box<T, A>
where\n A: Allocator,\n T: ?Sized,

source§

fn as_mut(&mut self) -> &mut T

Converts this type into a mutable reference of the (usually inferred) input type.
","AsMut","awc::connect::BoxedSocket"],["
1.63.0 · source§

impl<T> AsRawFd for Box<T>
where\n T: AsRawFd,

source§

fn as_raw_fd(&self) -> i32

Extracts the raw file descriptor. Read more
","AsRawFd","awc::connect::BoxedSocket"],["
1.5.0 · source§

impl<T, A> AsRef<T> for Box<T, A>
where\n A: Allocator,\n T: ?Sized,

source§

fn as_ref(&self) -> &T

Converts this type into a shared reference of the (usually inferred) input type.
","AsRef","awc::connect::BoxedSocket"],["
§

impl<T> AsyncBufRead for Box<T>
where\n T: AsyncBufRead + Unpin + ?Sized,

§

fn poll_fill_buf(\n self: Pin<&mut Box<T>>,\n cx: &mut Context<'_>\n) -> Poll<Result<&[u8], Error>>

Attempt to return the contents of the internal buffer, filling it with more data\nfrom the inner reader if it is empty. Read more
§

fn consume(self: Pin<&mut Box<T>>, amt: usize)

Tells this buffer that amt bytes have been consumed from the buffer,\nso they should no longer be returned in calls to poll_read. Read more
","AsyncBufRead","awc::connect::BoxedSocket"],["
§

impl<T> AsyncBufRead for Box<T>
where\n T: AsyncBufRead + Unpin + ?Sized,

§

fn poll_fill_buf(\n self: Pin<&mut Box<T>>,\n cx: &mut Context<'_>\n) -> Poll<Result<&[u8], Error>>

Attempts to return the contents of the internal buffer, filling it with more data\nfrom the inner reader if it is empty. Read more
§

fn consume(self: Pin<&mut Box<T>>, amt: usize)

Tells this buffer that amt bytes have been consumed from the buffer,\nso they should no longer be returned in calls to poll_read. Read more
","AsyncBufRead","awc::connect::BoxedSocket"],["
source§

impl<Args, F, A> AsyncFn<Args> for Box<F, A>
where\n Args: Tuple,\n F: AsyncFn<Args> + ?Sized,\n A: Allocator,

source§

extern "rust-call" fn async_call(\n &self,\n args: Args\n) -> <Box<F, A> as AsyncFnMut<Args>>::CallRefFuture<'_>

🔬This is a nightly-only experimental API. (async_fn_traits)
Call the AsyncFn, returning a future which may borrow from the called closure.
","AsyncFn","awc::connect::BoxedSocket"],["
source§

impl<Args, F, A> AsyncFnMut<Args> for Box<F, A>
where\n Args: Tuple,\n F: AsyncFnMut<Args> + ?Sized,\n A: Allocator,

§

type CallRefFuture<'a> = <F as AsyncFnMut<Args>>::CallRefFuture<'a>\nwhere\n Box<F, A>: 'a

🔬This is a nightly-only experimental API. (async_fn_traits)
source§

extern "rust-call" fn async_call_mut(\n &mut self,\n args: Args\n) -> <Box<F, A> as AsyncFnMut<Args>>::CallRefFuture<'_>

🔬This is a nightly-only experimental API. (async_fn_traits)
Call the AsyncFnMut, returning a future which may borrow from the called closure.
","AsyncFnMut","awc::connect::BoxedSocket"],["
source§

impl<Args, F, A> AsyncFnOnce<Args> for Box<F, A>
where\n Args: Tuple,\n F: AsyncFnOnce<Args> + ?Sized,\n A: Allocator,

§

type Output = <F as AsyncFnOnce<Args>>::Output

🔬This is a nightly-only experimental API. (async_fn_traits)
Output type of the called closure’s future.
§

type CallOnceFuture = <F as AsyncFnOnce<Args>>::CallOnceFuture

🔬This is a nightly-only experimental API. (async_fn_traits)
Future returned by AsyncFnOnce::async_call_once.
source§

extern "rust-call" fn async_call_once(\n self,\n args: Args\n) -> <Box<F, A> as AsyncFnOnce<Args>>::CallOnceFuture

🔬This is a nightly-only experimental API. (async_fn_traits)
Call the AsyncFnOnce, returning a future which may move out of the called closure.
","AsyncFnOnce","awc::connect::BoxedSocket"],["
source§

impl<S> AsyncIterator for Box<S>
where\n S: AsyncIterator + Unpin + ?Sized,

§

type Item = <S as AsyncIterator>::Item

🔬This is a nightly-only experimental API. (async_iterator)
The type of items yielded by the async iterator.
source§

fn poll_next(\n self: Pin<&mut Box<S>>,\n cx: &mut Context<'_>\n) -> Poll<Option<<Box<S> as AsyncIterator>::Item>>

🔬This is a nightly-only experimental API. (async_iterator)
Attempt to pull out the next value of this async iterator, registering the\ncurrent task for wakeup if the value is not yet available, and returning\nNone if the async iterator is exhausted. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

🔬This is a nightly-only experimental API. (async_iterator)
Returns the bounds on the remaining length of the async iterator. Read more
","AsyncIterator","awc::connect::BoxedSocket"],["
§

impl<T> AsyncRead for Box<T>
where\n T: AsyncRead + Unpin + ?Sized,

§

fn poll_read(\n self: Pin<&mut Box<T>>,\n cx: &mut Context<'_>,\n buf: &mut ReadBuf<'_>\n) -> Poll<Result<(), Error>>

Attempts to read from the AsyncRead into buf. Read more
","AsyncRead","awc::connect::BoxedSocket"],["
§

impl<T> AsyncRead for Box<T>
where\n T: AsyncRead + Unpin + ?Sized,

§

fn poll_read(\n self: Pin<&mut Box<T>>,\n cx: &mut Context<'_>,\n buf: &mut [u8]\n) -> Poll<Result<usize, Error>>

Attempt to read from the AsyncRead into buf. Read more
§

fn poll_read_vectored(\n self: Pin<&mut Box<T>>,\n cx: &mut Context<'_>,\n bufs: &mut [IoSliceMut<'_>]\n) -> Poll<Result<usize, Error>>

Attempt to read from the AsyncRead into bufs using vectored\nIO operations. Read more
","AsyncRead","awc::connect::BoxedSocket"],["
§

impl<T> AsyncSeek for Box<T>
where\n T: AsyncSeek + Unpin + ?Sized,

§

fn poll_seek(\n self: Pin<&mut Box<T>>,\n cx: &mut Context<'_>,\n pos: SeekFrom\n) -> Poll<Result<u64, Error>>

Attempt to seek to an offset, in bytes, in a stream. Read more
","AsyncSeek","awc::connect::BoxedSocket"],["
§

impl<T> AsyncSeek for Box<T>
where\n T: AsyncSeek + Unpin + ?Sized,

§

fn start_seek(self: Pin<&mut Box<T>>, pos: SeekFrom) -> Result<(), Error>

Attempts to seek to an offset, in bytes, in a stream. Read more
§

fn poll_complete(\n self: Pin<&mut Box<T>>,\n cx: &mut Context<'_>\n) -> Poll<Result<u64, Error>>

Waits for a seek operation to complete. Read more
","AsyncSeek","awc::connect::BoxedSocket"],["
§

impl<T> AsyncWrite for Box<T>
where\n T: AsyncWrite + Unpin + ?Sized,

§

fn poll_write(\n self: Pin<&mut Box<T>>,\n cx: &mut Context<'_>,\n buf: &[u8]\n) -> Poll<Result<usize, Error>>

Attempt to write bytes from buf into the object. Read more
§

fn poll_write_vectored(\n self: Pin<&mut Box<T>>,\n cx: &mut Context<'_>,\n bufs: &[IoSlice<'_>]\n) -> Poll<Result<usize, Error>>

Attempt to write bytes from bufs into the object using vectored\nIO operations. Read more
§

fn poll_flush(\n self: Pin<&mut Box<T>>,\n cx: &mut Context<'_>\n) -> Poll<Result<(), Error>>

Attempt to flush the object, ensuring that any buffered data reach\ntheir destination. Read more
§

fn poll_close(\n self: Pin<&mut Box<T>>,\n cx: &mut Context<'_>\n) -> Poll<Result<(), Error>>

Attempt to close the object. Read more
","AsyncWrite","awc::connect::BoxedSocket"],["
§

impl<T> AsyncWrite for Box<T>
where\n T: AsyncWrite + Unpin + ?Sized,

§

fn poll_write(\n self: Pin<&mut Box<T>>,\n cx: &mut Context<'_>,\n buf: &[u8]\n) -> Poll<Result<usize, Error>>

Attempt to write bytes from buf into the object. Read more
§

fn poll_write_vectored(\n self: Pin<&mut Box<T>>,\n cx: &mut Context<'_>,\n bufs: &[IoSlice<'_>]\n) -> Poll<Result<usize, Error>>

Like poll_write, except that it writes from a slice of buffers. Read more
§

fn is_write_vectored(&self) -> bool

Determines if this writer has an efficient poll_write_vectored\nimplementation. Read more
§

fn poll_flush(\n self: Pin<&mut Box<T>>,\n cx: &mut Context<'_>\n) -> Poll<Result<(), Error>>

Attempts to flush the object, ensuring that any buffered data reach\ntheir destination. Read more
§

fn poll_shutdown(\n self: Pin<&mut Box<T>>,\n cx: &mut Context<'_>\n) -> Poll<Result<(), Error>>

Initiates or attempts to shut down this writer, returning success when\nthe I/O connection has completely shut down. Read more
","AsyncWrite","awc::connect::BoxedSocket"],["
1.1.0 · source§

impl<T, A> Borrow<T> for Box<T, A>
where\n A: Allocator,\n T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
","Borrow","awc::connect::BoxedSocket"],["
1.1.0 · source§

impl<T, A> BorrowMut<T> for Box<T, A>
where\n A: Allocator,\n T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
","BorrowMut","awc::connect::BoxedSocket"],["
source§

impl<T> Box<T>

1.0.0 · source

pub fn new(x: T) -> Box<T>

Available on non-no_global_oom_handling only.

Allocates memory on the heap and then places x into it.

\n

This doesn’t actually allocate if T is zero-sized.

\n
§Examples
\n
let five = Box::new(5);
\n
source

pub fn new_uninit() -> Box<MaybeUninit<T>>

🔬This is a nightly-only experimental API. (new_uninit)
Available on non-no_global_oom_handling only.

Constructs a new box with uninitialized contents.

\n
§Examples
\n
#![feature(new_uninit)]\n\nlet mut five = Box::<u32>::new_uninit();\n\nlet five = unsafe {\n    // Deferred initialization:\n    five.as_mut_ptr().write(5);\n\n    five.assume_init()\n};\n\nassert_eq!(*five, 5)
\n
source

pub fn new_zeroed() -> Box<MaybeUninit<T>>

🔬This is a nightly-only experimental API. (new_uninit)
Available on non-no_global_oom_handling only.

Constructs a new Box with uninitialized contents, with the memory\nbeing filled with 0 bytes.

\n

See MaybeUninit::zeroed for examples of correct and incorrect usage\nof this method.

\n
§Examples
\n
#![feature(new_uninit)]\n\nlet zero = Box::<u32>::new_zeroed();\nlet zero = unsafe { zero.assume_init() };\n\nassert_eq!(*zero, 0)
\n
1.33.0 · source

pub fn pin(x: T) -> Pin<Box<T>>

Available on non-no_global_oom_handling only.

Constructs a new Pin<Box<T>>. If T does not implement Unpin, then\nx will be pinned in memory and unable to be moved.

\n

Constructing and pinning of the Box can also be done in two steps: Box::pin(x)\ndoes the same as Box::into_pin(Box::new(x)). Consider using\ninto_pin if you already have a Box<T>, or if you want to\nconstruct a (pinned) Box in a different way than with Box::new.

\n
source

pub fn try_new(x: T) -> Result<Box<T>, AllocError>

🔬This is a nightly-only experimental API. (allocator_api)

Allocates memory on the heap then places x into it,\nreturning an error if the allocation fails

\n

This doesn’t actually allocate if T is zero-sized.

\n
§Examples
\n
#![feature(allocator_api)]\n\nlet five = Box::try_new(5)?;
\n
source

pub fn try_new_uninit() -> Result<Box<MaybeUninit<T>>, AllocError>

🔬This is a nightly-only experimental API. (allocator_api)

Constructs a new box with uninitialized contents on the heap,\nreturning an error if the allocation fails

\n
§Examples
\n
#![feature(allocator_api, new_uninit)]\n\nlet mut five = Box::<u32>::try_new_uninit()?;\n\nlet five = unsafe {\n    // Deferred initialization:\n    five.as_mut_ptr().write(5);\n\n    five.assume_init()\n};\n\nassert_eq!(*five, 5);
\n
source

pub fn try_new_zeroed() -> Result<Box<MaybeUninit<T>>, AllocError>

🔬This is a nightly-only experimental API. (allocator_api)

Constructs a new Box with uninitialized contents, with the memory\nbeing filled with 0 bytes on the heap

\n

See MaybeUninit::zeroed for examples of correct and incorrect usage\nof this method.

\n
§Examples
\n
#![feature(allocator_api, new_uninit)]\n\nlet zero = Box::<u32>::try_new_zeroed()?;\nlet zero = unsafe { zero.assume_init() };\n\nassert_eq!(*zero, 0);
\n
",0,"awc::connect::BoxedSocket"],["
source§

impl<T> Box<T>
where\n T: ?Sized,

1.4.0 · source

pub unsafe fn from_raw(raw: *mut T) -> Box<T>

Constructs a box from a raw pointer.

\n

After calling this function, the raw pointer is owned by the\nresulting Box. Specifically, the Box destructor will call\nthe destructor of T and free the allocated memory. For this\nto be safe, the memory must have been allocated in accordance\nwith the memory layout used by Box .

\n
§Safety
\n

This function is unsafe because improper use may lead to\nmemory problems. For example, a double-free may occur if the\nfunction is called twice on the same raw pointer.

\n

The safety conditions are described in the memory layout section.

\n
§Examples
\n

Recreate a Box which was previously converted to a raw pointer\nusing Box::into_raw:

\n\n
let x = Box::new(5);\nlet ptr = Box::into_raw(x);\nlet x = unsafe { Box::from_raw(ptr) };
\n

Manually create a Box from scratch by using the global allocator:

\n\n
use std::alloc::{alloc, Layout};\n\nunsafe {\n    let ptr = alloc(Layout::new::<i32>()) as *mut i32;\n    // In general .write is required to avoid attempting to destruct\n    // the (uninitialized) previous contents of `ptr`, though for this\n    // simple example `*ptr = 5` would have worked as well.\n    ptr.write(5);\n    let x = Box::from_raw(ptr);\n}
\n
",0,"awc::connect::BoxedSocket"],["
source§

impl<T, A> Box<T, A>
where\n A: Allocator,

source

pub fn new_in(x: T, alloc: A) -> Box<T, A>
where\n A: Allocator,

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Allocates memory in the given allocator then places x into it.

\n

This doesn’t actually allocate if T is zero-sized.

\n
§Examples
\n
#![feature(allocator_api)]\n\nuse std::alloc::System;\n\nlet five = Box::new_in(5, System);
\n
source

pub fn try_new_in(x: T, alloc: A) -> Result<Box<T, A>, AllocError>
where\n A: Allocator,

🔬This is a nightly-only experimental API. (allocator_api)

Allocates memory in the given allocator then places x into it,\nreturning an error if the allocation fails

\n

This doesn’t actually allocate if T is zero-sized.

\n
§Examples
\n
#![feature(allocator_api)]\n\nuse std::alloc::System;\n\nlet five = Box::try_new_in(5, System)?;
\n
source

pub fn new_uninit_in(alloc: A) -> Box<MaybeUninit<T>, A>
where\n A: Allocator,

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Constructs a new box with uninitialized contents in the provided allocator.

\n
§Examples
\n
#![feature(allocator_api, new_uninit)]\n\nuse std::alloc::System;\n\nlet mut five = Box::<u32, _>::new_uninit_in(System);\n\nlet five = unsafe {\n    // Deferred initialization:\n    five.as_mut_ptr().write(5);\n\n    five.assume_init()\n};\n\nassert_eq!(*five, 5)
\n
source

pub fn try_new_uninit_in(alloc: A) -> Result<Box<MaybeUninit<T>, A>, AllocError>
where\n A: Allocator,

🔬This is a nightly-only experimental API. (allocator_api)

Constructs a new box with uninitialized contents in the provided allocator,\nreturning an error if the allocation fails

\n
§Examples
\n
#![feature(allocator_api, new_uninit)]\n\nuse std::alloc::System;\n\nlet mut five = Box::<u32, _>::try_new_uninit_in(System)?;\n\nlet five = unsafe {\n    // Deferred initialization:\n    five.as_mut_ptr().write(5);\n\n    five.assume_init()\n};\n\nassert_eq!(*five, 5);
\n
source

pub fn new_zeroed_in(alloc: A) -> Box<MaybeUninit<T>, A>
where\n A: Allocator,

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Constructs a new Box with uninitialized contents, with the memory\nbeing filled with 0 bytes in the provided allocator.

\n

See MaybeUninit::zeroed for examples of correct and incorrect usage\nof this method.

\n
§Examples
\n
#![feature(allocator_api, new_uninit)]\n\nuse std::alloc::System;\n\nlet zero = Box::<u32, _>::new_zeroed_in(System);\nlet zero = unsafe { zero.assume_init() };\n\nassert_eq!(*zero, 0)
\n
source

pub fn try_new_zeroed_in(alloc: A) -> Result<Box<MaybeUninit<T>, A>, AllocError>
where\n A: Allocator,

🔬This is a nightly-only experimental API. (allocator_api)

Constructs a new Box with uninitialized contents, with the memory\nbeing filled with 0 bytes in the provided allocator,\nreturning an error if the allocation fails,

\n

See MaybeUninit::zeroed for examples of correct and incorrect usage\nof this method.

\n
§Examples
\n
#![feature(allocator_api, new_uninit)]\n\nuse std::alloc::System;\n\nlet zero = Box::<u32, _>::try_new_zeroed_in(System)?;\nlet zero = unsafe { zero.assume_init() };\n\nassert_eq!(*zero, 0);
\n
source

pub fn pin_in(x: T, alloc: A) -> Pin<Box<T, A>>
where\n A: 'static + Allocator,

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Constructs a new Pin<Box<T, A>>. If T does not implement Unpin, then\nx will be pinned in memory and unable to be moved.

\n

Constructing and pinning of the Box can also be done in two steps: Box::pin_in(x, alloc)\ndoes the same as Box::into_pin(Box::new_in(x, alloc)). Consider using\ninto_pin if you already have a Box<T, A>, or if you want to\nconstruct a (pinned) Box in a different way than with Box::new_in.

\n
source

pub fn into_boxed_slice(boxed: Box<T, A>) -> Box<[T], A>

🔬This is a nightly-only experimental API. (box_into_boxed_slice)

Converts a Box<T> into a Box<[T]>

\n

This conversion does not allocate on the heap and happens in place.

\n
source

pub fn into_inner(boxed: Box<T, A>) -> T

🔬This is a nightly-only experimental API. (box_into_inner)

Consumes the Box, returning the wrapped value.

\n
§Examples
\n
#![feature(box_into_inner)]\n\nlet c = Box::new(5);\n\nassert_eq!(Box::into_inner(c), 5);
\n
",0,"awc::connect::BoxedSocket"],["
source§

impl<T, A> Box<T, A>
where\n A: Allocator,\n T: ?Sized,

const: unstable · source

pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Box<T, A>

🔬This is a nightly-only experimental API. (allocator_api)

Constructs a box from a raw pointer in the given allocator.

\n

After calling this function, the raw pointer is owned by the\nresulting Box. Specifically, the Box destructor will call\nthe destructor of T and free the allocated memory. For this\nto be safe, the memory must have been allocated in accordance\nwith the memory layout used by Box .

\n
§Safety
\n

This function is unsafe because improper use may lead to\nmemory problems. For example, a double-free may occur if the\nfunction is called twice on the same raw pointer.

\n
§Examples
\n

Recreate a Box which was previously converted to a raw pointer\nusing Box::into_raw_with_allocator:

\n\n
#![feature(allocator_api)]\n\nuse std::alloc::System;\n\nlet x = Box::new_in(5, System);\nlet (ptr, alloc) = Box::into_raw_with_allocator(x);\nlet x = unsafe { Box::from_raw_in(ptr, alloc) };
\n

Manually create a Box from scratch by using the system allocator:

\n\n
#![feature(allocator_api, slice_ptr_get)]\n\nuse std::alloc::{Allocator, Layout, System};\n\nunsafe {\n    let ptr = System.allocate(Layout::new::<i32>())?.as_mut_ptr() as *mut i32;\n    // In general .write is required to avoid attempting to destruct\n    // the (uninitialized) previous contents of `ptr`, though for this\n    // simple example `*ptr = 5` would have worked as well.\n    ptr.write(5);\n    let x = Box::from_raw_in(ptr, System);\n}
\n
1.4.0 · source

pub fn into_raw(b: Box<T, A>) -> *mut T

Consumes the Box, returning a wrapped raw pointer.

\n

The pointer will be properly aligned and non-null.

\n

After calling this function, the caller is responsible for the\nmemory previously managed by the Box. In particular, the\ncaller should properly destroy T and release the memory, taking\ninto account the memory layout used by Box. The easiest way to\ndo this is to convert the raw pointer back into a Box with the\nBox::from_raw function, allowing the Box destructor to perform\nthe cleanup.

\n

Note: this is an associated function, which means that you have\nto call it as Box::into_raw(b) instead of b.into_raw(). This\nis so that there is no conflict with a method on the inner type.

\n
§Examples
\n

Converting the raw pointer back into a Box with Box::from_raw\nfor automatic cleanup:

\n\n
let x = Box::new(String::from(\"Hello\"));\nlet ptr = Box::into_raw(x);\nlet x = unsafe { Box::from_raw(ptr) };
\n

Manual cleanup by explicitly running the destructor and deallocating\nthe memory:

\n\n
use std::alloc::{dealloc, Layout};\nuse std::ptr;\n\nlet x = Box::new(String::from(\"Hello\"));\nlet ptr = Box::into_raw(x);\nunsafe {\n    ptr::drop_in_place(ptr);\n    dealloc(ptr as *mut u8, Layout::new::<String>());\n}
\n

Note: This is equivalent to the following:

\n\n
let x = Box::new(String::from(\"Hello\"));\nlet ptr = Box::into_raw(x);\nunsafe {\n    drop(Box::from_raw(ptr));\n}
\n
source

pub fn into_raw_with_allocator(b: Box<T, A>) -> (*mut T, A)

🔬This is a nightly-only experimental API. (allocator_api)

Consumes the Box, returning a wrapped raw pointer and the allocator.

\n

The pointer will be properly aligned and non-null.

\n

After calling this function, the caller is responsible for the\nmemory previously managed by the Box. In particular, the\ncaller should properly destroy T and release the memory, taking\ninto account the memory layout used by Box. The easiest way to\ndo this is to convert the raw pointer back into a Box with the\nBox::from_raw_in function, allowing the Box destructor to perform\nthe cleanup.

\n

Note: this is an associated function, which means that you have\nto call it as Box::into_raw_with_allocator(b) instead of b.into_raw_with_allocator(). This\nis so that there is no conflict with a method on the inner type.

\n
§Examples
\n

Converting the raw pointer back into a Box with Box::from_raw_in\nfor automatic cleanup:

\n\n
#![feature(allocator_api)]\n\nuse std::alloc::System;\n\nlet x = Box::new_in(String::from(\"Hello\"), System);\nlet (ptr, alloc) = Box::into_raw_with_allocator(x);\nlet x = unsafe { Box::from_raw_in(ptr, alloc) };
\n

Manual cleanup by explicitly running the destructor and deallocating\nthe memory:

\n\n
#![feature(allocator_api)]\n\nuse std::alloc::{Allocator, Layout, System};\nuse std::ptr::{self, NonNull};\n\nlet x = Box::new_in(String::from(\"Hello\"), System);\nlet (ptr, alloc) = Box::into_raw_with_allocator(x);\nunsafe {\n    ptr::drop_in_place(ptr);\n    let non_null = NonNull::new_unchecked(ptr);\n    alloc.deallocate(non_null.cast(), Layout::new::<String>());\n}
\n
const: unstable · source

pub fn allocator(b: &Box<T, A>) -> &A

🔬This is a nightly-only experimental API. (allocator_api)

Returns a reference to the underlying allocator.

\n

Note: this is an associated function, which means that you have\nto call it as Box::allocator(&b) instead of b.allocator(). This\nis so that there is no conflict with a method on the inner type.

\n
1.26.0 · source

pub fn leak<'a>(b: Box<T, A>) -> &'a mut T
where\n A: 'a,

Consumes and leaks the Box, returning a mutable reference,\n&'a mut T. Note that the type T must outlive the chosen lifetime\n'a. If the type has only static references, or none at all, then this\nmay be chosen to be 'static.

\n

This function is mainly useful for data that lives for the remainder of\nthe program’s life. Dropping the returned reference will cause a memory\nleak. If this is not acceptable, the reference should first be wrapped\nwith the Box::from_raw function producing a Box. This Box can\nthen be dropped which will properly destroy T and release the\nallocated memory.

\n

Note: this is an associated function, which means that you have\nto call it as Box::leak(b) instead of b.leak(). This\nis so that there is no conflict with a method on the inner type.

\n
§Examples
\n

Simple usage:

\n\n
let x = Box::new(41);\nlet static_ref: &'static mut usize = Box::leak(x);\n*static_ref += 1;\nassert_eq!(*static_ref, 42);
\n

Unsized data:

\n\n
let x = vec![1, 2, 3].into_boxed_slice();\nlet static_ref = Box::leak(x);\nstatic_ref[0] = 4;\nassert_eq!(*static_ref, [4, 2, 3]);
\n
1.63.0 (const: unstable) · source

pub fn into_pin(boxed: Box<T, A>) -> Pin<Box<T, A>>
where\n A: 'static,

Converts a Box<T> into a Pin<Box<T>>. If T does not implement Unpin, then\n*boxed will be pinned in memory and unable to be moved.

\n

This conversion does not allocate on the heap and happens in place.

\n

This is also available via From.

\n

Constructing and pinning a Box with Box::into_pin(Box::new(x))\ncan also be written more concisely using Box::pin(x).\nThis into_pin method is useful if you already have a Box<T>, or you are\nconstructing a (pinned) Box in a different way than with Box::new.

\n
§Notes
\n

It’s not recommended that crates add an impl like From<Box<T>> for Pin<T>,\nas it’ll introduce an ambiguity when calling Pin::from.\nA demonstration of such a poor impl is shown below.

\n\n
struct Foo; // A type defined in this crate.\nimpl From<Box<()>> for Pin<Foo> {\n    fn from(_: Box<()>) -> Pin<Foo> {\n        Pin::new(Foo)\n    }\n}\n\nlet foo = Box::new(());\nlet bar = Pin::from(foo);
\n
",0,"awc::connect::BoxedSocket"],["
§

impl<T> Buf for Box<T>
where\n T: Buf + ?Sized,

§

fn remaining(&self) -> usize

Returns the number of bytes between the current position and the end of\nthe buffer. Read more
§

fn chunk(&self) -> &[u8]

Returns a slice starting at the current position and of length between 0\nand Buf::remaining(). Note that this can return shorter slice (this allows\nnon-continuous internal representation). Read more
§

fn chunks_vectored<'b>(&'b self, dst: &mut [IoSlice<'b>]) -> usize

Available on crate feature std only.
Fills dst with potentially multiple slices starting at self’s\ncurrent position. Read more
§

fn advance(&mut self, cnt: usize)

Advance the internal cursor of the Buf Read more
§

fn has_remaining(&self) -> bool

Returns true if there are any more bytes to consume Read more
§

fn copy_to_slice(&mut self, dst: &mut [u8])

Copies bytes from self into dst. Read more
§

fn get_u8(&mut self) -> u8

Gets an unsigned 8 bit integer from self. Read more
§

fn get_i8(&mut self) -> i8

Gets a signed 8 bit integer from self. Read more
§

fn get_u16(&mut self) -> u16

Gets an unsigned 16 bit integer from self in big-endian byte order. Read more
§

fn get_u16_le(&mut self) -> u16

Gets an unsigned 16 bit integer from self in little-endian byte order. Read more
§

fn get_u16_ne(&mut self) -> u16

Gets an unsigned 16 bit integer from self in native-endian byte order. Read more
§

fn get_i16(&mut self) -> i16

Gets a signed 16 bit integer from self in big-endian byte order. Read more
§

fn get_i16_le(&mut self) -> i16

Gets a signed 16 bit integer from self in little-endian byte order. Read more
§

fn get_i16_ne(&mut self) -> i16

Gets a signed 16 bit integer from self in native-endian byte order. Read more
§

fn get_u32(&mut self) -> u32

Gets an unsigned 32 bit integer from self in the big-endian byte order. Read more
§

fn get_u32_le(&mut self) -> u32

Gets an unsigned 32 bit integer from self in the little-endian byte order. Read more
§

fn get_u32_ne(&mut self) -> u32

Gets an unsigned 32 bit integer from self in native-endian byte order. Read more
§

fn get_i32(&mut self) -> i32

Gets a signed 32 bit integer from self in big-endian byte order. Read more
§

fn get_i32_le(&mut self) -> i32

Gets a signed 32 bit integer from self in little-endian byte order. Read more
§

fn get_i32_ne(&mut self) -> i32

Gets a signed 32 bit integer from self in native-endian byte order. Read more
§

fn get_u64(&mut self) -> u64

Gets an unsigned 64 bit integer from self in big-endian byte order. Read more
§

fn get_u64_le(&mut self) -> u64

Gets an unsigned 64 bit integer from self in little-endian byte order. Read more
§

fn get_u64_ne(&mut self) -> u64

Gets an unsigned 64 bit integer from self in native-endian byte order. Read more
§

fn get_i64(&mut self) -> i64

Gets a signed 64 bit integer from self in big-endian byte order. Read more
§

fn get_i64_le(&mut self) -> i64

Gets a signed 64 bit integer from self in little-endian byte order. Read more
§

fn get_i64_ne(&mut self) -> i64

Gets a signed 64 bit integer from self in native-endian byte order. Read more
§

fn get_uint(&mut self, nbytes: usize) -> u64

Gets an unsigned n-byte integer from self in big-endian byte order. Read more
§

fn get_uint_le(&mut self, nbytes: usize) -> u64

Gets an unsigned n-byte integer from self in little-endian byte order. Read more
§

fn get_uint_ne(&mut self, nbytes: usize) -> u64

Gets an unsigned n-byte integer from self in native-endian byte order. Read more
§

fn get_int(&mut self, nbytes: usize) -> i64

Gets a signed n-byte integer from self in big-endian byte order. Read more
§

fn get_int_le(&mut self, nbytes: usize) -> i64

Gets a signed n-byte integer from self in little-endian byte order. Read more
§

fn get_int_ne(&mut self, nbytes: usize) -> i64

Gets a signed n-byte integer from self in native-endian byte order. Read more
§

fn copy_to_bytes(&mut self, len: usize) -> Bytes

Consumes len bytes inside self and returns new instance of Bytes\nwith this data. Read more
§

fn get_u128(&mut self) -> u128

Gets an unsigned 128 bit integer from self in big-endian byte order. Read more
§

fn get_u128_le(&mut self) -> u128

Gets an unsigned 128 bit integer from self in little-endian byte order. Read more
§

fn get_u128_ne(&mut self) -> u128

Gets an unsigned 128 bit integer from self in native-endian byte order. Read more
§

fn get_i128(&mut self) -> i128

Gets a signed 128 bit integer from self in big-endian byte order. Read more
§

fn get_i128_le(&mut self) -> i128

Gets a signed 128 bit integer from self in little-endian byte order. Read more
§

fn get_i128_ne(&mut self) -> i128

Gets a signed 128 bit integer from self in native-endian byte order. Read more
§

fn get_f32(&mut self) -> f32

Gets an IEEE754 single-precision (4 bytes) floating point number from\nself in big-endian byte order. Read more
§

fn get_f32_le(&mut self) -> f32

Gets an IEEE754 single-precision (4 bytes) floating point number from\nself in little-endian byte order. Read more
§

fn get_f32_ne(&mut self) -> f32

Gets an IEEE754 single-precision (4 bytes) floating point number from\nself in native-endian byte order. Read more
§

fn get_f64(&mut self) -> f64

Gets an IEEE754 double-precision (8 bytes) floating point number from\nself in big-endian byte order. Read more
§

fn get_f64_le(&mut self) -> f64

Gets an IEEE754 double-precision (8 bytes) floating point number from\nself in little-endian byte order. Read more
§

fn get_f64_ne(&mut self) -> f64

Gets an IEEE754 double-precision (8 bytes) floating point number from\nself in native-endian byte order. Read more
§

fn take(self, limit: usize) -> Take<Self>
where\n Self: Sized,

Creates an adaptor which will read at most limit bytes from self. Read more
§

fn chain<U>(self, next: U) -> Chain<Self, U>
where\n U: Buf,\n Self: Sized,

Creates an adaptor which will chain this buffer with another. Read more
§

fn reader(self) -> Reader<Self>
where\n Self: Sized,

Available on crate feature std only.
Creates an adaptor which implements the Read trait for self. Read more
","Buf","awc::connect::BoxedSocket"],["
§

impl<T> BufMut for Box<T>
where\n T: BufMut + ?Sized,

§

fn remaining_mut(&self) -> usize

Returns the number of bytes that can be written from the current\nposition until the end of the buffer is reached. Read more
§

fn chunk_mut(&mut self) -> &mut UninitSlice

Returns a mutable slice starting at the current BufMut position and of\nlength between 0 and BufMut::remaining_mut(). Note that this can be shorter than the\nwhole remainder of the buffer (this allows non-continuous implementation). Read more
§

unsafe fn advance_mut(&mut self, cnt: usize)

Advance the internal cursor of the BufMut Read more
§

fn put_slice(&mut self, src: &[u8])

Transfer bytes into self from src and advance the cursor by the\nnumber of bytes written. Read more
§

fn put_u8(&mut self, n: u8)

Writes an unsigned 8 bit integer to self. Read more
§

fn put_i8(&mut self, n: i8)

Writes a signed 8 bit integer to self. Read more
§

fn put_u16(&mut self, n: u16)

Writes an unsigned 16 bit integer to self in big-endian byte order. Read more
§

fn put_u16_le(&mut self, n: u16)

Writes an unsigned 16 bit integer to self in little-endian byte order. Read more
§

fn put_u16_ne(&mut self, n: u16)

Writes an unsigned 16 bit integer to self in native-endian byte order. Read more
§

fn put_i16(&mut self, n: i16)

Writes a signed 16 bit integer to self in big-endian byte order. Read more
§

fn put_i16_le(&mut self, n: i16)

Writes a signed 16 bit integer to self in little-endian byte order. Read more
§

fn put_i16_ne(&mut self, n: i16)

Writes a signed 16 bit integer to self in native-endian byte order. Read more
§

fn put_u32(&mut self, n: u32)

Writes an unsigned 32 bit integer to self in big-endian byte order. Read more
§

fn put_u32_le(&mut self, n: u32)

Writes an unsigned 32 bit integer to self in little-endian byte order. Read more
§

fn put_u32_ne(&mut self, n: u32)

Writes an unsigned 32 bit integer to self in native-endian byte order. Read more
§

fn put_i32(&mut self, n: i32)

Writes a signed 32 bit integer to self in big-endian byte order. Read more
§

fn put_i32_le(&mut self, n: i32)

Writes a signed 32 bit integer to self in little-endian byte order. Read more
§

fn put_i32_ne(&mut self, n: i32)

Writes a signed 32 bit integer to self in native-endian byte order. Read more
§

fn put_u64(&mut self, n: u64)

Writes an unsigned 64 bit integer to self in the big-endian byte order. Read more
§

fn put_u64_le(&mut self, n: u64)

Writes an unsigned 64 bit integer to self in little-endian byte order. Read more
§

fn put_u64_ne(&mut self, n: u64)

Writes an unsigned 64 bit integer to self in native-endian byte order. Read more
§

fn put_i64(&mut self, n: i64)

Writes a signed 64 bit integer to self in the big-endian byte order. Read more
§

fn put_i64_le(&mut self, n: i64)

Writes a signed 64 bit integer to self in little-endian byte order. Read more
§

fn put_i64_ne(&mut self, n: i64)

Writes a signed 64 bit integer to self in native-endian byte order. Read more
§

fn has_remaining_mut(&self) -> bool

Returns true if there is space in self for more bytes. Read more
§

fn put<T>(&mut self, src: T)
where\n T: Buf,\n Self: Sized,

Transfer bytes into self from src and advance the cursor by the\nnumber of bytes written. Read more
§

fn put_bytes(&mut self, val: u8, cnt: usize)

Put cnt bytes val into self. Read more
§

fn put_u128(&mut self, n: u128)

Writes an unsigned 128 bit integer to self in the big-endian byte order. Read more
§

fn put_u128_le(&mut self, n: u128)

Writes an unsigned 128 bit integer to self in little-endian byte order. Read more
§

fn put_u128_ne(&mut self, n: u128)

Writes an unsigned 128 bit integer to self in native-endian byte order. Read more
§

fn put_i128(&mut self, n: i128)

Writes a signed 128 bit integer to self in the big-endian byte order. Read more
§

fn put_i128_le(&mut self, n: i128)

Writes a signed 128 bit integer to self in little-endian byte order. Read more
§

fn put_i128_ne(&mut self, n: i128)

Writes a signed 128 bit integer to self in native-endian byte order. Read more
§

fn put_uint(&mut self, n: u64, nbytes: usize)

Writes an unsigned n-byte integer to self in big-endian byte order. Read more
§

fn put_uint_le(&mut self, n: u64, nbytes: usize)

Writes an unsigned n-byte integer to self in the little-endian byte order. Read more
§

fn put_uint_ne(&mut self, n: u64, nbytes: usize)

Writes an unsigned n-byte integer to self in the native-endian byte order. Read more
§

fn put_int(&mut self, n: i64, nbytes: usize)

Writes low nbytes of a signed integer to self in big-endian byte order. Read more
§

fn put_int_le(&mut self, n: i64, nbytes: usize)

Writes low nbytes of a signed integer to self in little-endian byte order. Read more
§

fn put_int_ne(&mut self, n: i64, nbytes: usize)

Writes low nbytes of a signed integer to self in native-endian byte order. Read more
§

fn put_f32(&mut self, n: f32)

Writes an IEEE754 single-precision (4 bytes) floating point number to\nself in big-endian byte order. Read more
§

fn put_f32_le(&mut self, n: f32)

Writes an IEEE754 single-precision (4 bytes) floating point number to\nself in little-endian byte order. Read more
§

fn put_f32_ne(&mut self, n: f32)

Writes an IEEE754 single-precision (4 bytes) floating point number to\nself in native-endian byte order. Read more
§

fn put_f64(&mut self, n: f64)

Writes an IEEE754 double-precision (8 bytes) floating point number to\nself in big-endian byte order. Read more
§

fn put_f64_le(&mut self, n: f64)

Writes an IEEE754 double-precision (8 bytes) floating point number to\nself in little-endian byte order. Read more
§

fn put_f64_ne(&mut self, n: f64)

Writes an IEEE754 double-precision (8 bytes) floating point number to\nself in native-endian byte order. Read more
§

fn limit(self, limit: usize) -> Limit<Self>
where\n Self: Sized,

Creates an adaptor which can write at most limit bytes to self. Read more
§

fn writer(self) -> Writer<Self>
where\n Self: Sized,

Available on crate feature std only.
Creates an adaptor which implements the Write trait for self. Read more
§

fn chain_mut<U>(self, next: U) -> Chain<Self, U>
where\n U: BufMut,\n Self: Sized,

Creates an adapter which will chain this buffer with another. Read more
","BufMut","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<B> BufRead for Box<B>
where\n B: BufRead + ?Sized,

source§

fn fill_buf(&mut self) -> Result<&[u8], Error>

Returns the contents of the internal buffer, filling it with more data\nfrom the inner reader if it is empty. Read more
source§

fn consume(&mut self, amt: usize)

Tells this buffer that amt bytes have been consumed from the buffer,\nso they should no longer be returned in calls to read. Read more
source§

fn read_until(&mut self, byte: u8, buf: &mut Vec<u8>) -> Result<usize, Error>

Read all bytes into buf until the delimiter byte or EOF is reached. Read more
source§

fn read_line(&mut self, buf: &mut String) -> Result<usize, Error>

Read all bytes until a newline (the 0xA byte) is reached, and append\nthem to the provided String buffer. Read more
source§

fn has_data_left(&mut self) -> Result<bool, Error>

🔬This is a nightly-only experimental API. (buf_read_has_data_left)
Check if the underlying Read has any data left to be read. Read more
source§

fn skip_until(&mut self, byte: u8) -> Result<usize, Error>

🔬This is a nightly-only experimental API. (bufread_skip_until)
Skip all bytes until the delimiter byte or EOF is reached. Read more
1.0.0 · source§

fn split(self, byte: u8) -> Split<Self>
where\n Self: Sized,

Returns an iterator over the contents of this reader split on the byte\nbyte. Read more
1.0.0 · source§

fn lines(self) -> Lines<Self>
where\n Self: Sized,

Returns an iterator over the lines of this reader. Read more
","BufRead","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<T, A> Clone for Box<T, A>
where\n T: Clone,\n A: Allocator + Clone,

Available on non-no_global_oom_handling only.
source§

fn clone(&self) -> Box<T, A>

Returns a new box with a clone() of this box’s contents.

\n
§Examples
\n
let x = Box::new(5);\nlet y = x.clone();\n\n// The value is the same\nassert_eq!(x, y);\n\n// But they are unique objects\nassert_ne!(&*x as *const i32, &*y as *const i32);
\n
source§

fn clone_from(&mut self, source: &Box<T, A>)

Copies source’s contents into self without creating a new allocation.

\n
§Examples
\n
let x = Box::new(5);\nlet mut y = Box::new(10);\nlet yp: *const i32 = &*y;\n\ny.clone_from(&x);\n\n// The value is the same\nassert_eq!(x, y);\n\n// And no allocation occurred\nassert_eq!(yp, &*y);
\n
","Clone","awc::connect::BoxedSocket"],["
source§

impl<G, R, A> Coroutine<R> for Box<G, A>
where\n G: Coroutine<R> + Unpin + ?Sized,\n A: Allocator,

§

type Yield = <G as Coroutine<R>>::Yield

🔬This is a nightly-only experimental API. (coroutine_trait)
The type of value this coroutine yields. Read more
§

type Return = <G as Coroutine<R>>::Return

🔬This is a nightly-only experimental API. (coroutine_trait)
The type of value this coroutine returns. Read more
source§

fn resume(\n self: Pin<&mut Box<G, A>>,\n arg: R\n) -> CoroutineState<<Box<G, A> as Coroutine<R>>::Yield, <Box<G, A> as Coroutine<R>>::Return>

🔬This is a nightly-only experimental API. (coroutine_trait)
Resumes the execution of this coroutine. Read more
","Coroutine","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<T, A> Debug for Box<T, A>
where\n T: Debug + ?Sized,\n A: Allocator,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
","Debug","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<T> Default for Box<T>
where\n T: Default,

Available on non-no_global_oom_handling only.
source§

fn default() -> Box<T>

Creates a Box<T>, with the Default value for T.

\n
","Default","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<T, A> Deref for Box<T, A>
where\n A: Allocator,\n T: ?Sized,

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &T

Dereferences the value.
","Deref","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<T, A> DerefMut for Box<T, A>
where\n A: Allocator,\n T: ?Sized,

source§

fn deref_mut(&mut self) -> &mut T

Mutably dereferences the value.
","DerefMut","awc::connect::BoxedSocket"],["
source§

impl<'de, T> Deserialize<'de> for Box<T>
where\n T: Deserialize<'de>,

Available on crate features std or alloc only.
source§

fn deserialize<D>(\n deserializer: D\n) -> Result<Box<T>, <D as Deserializer<'de>>::Error>
where\n D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
","Deserialize<'de>","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<T, A> Display for Box<T, A>
where\n T: Display + ?Sized,\n A: Allocator,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
","Display","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<I, A> DoubleEndedIterator for Box<I, A>
where\n I: DoubleEndedIterator + ?Sized,\n A: Allocator,

source§

fn next_back(&mut self) -> Option<<I as Iterator>::Item>

Removes and returns an element from the end of the iterator. Read more
source§

fn nth_back(&mut self, n: usize) -> Option<<I as Iterator>::Item>

Returns the nth element from the end of the iterator. Read more
source§

fn advance_back_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator from the back by n elements. Read more
1.27.0 · source§

fn try_rfold<B, F, R>(&mut self, init: B, f: F) -> R
where\n Self: Sized,\n F: FnMut(B, Self::Item) -> R,\n R: Try<Output = B>,

This is the reverse version of Iterator::try_fold(): it takes\nelements starting from the back of the iterator. Read more
1.27.0 · source§

fn rfold<B, F>(self, init: B, f: F) -> B
where\n Self: Sized,\n F: FnMut(B, Self::Item) -> B,

An iterator method that reduces the iterator’s elements to a single,\nfinal value, starting from the back. Read more
1.27.0 · source§

fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
where\n Self: Sized,\n P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator from the back that satisfies a predicate. Read more
","DoubleEndedIterator","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<T, A> Drop for Box<T, A>
where\n A: Allocator,\n T: ?Sized,

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
","Drop","awc::connect::BoxedSocket"],["
1.8.0 · source§

impl<T> Error for Box<T>
where\n T: Error,

source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
source§

fn provide<'b>(&'b self, request: &mut Request<'b>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
","Error","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<I, A> ExactSizeIterator for Box<I, A>
where\n I: ExactSizeIterator + ?Sized,\n A: Allocator,

source§

fn len(&self) -> usize

Returns the exact remaining length of the iterator. Read more
source§

fn is_empty(&self) -> bool

🔬This is a nightly-only experimental API. (exact_size_is_empty)
Returns true if the iterator is empty. Read more
","ExactSizeIterator","awc::connect::BoxedSocket"],["
1.35.0 · source§

impl<Args, F, A> Fn<Args> for Box<F, A>
where\n Args: Tuple,\n F: Fn<Args> + ?Sized,\n A: Allocator,

source§

extern "rust-call" fn call(\n &self,\n args: Args\n) -> <Box<F, A> as FnOnce<Args>>::Output

🔬This is a nightly-only experimental API. (fn_traits)
Performs the call operation.
","Fn","awc::connect::BoxedSocket"],["
1.35.0 · source§

impl<Args, F, A> FnMut<Args> for Box<F, A>
where\n Args: Tuple,\n F: FnMut<Args> + ?Sized,\n A: Allocator,

source§

extern "rust-call" fn call_mut(\n &mut self,\n args: Args\n) -> <Box<F, A> as FnOnce<Args>>::Output

🔬This is a nightly-only experimental API. (fn_traits)
Performs the call operation.
","FnMut","awc::connect::BoxedSocket"],["
1.35.0 · source§

impl<Args, F, A> FnOnce<Args> for Box<F, A>
where\n Args: Tuple,\n F: FnOnce<Args> + ?Sized,\n A: Allocator,

§

type Output = <F as FnOnce<Args>>::Output

The returned type after the call operator is used.
source§

extern "rust-call" fn call_once(\n self,\n args: Args\n) -> <Box<F, A> as FnOnce<Args>>::Output

🔬This is a nightly-only experimental API. (fn_traits)
Performs the call operation.
","FnOnce","awc::connect::BoxedSocket"],["
1.6.0 · source§

impl<T> From<T> for Box<T>

Available on non-no_global_oom_handling only.
source§

fn from(t: T) -> Box<T>

Converts a T into a Box<T>

\n

The conversion allocates on the heap and moves t\nfrom the stack into it.

\n
§Examples
\n
let x = 5;\nlet boxed = Box::new(5);\n\nassert_eq!(Box::from(x), boxed);
\n
","From","awc::connect::BoxedSocket"],["
§

impl<F> FusedFuture for Box<F>
where\n F: FusedFuture + Unpin + ?Sized,

§

fn is_terminated(&self) -> bool

Returns true if the underlying future should no longer be polled.
","FusedFuture","awc::connect::BoxedSocket"],["
§

impl<S> FusedStream for Box<S>
where\n S: FusedStream + Unpin + ?Sized,

§

fn is_terminated(&self) -> bool

Returns true if the stream should no longer be polled.
","FusedStream","awc::connect::BoxedSocket"],["
1.36.0 · source§

impl<F, A> Future for Box<F, A>
where\n F: Future + Unpin + ?Sized,\n A: Allocator,

§

type Output = <F as Future>::Output

The type of value produced on completion.
source§

fn poll(\n self: Pin<&mut Box<F, A>>,\n cx: &mut Context<'_>\n) -> Poll<<Box<F, A> as Future>::Output>

Attempt to resolve the future to a final value, registering\nthe current task for wakeup if the value is not yet available. Read more
","Future","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<T, A> Hash for Box<T, A>
where\n T: Hash + ?Sized,\n A: Allocator,

source§

fn hash<H>(&self, state: &mut H)
where\n H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where\n H: Hasher,\n Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
","Hash","awc::connect::BoxedSocket"],["
1.22.0 · source§

impl<T, A> Hasher for Box<T, A>
where\n T: Hasher + ?Sized,\n A: Allocator,

source§

fn finish(&self) -> u64

Returns the hash value for the values written so far. Read more
source§

fn write(&mut self, bytes: &[u8])

Writes some data into this Hasher. Read more
source§

fn write_u8(&mut self, i: u8)

Writes a single u8 into this hasher.
source§

fn write_u16(&mut self, i: u16)

Writes a single u16 into this hasher.
source§

fn write_u32(&mut self, i: u32)

Writes a single u32 into this hasher.
source§

fn write_u64(&mut self, i: u64)

Writes a single u64 into this hasher.
source§

fn write_u128(&mut self, i: u128)

Writes a single u128 into this hasher.
source§

fn write_usize(&mut self, i: usize)

Writes a single usize into this hasher.
source§

fn write_i8(&mut self, i: i8)

Writes a single i8 into this hasher.
source§

fn write_i16(&mut self, i: i16)

Writes a single i16 into this hasher.
source§

fn write_i32(&mut self, i: i32)

Writes a single i32 into this hasher.
source§

fn write_i64(&mut self, i: i64)

Writes a single i64 into this hasher.
source§

fn write_i128(&mut self, i: i128)

Writes a single i128 into this hasher.
source§

fn write_isize(&mut self, i: isize)

Writes a single isize into this hasher.
source§

fn write_length_prefix(&mut self, len: usize)

🔬This is a nightly-only experimental API. (hasher_prefixfree_extras)
Writes a length prefix into this hasher, as part of being prefix-free. Read more
source§

fn write_str(&mut self, s: &str)

🔬This is a nightly-only experimental API. (hasher_prefixfree_extras)
Writes a single str into this hasher. Read more
","Hasher","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<I, A> Iterator for Box<I, A>
where\n I: Iterator + ?Sized,\n A: Allocator,

§

type Item = <I as Iterator>::Item

The type of the elements being iterated over.
source§

fn next(&mut self) -> Option<<I as Iterator>::Item>

Advances the iterator and returns the next value. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the iterator. Read more
source§

fn nth(&mut self, n: usize) -> Option<<I as Iterator>::Item>

Returns the nth element of the iterator. Read more
source§

fn last(self) -> Option<<I as Iterator>::Item>

Consumes the iterator, returning the last element. Read more
source§

fn next_chunk<const N: usize>(\n &mut self\n) -> Result<[Self::Item; N], IntoIter<Self::Item, N>>
where\n Self: Sized,

🔬This is a nightly-only experimental API. (iter_next_chunk)
Advances the iterator and returns an array containing the next N values. Read more
1.0.0 · source§

fn count(self) -> usize
where\n Self: Sized,

Consumes the iterator, counting the number of iterations and returning it. Read more
source§

fn advance_by(&mut self, n: usize) -> Result<(), NonZero<usize>>

🔬This is a nightly-only experimental API. (iter_advance_by)
Advances the iterator by n elements. Read more
1.28.0 · source§

fn step_by(self, step: usize) -> StepBy<Self>
where\n Self: Sized,

Creates an iterator starting at the same point, but stepping by\nthe given amount at each iteration. Read more
1.0.0 · source§

fn chain<U>(self, other: U) -> Chain<Self, <U as IntoIterator>::IntoIter>
where\n Self: Sized,\n U: IntoIterator<Item = Self::Item>,

Takes two iterators and creates a new iterator over both in sequence. Read more
1.0.0 · source§

fn zip<U>(self, other: U) -> Zip<Self, <U as IntoIterator>::IntoIter>
where\n Self: Sized,\n U: IntoIterator,

‘Zips up’ two iterators into a single iterator of pairs. Read more
source§

fn intersperse_with<G>(self, separator: G) -> IntersperseWith<Self, G>
where\n Self: Sized,\n G: FnMut() -> Self::Item,

🔬This is a nightly-only experimental API. (iter_intersperse)
Creates a new iterator which places an item generated by separator\nbetween adjacent items of the original iterator. Read more
1.0.0 · source§

fn map<B, F>(self, f: F) -> Map<Self, F>
where\n Self: Sized,\n F: FnMut(Self::Item) -> B,

Takes a closure and creates an iterator which calls that closure on each\nelement. Read more
1.21.0 · source§

fn for_each<F>(self, f: F)
where\n Self: Sized,\n F: FnMut(Self::Item),

Calls a closure on each element of an iterator. Read more
1.0.0 · source§

fn filter<P>(self, predicate: P) -> Filter<Self, P>
where\n Self: Sized,\n P: FnMut(&Self::Item) -> bool,

Creates an iterator which uses a closure to determine if an element\nshould be yielded. Read more
1.0.0 · source§

fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F>
where\n Self: Sized,\n F: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both filters and maps. Read more
1.0.0 · source§

fn enumerate(self) -> Enumerate<Self>
where\n Self: Sized,

Creates an iterator which gives the current iteration count as well as\nthe next value. Read more
1.0.0 · source§

fn peekable(self) -> Peekable<Self>
where\n Self: Sized,

Creates an iterator which can use the peek and peek_mut methods\nto look at the next element of the iterator without consuming it. See\ntheir documentation for more information. Read more
1.0.0 · source§

fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P>
where\n Self: Sized,\n P: FnMut(&Self::Item) -> bool,

Creates an iterator that skips elements based on a predicate. Read more
1.0.0 · source§

fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P>
where\n Self: Sized,\n P: FnMut(&Self::Item) -> bool,

Creates an iterator that yields elements based on a predicate. Read more
1.57.0 · source§

fn map_while<B, P>(self, predicate: P) -> MapWhile<Self, P>
where\n Self: Sized,\n P: FnMut(Self::Item) -> Option<B>,

Creates an iterator that both yields elements based on a predicate and maps. Read more
1.0.0 · source§

fn skip(self, n: usize) -> Skip<Self>
where\n Self: Sized,

Creates an iterator that skips the first n elements. Read more
1.0.0 · source§

fn take(self, n: usize) -> Take<Self>
where\n Self: Sized,

Creates an iterator that yields the first n elements, or fewer\nif the underlying iterator ends sooner. Read more
1.0.0 · source§

fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
where\n Self: Sized,\n F: FnMut(&mut St, Self::Item) -> Option<B>,

An iterator adapter which, like fold, holds internal state, but\nunlike fold, produces a new iterator. Read more
1.0.0 · source§

fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
where\n Self: Sized,\n U: IntoIterator,\n F: FnMut(Self::Item) -> U,

Creates an iterator that works like map, but flattens nested structure. Read more
source§

fn map_windows<F, R, const N: usize>(self, f: F) -> MapWindows<Self, F, N>
where\n Self: Sized,\n F: FnMut(&[Self::Item; N]) -> R,

🔬This is a nightly-only experimental API. (iter_map_windows)
Calls the given function f for each contiguous window of size N over\nself and returns an iterator over the outputs of f. Like slice::windows(),\nthe windows during mapping overlap as well. Read more
1.0.0 · source§

fn fuse(self) -> Fuse<Self>
where\n Self: Sized,

Creates an iterator which ends after the first None. Read more
1.0.0 · source§

fn inspect<F>(self, f: F) -> Inspect<Self, F>
where\n Self: Sized,\n F: FnMut(&Self::Item),

Does something with each element of an iterator, passing the value on. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where\n Self: Sized,

Borrows an iterator, rather than consuming it. Read more
1.0.0 · source§

fn collect<B>(self) -> B
where\n B: FromIterator<Self::Item>,\n Self: Sized,

Transforms an iterator into a collection. Read more
source§

fn collect_into<E>(self, collection: &mut E) -> &mut E
where\n E: Extend<Self::Item>,\n Self: Sized,

🔬This is a nightly-only experimental API. (iter_collect_into)
Collects all the items from an iterator into a collection. Read more
1.0.0 · source§

fn partition<B, F>(self, f: F) -> (B, B)
where\n Self: Sized,\n B: Default + Extend<Self::Item>,\n F: FnMut(&Self::Item) -> bool,

Consumes an iterator, creating two collections from it. Read more
source§

fn is_partitioned<P>(self, predicate: P) -> bool
where\n Self: Sized,\n P: FnMut(Self::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_is_partitioned)
Checks if the elements of this iterator are partitioned according to the given predicate,\nsuch that all those that return true precede all those that return false. Read more
1.27.0 · source§

fn try_fold<B, F, R>(&mut self, init: B, f: F) -> R
where\n Self: Sized,\n F: FnMut(B, Self::Item) -> R,\n R: Try<Output = B>,

An iterator method that applies a function as long as it returns\nsuccessfully, producing a single, final value. Read more
1.27.0 · source§

fn try_for_each<F, R>(&mut self, f: F) -> R
where\n Self: Sized,\n F: FnMut(Self::Item) -> R,\n R: Try<Output = ()>,

An iterator method that applies a fallible function to each item in the\niterator, stopping at the first error and returning that error. Read more
1.0.0 · source§

fn fold<B, F>(self, init: B, f: F) -> B
where\n Self: Sized,\n F: FnMut(B, Self::Item) -> B,

Folds every element into an accumulator by applying an operation,\nreturning the final result. Read more
1.51.0 · source§

fn reduce<F>(self, f: F) -> Option<Self::Item>
where\n Self: Sized,\n F: FnMut(Self::Item, Self::Item) -> Self::Item,

Reduces the elements to a single one, by repeatedly applying a reducing\noperation. Read more
source§

fn try_reduce<F, R>(\n &mut self,\n f: F\n) -> <<R as Try>::Residual as Residual<Option<<R as Try>::Output>>>::TryType
where\n Self: Sized,\n F: FnMut(Self::Item, Self::Item) -> R,\n R: Try<Output = Self::Item>,\n <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (iterator_try_reduce)
Reduces the elements to a single one by repeatedly applying a reducing operation. If the\nclosure returns a failure, the failure is propagated back to the caller immediately. Read more
1.0.0 · source§

fn all<F>(&mut self, f: F) -> bool
where\n Self: Sized,\n F: FnMut(Self::Item) -> bool,

Tests if every element of the iterator matches a predicate. Read more
1.0.0 · source§

fn any<F>(&mut self, f: F) -> bool
where\n Self: Sized,\n F: FnMut(Self::Item) -> bool,

Tests if any element of the iterator matches a predicate. Read more
1.0.0 · source§

fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
where\n Self: Sized,\n P: FnMut(&Self::Item) -> bool,

Searches for an element of an iterator that satisfies a predicate. Read more
1.30.0 · source§

fn find_map<B, F>(&mut self, f: F) -> Option<B>
where\n Self: Sized,\n F: FnMut(Self::Item) -> Option<B>,

Applies function to the elements of iterator and returns\nthe first non-none result. Read more
source§

fn try_find<F, R>(\n &mut self,\n f: F\n) -> <<R as Try>::Residual as Residual<Option<Self::Item>>>::TryType
where\n Self: Sized,\n F: FnMut(&Self::Item) -> R,\n R: Try<Output = bool>,\n <R as Try>::Residual: Residual<Option<Self::Item>>,

🔬This is a nightly-only experimental API. (try_find)
Applies function to the elements of iterator and returns\nthe first true result or the first error. Read more
1.0.0 · source§

fn position<P>(&mut self, predicate: P) -> Option<usize>
where\n Self: Sized,\n P: FnMut(Self::Item) -> bool,

Searches for an element in an iterator, returning its index. Read more
1.6.0 · source§

fn max_by_key<B, F>(self, f: F) -> Option<Self::Item>
where\n B: Ord,\n Self: Sized,\n F: FnMut(&Self::Item) -> B,

Returns the element that gives the maximum value from the\nspecified function. Read more
1.15.0 · source§

fn max_by<F>(self, compare: F) -> Option<Self::Item>
where\n Self: Sized,\n F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the maximum value with respect to the\nspecified comparison function. Read more
1.6.0 · source§

fn min_by_key<B, F>(self, f: F) -> Option<Self::Item>
where\n B: Ord,\n Self: Sized,\n F: FnMut(&Self::Item) -> B,

Returns the element that gives the minimum value from the\nspecified function. Read more
1.15.0 · source§

fn min_by<F>(self, compare: F) -> Option<Self::Item>
where\n Self: Sized,\n F: FnMut(&Self::Item, &Self::Item) -> Ordering,

Returns the element that gives the minimum value with respect to the\nspecified comparison function. Read more
1.0.0 · source§

fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB)
where\n FromA: Default + Extend<A>,\n FromB: Default + Extend<B>,\n Self: Sized + Iterator<Item = (A, B)>,

Converts an iterator of pairs into a pair of containers. Read more
1.36.0 · source§

fn copied<'a, T>(self) -> Copied<Self>
where\n T: 'a + Copy,\n Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which copies all of its elements. Read more
1.0.0 · source§

fn cloned<'a, T>(self) -> Cloned<Self>
where\n T: 'a + Clone,\n Self: Sized + Iterator<Item = &'a T>,

Creates an iterator which clones all of its elements. Read more
source§

fn array_chunks<const N: usize>(self) -> ArrayChunks<Self, N>
where\n Self: Sized,

🔬This is a nightly-only experimental API. (iter_array_chunks)
Returns an iterator over N elements of the iterator at a time. Read more
1.11.0 · source§

fn sum<S>(self) -> S
where\n Self: Sized,\n S: Sum<Self::Item>,

Sums the elements of an iterator. Read more
1.11.0 · source§

fn product<P>(self) -> P
where\n Self: Sized,\n P: Product<Self::Item>,

Iterates over the entire iterator, multiplying all the elements Read more
source§

fn cmp_by<I, F>(self, other: I, cmp: F) -> Ordering
where\n Self: Sized,\n I: IntoIterator,\n F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Ordering,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those\nof another with respect to the specified comparison function. Read more
1.5.0 · source§

fn partial_cmp<I>(self, other: I) -> Option<Ordering>
where\n I: IntoIterator,\n Self::Item: PartialOrd<<I as IntoIterator>::Item>,\n Self: Sized,

Lexicographically compares the PartialOrd elements of\nthis Iterator with those of another. The comparison works like short-circuit\nevaluation, returning a result without comparing the remaining elements.\nAs soon as an order can be determined, the evaluation stops and a result is returned. Read more
source§

fn partial_cmp_by<I, F>(self, other: I, partial_cmp: F) -> Option<Ordering>
where\n Self: Sized,\n I: IntoIterator,\n F: FnMut(Self::Item, <I as IntoIterator>::Item) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (iter_order_by)
Lexicographically compares the elements of this Iterator with those\nof another with respect to the specified comparison function. Read more
1.5.0 · source§

fn eq<I>(self, other: I) -> bool
where\n I: IntoIterator,\n Self::Item: PartialEq<<I as IntoIterator>::Item>,\n Self: Sized,

Determines if the elements of this Iterator are equal to those of\nanother. Read more
source§

fn eq_by<I, F>(self, other: I, eq: F) -> bool
where\n Self: Sized,\n I: IntoIterator,\n F: FnMut(Self::Item, <I as IntoIterator>::Item) -> bool,

🔬This is a nightly-only experimental API. (iter_order_by)
Determines if the elements of this Iterator are equal to those of\nanother with respect to the specified equality function. Read more
1.5.0 · source§

fn ne<I>(self, other: I) -> bool
where\n I: IntoIterator,\n Self::Item: PartialEq<<I as IntoIterator>::Item>,\n Self: Sized,

Determines if the elements of this Iterator are not equal to those of\nanother. Read more
1.5.0 · source§

fn lt<I>(self, other: I) -> bool
where\n I: IntoIterator,\n Self::Item: PartialOrd<<I as IntoIterator>::Item>,\n Self: Sized,

Determines if the elements of this Iterator are lexicographically\nless than those of another. Read more
1.5.0 · source§

fn le<I>(self, other: I) -> bool
where\n I: IntoIterator,\n Self::Item: PartialOrd<<I as IntoIterator>::Item>,\n Self: Sized,

Determines if the elements of this Iterator are lexicographically\nless or equal to those of another. Read more
1.5.0 · source§

fn gt<I>(self, other: I) -> bool
where\n I: IntoIterator,\n Self::Item: PartialOrd<<I as IntoIterator>::Item>,\n Self: Sized,

Determines if the elements of this Iterator are lexicographically\ngreater than those of another. Read more
1.5.0 · source§

fn ge<I>(self, other: I) -> bool
where\n I: IntoIterator,\n Self::Item: PartialOrd<<I as IntoIterator>::Item>,\n Self: Sized,

Determines if the elements of this Iterator are lexicographically\ngreater than or equal to those of another. Read more
source§

fn is_sorted_by<F>(self, compare: F) -> bool
where\n Self: Sized,\n F: FnMut(&Self::Item, &Self::Item) -> bool,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given comparator function. Read more
source§

fn is_sorted_by_key<F, K>(self, f: F) -> bool
where\n Self: Sized,\n F: FnMut(Self::Item) -> K,\n K: PartialOrd,

🔬This is a nightly-only experimental API. (is_sorted)
Checks if the elements of this iterator are sorted using the given key extraction\nfunction. Read more
","Iterator","awc::connect::BoxedSocket"],["
§

impl<Sp> LocalSpawn for Box<Sp>
where\n Sp: LocalSpawn + ?Sized,

§

fn spawn_local_obj(\n &self,\n future: LocalFutureObj<'static, ()>\n) -> Result<(), SpawnError>

Spawns a future that will be run to completion. Read more
§

fn status_local(&self) -> Result<(), SpawnError>

Determines whether the executor is able to spawn new tasks. Read more
","LocalSpawn","awc::connect::BoxedSocket"],["
§

impl<B> MessageBody for Box<B>
where\n B: MessageBody + Unpin + ?Sized,

§

type Error = <B as MessageBody>::Error

The type of error that will be returned if streaming body fails. Read more
§

fn size(&self) -> BodySize

Body size hint. Read more
§

fn poll_next(\n self: Pin<&mut Box<B>>,\n cx: &mut Context<'_>\n) -> Poll<Option<Result<Bytes, <Box<B> as MessageBody>::Error>>>

Attempt to pull out the next chunk of body bytes. Read more
§

fn try_into_bytes(self) -> Result<Bytes, Self>
where\n Self: Sized,

Try to convert into the complete chunk of body bytes. Read more
§

fn boxed(self) -> BoxBody
where\n Self: Sized + 'static,

Wraps this body into a BoxBody. Read more
","MessageBody","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<T, A> Ord for Box<T, A>
where\n T: Ord + ?Sized,\n A: Allocator,

source§

fn cmp(&self, other: &Box<T, A>) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where\n Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where\n Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where\n Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
","Ord","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<T, A> PartialEq for Box<T, A>
where\n T: PartialEq + ?Sized,\n A: Allocator,

source§

fn eq(&self, other: &Box<T, A>) -> bool

This method tests for self and other values to be equal, and is used\nby ==.
source§

fn ne(&self, other: &Box<T, A>) -> bool

This method tests for !=. The default implementation is almost always\nsufficient, and should not be overridden without very good reason.
","PartialEq","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<T, A> PartialOrd for Box<T, A>
where\n T: PartialOrd + ?Sized,\n A: Allocator,

source§

fn partial_cmp(&self, other: &Box<T, A>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
source§

fn lt(&self, other: &Box<T, A>) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
source§

fn le(&self, other: &Box<T, A>) -> bool

This method tests less than or equal to (for self and other) and is used by the <=\noperator. Read more
source§

fn ge(&self, other: &Box<T, A>) -> bool

This method tests greater than or equal to (for self and other) and is used by the >=\noperator. Read more
source§

fn gt(&self, other: &Box<T, A>) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
","PartialOrd","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<T, A> Pointer for Box<T, A>
where\n A: Allocator,\n T: ?Sized,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
","Pointer","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<R> Read for Box<R>
where\n R: Read + ?Sized,

source§

fn read(&mut self, buf: &mut [u8]) -> Result<usize, Error>

Pull some bytes from this source into the specified buffer, returning\nhow many bytes were read. Read more
source§

fn read_buf(&mut self, cursor: BorrowedCursor<'_>) -> Result<(), Error>

🔬This is a nightly-only experimental API. (read_buf)
Pull some bytes from this source into the specified buffer. Read more
source§

fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize, Error>

Like read, except that it reads into a slice of buffers. Read more
source§

fn is_read_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Reader has an efficient read_vectored\nimplementation. Read more
source§

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize, Error>

Read all bytes until EOF in this source, placing them into buf. Read more
source§

fn read_to_string(&mut self, buf: &mut String) -> Result<usize, Error>

Read all bytes until EOF in this source, appending them to buf. Read more
source§

fn read_exact(&mut self, buf: &mut [u8]) -> Result<(), Error>

Read the exact number of bytes required to fill buf. Read more
source§

fn read_buf_exact(&mut self, cursor: BorrowedCursor<'_>) -> Result<(), Error>

🔬This is a nightly-only experimental API. (read_buf)
Read the exact number of bytes required to fill cursor. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where\n Self: Sized,

Creates a “by reference” adaptor for this instance of Read. Read more
1.0.0 · source§

fn bytes(self) -> Bytes<Self>
where\n Self: Sized,

Transforms this Read instance to an Iterator over its bytes. Read more
1.0.0 · source§

fn chain<R>(self, next: R) -> Chain<Self, R>
where\n R: Read,\n Self: Sized,

Creates an adapter which will chain this stream with another. Read more
1.0.0 · source§

fn take(self, limit: u64) -> Take<Self>
where\n Self: Sized,

Creates an adapter which will read at most limit bytes from it. Read more
","Read","awc::connect::BoxedSocket"],["
source§

impl<R> RngCore for Box<R>
where\n R: RngCore + ?Sized,

Available on crate feature alloc only.
source§

fn next_u32(&mut self) -> u32

Return the next random u32. Read more
source§

fn next_u64(&mut self) -> u64

Return the next random u64. Read more
source§

fn fill_bytes(&mut self, dest: &mut [u8])

Fill dest with random data. Read more
source§

fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Error>

Fill dest entirely with random data. Read more
","RngCore","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<S> Seek for Box<S>
where\n S: Seek + ?Sized,

source§

fn seek(&mut self, pos: SeekFrom) -> Result<u64, Error>

Seek to an offset, in bytes, in a stream. Read more
source§

fn stream_position(&mut self) -> Result<u64, Error>

Returns the current seek position from the start of the stream. Read more
1.55.0 · source§

fn rewind(&mut self) -> Result<(), Error>

Rewind to the beginning of a stream. Read more
source§

fn stream_len(&mut self) -> Result<u64, Error>

🔬This is a nightly-only experimental API. (seek_stream_len)
Returns the length of this stream (in bytes). Read more
1.80.0 · source§

fn seek_relative(&mut self, offset: i64) -> Result<(), Error>

Seeks relative to the current position. Read more
","Seek","awc::connect::BoxedSocket"],["
source§

impl<T> Serialize for Box<T>
where\n T: Serialize + ?Sized,

Available on crate features std or alloc only.
source§

fn serialize<S>(\n &self,\n serializer: S\n) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where\n S: Serializer,

Serialize this value into the given Serde serializer. Read more
","Serialize","awc::connect::BoxedSocket"],["
§

impl<S, Req> Service<Req> for Box<S>
where\n S: Service<Req> + ?Sized,

§

type Response = <S as Service<Req>>::Response

Responses given by the service.
§

type Error = <S as Service<Req>>::Error

Errors produced by the service when polling readiness or executing call.
§

type Future = <S as Service<Req>>::Future

The future response value.
§

fn poll_ready(\n &self,\n ctx: &mut Context<'_>\n) -> Poll<Result<(), <S as Service<Req>>::Error>>

Returns Ready when the service is able to process requests. Read more
§

fn call(&self, request: Req) -> <S as Service<Req>>::Future

Process the request and return the response asynchronously. Read more
","Service","awc::connect::BoxedSocket"],["
§

impl<S, Item> Sink<Item> for Box<S>
where\n S: Sink<Item> + Unpin + ?Sized,

§

type Error = <S as Sink<Item>>::Error

The type of value produced by the sink when an error occurs.
§

fn poll_ready(\n self: Pin<&mut Box<S>>,\n cx: &mut Context<'_>\n) -> Poll<Result<(), <Box<S> as Sink<Item>>::Error>>

Attempts to prepare the Sink to receive a value. Read more
§

fn start_send(\n self: Pin<&mut Box<S>>,\n item: Item\n) -> Result<(), <Box<S> as Sink<Item>>::Error>

Begin the process of sending a value to the sink.\nEach call to this function must be preceded by a successful call to\npoll_ready which returned Poll::Ready(Ok(())). Read more
§

fn poll_flush(\n self: Pin<&mut Box<S>>,\n cx: &mut Context<'_>\n) -> Poll<Result<(), <Box<S> as Sink<Item>>::Error>>

Flush any remaining output from this sink. Read more
§

fn poll_close(\n self: Pin<&mut Box<S>>,\n cx: &mut Context<'_>\n) -> Poll<Result<(), <Box<S> as Sink<Item>>::Error>>

Flush any remaining output and close this sink, if necessary. Read more
","Sink","awc::connect::BoxedSocket"],["
§

impl<T> Source for Box<T>
where\n T: Source + ?Sized,

§

fn register(\n &mut self,\n registry: &Registry,\n token: Token,\n interests: Interest\n) -> Result<(), Error>

Register self with the given Registry instance. Read more
§

fn reregister(\n &mut self,\n registry: &Registry,\n token: Token,\n interests: Interest\n) -> Result<(), Error>

Re-register self with the given Registry instance. Read more
§

fn deregister(&mut self, registry: &Registry) -> Result<(), Error>

Deregister self from the given Registry instance. Read more
","Source","awc::connect::BoxedSocket"],["
§

impl<Sp> Spawn for Box<Sp>
where\n Sp: Spawn + ?Sized,

§

fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError>

Spawns a future that will be run to completion. Read more
§

fn status(&self) -> Result<(), SpawnError>

Determines whether the executor is able to spawn new tasks. Read more
","Spawn","awc::connect::BoxedSocket"],["
§

impl<S> Stream for Box<S>
where\n S: Stream + Unpin + ?Sized,

§

type Item = <S as Stream>::Item

Values yielded by the stream.
§

fn poll_next(\n self: Pin<&mut Box<S>>,\n cx: &mut Context<'_>\n) -> Poll<Option<<Box<S> as Stream>::Item>>

Attempt to pull out the next value of this stream, registering the\ncurrent task for wakeup if the value is not yet available, and returning\nNone if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more
","Stream","awc::connect::BoxedSocket"],["
§

impl<S> Subscriber for Box<S>
where\n S: Subscriber + ?Sized,

§

fn register_callsite(&self, metadata: &'static Metadata<'static>) -> Interest

Registers a new callsite with this subscriber, returning whether or not\nthe subscriber is interested in being notified about the callsite. Read more
§

fn enabled(&self, metadata: &Metadata<'_>) -> bool

Returns true if a span or event with the specified metadata would be\nrecorded. Read more
§

fn max_level_hint(&self) -> Option<LevelFilter>

Returns the highest verbosity level that this Subscriber will\nenable, or None, if the subscriber does not implement level-based\nfiltering or chooses not to implement this method. Read more
§

fn new_span(&self, span: &Attributes<'_>) -> Id

Visit the construction of a new span, returning a new span ID for the\nspan being constructed. Read more
§

fn record(&self, span: &Id, values: &Record<'_>)

Record a set of values on a span. Read more
§

fn record_follows_from(&self, span: &Id, follows: &Id)

Adds an indication that span follows from the span with the id\nfollows. Read more
§

fn event_enabled(&self, event: &Event<'_>) -> bool

Determine if an [Event] should be recorded. Read more
§

fn event(&self, event: &Event<'_>)

Records that an Event has occurred. Read more
§

fn enter(&self, span: &Id)

Records that a span has been entered. Read more
§

fn exit(&self, span: &Id)

Records that a span has been exited. Read more
§

fn clone_span(&self, id: &Id) -> Id

Notifies the subscriber that a span ID has been cloned. Read more
§

fn try_close(&self, id: Id) -> bool

Notifies the subscriber that a span ID has been dropped, and returns\ntrue if there are now 0 IDs that refer to that span. Read more
§

fn drop_span(&self, id: Id)

👎Deprecated since 0.1.2: use Subscriber::try_close instead
This method is deprecated. Read more
§

fn current_span(&self) -> Current

Returns a type representing this subscriber’s view of the current span. Read more
§

unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()>

If self is the same type as the provided TypeId, returns an untyped\n*const pointer to that type. Otherwise, returns None. Read more
§

fn on_register_dispatch(&self, subscriber: &Dispatch)

Invoked when this subscriber becomes a [Dispatch]. Read more
","Subscriber","awc::connect::BoxedSocket"],["
§

impl<'a, T, F> UnsafeFutureObj<'a, T> for Box<F>
where\n F: Future<Output = T> + 'a,

§

fn into_raw(self) -> *mut dyn Future<Output = T> + 'a

Convert an owned instance into a (conceptually owned) fat pointer. Read more
§

unsafe fn drop(ptr: *mut dyn Future<Output = T> + 'a)

Drops the future represented by the given fat pointer. Read more
","UnsafeFutureObj<'a, T>","awc::connect::BoxedSocket"],["
§

impl<T> Value for Box<T>
where\n T: Value + ?Sized,

§

fn record(&self, key: &Field, visitor: &mut dyn Visit)

Visits this value with the given Visitor.
","Value","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<W> Write for Box<W>
where\n W: Write + ?Sized,

source§

fn write(&mut self, buf: &[u8]) -> Result<usize, Error>

Write a buffer into this writer, returning how many bytes were written. Read more
source§

fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize, Error>

Like write, except that it writes from a slice of buffers. Read more
source§

fn is_write_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Writer has an efficient write_vectored\nimplementation. Read more
source§

fn flush(&mut self) -> Result<(), Error>

Flush this output stream, ensuring that all intermediately buffered\ncontents reach their destination. Read more
source§

fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>

Attempts to write an entire buffer into this writer. Read more
source§

fn write_fmt(&mut self, fmt: Arguments<'_>) -> Result<(), Error>

Writes a formatted string into this writer, returning any error\nencountered. Read more
source§

fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>

🔬This is a nightly-only experimental API. (write_all_vectored)
Attempts to write multiple buffers into this writer. Read more
1.0.0 · source§

fn by_ref(&mut self) -> &mut Self
where\n Self: Sized,

Creates a “by reference” adapter for this instance of Write. Read more
","Write","awc::connect::BoxedSocket"],["
source§

impl<T, U, A> CoerceUnsized<Box<U, A>> for Box<T, A>
where\n T: Unsize<U> + ?Sized,\n A: Allocator,\n U: ?Sized,

","CoerceUnsized>","awc::connect::BoxedSocket"],["
source§

impl<R> CryptoRng for Box<R>
where\n R: CryptoRng + ?Sized,

Available on crate feature alloc only.
","CryptoRng","awc::connect::BoxedSocket"],["
source§

impl<T, A> DerefPure for Box<T, A>
where\n A: Allocator,\n T: ?Sized,

","DerefPure","awc::connect::BoxedSocket"],["
source§

impl<T, U> DispatchFromDyn<Box<U>> for Box<T>
where\n T: Unsize<U> + ?Sized,\n U: ?Sized,

","DispatchFromDyn>","awc::connect::BoxedSocket"],["
1.0.0 · source§

impl<T, A> Eq for Box<T, A>
where\n T: Eq + ?Sized,\n A: Allocator,

","Eq","awc::connect::BoxedSocket"],["
1.26.0 · source§

impl<I, A> FusedIterator for Box<I, A>
where\n I: FusedIterator + ?Sized,\n A: Allocator,

","FusedIterator","awc::connect::BoxedSocket"],["
1.33.0 · source§

impl<T, A> Unpin for Box<T, A>
where\n A: Allocator,\n T: ?Sized,

","Unpin","awc::connect::BoxedSocket"]] +};if (window.register_type_impls) {window.register_type_impls(type_impls);} else {window.pending_type_impls = type_impls;}})() \ No newline at end of file diff --git a/type.impl/alloc/rc/struct.Rc.js b/type.impl/alloc/rc/struct.Rc.js new file mode 100644 index 000000000..f283c1e11 --- /dev/null +++ b/type.impl/alloc/rc/struct.Rc.js @@ -0,0 +1,3 @@ +(function() {var type_impls = { +"awc":[["
1.69.0 · source§

impl<T> AsFd for Rc<T>
where\n T: AsFd + ?Sized,

source§

fn as_fd(&self) -> BorrowedFd<'_>

Borrows the file descriptor. Read more
","AsFd","awc::connect::BoxConnectorService"],["
1.69.0 · source§

impl<T> AsRawFd for Rc<T>
where\n T: AsRawFd,

source§

fn as_raw_fd(&self) -> i32

Extracts the raw file descriptor. Read more
","AsRawFd","awc::connect::BoxConnectorService"],["
1.5.0 · source§

impl<T, A> AsRef<T> for Rc<T, A>
where\n A: Allocator,\n T: ?Sized,

source§

fn as_ref(&self) -> &T

Converts this type into a shared reference of the (usually inferred) input type.
","AsRef","awc::connect::BoxConnectorService"],["
1.0.0 · source§

impl<T, A> Borrow<T> for Rc<T, A>
where\n A: Allocator,\n T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
","Borrow","awc::connect::BoxConnectorService"],["
1.0.0 · source§

impl<T, A> Clone for Rc<T, A>
where\n A: Allocator + Clone,\n T: ?Sized,

source§

fn clone(&self) -> Rc<T, A>

Makes a clone of the Rc pointer.

\n

This creates another pointer to the same allocation, increasing the\nstrong reference count.

\n
§Examples
\n
use std::rc::Rc;\n\nlet five = Rc::new(5);\n\nlet _ = Rc::clone(&five);
\n
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
","Clone","awc::connect::BoxConnectorService"],["
1.0.0 · source§

impl<T, A> Debug for Rc<T, A>
where\n T: Debug + ?Sized,\n A: Allocator,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
","Debug","awc::connect::BoxConnectorService"],["
1.0.0 · source§

impl<T> Default for Rc<T>
where\n T: Default,

Available on non-no_global_oom_handling only.
source§

fn default() -> Rc<T>

Creates a new Rc<T>, with the Default value for T.

\n
§Examples
\n
use std::rc::Rc;\n\nlet x: Rc<i32> = Default::default();\nassert_eq!(*x, 0);
\n
","Default","awc::connect::BoxConnectorService"],["
1.0.0 · source§

impl<T, A> Deref for Rc<T, A>
where\n A: Allocator,\n T: ?Sized,

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &T

Dereferences the value.
","Deref","awc::connect::BoxConnectorService"],["
1.0.0 · source§

impl<T, A> Display for Rc<T, A>
where\n T: Display + ?Sized,\n A: Allocator,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
","Display","awc::connect::BoxConnectorService"],["
1.0.0 · source§

impl<T, A> Drop for Rc<T, A>
where\n A: Allocator,\n T: ?Sized,

source§

fn drop(&mut self)

Drops the Rc.

\n

This will decrement the strong reference count. If the strong reference\ncount reaches zero then the only other references (if any) are\nWeak, so we drop the inner value.

\n
§Examples
\n
use std::rc::Rc;\n\nstruct Foo;\n\nimpl Drop for Foo {\n    fn drop(&mut self) {\n        println!(\"dropped!\");\n    }\n}\n\nlet foo  = Rc::new(Foo);\nlet foo2 = Rc::clone(&foo);\n\ndrop(foo);    // Doesn't print anything\ndrop(foo2);   // Prints \"dropped!\"
\n
","Drop","awc::connect::BoxConnectorService"],["
1.21.0 · source§

impl<T, A> From<Box<T, A>> for Rc<T, A>
where\n A: Allocator,\n T: ?Sized,

Available on non-no_global_oom_handling only.
source§

fn from(v: Box<T, A>) -> Rc<T, A>

Move a boxed object to a new, reference counted, allocation.

\n
§Example
\n
let original: Box<i32> = Box::new(1);\nlet shared: Rc<i32> = Rc::from(original);\nassert_eq!(1, *shared);
\n
","From>","awc::connect::BoxConnectorService"],["
1.45.0 · source§

impl<'a, B> From<Cow<'a, B>> for Rc<B>
where\n B: ToOwned + ?Sized,\n Rc<B>: From<&'a B> + From<<B as ToOwned>::Owned>,

source§

fn from(cow: Cow<'a, B>) -> Rc<B>

Create a reference-counted pointer from\na clone-on-write pointer by copying its content.

\n
§Example
\n
let cow: Cow<'_, str> = Cow::Borrowed(\"eggplant\");\nlet shared: Rc<str> = Rc::from(cow);\nassert_eq!(\"eggplant\", &shared[..]);
\n
","From>","awc::connect::BoxConnectorService"],["
1.6.0 · source§

impl<T> From<T> for Rc<T>

Available on non-no_global_oom_handling only.
source§

fn from(t: T) -> Rc<T>

Converts a generic type T into an Rc<T>

\n

The conversion allocates on the heap and moves t\nfrom the stack into it.

\n
§Example
\n
let x = 5;\nlet rc = Rc::new(5);\n\nassert_eq!(Rc::from(x), rc);
\n
","From","awc::connect::BoxConnectorService"],["
1.0.0 · source§

impl<T, A> Hash for Rc<T, A>
where\n T: Hash + ?Sized,\n A: Allocator,

source§

fn hash<H>(&self, state: &mut H)
where\n H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where\n H: Hasher,\n Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
","Hash","awc::connect::BoxConnectorService"],["
§

impl<Sp> LocalSpawn for Rc<Sp>
where\n Sp: LocalSpawn + ?Sized,

§

fn spawn_local_obj(\n &self,\n future: LocalFutureObj<'static, ()>\n) -> Result<(), SpawnError>

Spawns a future that will be run to completion. Read more
§

fn status_local(&self) -> Result<(), SpawnError>

Determines whether the executor is able to spawn new tasks. Read more
","LocalSpawn","awc::connect::BoxConnectorService"],["
1.0.0 · source§

impl<T, A> Ord for Rc<T, A>
where\n T: Ord + ?Sized,\n A: Allocator,

source§

fn cmp(&self, other: &Rc<T, A>) -> Ordering

Comparison for two Rcs.

\n

The two are compared by calling cmp() on their inner values.

\n
§Examples
\n
use std::rc::Rc;\nuse std::cmp::Ordering;\n\nlet five = Rc::new(5);\n\nassert_eq!(Ordering::Less, five.cmp(&Rc::new(6)));
\n
1.21.0 · source§

fn max(self, other: Self) -> Self
where\n Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where\n Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where\n Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
","Ord","awc::connect::BoxConnectorService"],["
1.0.0 · source§

impl<T, A> PartialEq for Rc<T, A>
where\n T: PartialEq + ?Sized,\n A: Allocator,

source§

fn eq(&self, other: &Rc<T, A>) -> bool

Equality for two Rcs.

\n

Two Rcs are equal if their inner values are equal, even if they are\nstored in different allocation.

\n

If T also implements Eq (implying reflexivity of equality),\ntwo Rcs that point to the same allocation are\nalways equal.

\n
§Examples
\n
use std::rc::Rc;\n\nlet five = Rc::new(5);\n\nassert!(five == Rc::new(5));
\n
source§

fn ne(&self, other: &Rc<T, A>) -> bool

Inequality for two Rcs.

\n

Two Rcs are not equal if their inner values are not equal.

\n

If T also implements Eq (implying reflexivity of equality),\ntwo Rcs that point to the same allocation are\nalways equal.

\n
§Examples
\n
use std::rc::Rc;\n\nlet five = Rc::new(5);\n\nassert!(five != Rc::new(6));
\n
","PartialEq","awc::connect::BoxConnectorService"],["
1.0.0 · source§

impl<T, A> PartialOrd for Rc<T, A>
where\n T: PartialOrd + ?Sized,\n A: Allocator,

source§

fn partial_cmp(&self, other: &Rc<T, A>) -> Option<Ordering>

Partial comparison for two Rcs.

\n

The two are compared by calling partial_cmp() on their inner values.

\n
§Examples
\n
use std::rc::Rc;\nuse std::cmp::Ordering;\n\nlet five = Rc::new(5);\n\nassert_eq!(Some(Ordering::Less), five.partial_cmp(&Rc::new(6)));
\n
source§

fn lt(&self, other: &Rc<T, A>) -> bool

Less-than comparison for two Rcs.

\n

The two are compared by calling < on their inner values.

\n
§Examples
\n
use std::rc::Rc;\n\nlet five = Rc::new(5);\n\nassert!(five < Rc::new(6));
\n
source§

fn le(&self, other: &Rc<T, A>) -> bool

‘Less than or equal to’ comparison for two Rcs.

\n

The two are compared by calling <= on their inner values.

\n
§Examples
\n
use std::rc::Rc;\n\nlet five = Rc::new(5);\n\nassert!(five <= Rc::new(5));
\n
source§

fn gt(&self, other: &Rc<T, A>) -> bool

Greater-than comparison for two Rcs.

\n

The two are compared by calling > on their inner values.

\n
§Examples
\n
use std::rc::Rc;\n\nlet five = Rc::new(5);\n\nassert!(five > Rc::new(4));
\n
source§

fn ge(&self, other: &Rc<T, A>) -> bool

‘Greater than or equal to’ comparison for two Rcs.

\n

The two are compared by calling >= on their inner values.

\n
§Examples
\n
use std::rc::Rc;\n\nlet five = Rc::new(5);\n\nassert!(five >= Rc::new(5));
\n
","PartialOrd","awc::connect::BoxConnectorService"],["
1.0.0 · source§

impl<T, A> Pointer for Rc<T, A>
where\n A: Allocator,\n T: ?Sized,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
","Pointer","awc::connect::BoxConnectorService"],["
source§

impl<T> Rc<T>
where\n T: ?Sized,

1.17.0 · source

pub unsafe fn from_raw(ptr: *const T) -> Rc<T>

Constructs an Rc<T> from a raw pointer.

\n

The raw pointer must have been previously returned by a call to\nRc<U>::into_raw with the following requirements:

\n
    \n
  • If U is sized, it must have the same size and alignment as T. This\nis trivially true if U is T.
  • \n
  • If U is unsized, its data pointer must have the same size and\nalignment as T. This is trivially true if Rc<U> was constructed\nthrough Rc<T> and then converted to Rc<U> through an unsized\ncoercion.
  • \n
\n

Note that if U or U’s data pointer is not T but has the same size\nand alignment, this is basically like transmuting references of\ndifferent types. See mem::transmute for more information\non what restrictions apply in this case.

\n

The raw pointer must point to a block of memory allocated by the global allocator

\n

The user of from_raw has to make sure a specific value of T is only\ndropped once.

\n

This function is unsafe because improper use may lead to memory unsafety,\neven if the returned Rc<T> is never accessed.

\n
§Examples
\n
use std::rc::Rc;\n\nlet x = Rc::new(\"hello\".to_owned());\nlet x_ptr = Rc::into_raw(x);\n\nunsafe {\n    // Convert back to an `Rc` to prevent leak.\n    let x = Rc::from_raw(x_ptr);\n    assert_eq!(&*x, \"hello\");\n\n    // Further calls to `Rc::from_raw(x_ptr)` would be memory-unsafe.\n}\n\n// The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
\n

Convert a slice back into its original array:

\n\n
use std::rc::Rc;\n\nlet x: Rc<[u32]> = Rc::new([1, 2, 3]);\nlet x_ptr: *const [u32] = Rc::into_raw(x);\n\nunsafe {\n    let x: Rc<[u32; 3]> = Rc::from_raw(x_ptr.cast::<[u32; 3]>());\n    assert_eq!(&*x, &[1, 2, 3]);\n}
\n
1.53.0 · source

pub unsafe fn increment_strong_count(ptr: *const T)

Increments the strong reference count on the Rc<T> associated with the\nprovided pointer by one.

\n
§Safety
\n

The pointer must have been obtained through Rc::into_raw, the\nassociated Rc instance must be valid (i.e. the strong count must be at\nleast 1) for the duration of this method, and ptr must point to a block of memory\nallocated by the global allocator.

\n
§Examples
\n
use std::rc::Rc;\n\nlet five = Rc::new(5);\n\nunsafe {\n    let ptr = Rc::into_raw(five);\n    Rc::increment_strong_count(ptr);\n\n    let five = Rc::from_raw(ptr);\n    assert_eq!(2, Rc::strong_count(&five));\n}
\n
1.53.0 · source

pub unsafe fn decrement_strong_count(ptr: *const T)

Decrements the strong reference count on the Rc<T> associated with the\nprovided pointer by one.

\n
§Safety
\n

The pointer must have been obtained through Rc::into_raw, the\nassociated Rc instance must be valid (i.e. the strong count must be at\nleast 1) when invoking this method, and ptr must point to a block of memory\nallocated by the global allocator. This method can be used to release the final Rc and\nbacking storage, but should not be called after the final Rc has been released.

\n
§Examples
\n
use std::rc::Rc;\n\nlet five = Rc::new(5);\n\nunsafe {\n    let ptr = Rc::into_raw(five);\n    Rc::increment_strong_count(ptr);\n\n    let five = Rc::from_raw(ptr);\n    assert_eq!(2, Rc::strong_count(&five));\n    Rc::decrement_strong_count(ptr);\n    assert_eq!(1, Rc::strong_count(&five));\n}
\n
",0,"awc::connect::BoxConnectorService"],["
source§

impl<T> Rc<T>

1.0.0 · source

pub fn new(value: T) -> Rc<T>

Available on non-no_global_oom_handling only.

Constructs a new Rc<T>.

\n
§Examples
\n
use std::rc::Rc;\n\nlet five = Rc::new(5);
\n
1.60.0 · source

pub fn new_cyclic<F>(data_fn: F) -> Rc<T>
where\n F: FnOnce(&Weak<T>) -> T,

Available on non-no_global_oom_handling only.

Constructs a new Rc<T> while giving you a Weak<T> to the allocation,\nto allow you to construct a T which holds a weak pointer to itself.

\n

Generally, a structure circularly referencing itself, either directly or\nindirectly, should not hold a strong reference to itself to prevent a memory leak.\nUsing this function, you get access to the weak pointer during the\ninitialization of T, before the Rc<T> is created, such that you can\nclone and store it inside the T.

\n

new_cyclic first allocates the managed allocation for the Rc<T>,\nthen calls your closure, giving it a Weak<T> to this allocation,\nand only afterwards completes the construction of the Rc<T> by placing\nthe T returned from your closure into the allocation.

\n

Since the new Rc<T> is not fully-constructed until Rc<T>::new_cyclic\nreturns, calling upgrade on the weak reference inside your closure will\nfail and result in a None value.

\n
§Panics
\n

If data_fn panics, the panic is propagated to the caller, and the\ntemporary Weak<T> is dropped normally.

\n
§Examples
\n
use std::rc::{Rc, Weak};\n\nstruct Gadget {\n    me: Weak<Gadget>,\n}\n\nimpl Gadget {\n    /// Construct a reference counted Gadget.\n    fn new() -> Rc<Self> {\n        // `me` is a `Weak<Gadget>` pointing at the new allocation of the\n        // `Rc` we're constructing.\n        Rc::new_cyclic(|me| {\n            // Create the actual struct here.\n            Gadget { me: me.clone() }\n        })\n    }\n\n    /// Return a reference counted pointer to Self.\n    fn me(&self) -> Rc<Self> {\n        self.me.upgrade().unwrap()\n    }\n}
\n
source

pub fn new_uninit() -> Rc<MaybeUninit<T>>

🔬This is a nightly-only experimental API. (new_uninit)
Available on non-no_global_oom_handling only.

Constructs a new Rc with uninitialized contents.

\n
§Examples
\n
#![feature(new_uninit)]\n#![feature(get_mut_unchecked)]\n\nuse std::rc::Rc;\n\nlet mut five = Rc::<u32>::new_uninit();\n\n// Deferred initialization:\nRc::get_mut(&mut five).unwrap().write(5);\n\nlet five = unsafe { five.assume_init() };\n\nassert_eq!(*five, 5)
\n
source

pub fn new_zeroed() -> Rc<MaybeUninit<T>>

🔬This is a nightly-only experimental API. (new_uninit)
Available on non-no_global_oom_handling only.

Constructs a new Rc with uninitialized contents, with the memory\nbeing filled with 0 bytes.

\n

See MaybeUninit::zeroed for examples of correct and\nincorrect usage of this method.

\n
§Examples
\n
#![feature(new_uninit)]\n\nuse std::rc::Rc;\n\nlet zero = Rc::<u32>::new_zeroed();\nlet zero = unsafe { zero.assume_init() };\n\nassert_eq!(*zero, 0)
\n
source

pub fn try_new(value: T) -> Result<Rc<T>, AllocError>

🔬This is a nightly-only experimental API. (allocator_api)

Constructs a new Rc<T>, returning an error if the allocation fails

\n
§Examples
\n
#![feature(allocator_api)]\nuse std::rc::Rc;\n\nlet five = Rc::try_new(5);
\n
source

pub fn try_new_uninit() -> Result<Rc<MaybeUninit<T>>, AllocError>

🔬This is a nightly-only experimental API. (allocator_api)

Constructs a new Rc with uninitialized contents, returning an error if the allocation fails

\n
§Examples
\n
#![feature(allocator_api, new_uninit)]\n#![feature(get_mut_unchecked)]\n\nuse std::rc::Rc;\n\nlet mut five = Rc::<u32>::try_new_uninit()?;\n\n// Deferred initialization:\nRc::get_mut(&mut five).unwrap().write(5);\n\nlet five = unsafe { five.assume_init() };\n\nassert_eq!(*five, 5);
\n
source

pub fn try_new_zeroed() -> Result<Rc<MaybeUninit<T>>, AllocError>

🔬This is a nightly-only experimental API. (allocator_api)

Constructs a new Rc with uninitialized contents, with the memory\nbeing filled with 0 bytes, returning an error if the allocation fails

\n

See MaybeUninit::zeroed for examples of correct and\nincorrect usage of this method.

\n
§Examples
\n
#![feature(allocator_api, new_uninit)]\n\nuse std::rc::Rc;\n\nlet zero = Rc::<u32>::try_new_zeroed()?;\nlet zero = unsafe { zero.assume_init() };\n\nassert_eq!(*zero, 0);
\n
1.33.0 · source

pub fn pin(value: T) -> Pin<Rc<T>>

Available on non-no_global_oom_handling only.

Constructs a new Pin<Rc<T>>. If T does not implement Unpin, then\nvalue will be pinned in memory and unable to be moved.

\n
",0,"awc::connect::BoxConnectorService"],["
source§

impl<T, A> Rc<T, A>
where\n A: Allocator,\n T: ?Sized,

1.17.0 · source

pub fn into_raw(this: Rc<T, A>) -> *const T

Consumes the Rc, returning the wrapped pointer.

\n

To avoid a memory leak the pointer must be converted back to an Rc using\nRc::from_raw.

\n
§Examples
\n
use std::rc::Rc;\n\nlet x = Rc::new(\"hello\".to_owned());\nlet x_ptr = Rc::into_raw(x);\nassert_eq!(unsafe { &*x_ptr }, \"hello\");
\n
source

pub fn into_raw_with_allocator(this: Rc<T, A>) -> (*const T, A)

🔬This is a nightly-only experimental API. (allocator_api)

Consumes the Rc, returning the wrapped pointer and allocator.

\n

To avoid a memory leak the pointer must be converted back to an Rc using\nRc::from_raw_in.

\n
§Examples
\n
#![feature(allocator_api)]\nuse std::rc::Rc;\nuse std::alloc::System;\n\nlet x = Rc::new_in(\"hello\".to_owned(), System);\nlet (ptr, alloc) = Rc::into_raw_with_allocator(x);\nassert_eq!(unsafe { &*ptr }, \"hello\");\nlet x = unsafe { Rc::from_raw_in(ptr, alloc) };\nassert_eq!(&*x, \"hello\");
\n
1.45.0 · source

pub fn as_ptr(this: &Rc<T, A>) -> *const T

Provides a raw pointer to the data.

\n

The counts are not affected in any way and the Rc is not consumed. The pointer is valid\nfor as long there are strong counts in the Rc.

\n
§Examples
\n
use std::rc::Rc;\n\nlet x = Rc::new(\"hello\".to_owned());\nlet y = Rc::clone(&x);\nlet x_ptr = Rc::as_ptr(&x);\nassert_eq!(x_ptr, Rc::as_ptr(&y));\nassert_eq!(unsafe { &*x_ptr }, \"hello\");
\n
source

pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Rc<T, A>

🔬This is a nightly-only experimental API. (allocator_api)

Constructs an Rc<T, A> from a raw pointer in the provided allocator.

\n

The raw pointer must have been previously returned by a call to Rc<U, A>::into_raw with the following requirements:

\n
    \n
  • If U is sized, it must have the same size and alignment as T. This\nis trivially true if U is T.
  • \n
  • If U is unsized, its data pointer must have the same size and\nalignment as T. This is trivially true if Rc<U> was constructed\nthrough Rc<T> and then converted to Rc<U> through an unsized\ncoercion.
  • \n
\n

Note that if U or U’s data pointer is not T but has the same size\nand alignment, this is basically like transmuting references of\ndifferent types. See mem::transmute for more information\non what restrictions apply in this case.

\n

The raw pointer must point to a block of memory allocated by alloc

\n

The user of from_raw has to make sure a specific value of T is only\ndropped once.

\n

This function is unsafe because improper use may lead to memory unsafety,\neven if the returned Rc<T> is never accessed.

\n
§Examples
\n
#![feature(allocator_api)]\n\nuse std::rc::Rc;\nuse std::alloc::System;\n\nlet x = Rc::new_in(\"hello\".to_owned(), System);\nlet x_ptr = Rc::into_raw(x);\n\nunsafe {\n    // Convert back to an `Rc` to prevent leak.\n    let x = Rc::from_raw_in(x_ptr, System);\n    assert_eq!(&*x, \"hello\");\n\n    // Further calls to `Rc::from_raw(x_ptr)` would be memory-unsafe.\n}\n\n// The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
\n

Convert a slice back into its original array:

\n\n
#![feature(allocator_api)]\n\nuse std::rc::Rc;\nuse std::alloc::System;\n\nlet x: Rc<[u32], _> = Rc::new_in([1, 2, 3], System);\nlet x_ptr: *const [u32] = Rc::into_raw(x);\n\nunsafe {\n    let x: Rc<[u32; 3], _> = Rc::from_raw_in(x_ptr.cast::<[u32; 3]>(), System);\n    assert_eq!(&*x, &[1, 2, 3]);\n}
\n
1.4.0 · source

pub fn downgrade(this: &Rc<T, A>) -> Weak<T, A>
where\n A: Clone,

Creates a new Weak pointer to this allocation.

\n
§Examples
\n
use std::rc::Rc;\n\nlet five = Rc::new(5);\n\nlet weak_five = Rc::downgrade(&five);
\n
1.15.0 · source

pub fn weak_count(this: &Rc<T, A>) -> usize

Gets the number of Weak pointers to this allocation.

\n
§Examples
\n
use std::rc::Rc;\n\nlet five = Rc::new(5);\nlet _weak_five = Rc::downgrade(&five);\n\nassert_eq!(1, Rc::weak_count(&five));
\n
1.15.0 · source

pub fn strong_count(this: &Rc<T, A>) -> usize

Gets the number of strong (Rc) pointers to this allocation.

\n
§Examples
\n
use std::rc::Rc;\n\nlet five = Rc::new(5);\nlet _also_five = Rc::clone(&five);\n\nassert_eq!(2, Rc::strong_count(&five));
\n
source

pub unsafe fn increment_strong_count_in(ptr: *const T, alloc: A)
where\n A: Clone,

🔬This is a nightly-only experimental API. (allocator_api)

Increments the strong reference count on the Rc<T> associated with the\nprovided pointer by one.

\n
§Safety
\n

The pointer must have been obtained through Rc::into_raw, the\nassociated Rc instance must be valid (i.e. the strong count must be at\nleast 1) for the duration of this method, and ptr must point to a block of memory\nallocated by alloc

\n
§Examples
\n
#![feature(allocator_api)]\n\nuse std::rc::Rc;\nuse std::alloc::System;\n\nlet five = Rc::new_in(5, System);\n\nunsafe {\n    let ptr = Rc::into_raw(five);\n    Rc::increment_strong_count_in(ptr, System);\n\n    let five = Rc::from_raw_in(ptr, System);\n    assert_eq!(2, Rc::strong_count(&five));\n}
\n
source

pub unsafe fn decrement_strong_count_in(ptr: *const T, alloc: A)

🔬This is a nightly-only experimental API. (allocator_api)

Decrements the strong reference count on the Rc<T> associated with the\nprovided pointer by one.

\n
§Safety
\n

The pointer must have been obtained through Rc::into_raw, the\nassociated Rc instance must be valid (i.e. the strong count must be at\nleast 1) when invoking this method, and ptr must point to a block of memory\nallocated by alloc. This method can be used to release the final Rc and backing storage,\nbut should not be called after the final Rc has been released.

\n
§Examples
\n
#![feature(allocator_api)]\n\nuse std::rc::Rc;\nuse std::alloc::System;\n\nlet five = Rc::new_in(5, System);\n\nunsafe {\n    let ptr = Rc::into_raw(five);\n    Rc::increment_strong_count_in(ptr, System);\n\n    let five = Rc::from_raw_in(ptr, System);\n    assert_eq!(2, Rc::strong_count(&five));\n    Rc::decrement_strong_count_in(ptr, System);\n    assert_eq!(1, Rc::strong_count(&five));\n}
\n
1.4.0 · source

pub fn get_mut(this: &mut Rc<T, A>) -> Option<&mut T>

Returns a mutable reference into the given Rc, if there are\nno other Rc or Weak pointers to the same allocation.

\n

Returns None otherwise, because it is not safe to\nmutate a shared value.

\n

See also make_mut, which will clone\nthe inner value when there are other Rc pointers.

\n
§Examples
\n
use std::rc::Rc;\n\nlet mut x = Rc::new(3);\n*Rc::get_mut(&mut x).unwrap() = 4;\nassert_eq!(*x, 4);\n\nlet _y = Rc::clone(&x);\nassert!(Rc::get_mut(&mut x).is_none());
\n
source

pub unsafe fn get_mut_unchecked(this: &mut Rc<T, A>) -> &mut T

🔬This is a nightly-only experimental API. (get_mut_unchecked)

Returns a mutable reference into the given Rc,\nwithout any check.

\n

See also get_mut, which is safe and does appropriate checks.

\n
§Safety
\n

If any other Rc or Weak pointers to the same allocation exist, then\nthey must not be dereferenced or have active borrows for the duration\nof the returned borrow, and their inner type must be exactly the same as the\ninner type of this Rc (including lifetimes). This is trivially the case if no\nsuch pointers exist, for example immediately after Rc::new.

\n
§Examples
\n
#![feature(get_mut_unchecked)]\n\nuse std::rc::Rc;\n\nlet mut x = Rc::new(String::new());\nunsafe {\n    Rc::get_mut_unchecked(&mut x).push_str(\"foo\")\n}\nassert_eq!(*x, \"foo\");
\n

Other Rc pointers to the same allocation must be to the same type.

\n\n
#![feature(get_mut_unchecked)]\n\nuse std::rc::Rc;\n\nlet x: Rc<str> = Rc::from(\"Hello, world!\");\nlet mut y: Rc<[u8]> = x.clone().into();\nunsafe {\n    // this is Undefined Behavior, because x's inner type is str, not [u8]\n    Rc::get_mut_unchecked(&mut y).fill(0xff); // 0xff is invalid in UTF-8\n}\nprintln!(\"{}\", &*x); // Invalid UTF-8 in a str
\n

Other Rc pointers to the same allocation must be to the exact same type, including lifetimes.

\n\n
#![feature(get_mut_unchecked)]\n\nuse std::rc::Rc;\n\nlet x: Rc<&str> = Rc::new(\"Hello, world!\");\n{\n    let s = String::from(\"Oh, no!\");\n    let mut y: Rc<&str> = x.clone().into();\n    unsafe {\n        // this is Undefined Behavior, because x's inner type\n        // is &'long str, not &'short str\n        *Rc::get_mut_unchecked(&mut y) = &s;\n    }\n}\nprintln!(\"{}\", &*x); // Use-after-free
\n
1.17.0 · source

pub fn ptr_eq(this: &Rc<T, A>, other: &Rc<T, A>) -> bool

Returns true if the two Rcs point to the same allocation in a vein similar to\nptr::eq. This function ignores the metadata of dyn Trait pointers.

\n
§Examples
\n
use std::rc::Rc;\n\nlet five = Rc::new(5);\nlet same_five = Rc::clone(&five);\nlet other_five = Rc::new(5);\n\nassert!(Rc::ptr_eq(&five, &same_five));\nassert!(!Rc::ptr_eq(&five, &other_five));
\n
",0,"awc::connect::BoxConnectorService"],["
source§

impl<T, A> Rc<T, A>
where\n T: Clone,\n A: Allocator + Clone,

1.4.0 · source

pub fn make_mut(this: &mut Rc<T, A>) -> &mut T

Available on non-no_global_oom_handling only.

Makes a mutable reference into the given Rc.

\n

If there are other Rc pointers to the same allocation, then make_mut will\nclone the inner value to a new allocation to ensure unique ownership. This is also\nreferred to as clone-on-write.

\n

However, if there are no other Rc pointers to this allocation, but some Weak\npointers, then the Weak pointers will be disassociated and the inner value will not\nbe cloned.

\n

See also get_mut, which will fail rather than cloning the inner value\nor disassociating Weak pointers.

\n
§Examples
\n
use std::rc::Rc;\n\nlet mut data = Rc::new(5);\n\n*Rc::make_mut(&mut data) += 1;         // Won't clone anything\nlet mut other_data = Rc::clone(&data); // Won't clone inner data\n*Rc::make_mut(&mut data) += 1;         // Clones inner data\n*Rc::make_mut(&mut data) += 1;         // Won't clone anything\n*Rc::make_mut(&mut other_data) *= 2;   // Won't clone anything\n\n// Now `data` and `other_data` point to different allocations.\nassert_eq!(*data, 8);\nassert_eq!(*other_data, 12);
\n

Weak pointers will be disassociated:

\n\n
use std::rc::Rc;\n\nlet mut data = Rc::new(75);\nlet weak = Rc::downgrade(&data);\n\nassert!(75 == *data);\nassert!(75 == *weak.upgrade().unwrap());\n\n*Rc::make_mut(&mut data) += 1;\n\nassert!(76 == *data);\nassert!(weak.upgrade().is_none());
\n
",0,"awc::connect::BoxConnectorService"],["
source§

impl<T, A> Rc<T, A>
where\n T: Clone,\n A: Allocator,

1.76.0 · source

pub fn unwrap_or_clone(this: Rc<T, A>) -> T

If we have the only reference to T then unwrap it. Otherwise, clone T and return the\nclone.

\n

Assuming rc_t is of type Rc<T>, this function is functionally equivalent to\n(*rc_t).clone(), but will avoid cloning the inner value where possible.

\n
§Examples
\n
let inner = String::from(\"test\");\nlet ptr = inner.as_ptr();\n\nlet rc = Rc::new(inner);\nlet inner = Rc::unwrap_or_clone(rc);\n// The inner value was not cloned\nassert!(ptr::eq(ptr, inner.as_ptr()));\n\nlet rc = Rc::new(inner);\nlet rc2 = rc.clone();\nlet inner = Rc::unwrap_or_clone(rc);\n// Because there were 2 references, we had to clone the inner value.\nassert!(!ptr::eq(ptr, inner.as_ptr()));\n// `rc2` is the last reference, so when we unwrap it we get back\n// the original `String`.\nlet inner = Rc::unwrap_or_clone(rc2);\nassert!(ptr::eq(ptr, inner.as_ptr()));
\n
",0,"awc::connect::BoxConnectorService"],["
source§

impl<T, A> Rc<T, A>
where\n A: Allocator,

source

pub fn allocator(this: &Rc<T, A>) -> &A

🔬This is a nightly-only experimental API. (allocator_api)

Returns a reference to the underlying allocator.

\n

Note: this is an associated function, which means that you have\nto call it as Rc::allocator(&r) instead of r.allocator(). This\nis so that there is no conflict with a method on the inner type.

\n
source

pub fn new_in(value: T, alloc: A) -> Rc<T, A>

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Constructs a new Rc in the provided allocator.

\n
§Examples
\n
#![feature(allocator_api)]\nuse std::rc::Rc;\nuse std::alloc::System;\n\nlet five = Rc::new_in(5, System);
\n
source

pub fn new_uninit_in(alloc: A) -> Rc<MaybeUninit<T>, A>

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Constructs a new Rc with uninitialized contents in the provided allocator.

\n
§Examples
\n
#![feature(new_uninit)]\n#![feature(get_mut_unchecked)]\n#![feature(allocator_api)]\n\nuse std::rc::Rc;\nuse std::alloc::System;\n\nlet mut five = Rc::<u32, _>::new_uninit_in(System);\n\nlet five = unsafe {\n    // Deferred initialization:\n    Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);\n\n    five.assume_init()\n};\n\nassert_eq!(*five, 5)
\n
source

pub fn new_zeroed_in(alloc: A) -> Rc<MaybeUninit<T>, A>

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Constructs a new Rc with uninitialized contents, with the memory\nbeing filled with 0 bytes, in the provided allocator.

\n

See MaybeUninit::zeroed for examples of correct and\nincorrect usage of this method.

\n
§Examples
\n
#![feature(new_uninit)]\n#![feature(allocator_api)]\n\nuse std::rc::Rc;\nuse std::alloc::System;\n\nlet zero = Rc::<u32, _>::new_zeroed_in(System);\nlet zero = unsafe { zero.assume_init() };\n\nassert_eq!(*zero, 0)
\n
source

pub fn try_new_in(value: T, alloc: A) -> Result<Rc<T, A>, AllocError>

🔬This is a nightly-only experimental API. (allocator_api)

Constructs a new Rc<T> in the provided allocator, returning an error if the allocation\nfails

\n
§Examples
\n
#![feature(allocator_api)]\nuse std::rc::Rc;\nuse std::alloc::System;\n\nlet five = Rc::try_new_in(5, System);
\n
source

pub fn try_new_uninit_in(alloc: A) -> Result<Rc<MaybeUninit<T>, A>, AllocError>

🔬This is a nightly-only experimental API. (allocator_api)

Constructs a new Rc with uninitialized contents, in the provided allocator, returning an\nerror if the allocation fails

\n
§Examples
\n
#![feature(allocator_api, new_uninit)]\n#![feature(get_mut_unchecked)]\n\nuse std::rc::Rc;\nuse std::alloc::System;\n\nlet mut five = Rc::<u32, _>::try_new_uninit_in(System)?;\n\nlet five = unsafe {\n    // Deferred initialization:\n    Rc::get_mut_unchecked(&mut five).as_mut_ptr().write(5);\n\n    five.assume_init()\n};\n\nassert_eq!(*five, 5);
\n
source

pub fn try_new_zeroed_in(alloc: A) -> Result<Rc<MaybeUninit<T>, A>, AllocError>

🔬This is a nightly-only experimental API. (allocator_api)

Constructs a new Rc with uninitialized contents, with the memory\nbeing filled with 0 bytes, in the provided allocator, returning an error if the allocation\nfails

\n

See MaybeUninit::zeroed for examples of correct and\nincorrect usage of this method.

\n
§Examples
\n
#![feature(allocator_api, new_uninit)]\n\nuse std::rc::Rc;\nuse std::alloc::System;\n\nlet zero = Rc::<u32, _>::try_new_zeroed_in(System)?;\nlet zero = unsafe { zero.assume_init() };\n\nassert_eq!(*zero, 0);
\n
source

pub fn pin_in(value: T, alloc: A) -> Pin<Rc<T, A>>
where\n A: 'static,

🔬This is a nightly-only experimental API. (allocator_api)
Available on non-no_global_oom_handling only.

Constructs a new Pin<Rc<T>> in the provided allocator. If T does not implement Unpin, then\nvalue will be pinned in memory and unable to be moved.

\n
1.4.0 · source

pub fn try_unwrap(this: Rc<T, A>) -> Result<T, Rc<T, A>>

Returns the inner value, if the Rc has exactly one strong reference.

\n

Otherwise, an Err is returned with the same Rc that was\npassed in.

\n

This will succeed even if there are outstanding weak references.

\n
§Examples
\n
use std::rc::Rc;\n\nlet x = Rc::new(3);\nassert_eq!(Rc::try_unwrap(x), Ok(3));\n\nlet x = Rc::new(4);\nlet _y = Rc::clone(&x);\nassert_eq!(*Rc::try_unwrap(x).unwrap_err(), 4);
\n
1.70.0 · source

pub fn into_inner(this: Rc<T, A>) -> Option<T>

Returns the inner value, if the Rc has exactly one strong reference.

\n

Otherwise, None is returned and the Rc is dropped.

\n

This will succeed even if there are outstanding weak references.

\n

If Rc::into_inner is called on every clone of this Rc,\nit is guaranteed that exactly one of the calls returns the inner value.\nThis means in particular that the inner value is not dropped.

\n

Rc::try_unwrap is conceptually similar to Rc::into_inner.\nAnd while they are meant for different use-cases, Rc::into_inner(this)\nis in fact equivalent to Rc::try_unwrap(this).ok().\n(Note that the same kind of equivalence does not hold true for\nArc, due to race conditions that do not apply to Rc!)

\n
§Examples
\n
use std::rc::Rc;\n\nlet x = Rc::new(3);\nassert_eq!(Rc::into_inner(x), Some(3));\n\nlet x = Rc::new(4);\nlet y = Rc::clone(&x);\n\nassert_eq!(Rc::into_inner(y), None);\nassert_eq!(Rc::into_inner(x), Some(4));
\n
",0,"awc::connect::BoxConnectorService"],["
§

impl<S, Req> Service<Req> for Rc<S>
where\n S: Service<Req> + ?Sized,

§

type Response = <S as Service<Req>>::Response

Responses given by the service.
§

type Error = <S as Service<Req>>::Error

Errors produced by the service when polling readiness or executing call.
§

type Future = <S as Service<Req>>::Future

The future response value.
§

fn poll_ready(\n &self,\n ctx: &mut Context<'_>\n) -> Poll<Result<(), <Rc<S> as Service<Req>>::Error>>

Returns Ready when the service is able to process requests. Read more
§

fn call(&self, request: Req) -> <S as Service<Req>>::Future

Process the request and return the response asynchronously. Read more
","Service","awc::connect::BoxConnectorService"],["
§

impl<S, Req> ServiceFactory<Req> for Rc<S>
where\n S: ServiceFactory<Req>,

§

type Response = <S as ServiceFactory<Req>>::Response

Responses given by the created services.
§

type Error = <S as ServiceFactory<Req>>::Error

Errors produced by the created services.
§

type Config = <S as ServiceFactory<Req>>::Config

Service factory configuration.
§

type Service = <S as ServiceFactory<Req>>::Service

The kind of Service created by this factory.
§

type InitError = <S as ServiceFactory<Req>>::InitError

Errors potentially raised while building a service.
§

type Future = <S as ServiceFactory<Req>>::Future

The future of the Service instance.g
§

fn new_service(\n &self,\n cfg: <S as ServiceFactory<Req>>::Config\n) -> <S as ServiceFactory<Req>>::Future

Create and return a new service asynchronously.
","ServiceFactory","awc::connect::BoxConnectorService"],["
§

impl<Sp> Spawn for Rc<Sp>
where\n Sp: Spawn + ?Sized,

§

fn spawn_obj(&self, future: FutureObj<'static, ()>) -> Result<(), SpawnError>

Spawns a future that will be run to completion. Read more
§

fn status(&self) -> Result<(), SpawnError>

Determines whether the executor is able to spawn new tasks. Read more
","Spawn","awc::connect::BoxConnectorService"],["
§

impl<T, S, Req> Transform<S, Req> for Rc<T>
where\n T: Transform<S, Req>,

§

type Response = <T as Transform<S, Req>>::Response

Responses produced by the service.
§

type Error = <T as Transform<S, Req>>::Error

Errors produced by the service.
§

type Transform = <T as Transform<S, Req>>::Transform

The TransformService value created by this factory
§

type InitError = <T as Transform<S, Req>>::InitError

Errors produced while building a transform service.
§

type Future = <T as Transform<S, Req>>::Future

The future response value.
§

fn new_transform(&self, service: S) -> <T as Transform<S, Req>>::Future

Creates and returns a new Transform component, asynchronously
","Transform","awc::connect::BoxConnectorService"],["
source§

impl<T, U, A> CoerceUnsized<Rc<U, A>> for Rc<T, A>
where\n T: Unsize<U> + ?Sized,\n A: Allocator,\n U: ?Sized,

","CoerceUnsized>","awc::connect::BoxConnectorService"],["
source§

impl<T, A> DerefPure for Rc<T, A>
where\n A: Allocator,\n T: ?Sized,

","DerefPure","awc::connect::BoxConnectorService"],["
source§

impl<T, U> DispatchFromDyn<Rc<U>> for Rc<T>
where\n T: Unsize<U> + ?Sized,\n U: ?Sized,

","DispatchFromDyn>","awc::connect::BoxConnectorService"],["
1.0.0 · source§

impl<T, A> Eq for Rc<T, A>
where\n T: Eq + ?Sized,\n A: Allocator,

","Eq","awc::connect::BoxConnectorService"],["
1.58.0 · source§

impl<T, A> RefUnwindSafe for Rc<T, A>
where\n T: RefUnwindSafe + ?Sized,\n A: Allocator + UnwindSafe,

","RefUnwindSafe","awc::connect::BoxConnectorService"],["
1.0.0 · source§

impl<T, A> !Send for Rc<T, A>
where\n A: Allocator,\n T: ?Sized,

","Send","awc::connect::BoxConnectorService"],["
1.0.0 · source§

impl<T, A> !Sync for Rc<T, A>
where\n A: Allocator,\n T: ?Sized,

","Sync","awc::connect::BoxConnectorService"],["
1.33.0 · source§

impl<T, A> Unpin for Rc<T, A>
where\n A: Allocator,\n T: ?Sized,

","Unpin","awc::connect::BoxConnectorService"],["
1.9.0 · source§

impl<T, A> UnwindSafe for Rc<T, A>
where\n T: RefUnwindSafe + ?Sized,\n A: Allocator + UnwindSafe,

","UnwindSafe","awc::connect::BoxConnectorService"]] +};if (window.register_type_impls) {window.register_type_impls(type_impls);} else {window.pending_type_impls = type_impls;}})() \ No newline at end of file diff --git a/type.impl/awc/struct.ResponseBody.js b/type.impl/awc/struct.ResponseBody.js new file mode 100644 index 000000000..d08b48d10 --- /dev/null +++ b/type.impl/awc/struct.ResponseBody.js @@ -0,0 +1,3 @@ +(function() {var type_impls = { +"awc":[["
source§

impl<S> Future for ResponseBody<S>
where\n S: Stream<Item = Result<Bytes, PayloadError>>,

§

type Output = Result<Bytes, PayloadError>

The type of value produced on completion.
source§

fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>

Attempt to resolve the future to a final value, registering\nthe current task for wakeup if the value is not yet available. Read more
","Future","awc::responses::response_body::MessageBody"],["
source§

impl<S> ResponseBody<S>
where\n S: Stream<Item = Result<Bytes, PayloadError>>,

source

pub fn new(res: &mut ClientResponse<S>) -> ResponseBody<S>

Creates a body stream reader from a response by taking its payload.

\n
source

pub fn limit(self, limit: usize) -> Self

Change max size limit of payload.

\n

The default limit is 2 MiB.

\n
",0,"awc::responses::response_body::MessageBody"],["
source§

impl<'__pin, S> Unpin for ResponseBody<S>
where\n __Origin<'__pin, S>: Unpin,

","Unpin","awc::responses::response_body::MessageBody"]] +};if (window.register_type_impls) {window.register_type_impls(type_impls);} else {window.pending_type_impls = type_impls;}})() \ No newline at end of file diff --git a/type.impl/core/pin/struct.Pin.js b/type.impl/core/pin/struct.Pin.js new file mode 100644 index 000000000..0667a144d --- /dev/null +++ b/type.impl/core/pin/struct.Pin.js @@ -0,0 +1,3 @@ +(function() {var type_impls = { +"actix_http":[["
§

impl<P> AsyncBufRead for Pin<P>
where\n P: DerefMut + Unpin,\n <P as Deref>::Target: AsyncBufRead,

§

fn poll_fill_buf(\n self: Pin<&mut Pin<P>>,\n cx: &mut Context<'_>\n) -> Poll<Result<&[u8], Error>>

Attempts to return the contents of the internal buffer, filling it with more data\nfrom the inner reader if it is empty. Read more
§

fn consume(self: Pin<&mut Pin<P>>, amt: usize)

Tells this buffer that amt bytes have been consumed from the buffer,\nso they should no longer be returned in calls to poll_read. Read more
","AsyncBufRead","actix_http::payload::BoxedPayloadStream"],["
source§

impl<P> AsyncIterator for Pin<P>
where\n P: DerefMut,\n <P as Deref>::Target: AsyncIterator,

§

type Item = <<P as Deref>::Target as AsyncIterator>::Item

🔬This is a nightly-only experimental API. (async_iterator)
The type of items yielded by the async iterator.
source§

fn poll_next(\n self: Pin<&mut Pin<P>>,\n cx: &mut Context<'_>\n) -> Poll<Option<<Pin<P> as AsyncIterator>::Item>>

🔬This is a nightly-only experimental API. (async_iterator)
Attempt to pull out the next value of this async iterator, registering the\ncurrent task for wakeup if the value is not yet available, and returning\nNone if the async iterator is exhausted. Read more
source§

fn size_hint(&self) -> (usize, Option<usize>)

🔬This is a nightly-only experimental API. (async_iterator)
Returns the bounds on the remaining length of the async iterator. Read more
","AsyncIterator","actix_http::payload::BoxedPayloadStream"],["
§

impl<P> AsyncRead for Pin<P>
where\n P: DerefMut + Unpin,\n <P as Deref>::Target: AsyncRead,

§

fn poll_read(\n self: Pin<&mut Pin<P>>,\n cx: &mut Context<'_>,\n buf: &mut ReadBuf<'_>\n) -> Poll<Result<(), Error>>

Attempts to read from the AsyncRead into buf. Read more
","AsyncRead","actix_http::payload::BoxedPayloadStream"],["
§

impl<P> AsyncSeek for Pin<P>
where\n P: DerefMut + Unpin,\n <P as Deref>::Target: AsyncSeek,

§

fn start_seek(self: Pin<&mut Pin<P>>, pos: SeekFrom) -> Result<(), Error>

Attempts to seek to an offset, in bytes, in a stream. Read more
§

fn poll_complete(\n self: Pin<&mut Pin<P>>,\n cx: &mut Context<'_>\n) -> Poll<Result<u64, Error>>

Waits for a seek operation to complete. Read more
","AsyncSeek","actix_http::payload::BoxedPayloadStream"],["
§

impl<P> AsyncWrite for Pin<P>
where\n P: DerefMut + Unpin,\n <P as Deref>::Target: AsyncWrite,

§

fn poll_write(\n self: Pin<&mut Pin<P>>,\n cx: &mut Context<'_>,\n buf: &[u8]\n) -> Poll<Result<usize, Error>>

Attempt to write bytes from buf into the object. Read more
§

fn poll_write_vectored(\n self: Pin<&mut Pin<P>>,\n cx: &mut Context<'_>,\n bufs: &[IoSlice<'_>]\n) -> Poll<Result<usize, Error>>

Like poll_write, except that it writes from a slice of buffers. Read more
§

fn is_write_vectored(&self) -> bool

Determines if this writer has an efficient poll_write_vectored\nimplementation. Read more
§

fn poll_flush(\n self: Pin<&mut Pin<P>>,\n cx: &mut Context<'_>\n) -> Poll<Result<(), Error>>

Attempts to flush the object, ensuring that any buffered data reach\ntheir destination. Read more
§

fn poll_shutdown(\n self: Pin<&mut Pin<P>>,\n cx: &mut Context<'_>\n) -> Poll<Result<(), Error>>

Initiates or attempts to shut down this writer, returning success when\nthe I/O connection has completely shut down. Read more
","AsyncWrite","actix_http::payload::BoxedPayloadStream"],["
1.33.0 · source§

impl<Ptr> Clone for Pin<Ptr>
where\n Ptr: Clone,

source§

fn clone(&self) -> Pin<Ptr>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
","Clone","actix_http::payload::BoxedPayloadStream"],["
source§

impl<G, R, A> Coroutine<R> for Pin<Box<G, A>>
where\n G: Coroutine<R> + ?Sized,\n A: Allocator + 'static,

§

type Yield = <G as Coroutine<R>>::Yield

🔬This is a nightly-only experimental API. (coroutine_trait)
The type of value this coroutine yields. Read more
§

type Return = <G as Coroutine<R>>::Return

🔬This is a nightly-only experimental API. (coroutine_trait)
The type of value this coroutine returns. Read more
source§

fn resume(\n self: Pin<&mut Pin<Box<G, A>>>,\n arg: R\n) -> CoroutineState<<Pin<Box<G, A>> as Coroutine<R>>::Yield, <Pin<Box<G, A>> as Coroutine<R>>::Return>

🔬This is a nightly-only experimental API. (coroutine_trait)
Resumes the execution of this coroutine. Read more
","Coroutine","actix_http::payload::BoxedPayloadStream"],["
1.33.0 · source§

impl<Ptr> Debug for Pin<Ptr>
where\n Ptr: Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
","Debug","actix_http::payload::BoxedPayloadStream"],["
1.33.0 · source§

impl<Ptr> Deref for Pin<Ptr>
where\n Ptr: Deref,

§

type Target = <Ptr as Deref>::Target

The resulting type after dereferencing.
source§

fn deref(&self) -> &<Ptr as Deref>::Target

Dereferences the value.
","Deref","actix_http::payload::BoxedPayloadStream"],["
1.33.0 · source§

impl<Ptr> DerefMut for Pin<Ptr>
where\n Ptr: DerefMut,\n <Ptr as Deref>::Target: Unpin,

source§

fn deref_mut(&mut self) -> &mut <Ptr as Deref>::Target

Mutably dereferences the value.
","DerefMut","actix_http::payload::BoxedPayloadStream"],["
1.33.0 · source§

impl<Ptr> Display for Pin<Ptr>
where\n Ptr: Display,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
","Display","actix_http::payload::BoxedPayloadStream"],["
1.33.0 · source§

impl<T, A> From<Box<T, A>> for Pin<Box<T, A>>
where\n A: Allocator + 'static,\n T: ?Sized,

source§

fn from(boxed: Box<T, A>) -> Pin<Box<T, A>>

Converts a Box<T> into a Pin<Box<T>>. If T does not implement Unpin, then\n*boxed will be pinned in memory and unable to be moved.

\n

This conversion does not allocate on the heap and happens in place.

\n

This is also available via Box::into_pin.

\n

Constructing and pinning a Box with <Pin<Box<T>>>::from(Box::new(x))\ncan also be written more concisely using Box::pin(x).\nThis From implementation is useful if you already have a Box<T>, or you are\nconstructing a (pinned) Box in a different way than with Box::new.

\n
","From>","actix_http::payload::BoxedPayloadStream"],["
§

impl<P> FusedFuture for Pin<P>
where\n P: DerefMut + Unpin,\n <P as Deref>::Target: FusedFuture,

§

fn is_terminated(&self) -> bool

Returns true if the underlying future should no longer be polled.
","FusedFuture","actix_http::payload::BoxedPayloadStream"],["
§

impl<P> FusedStream for Pin<P>
where\n P: DerefMut + Unpin,\n <P as Deref>::Target: FusedStream,

§

fn is_terminated(&self) -> bool

Returns true if the stream should no longer be polled.
","FusedStream","actix_http::payload::BoxedPayloadStream"],["
1.36.0 · source§

impl<P> Future for Pin<P>
where\n P: DerefMut,\n <P as Deref>::Target: Future,

§

type Output = <<P as Deref>::Target as Future>::Output

The type of value produced on completion.
source§

fn poll(\n self: Pin<&mut Pin<P>>,\n cx: &mut Context<'_>\n) -> Poll<<Pin<P> as Future>::Output>

Attempt to resolve the future to a final value, registering\nthe current task for wakeup if the value is not yet available. Read more
","Future","actix_http::payload::BoxedPayloadStream"],["
1.41.0 · source§

impl<Ptr> Hash for Pin<Ptr>
where\n Ptr: Deref,\n <Ptr as Deref>::Target: Hash,

source§

fn hash<H>(&self, state: &mut H)
where\n H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where\n H: Hasher,\n Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
","Hash","actix_http::payload::BoxedPayloadStream"],["
source§

impl<T, B> MessageBody for Pin<T>
where\n T: DerefMut<Target = B> + Unpin,\n B: MessageBody + ?Sized,

§

type Error = <B as MessageBody>::Error

The type of error that will be returned if streaming body fails. Read more
source§

fn size(&self) -> BodySize

Body size hint. Read more
source§

fn poll_next(\n self: Pin<&mut Self>,\n cx: &mut Context<'_>\n) -> Poll<Option<Result<Bytes, Self::Error>>>

Attempt to pull out the next chunk of body bytes. Read more
source§

fn try_into_bytes(self) -> Result<Bytes, Self>
where\n Self: Sized,

Try to convert into the complete chunk of body bytes. Read more
source§

fn boxed(self) -> BoxBody
where\n Self: Sized + 'static,

Wraps this body into a BoxBody. Read more
","MessageBody","actix_http::payload::BoxedPayloadStream"],["
1.41.0 · source§

impl<Ptr> Ord for Pin<Ptr>
where\n Ptr: Deref,\n <Ptr as Deref>::Target: Ord,

source§

fn cmp(&self, other: &Pin<Ptr>) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where\n Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where\n Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where\n Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
","Ord","actix_http::payload::BoxedPayloadStream"],["
1.41.0 · source§

impl<Ptr, Q> PartialEq<Pin<Q>> for Pin<Ptr>
where\n Ptr: Deref,\n Q: Deref,\n <Ptr as Deref>::Target: PartialEq<<Q as Deref>::Target>,

source§

fn eq(&self, other: &Pin<Q>) -> bool

This method tests for self and other values to be equal, and is used\nby ==.
source§

fn ne(&self, other: &Pin<Q>) -> bool

This method tests for !=. The default implementation is almost always\nsufficient, and should not be overridden without very good reason.
","PartialEq>","actix_http::payload::BoxedPayloadStream"],["
1.41.0 · source§

impl<Ptr, Q> PartialOrd<Pin<Q>> for Pin<Ptr>
where\n Ptr: Deref,\n Q: Deref,\n <Ptr as Deref>::Target: PartialOrd<<Q as Deref>::Target>,

source§

fn partial_cmp(&self, other: &Pin<Q>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
source§

fn lt(&self, other: &Pin<Q>) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
source§

fn le(&self, other: &Pin<Q>) -> bool

This method tests less than or equal to (for self and other) and is used by the <=\noperator. Read more
source§

fn gt(&self, other: &Pin<Q>) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
source§

fn ge(&self, other: &Pin<Q>) -> bool

This method tests greater than or equal to (for self and other) and is used by the >=\noperator. Read more
","PartialOrd>","actix_http::payload::BoxedPayloadStream"],["
source§

impl<Ptr> Pin<Ptr>
where\n Ptr: Deref,\n <Ptr as Deref>::Target: Unpin,

1.33.0 (const: unstable) · source

pub fn new(pointer: Ptr) -> Pin<Ptr>

Construct a new Pin<Ptr> around a pointer to some data of a type that\nimplements Unpin.

\n

Unlike Pin::new_unchecked, this method is safe because the pointer\nPtr dereferences to an Unpin type, which cancels the pinning guarantees.

\n
§Examples
\n
use std::pin::Pin;\n\nlet mut val: u8 = 5;\n\n// Since `val` doesn't care about being moved, we can safely create a \"facade\" `Pin`\n// which will allow `val` to participate in `Pin`-bound apis  without checking that\n// pinning guarantees are actually upheld.\nlet mut pinned: Pin<&mut u8> = Pin::new(&mut val);
\n
1.39.0 (const: unstable) · source

pub fn into_inner(pin: Pin<Ptr>) -> Ptr

Unwraps this Pin<Ptr>, returning the underlying pointer.

\n

Doing this operation safely requires that the data pointed at by this pinning pointer\nimplements Unpin so that we can ignore the pinning invariants when unwrapping it.

\n
§Examples
\n
use std::pin::Pin;\n\nlet mut val: u8 = 5;\nlet pinned: Pin<&mut u8> = Pin::new(&mut val);\n\n// Unwrap the pin to get the underlying mutable reference to the value. We can do\n// this because `val` doesn't care about being moved, so the `Pin` was just\n// a \"facade\" anyway.\nlet r = Pin::into_inner(pinned);\nassert_eq!(*r, 5);
\n
",0,"actix_http::payload::BoxedPayloadStream"],["
source§

impl<Ptr> Pin<Ptr>
where\n Ptr: Deref,

1.33.0 (const: unstable) · source

pub unsafe fn new_unchecked(pointer: Ptr) -> Pin<Ptr>

Construct a new Pin<Ptr> around a reference to some data of a type that\nmay or may not implement Unpin.

\n

If pointer dereferences to an Unpin type, Pin::new should be used\ninstead.

\n
§Safety
\n

This constructor is unsafe because we cannot guarantee that the data\npointed to by pointer is pinned. At its core, pinning a value means making the\nguarantee that the value’s data will not be moved nor have its storage invalidated until\nit gets dropped. For a more thorough explanation of pinning, see the pin module docs.

\n

If the caller that is constructing this Pin<Ptr> does not ensure that the data Ptr\npoints to is pinned, that is a violation of the API contract and may lead to undefined\nbehavior in later (even safe) operations.

\n

By using this method, you are also making a promise about the Deref and\nDerefMut implementations of Ptr, if they exist. Most importantly, they\nmust not move out of their self arguments: Pin::as_mut and Pin::as_ref\nwill call DerefMut::deref_mut and Deref::deref on the pointer type Ptr\nand expect these methods to uphold the pinning invariants.\nMoreover, by calling this method you promise that the reference Ptr\ndereferences to will not be moved out of again; in particular, it\nmust not be possible to obtain a &mut Ptr::Target and then\nmove out of that reference (using, for example mem::swap).

\n

For example, calling Pin::new_unchecked on an &'a mut T is unsafe because\nwhile you are able to pin it for the given lifetime 'a, you have no control\nover whether it is kept pinned once 'a ends, and therefore cannot uphold the\nguarantee that a value, once pinned, remains pinned until it is dropped:

\n\n
use std::mem;\nuse std::pin::Pin;\n\nfn move_pinned_ref<T>(mut a: T, mut b: T) {\n    unsafe {\n        let p: Pin<&mut T> = Pin::new_unchecked(&mut a);\n        // This should mean the pointee `a` can never move again.\n    }\n    mem::swap(&mut a, &mut b); // Potential UB down the road ⚠️\n    // The address of `a` changed to `b`'s stack slot, so `a` got moved even\n    // though we have previously pinned it! We have violated the pinning API contract.\n}
\n

A value, once pinned, must remain pinned until it is dropped (unless its type implements\nUnpin). Because Pin<&mut T> does not own the value, dropping the Pin will not drop\nthe value and will not end the pinning contract. So moving the value after dropping the\nPin<&mut T> is still a violation of the API contract.

\n

Similarly, calling Pin::new_unchecked on an Rc<T> is unsafe because there could be\naliases to the same data that are not subject to the pinning restrictions:

\n\n
use std::rc::Rc;\nuse std::pin::Pin;\n\nfn move_pinned_rc<T>(mut x: Rc<T>) {\n    // This should mean the pointee can never move again.\n    let pin = unsafe { Pin::new_unchecked(Rc::clone(&x)) };\n    {\n        let p: Pin<&T> = pin.as_ref();\n        // ...\n    }\n    drop(pin);\n\n    let content = Rc::get_mut(&mut x).unwrap(); // Potential UB down the road ⚠️\n    // Now, if `x` was the only reference, we have a mutable reference to\n    // data that we pinned above, which we could use to move it as we have\n    // seen in the previous example. We have violated the pinning API contract.\n }
\n
§Pinning of closure captures
\n

Particular care is required when using Pin::new_unchecked in a closure:\nPin::new_unchecked(&mut var) where var is a by-value (moved) closure capture\nimplicitly makes the promise that the closure itself is pinned, and that all uses\nof this closure capture respect that pinning.

\n\n
use std::pin::Pin;\nuse std::task::Context;\nuse std::future::Future;\n\nfn move_pinned_closure(mut x: impl Future, cx: &mut Context<'_>) {\n    // Create a closure that moves `x`, and then internally uses it in a pinned way.\n    let mut closure = move || unsafe {\n        let _ignore = Pin::new_unchecked(&mut x).poll(cx);\n    };\n    // Call the closure, so the future can assume it has been pinned.\n    closure();\n    // Move the closure somewhere else. This also moves `x`!\n    let mut moved = closure;\n    // Calling it again means we polled the future from two different locations,\n    // violating the pinning API contract.\n    moved(); // Potential UB ⚠️\n}
\n

When passing a closure to another API, it might be moving the closure any time, so\nPin::new_unchecked on closure captures may only be used if the API explicitly documents\nthat the closure is pinned.

\n

The better alternative is to avoid all that trouble and do the pinning in the outer function\ninstead (here using the pin! macro):

\n\n
use std::pin::pin;\nuse std::task::Context;\nuse std::future::Future;\n\nfn move_pinned_closure(mut x: impl Future, cx: &mut Context<'_>) {\n    let mut x = pin!(x);\n    // Create a closure that captures `x: Pin<&mut _>`, which is safe to move.\n    let mut closure = move || {\n        let _ignore = x.as_mut().poll(cx);\n    };\n    // Call the closure, so the future can assume it has been pinned.\n    closure();\n    // Move the closure somewhere else.\n    let mut moved = closure;\n    // Calling it again here is fine (except that we might be polling a future that already\n    // returned `Poll::Ready`, but that is a separate problem).\n    moved();\n}
\n
1.33.0 · source

pub fn as_ref(&self) -> Pin<&<Ptr as Deref>::Target>

Gets a shared reference to the pinned value this Pin points to.

\n

This is a generic method to go from &Pin<Pointer<T>> to Pin<&T>.\nIt is safe because, as part of the contract of Pin::new_unchecked,\nthe pointee cannot move after Pin<Pointer<T>> got created.\n“Malicious” implementations of Pointer::Deref are likewise\nruled out by the contract of Pin::new_unchecked.

\n
1.39.0 (const: unstable) · source

pub unsafe fn into_inner_unchecked(pin: Pin<Ptr>) -> Ptr

Unwraps this Pin<Ptr>, returning the underlying Ptr.

\n
§Safety
\n

This function is unsafe. You must guarantee that you will continue to\ntreat the pointer Ptr as pinned after you call this function, so that\nthe invariants on the Pin type can be upheld. If the code using the\nresulting Ptr does not continue to maintain the pinning invariants that\nis a violation of the API contract and may lead to undefined behavior in\nlater (safe) operations.

\n

Note that you must be able to guarantee that the data pointed to by Ptr\nwill be treated as pinned all the way until its drop handler is complete!

\n

For more information, see the pin module docs

\n

If the underlying data is Unpin, Pin::into_inner should be used\ninstead.

\n
",0,"actix_http::payload::BoxedPayloadStream"],["
source§

impl<Ptr> Pin<Ptr>
where\n Ptr: DerefMut,

1.33.0 · source

pub fn as_mut(&mut self) -> Pin<&mut <Ptr as Deref>::Target>

Gets a mutable reference to the pinned value this Pin<Ptr> points to.

\n

This is a generic method to go from &mut Pin<Pointer<T>> to Pin<&mut T>.\nIt is safe because, as part of the contract of Pin::new_unchecked,\nthe pointee cannot move after Pin<Pointer<T>> got created.\n“Malicious” implementations of Pointer::DerefMut are likewise\nruled out by the contract of Pin::new_unchecked.

\n

This method is useful when doing multiple calls to functions that consume the\npinning pointer.

\n
§Example
\n
use std::pin::Pin;\n\nimpl Type {\n    fn method(self: Pin<&mut Self>) {\n        // do something\n    }\n\n    fn call_method_twice(mut self: Pin<&mut Self>) {\n        // `method` consumes `self`, so reborrow the `Pin<&mut Self>` via `as_mut`.\n        self.as_mut().method();\n        self.as_mut().method();\n    }\n}
\n
1.33.0 · source

pub fn set(&mut self, value: <Ptr as Deref>::Target)
where\n <Ptr as Deref>::Target: Sized,

Assigns a new value to the memory location pointed to by the Pin<Ptr>.

\n

This overwrites pinned data, but that is okay: the original pinned value’s destructor gets\nrun before being overwritten and the new value is also a valid value of the same type, so\nno pinning invariant is violated. See the pin module documentation\nfor more information on how this upholds the pinning invariants.

\n
§Example
\n
use std::pin::Pin;\n\nlet mut val: u8 = 5;\nlet mut pinned: Pin<&mut u8> = Pin::new(&mut val);\nprintln!(\"{}\", pinned); // 5\npinned.set(10);\nprintln!(\"{}\", pinned); // 10
\n
",0,"actix_http::payload::BoxedPayloadStream"],["
1.33.0 · source§

impl<Ptr> Pointer for Pin<Ptr>
where\n Ptr: Pointer,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
","Pointer","actix_http::payload::BoxedPayloadStream"],["
§

impl<P, Item> Sink<Item> for Pin<P>
where\n P: DerefMut + Unpin,\n <P as Deref>::Target: Sink<Item>,

§

type Error = <<P as Deref>::Target as Sink<Item>>::Error

The type of value produced by the sink when an error occurs.
§

fn poll_ready(\n self: Pin<&mut Pin<P>>,\n cx: &mut Context<'_>\n) -> Poll<Result<(), <Pin<P> as Sink<Item>>::Error>>

Attempts to prepare the Sink to receive a value. Read more
§

fn start_send(\n self: Pin<&mut Pin<P>>,\n item: Item\n) -> Result<(), <Pin<P> as Sink<Item>>::Error>

Begin the process of sending a value to the sink.\nEach call to this function must be preceded by a successful call to\npoll_ready which returned Poll::Ready(Ok(())). Read more
§

fn poll_flush(\n self: Pin<&mut Pin<P>>,\n cx: &mut Context<'_>\n) -> Poll<Result<(), <Pin<P> as Sink<Item>>::Error>>

Flush any remaining output from this sink. Read more
§

fn poll_close(\n self: Pin<&mut Pin<P>>,\n cx: &mut Context<'_>\n) -> Poll<Result<(), <Pin<P> as Sink<Item>>::Error>>

Flush any remaining output and close this sink, if necessary. Read more
","Sink","actix_http::payload::BoxedPayloadStream"],["
§

impl<P> Stream for Pin<P>
where\n P: DerefMut + Unpin,\n <P as Deref>::Target: Stream,

§

type Item = <<P as Deref>::Target as Stream>::Item

Values yielded by the stream.
§

fn poll_next(\n self: Pin<&mut Pin<P>>,\n cx: &mut Context<'_>\n) -> Poll<Option<<Pin<P> as Stream>::Item>>

Attempt to pull out the next value of this stream, registering the\ncurrent task for wakeup if the value is not yet available, and returning\nNone if the stream is exhausted. Read more
§

fn size_hint(&self) -> (usize, Option<usize>)

Returns the bounds on the remaining length of the stream. Read more
","Stream","actix_http::payload::BoxedPayloadStream"],["
§

impl<'a, T, F> UnsafeFutureObj<'a, T> for Pin<Box<F>>
where\n F: Future<Output = T> + 'a,

§

fn into_raw(self) -> *mut dyn Future<Output = T> + 'a

Convert an owned instance into a (conceptually owned) fat pointer. Read more
§

unsafe fn drop(ptr: *mut dyn Future<Output = T> + 'a)

Drops the future represented by the given fat pointer. Read more
","UnsafeFutureObj<'a, T>","actix_http::payload::BoxedPayloadStream"],["
1.33.0 · source§

impl<Ptr, U> CoerceUnsized<Pin<U>> for Pin<Ptr>
where\n Ptr: CoerceUnsized<U>,

","CoerceUnsized>","actix_http::payload::BoxedPayloadStream"],["
1.33.0 · source§

impl<Ptr> Copy for Pin<Ptr>
where\n Ptr: Copy,

","Copy","actix_http::payload::BoxedPayloadStream"],["
source§

impl<Ptr> DerefPure for Pin<Ptr>
where\n Ptr: DerefPure,

","DerefPure","actix_http::payload::BoxedPayloadStream"],["
1.33.0 · source§

impl<Ptr, U> DispatchFromDyn<Pin<U>> for Pin<Ptr>
where\n Ptr: DispatchFromDyn<U>,

","DispatchFromDyn>","actix_http::payload::BoxedPayloadStream"],["
1.41.0 · source§

impl<Ptr> Eq for Pin<Ptr>
where\n Ptr: Deref,\n <Ptr as Deref>::Target: Eq,

","Eq","actix_http::payload::BoxedPayloadStream"]] +};if (window.register_type_impls) {window.register_type_impls(type_impls);} else {window.pending_type_impls = type_impls;}})() \ No newline at end of file diff --git a/type.impl/core/result/enum.Result.js b/type.impl/core/result/enum.Result.js new file mode 100644 index 000000000..fddb1d69c --- /dev/null +++ b/type.impl/core/result/enum.Result.js @@ -0,0 +1,3 @@ +(function() {var type_impls = { +"actix_web":[["
1.0.0 · source§

impl<T, E> Clone for Result<T, E>
where\n T: Clone,\n E: Clone,

source§

fn clone(&self) -> Result<T, E>

Returns a copy of the value. Read more
source§

fn clone_from(&mut self, source: &Result<T, E>)

Performs copy-assignment from source. Read more
","Clone","actix_web::error::Result","actix_web::cookie::time::Result"],["
1.0.0 · source§

impl<T, E> Debug for Result<T, E>
where\n T: Debug,\n E: Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
","Debug","actix_web::error::Result","actix_web::cookie::time::Result"],["
source§

impl<'de, T, E> Deserialize<'de> for Result<T, E>
where\n T: Deserialize<'de>,\n E: Deserialize<'de>,

source§

fn deserialize<D>(\n deserializer: D\n) -> Result<Result<T, E>, <D as Deserializer<'de>>::Error>
where\n D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
","Deserialize<'de>","actix_web::error::Result","actix_web::cookie::time::Result"],["
source§

impl From<&StreamResult> for Result<MZStatus, MZError>

source§

fn from(res: &StreamResult) -> Result<MZStatus, MZError>

Converts to this type from the input type.
","From<&StreamResult>","actix_web::error::Result"],["
§

impl From<&StreamResult> for Result<MZStatus, MZError>

§

fn from(res: &StreamResult) -> Result<MZStatus, MZError>

Converts to this type from the input type.
","From<&StreamResult>","actix_web::error::Result"],["
§

impl From<Errors> for Result<(), Errors>

§

fn from(e: Errors) -> Result<(), Errors>

Converts to this type from the input type.
","From","actix_web::error::Result"],["
source§

impl From<Result> for Result<(), Unspecified>

source§

fn from(ret: Result) -> Result<(), Unspecified>

Converts to this type from the input type.
","From","actix_web::error::Result"],["
§

impl From<Result> for Result<(), Unspecified>

§

fn from(ret: Result) -> Result<(), Unspecified>

Converts to this type from the input type.
","From","actix_web::error::Result"],["
source§

impl From<StreamResult> for Result<MZStatus, MZError>

source§

fn from(res: StreamResult) -> Result<MZStatus, MZError>

Converts to this type from the input type.
","From","actix_web::error::Result"],["
§

impl From<StreamResult> for Result<MZStatus, MZError>

§

fn from(res: StreamResult) -> Result<MZStatus, MZError>

Converts to this type from the input type.
","From","actix_web::error::Result"],["
1.0.0 · source§

impl<A, E, V> FromIterator<Result<A, E>> for Result<V, E>
where\n V: FromIterator<A>,

source§

fn from_iter<I>(iter: I) -> Result<V, E>
where\n I: IntoIterator<Item = Result<A, E>>,

Takes each element in the Iterator: if it is an Err, no further\nelements are taken, and the Err is returned. Should no Err occur, a\ncontainer with the values of each Result is returned.

\n

Here is an example which increments every integer in a vector,\nchecking for overflow:

\n\n
let v = vec![1, 2];\nlet res: Result<Vec<u32>, &'static str> = v.iter().map(|x: &u32|\n    x.checked_add(1).ok_or(\"Overflow!\")\n).collect();\nassert_eq!(res, Ok(vec![2, 3]));
\n

Here is another example that tries to subtract one from another list\nof integers, this time checking for underflow:

\n\n
let v = vec![1, 2, 0];\nlet res: Result<Vec<u32>, &'static str> = v.iter().map(|x: &u32|\n    x.checked_sub(1).ok_or(\"Underflow!\")\n).collect();\nassert_eq!(res, Err(\"Underflow!\"));
\n

Here is a variation on the previous example, showing that no\nfurther elements are taken from iter after the first Err.

\n\n
let v = vec![3, 2, 1, 10];\nlet mut shared = 0;\nlet res: Result<Vec<u32>, &'static str> = v.iter().map(|x: &u32| {\n    shared += x;\n    x.checked_sub(2).ok_or(\"Underflow!\")\n}).collect();\nassert_eq!(res, Err(\"Underflow!\"));\nassert_eq!(shared, 6);
\n

Since the third element caused an underflow, no further elements were taken,\nso the final value of shared is 6 (= 3 + 2 + 1), not 16.

\n
","FromIterator>","actix_web::error::Result","actix_web::cookie::time::Result"],["
source§

impl<T, E> FromRequest for Result<T, E>
where\n T: FromRequest,\n T::Error: Into<E>,

Extract from the request, passing error type through to handler.

\n

If the inner T::from_request returns an error, allow handler to receive the error rather than\nimmediately returning an error response.

\n

§Examples

\n
use actix_web::{web, dev, App, Result, Error, HttpRequest, FromRequest};\nuse actix_web::error::ErrorBadRequest;\nuse futures_util::future::{ok, err, Ready};\nuse serde::Deserialize;\nuse rand;\n\n#[derive(Debug, Deserialize)]\nstruct Thing {\n    name: String\n}\n\nimpl FromRequest for Thing {\n    type Error = Error;\n    type Future = Ready<Result<Thing, Error>>;\n\n    fn from_request(req: &HttpRequest, payload: &mut dev::Payload) -> Self::Future {\n        if rand::random() {\n            ok(Thing { name: \"thingy\".into() })\n        } else {\n            err(ErrorBadRequest(\"no luck\"))\n        }\n    }\n}\n\n/// extract `Thing` from request\nasync fn index(supplied_thing: Result<Thing>) -> String {\n    match supplied_thing {\n        Ok(thing) => format!(\"Got thing: {thing:?}\"),\n        Err(err) => format!(\"Error extracting thing: {err}\"),\n    }\n}\n\nlet app = App::new().service(\n    web::resource(\"/users/:first\").route(web::post().to(index))\n);
\n
§

type Error = Infallible

The associated error which can be returned.
§

type Future = FromRequestResFuture<<T as FromRequest>::Future, E>

Future that resolves to a Self. Read more
source§

fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future

Create a Self from request parts asynchronously.
source§

fn extract(req: &HttpRequest) -> Self::Future

Create a Self from request head asynchronously. Read more
","FromRequest","actix_web::error::Result","actix_web::cookie::time::Result"],["
source§

impl<T, E, F> FromResidual<Result<Infallible, E>> for Result<T, F>
where\n F: From<E>,

source§

fn from_residual(residual: Result<Infallible, E>) -> Result<T, F>

🔬This is a nightly-only experimental API. (try_trait_v2)
Constructs the type from a compatible Residual type. Read more
","FromResidual>","actix_web::error::Result","actix_web::cookie::time::Result"],["
source§

impl<T, E, F> FromResidual<Yeet<E>> for Result<T, F>
where\n F: From<E>,

source§

fn from_residual(_: Yeet<E>) -> Result<T, F>

🔬This is a nightly-only experimental API. (try_trait_v2)
Constructs the type from a compatible Residual type. Read more
","FromResidual>","actix_web::error::Result","actix_web::cookie::time::Result"],["
1.0.0 · source§

impl<T, E> Hash for Result<T, E>
where\n T: Hash,\n E: Hash,

source§

fn hash<__H>(&self, state: &mut __H)
where\n __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where\n H: Hasher,\n Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
","Hash","actix_web::error::Result","actix_web::cookie::time::Result"],["
1.0.0 · source§

impl<T, E> IntoIterator for Result<T, E>

source§

fn into_iter(self) -> IntoIter<T>

Returns a consuming iterator over the possibly contained value.

\n

The iterator yields one value if the result is Result::Ok, otherwise none.

\n
§Examples
\n
let x: Result<u32, &str> = Ok(5);\nlet v: Vec<u32> = x.into_iter().collect();\nassert_eq!(v, [5]);\n\nlet x: Result<u32, &str> = Err(\"nothing!\");\nlet v: Vec<u32> = x.into_iter().collect();\nassert_eq!(v, []);
\n
§

type Item = T

The type of the elements being iterated over.
§

type IntoIter = IntoIter<T>

Which kind of iterator are we turning this into?
","IntoIterator","actix_web::error::Result","actix_web::cookie::time::Result"],["
1.0.0 · source§

impl<T, E> Ord for Result<T, E>
where\n T: Ord,\n E: Ord,

source§

fn cmp(&self, other: &Result<T, E>) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where\n Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where\n Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where\n Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
","Ord","actix_web::error::Result","actix_web::cookie::time::Result"],["
1.0.0 · source§

impl<T, E> PartialEq for Result<T, E>
where\n T: PartialEq,\n E: PartialEq,

source§

fn eq(&self, other: &Result<T, E>) -> bool

This method tests for self and other values to be equal, and is used\nby ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always\nsufficient, and should not be overridden without very good reason.
","PartialEq","actix_web::error::Result","actix_web::cookie::time::Result"],["
1.0.0 · source§

impl<T, E> PartialOrd for Result<T, E>
where\n T: PartialOrd,\n E: PartialOrd,

source§

fn partial_cmp(&self, other: &Result<T, E>) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <=\noperator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >=\noperator. Read more
","PartialOrd","actix_web::error::Result","actix_web::cookie::time::Result"],["
1.16.0 · source§

impl<T, U, E> Product<Result<U, E>> for Result<T, E>
where\n T: Product<U>,

source§

fn product<I>(iter: I) -> Result<T, E>
where\n I: Iterator<Item = Result<U, E>>,

Takes each element in the Iterator: if it is an Err, no further\nelements are taken, and the Err is returned. Should no Err\noccur, the product of all elements is returned.

\n
§Examples
\n

This multiplies each number in a vector of strings,\nif a string could not be parsed the operation returns Err:

\n\n
let nums = vec![\"5\", \"10\", \"1\", \"2\"];\nlet total: Result<usize, _> = nums.iter().map(|w| w.parse::<usize>()).product();\nassert_eq!(total, Ok(100));\nlet nums = vec![\"5\", \"10\", \"one\", \"2\"];\nlet total: Result<usize, _> = nums.iter().map(|w| w.parse::<usize>()).product();\nassert!(total.is_err());
\n
","Product>","actix_web::error::Result","actix_web::cookie::time::Result"],["
source§

impl<T, E> Residual<T> for Result<Infallible, E>

§

type TryType = Result<T, E>

🔬This is a nightly-only experimental API. (try_trait_v2_residual)
The “return” type of this meta-function.
","Residual","actix_web::error::Result","actix_web::cookie::time::Result"],["
source§

impl<R, E> Responder for Result<R, E>
where\n R: Responder,\n E: Into<Error>,

§

type Body = EitherBody<<R as Responder>::Body>

source§

fn respond_to(self, req: &HttpRequest) -> HttpResponse<Self::Body>

Convert self to HttpResponse.
source§

fn customize(self) -> CustomizeResponder<Self>
where\n Self: Sized,

Wraps responder to allow alteration of its response. Read more
","Responder","actix_web::error::Result","actix_web::cookie::time::Result"],["
source§

impl<T, E> Result<&T, E>

1.59.0 · source

pub fn copied(self) -> Result<T, E>
where\n T: Copy,

Maps a Result<&T, E> to a Result<T, E> by copying the contents of the\nOk part.

\n
§Examples
\n
let val = 12;\nlet x: Result<&i32, i32> = Ok(&val);\nassert_eq!(x, Ok(&12));\nlet copied = x.copied();\nassert_eq!(copied, Ok(12));
\n
1.59.0 · source

pub fn cloned(self) -> Result<T, E>
where\n T: Clone,

Maps a Result<&T, E> to a Result<T, E> by cloning the contents of the\nOk part.

\n
§Examples
\n
let val = 12;\nlet x: Result<&i32, i32> = Ok(&val);\nassert_eq!(x, Ok(&12));\nlet cloned = x.cloned();\nassert_eq!(cloned, Ok(12));
\n
",0,"actix_web::error::Result","actix_web::cookie::time::Result"],["
source§

impl<T, E> Result<&mut T, E>

1.59.0 · source

pub fn copied(self) -> Result<T, E>
where\n T: Copy,

Maps a Result<&mut T, E> to a Result<T, E> by copying the contents of the\nOk part.

\n
§Examples
\n
let mut val = 12;\nlet x: Result<&mut i32, i32> = Ok(&mut val);\nassert_eq!(x, Ok(&mut 12));\nlet copied = x.copied();\nassert_eq!(copied, Ok(12));
\n
1.59.0 · source

pub fn cloned(self) -> Result<T, E>
where\n T: Clone,

Maps a Result<&mut T, E> to a Result<T, E> by cloning the contents of the\nOk part.

\n
§Examples
\n
let mut val = 12;\nlet x: Result<&mut i32, i32> = Ok(&mut val);\nassert_eq!(x, Ok(&mut 12));\nlet cloned = x.cloned();\nassert_eq!(cloned, Ok(12));
\n
",0,"actix_web::error::Result","actix_web::cookie::time::Result"],["
source§

impl<T, E> Result<Option<T>, E>

1.33.0 (const: unstable) · source

pub fn transpose(self) -> Option<Result<T, E>>

Transposes a Result of an Option into an Option of a Result.

\n

Ok(None) will be mapped to None.\nOk(Some(_)) and Err(_) will be mapped to Some(Ok(_)) and Some(Err(_)).

\n
§Examples
\n
#[derive(Debug, Eq, PartialEq)]\nstruct SomeErr;\n\nlet x: Result<Option<i32>, SomeErr> = Ok(Some(5));\nlet y: Option<Result<i32, SomeErr>> = Some(Ok(5));\nassert_eq!(x.transpose(), y);
\n
",0,"actix_web::error::Result","actix_web::cookie::time::Result"],["
source§

impl<T, E> Result<Result<T, E>, E>

source

pub fn flatten(self) -> Result<T, E>

🔬This is a nightly-only experimental API. (result_flattening)

Converts from Result<Result<T, E>, E> to Result<T, E>

\n
§Examples
\n
#![feature(result_flattening)]\nlet x: Result<Result<&'static str, u32>, u32> = Ok(Ok(\"hello\"));\nassert_eq!(Ok(\"hello\"), x.flatten());\n\nlet x: Result<Result<&'static str, u32>, u32> = Ok(Err(6));\nassert_eq!(Err(6), x.flatten());\n\nlet x: Result<Result<&'static str, u32>, u32> = Err(6);\nassert_eq!(Err(6), x.flatten());
\n

Flattening only removes one level of nesting at a time:

\n\n
#![feature(result_flattening)]\nlet x: Result<Result<Result<&'static str, u32>, u32>, u32> = Ok(Ok(Ok(\"hello\")));\nassert_eq!(Ok(Ok(\"hello\")), x.flatten());\nassert_eq!(Ok(\"hello\"), x.flatten().flatten());
\n
",0,"actix_web::error::Result","actix_web::cookie::time::Result"],["
source§

impl<T, E> Result<T, E>

1.0.0 (const: 1.48.0) · source

pub const fn is_ok(&self) -> bool

Returns true if the result is Ok.

\n
§Examples
\n
let x: Result<i32, &str> = Ok(-3);\nassert_eq!(x.is_ok(), true);\n\nlet x: Result<i32, &str> = Err(\"Some error message\");\nassert_eq!(x.is_ok(), false);
\n
1.70.0 · source

pub fn is_ok_and(self, f: impl FnOnce(T) -> bool) -> bool

Returns true if the result is Ok and the value inside of it matches a predicate.

\n
§Examples
\n
let x: Result<u32, &str> = Ok(2);\nassert_eq!(x.is_ok_and(|x| x > 1), true);\n\nlet x: Result<u32, &str> = Ok(0);\nassert_eq!(x.is_ok_and(|x| x > 1), false);\n\nlet x: Result<u32, &str> = Err(\"hey\");\nassert_eq!(x.is_ok_and(|x| x > 1), false);
\n
1.0.0 (const: 1.48.0) · source

pub const fn is_err(&self) -> bool

Returns true if the result is Err.

\n
§Examples
\n
let x: Result<i32, &str> = Ok(-3);\nassert_eq!(x.is_err(), false);\n\nlet x: Result<i32, &str> = Err(\"Some error message\");\nassert_eq!(x.is_err(), true);
\n
1.70.0 · source

pub fn is_err_and(self, f: impl FnOnce(E) -> bool) -> bool

Returns true if the result is Err and the value inside of it matches a predicate.

\n
§Examples
\n
use std::io::{Error, ErrorKind};\n\nlet x: Result<u32, Error> = Err(Error::new(ErrorKind::NotFound, \"!\"));\nassert_eq!(x.is_err_and(|x| x.kind() == ErrorKind::NotFound), true);\n\nlet x: Result<u32, Error> = Err(Error::new(ErrorKind::PermissionDenied, \"!\"));\nassert_eq!(x.is_err_and(|x| x.kind() == ErrorKind::NotFound), false);\n\nlet x: Result<u32, Error> = Ok(123);\nassert_eq!(x.is_err_and(|x| x.kind() == ErrorKind::NotFound), false);
\n
1.0.0 · source

pub fn ok(self) -> Option<T>

Converts from Result<T, E> to Option<T>.

\n

Converts self into an Option<T>, consuming self,\nand discarding the error, if any.

\n
§Examples
\n
let x: Result<u32, &str> = Ok(2);\nassert_eq!(x.ok(), Some(2));\n\nlet x: Result<u32, &str> = Err(\"Nothing here\");\nassert_eq!(x.ok(), None);
\n
1.0.0 · source

pub fn err(self) -> Option<E>

Converts from Result<T, E> to Option<E>.

\n

Converts self into an Option<E>, consuming self,\nand discarding the success value, if any.

\n
§Examples
\n
let x: Result<u32, &str> = Ok(2);\nassert_eq!(x.err(), None);\n\nlet x: Result<u32, &str> = Err(\"Nothing here\");\nassert_eq!(x.err(), Some(\"Nothing here\"));
\n
1.0.0 (const: 1.48.0) · source

pub const fn as_ref(&self) -> Result<&T, &E>

Converts from &Result<T, E> to Result<&T, &E>.

\n

Produces a new Result, containing a reference\ninto the original, leaving the original in place.

\n
§Examples
\n
let x: Result<u32, &str> = Ok(2);\nassert_eq!(x.as_ref(), Ok(&2));\n\nlet x: Result<u32, &str> = Err(\"Error\");\nassert_eq!(x.as_ref(), Err(&\"Error\"));
\n
1.0.0 (const: unstable) · source

pub fn as_mut(&mut self) -> Result<&mut T, &mut E>

Converts from &mut Result<T, E> to Result<&mut T, &mut E>.

\n
§Examples
\n
fn mutate(r: &mut Result<i32, i32>) {\n    match r.as_mut() {\n        Ok(v) => *v = 42,\n        Err(e) => *e = 0,\n    }\n}\n\nlet mut x: Result<i32, i32> = Ok(2);\nmutate(&mut x);\nassert_eq!(x.unwrap(), 42);\n\nlet mut x: Result<i32, i32> = Err(13);\nmutate(&mut x);\nassert_eq!(x.unwrap_err(), 0);
\n
1.0.0 · source

pub fn map<U, F>(self, op: F) -> Result<U, E>
where\n F: FnOnce(T) -> U,

Maps a Result<T, E> to Result<U, E> by applying a function to a\ncontained Ok value, leaving an Err value untouched.

\n

This function can be used to compose the results of two functions.

\n
§Examples
\n

Print the numbers on each line of a string multiplied by two.

\n\n
let line = \"1\\n2\\n3\\n4\\n\";\n\nfor num in line.lines() {\n    match num.parse::<i32>().map(|i| i * 2) {\n        Ok(n) => println!(\"{n}\"),\n        Err(..) => {}\n    }\n}
\n
1.41.0 · source

pub fn map_or<U, F>(self, default: U, f: F) -> U
where\n F: FnOnce(T) -> U,

Returns the provided default (if Err), or\napplies a function to the contained value (if Ok).

\n

Arguments passed to map_or are eagerly evaluated; if you are passing\nthe result of a function call, it is recommended to use map_or_else,\nwhich is lazily evaluated.

\n
§Examples
\n
let x: Result<_, &str> = Ok(\"foo\");\nassert_eq!(x.map_or(42, |v| v.len()), 3);\n\nlet x: Result<&str, _> = Err(\"bar\");\nassert_eq!(x.map_or(42, |v| v.len()), 42);
\n
1.41.0 · source

pub fn map_or_else<U, D, F>(self, default: D, f: F) -> U
where\n D: FnOnce(E) -> U,\n F: FnOnce(T) -> U,

Maps a Result<T, E> to U by applying fallback function default to\na contained Err value, or function f to a contained Ok value.

\n

This function can be used to unpack a successful result\nwhile handling an error.

\n
§Examples
\n
let k = 21;\n\nlet x : Result<_, &str> = Ok(\"foo\");\nassert_eq!(x.map_or_else(|e| k * 2, |v| v.len()), 3);\n\nlet x : Result<&str, _> = Err(\"bar\");\nassert_eq!(x.map_or_else(|e| k * 2, |v| v.len()), 42);
\n
1.0.0 · source

pub fn map_err<F, O>(self, op: O) -> Result<T, F>
where\n O: FnOnce(E) -> F,

Maps a Result<T, E> to Result<T, F> by applying a function to a\ncontained Err value, leaving an Ok value untouched.

\n

This function can be used to pass through a successful result while handling\nan error.

\n
§Examples
\n
fn stringify(x: u32) -> String { format!(\"error code: {x}\") }\n\nlet x: Result<u32, u32> = Ok(2);\nassert_eq!(x.map_err(stringify), Ok(2));\n\nlet x: Result<u32, u32> = Err(13);\nassert_eq!(x.map_err(stringify), Err(\"error code: 13\".to_string()));
\n
1.76.0 · source

pub fn inspect<F>(self, f: F) -> Result<T, E>
where\n F: FnOnce(&T),

Calls a function with a reference to the contained value if Ok.

\n

Returns the original result.

\n
§Examples
\n
let x: u8 = \"4\"\n    .parse::<u8>()\n    .inspect(|x| println!(\"original: {x}\"))\n    .map(|x| x.pow(3))\n    .expect(\"failed to parse number\");
\n
1.76.0 · source

pub fn inspect_err<F>(self, f: F) -> Result<T, E>
where\n F: FnOnce(&E),

Calls a function with a reference to the contained value if Err.

\n

Returns the original result.

\n
§Examples
\n
use std::{fs, io};\n\nfn read() -> io::Result<String> {\n    fs::read_to_string(\"address.txt\")\n        .inspect_err(|e| eprintln!(\"failed to read file: {e}\"))\n}
\n
1.47.0 · source

pub fn as_deref(&self) -> Result<&<T as Deref>::Target, &E>
where\n T: Deref,

Converts from Result<T, E> (or &Result<T, E>) to Result<&<T as Deref>::Target, &E>.

\n

Coerces the Ok variant of the original Result via Deref\nand returns the new Result.

\n
§Examples
\n
let x: Result<String, u32> = Ok(\"hello\".to_string());\nlet y: Result<&str, &u32> = Ok(\"hello\");\nassert_eq!(x.as_deref(), y);\n\nlet x: Result<String, u32> = Err(42);\nlet y: Result<&str, &u32> = Err(&42);\nassert_eq!(x.as_deref(), y);
\n
1.47.0 · source

pub fn as_deref_mut(&mut self) -> Result<&mut <T as Deref>::Target, &mut E>
where\n T: DerefMut,

Converts from Result<T, E> (or &mut Result<T, E>) to Result<&mut <T as DerefMut>::Target, &mut E>.

\n

Coerces the Ok variant of the original Result via DerefMut\nand returns the new Result.

\n
§Examples
\n
let mut s = \"HELLO\".to_string();\nlet mut x: Result<String, u32> = Ok(\"hello\".to_string());\nlet y: Result<&mut str, &mut u32> = Ok(&mut s);\nassert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y);\n\nlet mut i = 42;\nlet mut x: Result<String, u32> = Err(42);\nlet y: Result<&mut str, &mut u32> = Err(&mut i);\nassert_eq!(x.as_deref_mut().map(|x| { x.make_ascii_uppercase(); x }), y);
\n
1.0.0 · source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the possibly contained value.

\n

The iterator yields one value if the result is Result::Ok, otherwise none.

\n
§Examples
\n
let x: Result<u32, &str> = Ok(7);\nassert_eq!(x.iter().next(), Some(&7));\n\nlet x: Result<u32, &str> = Err(\"nothing!\");\nassert_eq!(x.iter().next(), None);
\n
1.0.0 · source

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Returns a mutable iterator over the possibly contained value.

\n

The iterator yields one value if the result is Result::Ok, otherwise none.

\n
§Examples
\n
let mut x: Result<u32, &str> = Ok(7);\nmatch x.iter_mut().next() {\n    Some(v) => *v = 40,\n    None => {},\n}\nassert_eq!(x, Ok(40));\n\nlet mut x: Result<u32, &str> = Err(\"nothing!\");\nassert_eq!(x.iter_mut().next(), None);
\n
1.4.0 · source

pub fn expect(self, msg: &str) -> T
where\n E: Debug,

Returns the contained Ok value, consuming the self value.

\n

Because this function may panic, its use is generally discouraged.\nInstead, prefer to use pattern matching and handle the Err\ncase explicitly, or call unwrap_or, unwrap_or_else, or\nunwrap_or_default.

\n
§Panics
\n

Panics if the value is an Err, with a panic message including the\npassed message, and the content of the Err.

\n
§Examples
\n
let x: Result<u32, &str> = Err(\"emergency failure\");\nx.expect(\"Testing expect\"); // panics with `Testing expect: emergency failure`
\n
§Recommended Message Style
\n

We recommend that expect messages are used to describe the reason you\nexpect the Result should be Ok.

\n\n
let path = std::env::var(\"IMPORTANT_PATH\")\n    .expect(\"env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`\");
\n

Hint: If you’re having trouble remembering how to phrase expect\nerror messages remember to focus on the word “should” as in “env\nvariable should be set by blah” or “the given binary should be available\nand executable by the current user”.

\n

For more detail on expect message styles and the reasoning behind our recommendation please\nrefer to the section on “Common Message\nStyles” in the\nstd::error module docs.

\n
1.0.0 · source

pub fn unwrap(self) -> T
where\n E: Debug,

Returns the contained Ok value, consuming the self value.

\n

Because this function may panic, its use is generally discouraged.\nInstead, prefer to use pattern matching and handle the Err\ncase explicitly, or call unwrap_or, unwrap_or_else, or\nunwrap_or_default.

\n
§Panics
\n

Panics if the value is an Err, with a panic message provided by the\nErr’s value.

\n
§Examples
\n

Basic usage:

\n\n
let x: Result<u32, &str> = Ok(2);\nassert_eq!(x.unwrap(), 2);
\n\n
let x: Result<u32, &str> = Err(\"emergency failure\");\nx.unwrap(); // panics with `emergency failure`
\n
1.16.0 · source

pub fn unwrap_or_default(self) -> T
where\n T: Default,

Returns the contained Ok value or a default

\n

Consumes the self argument then, if Ok, returns the contained\nvalue, otherwise if Err, returns the default value for that\ntype.

\n
§Examples
\n

Converts a string to an integer, turning poorly-formed strings\ninto 0 (the default value for integers). parse converts\na string to any other type that implements FromStr, returning an\nErr on error.

\n\n
let good_year_from_input = \"1909\";\nlet bad_year_from_input = \"190blarg\";\nlet good_year = good_year_from_input.parse().unwrap_or_default();\nlet bad_year = bad_year_from_input.parse().unwrap_or_default();\n\nassert_eq!(1909, good_year);\nassert_eq!(0, bad_year);
\n
1.17.0 · source

pub fn expect_err(self, msg: &str) -> E
where\n T: Debug,

Returns the contained Err value, consuming the self value.

\n
§Panics
\n

Panics if the value is an Ok, with a panic message including the\npassed message, and the content of the Ok.

\n
§Examples
\n
let x: Result<u32, &str> = Ok(10);\nx.expect_err(\"Testing expect_err\"); // panics with `Testing expect_err: 10`
\n
1.0.0 · source

pub fn unwrap_err(self) -> E
where\n T: Debug,

Returns the contained Err value, consuming the self value.

\n
§Panics
\n

Panics if the value is an Ok, with a custom panic message provided\nby the Ok’s value.

\n
§Examples
\n
let x: Result<u32, &str> = Ok(2);\nx.unwrap_err(); // panics with `2`
\n\n
let x: Result<u32, &str> = Err(\"emergency failure\");\nassert_eq!(x.unwrap_err(), \"emergency failure\");
\n
source

pub fn into_ok(self) -> T
where\n E: Into<!>,

🔬This is a nightly-only experimental API. (unwrap_infallible)

Returns the contained Ok value, but never panics.

\n

Unlike unwrap, this method is known to never panic on the\nresult types it is implemented for. Therefore, it can be used\ninstead of unwrap as a maintainability safeguard that will fail\nto compile if the error type of the Result is later changed\nto an error that can actually occur.

\n
§Examples
\n
\nfn only_good_news() -> Result<String, !> {\n    Ok(\"this is fine\".into())\n}\n\nlet s: String = only_good_news().into_ok();\nprintln!(\"{s}\");
\n
source

pub fn into_err(self) -> E
where\n T: Into<!>,

🔬This is a nightly-only experimental API. (unwrap_infallible)

Returns the contained Err value, but never panics.

\n

Unlike unwrap_err, this method is known to never panic on the\nresult types it is implemented for. Therefore, it can be used\ninstead of unwrap_err as a maintainability safeguard that will fail\nto compile if the ok type of the Result is later changed\nto a type that can actually occur.

\n
§Examples
\n
\nfn only_bad_news() -> Result<!, String> {\n    Err(\"Oops, it failed\".into())\n}\n\nlet error: String = only_bad_news().into_err();\nprintln!(\"{error}\");
\n
1.0.0 · source

pub fn and<U>(self, res: Result<U, E>) -> Result<U, E>

Returns res if the result is Ok, otherwise returns the Err value of self.

\n

Arguments passed to and are eagerly evaluated; if you are passing the\nresult of a function call, it is recommended to use and_then, which is\nlazily evaluated.

\n
§Examples
\n
let x: Result<u32, &str> = Ok(2);\nlet y: Result<&str, &str> = Err(\"late error\");\nassert_eq!(x.and(y), Err(\"late error\"));\n\nlet x: Result<u32, &str> = Err(\"early error\");\nlet y: Result<&str, &str> = Ok(\"foo\");\nassert_eq!(x.and(y), Err(\"early error\"));\n\nlet x: Result<u32, &str> = Err(\"not a 2\");\nlet y: Result<&str, &str> = Err(\"late error\");\nassert_eq!(x.and(y), Err(\"not a 2\"));\n\nlet x: Result<u32, &str> = Ok(2);\nlet y: Result<&str, &str> = Ok(\"different result type\");\nassert_eq!(x.and(y), Ok(\"different result type\"));
\n
1.0.0 · source

pub fn and_then<U, F>(self, op: F) -> Result<U, E>
where\n F: FnOnce(T) -> Result<U, E>,

Calls op if the result is Ok, otherwise returns the Err value of self.

\n

This function can be used for control flow based on Result values.

\n
§Examples
\n
fn sq_then_to_string(x: u32) -> Result<String, &'static str> {\n    x.checked_mul(x).map(|sq| sq.to_string()).ok_or(\"overflowed\")\n}\n\nassert_eq!(Ok(2).and_then(sq_then_to_string), Ok(4.to_string()));\nassert_eq!(Ok(1_000_000).and_then(sq_then_to_string), Err(\"overflowed\"));\nassert_eq!(Err(\"not a number\").and_then(sq_then_to_string), Err(\"not a number\"));
\n

Often used to chain fallible operations that may return Err.

\n\n
use std::{io::ErrorKind, path::Path};\n\n// Note: on Windows \"/\" maps to \"C:\\\"\nlet root_modified_time = Path::new(\"/\").metadata().and_then(|md| md.modified());\nassert!(root_modified_time.is_ok());\n\nlet should_fail = Path::new(\"/bad/path\").metadata().and_then(|md| md.modified());\nassert!(should_fail.is_err());\nassert_eq!(should_fail.unwrap_err().kind(), ErrorKind::NotFound);
\n
1.0.0 · source

pub fn or<F>(self, res: Result<T, F>) -> Result<T, F>

Returns res if the result is Err, otherwise returns the Ok value of self.

\n

Arguments passed to or are eagerly evaluated; if you are passing the\nresult of a function call, it is recommended to use or_else, which is\nlazily evaluated.

\n
§Examples
\n
let x: Result<u32, &str> = Ok(2);\nlet y: Result<u32, &str> = Err(\"late error\");\nassert_eq!(x.or(y), Ok(2));\n\nlet x: Result<u32, &str> = Err(\"early error\");\nlet y: Result<u32, &str> = Ok(2);\nassert_eq!(x.or(y), Ok(2));\n\nlet x: Result<u32, &str> = Err(\"not a 2\");\nlet y: Result<u32, &str> = Err(\"late error\");\nassert_eq!(x.or(y), Err(\"late error\"));\n\nlet x: Result<u32, &str> = Ok(2);\nlet y: Result<u32, &str> = Ok(100);\nassert_eq!(x.or(y), Ok(2));
\n
1.0.0 · source

pub fn or_else<F, O>(self, op: O) -> Result<T, F>
where\n O: FnOnce(E) -> Result<T, F>,

Calls op if the result is Err, otherwise returns the Ok value of self.

\n

This function can be used for control flow based on result values.

\n
§Examples
\n
fn sq(x: u32) -> Result<u32, u32> { Ok(x * x) }\nfn err(x: u32) -> Result<u32, u32> { Err(x) }\n\nassert_eq!(Ok(2).or_else(sq).or_else(sq), Ok(2));\nassert_eq!(Ok(2).or_else(err).or_else(sq), Ok(2));\nassert_eq!(Err(3).or_else(sq).or_else(err), Ok(9));\nassert_eq!(Err(3).or_else(err).or_else(err), Err(3));
\n
1.0.0 · source

pub fn unwrap_or(self, default: T) -> T

Returns the contained Ok value or a provided default.

\n

Arguments passed to unwrap_or are eagerly evaluated; if you are passing\nthe result of a function call, it is recommended to use unwrap_or_else,\nwhich is lazily evaluated.

\n
§Examples
\n
let default = 2;\nlet x: Result<u32, &str> = Ok(9);\nassert_eq!(x.unwrap_or(default), 9);\n\nlet x: Result<u32, &str> = Err(\"error\");\nassert_eq!(x.unwrap_or(default), default);
\n
1.0.0 · source

pub fn unwrap_or_else<F>(self, op: F) -> T
where\n F: FnOnce(E) -> T,

Returns the contained Ok value or computes it from a closure.

\n
§Examples
\n
fn count(x: &str) -> usize { x.len() }\n\nassert_eq!(Ok(2).unwrap_or_else(count), 2);\nassert_eq!(Err(\"foo\").unwrap_or_else(count), 3);
\n
1.58.0 · source

pub unsafe fn unwrap_unchecked(self) -> T

Returns the contained Ok value, consuming the self value,\nwithout checking that the value is not an Err.

\n
§Safety
\n

Calling this method on an Err is undefined behavior.

\n
§Examples
\n
let x: Result<u32, &str> = Ok(2);\nassert_eq!(unsafe { x.unwrap_unchecked() }, 2);
\n\n
let x: Result<u32, &str> = Err(\"emergency failure\");\nunsafe { x.unwrap_unchecked(); } // Undefined behavior!
\n
1.58.0 · source

pub unsafe fn unwrap_err_unchecked(self) -> E

Returns the contained Err value, consuming the self value,\nwithout checking that the value is not an Ok.

\n
§Safety
\n

Calling this method on an Ok is undefined behavior.

\n
§Examples
\n
let x: Result<u32, &str> = Ok(2);\nunsafe { x.unwrap_err_unchecked() }; // Undefined behavior!
\n\n
let x: Result<u32, &str> = Err(\"emergency failure\");\nassert_eq!(unsafe { x.unwrap_err_unchecked() }, \"emergency failure\");
\n
",0,"actix_web::error::Result","actix_web::cookie::time::Result"],["
source§

impl<T, E> Serialize for Result<T, E>
where\n T: Serialize,\n E: Serialize,

source§

fn serialize<S>(\n &self,\n serializer: S\n) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where\n S: Serializer,

Serialize this value into the given Serde serializer. Read more
","Serialize","actix_web::error::Result","actix_web::cookie::time::Result"],["
1.16.0 · source§

impl<T, U, E> Sum<Result<U, E>> for Result<T, E>
where\n T: Sum<U>,

source§

fn sum<I>(iter: I) -> Result<T, E>
where\n I: Iterator<Item = Result<U, E>>,

Takes each element in the Iterator: if it is an Err, no further\nelements are taken, and the Err is returned. Should no Err\noccur, the sum of all elements is returned.

\n
§Examples
\n

This sums up every integer in a vector, rejecting the sum if a negative\nelement is encountered:

\n\n
let f = |&x: &i32| if x < 0 { Err(\"Negative element found\") } else { Ok(x) };\nlet v = vec![1, 2];\nlet res: Result<i32, _> = v.iter().map(f).sum();\nassert_eq!(res, Ok(3));\nlet v = vec![1, -2];\nlet res: Result<i32, _> = v.iter().map(f).sum();\nassert_eq!(res, Err(\"Negative element found\"));
\n
","Sum>","actix_web::error::Result","actix_web::cookie::time::Result"],["
1.61.0 · source§

impl<T, E> Termination for Result<T, E>
where\n T: Termination,\n E: Debug,

source§

fn report(self) -> ExitCode

Is called to get the representation of the value as status code.\nThis status code is returned to the operating system.
","Termination","actix_web::error::Result","actix_web::cookie::time::Result"],["
source§

impl<T, E> Try for Result<T, E>

§

type Output = T

🔬This is a nightly-only experimental API. (try_trait_v2)
The type of the value produced by ? when not short-circuiting.
§

type Residual = Result<Infallible, E>

🔬This is a nightly-only experimental API. (try_trait_v2)
The type of the value passed to FromResidual::from_residual\nas part of ? when short-circuiting. Read more
source§

fn from_output(output: <Result<T, E> as Try>::Output) -> Result<T, E>

🔬This is a nightly-only experimental API. (try_trait_v2)
Constructs the type from its Output type. Read more
source§

fn branch(\n self\n) -> ControlFlow<<Result<T, E> as Try>::Residual, <Result<T, E> as Try>::Output>

🔬This is a nightly-only experimental API. (try_trait_v2)
Used in ? to decide whether the operator should produce a value\n(because this returned ControlFlow::Continue)\nor propagate a value back to the caller\n(because this returned ControlFlow::Break). Read more
","Try","actix_web::error::Result","actix_web::cookie::time::Result"],["
1.0.0 · source§

impl<T, E> Copy for Result<T, E>
where\n T: Copy,\n E: Copy,

","Copy","actix_web::error::Result","actix_web::cookie::time::Result"],["
1.0.0 · source§

impl<T, E> Eq for Result<T, E>
where\n T: Eq,\n E: Eq,

","Eq","actix_web::error::Result","actix_web::cookie::time::Result"],["
1.0.0 · source§

impl<T, E> StructuralPartialEq for Result<T, E>

","StructuralPartialEq","actix_web::error::Result","actix_web::cookie::time::Result"]] +};if (window.register_type_impls) {window.register_type_impls(type_impls);} else {window.pending_type_impls = type_impls;}})() \ No newline at end of file diff --git a/type.impl/std/primitive.u128.js b/type.impl/std/primitive.u128.js new file mode 100644 index 000000000..28ed6aafb --- /dev/null +++ b/type.impl/std/primitive.u128.js @@ -0,0 +1,3 @@ +(function() {var type_impls = { +"actix_web":[] +};if (window.register_type_impls) {window.register_type_impls(type_impls);} else {window.pending_type_impls = type_impls;}})() \ No newline at end of file